summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/README4
-rw-r--r--[-rwxr-xr-x]generic/default.h0
-rw-r--r--generic/prolog.ps283
-rw-r--r--generic/tk.decls99
-rw-r--r--generic/tk.h1053
-rw-r--r--generic/tk3d.c667
-rw-r--r--generic/tk3d.h74
-rw-r--r--generic/tkArgv.c467
-rw-r--r--generic/tkAtom.c135
-rw-r--r--generic/tkBind.c3472
-rw-r--r--generic/tkBitmap.c808
-rw-r--r--generic/tkButton.c891
-rw-r--r--generic/tkButton.h244
-rw-r--r--generic/tkCanvArc.c979
-rw-r--r--generic/tkCanvBmap.c518
-rw-r--r--generic/tkCanvImg.c526
-rw-r--r--generic/tkCanvLine.c1110
-rw-r--r--generic/tkCanvPoly.c934
-rw-r--r--generic/tkCanvPs.c1550
-rw-r--r--generic/tkCanvText.c747
-rw-r--r--generic/tkCanvUtil.c1304
-rw-r--r--generic/tkCanvWind.c622
-rw-r--r--generic/tkCanvas.c3552
-rw-r--r--generic/tkCanvas.h257
-rw-r--r--generic/tkClipboard.c566
-rw-r--r--generic/tkCmds.c2060
-rw-r--r--[-rwxr-xr-x]generic/tkColor.c126
-rw-r--r--generic/tkColor.h72
-rw-r--r--generic/tkConfig.c1955
-rw-r--r--generic/tkConsole.c387
-rw-r--r--generic/tkCursor.c495
-rw-r--r--generic/tkDecls.h2458
-rw-r--r--generic/tkEntry.c3403
-rw-r--r--generic/tkEntry.h189
-rw-r--r--generic/tkError.c225
-rw-r--r--generic/tkEvent.c2008
-rw-r--r--generic/tkFileFilter.c383
-rw-r--r--generic/tkFileFilter.h84
-rw-r--r--generic/tkFocus.c779
-rw-r--r--generic/tkFont.c2347
-rw-r--r--generic/tkFont.h154
-rw-r--r--generic/tkFrame.c1197
-rw-r--r--generic/tkGC.c148
-rw-r--r--generic/tkGeometry.c342
-rw-r--r--generic/tkGet.c503
-rw-r--r--generic/tkGrab.c963
-rw-r--r--generic/tkGrid.c2546
-rw-r--r--generic/tkImage.c947
-rw-r--r--generic/tkImgBmap.c597
-rw-r--r--generic/tkImgGIF.c1954
-rw-r--r--generic/tkImgPPM.c373
-rw-r--r--generic/tkImgPhoto.c3228
-rw-r--r--generic/tkImgUtil.c37
-rw-r--r--generic/tkInitScript.h56
-rw-r--r--generic/tkInt.decls125
-rw-r--r--generic/tkInt.h1196
-rw-r--r--generic/tkIntDecls.h1427
-rw-r--r--generic/tkIntPlatDecls.h837
-rw-r--r--generic/tkIntXlibDecls.h1820
-rw-r--r--generic/tkListbox.c2531
-rw-r--r--generic/tkMacWinMenu.c139
-rw-r--r--generic/tkMain.c295
-rw-r--r--[-rwxr-xr-x]generic/tkMenu.c2452
-rw-r--r--generic/tkMenu.h543
-rw-r--r--generic/tkMenuDraw.c443
-rw-r--r--generic/tkMenubutton.c493
-rw-r--r--generic/tkMenubutton.h191
-rw-r--r--generic/tkMessage.c387
-rw-r--r--generic/tkObj.c685
-rw-r--r--generic/tkOldConfig.c1084
-rw-r--r--generic/tkOldTest.c404
-rw-r--r--generic/tkOption.c931
-rw-r--r--generic/tkPack.c879
-rw-r--r--generic/tkPanedWindow.c1912
-rw-r--r--generic/tkPlace.c819
-rw-r--r--generic/tkPlatDecls.h132
-rw-r--r--generic/tkPointer.c301
-rw-r--r--generic/tkRectOval.c808
-rw-r--r--generic/tkScale.c818
-rw-r--r--generic/tkScale.h178
-rw-r--r--generic/tkScrollbar.c293
-rw-r--r--generic/tkScrollbar.h169
-rw-r--r--generic/tkSelect.c1183
-rw-r--r--generic/tkSelect.h180
-rw-r--r--generic/tkSquare.c337
-rw-r--r--generic/tkStubImg.c74
-rw-r--r--generic/tkStubInit.c78
-rw-r--r--generic/tkStubLib.c28
-rw-r--r--generic/tkStyle.c827
-rw-r--r--generic/tkTest.c2280
-rw-r--r--generic/tkText.c6920
-rw-r--r--generic/tkText.h1430
-rw-r--r--generic/tkTextBTree.c3106
-rw-r--r--generic/tkTextDisp.c6879
-rw-r--r--generic/tkTextImage.c804
-rw-r--r--generic/tkTextIndex.c1716
-rw-r--r--generic/tkTextMark.c841
-rw-r--r--generic/tkTextTag.c1526
-rw-r--r--generic/tkTextWind.c1322
-rw-r--r--generic/tkTrig.c992
-rw-r--r--generic/tkUndo.c725
-rw-r--r--generic/tkUndo.h133
-rw-r--r--generic/tkUtil.c1022
-rw-r--r--generic/tkVisual.c288
-rw-r--r--generic/tkWindow.c1772
-rw-r--r--generic/ttk/ttk.decls150
-rw-r--r--generic/ttk/ttkBlink.c166
-rw-r--r--generic/ttk/ttkButton.c853
-rw-r--r--generic/ttk/ttkCache.c350
-rw-r--r--generic/ttk/ttkClamTheme.c971
-rw-r--r--generic/ttk/ttkClassicTheme.c513
-rw-r--r--generic/ttk/ttkDecls.h272
-rw-r--r--generic/ttk/ttkDefaultTheme.c1130
-rw-r--r--generic/ttk/ttkElements.c1281
-rw-r--r--generic/ttk/ttkEntry.c2048
-rw-r--r--generic/ttk/ttkFrame.c654
-rw-r--r--generic/ttk/ttkGenStubs.tcl921
-rw-r--r--generic/ttk/ttkImage.c415
-rw-r--r--generic/ttk/ttkInit.c282
-rw-r--r--generic/ttk/ttkLabel.c693
-rw-r--r--generic/ttk/ttkLayout.c1252
-rw-r--r--generic/ttk/ttkManager.c552
-rw-r--r--generic/ttk/ttkManager.h92
-rw-r--r--generic/ttk/ttkNotebook.c1413
-rw-r--r--generic/ttk/ttkPanedwindow.c975
-rw-r--r--generic/ttk/ttkProgress.c545
-rw-r--r--generic/ttk/ttkScale.c515
-rw-r--r--generic/ttk/ttkScroll.c252
-rw-r--r--generic/ttk/ttkScrollbar.c345
-rw-r--r--generic/ttk/ttkSeparator.c136
-rw-r--r--generic/ttk/ttkSquare.c301
-rw-r--r--generic/ttk/ttkState.c273
-rw-r--r--generic/ttk/ttkStubInit.c61
-rw-r--r--generic/ttk/ttkStubLib.c74
-rw-r--r--generic/ttk/ttkTagSet.c306
-rw-r--r--generic/ttk/ttkTheme.c1737
-rw-r--r--generic/ttk/ttkTheme.h444
-rw-r--r--generic/ttk/ttkThemeInt.h42
-rw-r--r--generic/ttk/ttkTrace.c190
-rw-r--r--generic/ttk/ttkTrack.c183
-rw-r--r--generic/ttk/ttkTreeview.c3442
-rw-r--r--generic/ttk/ttkWidget.c789
-rw-r--r--generic/ttk/ttkWidget.h273
143 files changed, 85921 insertions, 46603 deletions
diff --git a/generic/README b/generic/README
index 285127c..6ac6bb4 100644
--- a/generic/README
+++ b/generic/README
@@ -1,3 +1,3 @@
This directory contains Tk source files that work on all the platforms
-where Tk runs (e.g. UNIX, PCs, and Macintoshes). Platform-specific
-sources are in the directories ../unix, ../win, ../macosx, and ../mac.
+where Tk runs (e.g. UNIX, PCs, and MacOSX). Platform-specific
+sources are in the directories ../unix, ../win, and ../macosx.
diff --git a/generic/default.h b/generic/default.h
index 6156f4d..6156f4d 100755..100644
--- a/generic/default.h
+++ b/generic/default.h
diff --git a/generic/prolog.ps b/generic/prolog.ps
deleted file mode 100644
index 4076282..0000000
--- a/generic/prolog.ps
+++ /dev/null
@@ -1,283 +0,0 @@
-%%BeginProlog
-50 dict begin
-
-% This is a standard prolog for Postscript generated by Tk's canvas
-% widget.
-
-% 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 b64cc43..50b2837 100644
--- a/generic/tk.decls
+++ b/generic/tk.decls
@@ -6,6 +6,7 @@
# tkStub.c, and tkPlatStub.c files.
#
# Copyright (c) 1998-2000 Ajuba Solutions.
+# Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -163,7 +164,7 @@ declare 32 {
declare 33 {
unsigned long Tk_CreateBinding(Tcl_Interp *interp,
Tk_BindingTable bindingTable, ClientData object,
- const char *eventStr, const char *script, int append)
+ const char *eventStr, const char *command, int append)
}
declare 34 {
Tk_BindingTable Tk_CreateBindingTable(Tcl_Interp *interp)
@@ -495,7 +496,7 @@ declare 123 {
}
declare 124 {
void Tk_ManageGeometry(Tk_Window tkwin,
- Tk_GeomMgr *mgrPtr, ClientData clientData)
+ const Tk_GeomMgr *mgrPtr, ClientData clientData)
}
declare 125 {
void Tk_MapWindow(Tk_Window tkwin)
@@ -580,13 +581,13 @@ declare 147 {
void Tk_PhotoBlank(Tk_PhotoHandle handle)
}
declare 148 {
- void Tk_PhotoExpand(Tk_PhotoHandle handle, int width, int height )
+ void Tk_PhotoExpand_Panic(Tk_PhotoHandle handle, int width, int height )
}
declare 149 {
void Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr, int *heightPtr)
}
declare 150 {
- void Tk_PhotoSetSize(Tk_PhotoHandle handle, int width, int height)
+ void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle, int width, int height)
}
declare 151 {
int Tk_PointToChar(Tk_TextLayout layout, int x, int y)
@@ -942,12 +943,12 @@ declare 245 {
void Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height)
}
declare 246 {
- void Tk_PhotoPutBlock(Tk_PhotoHandle handle,
+ void Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr, int x, int y,
int width, int height, int compRule)
}
declare 247 {
- void Tk_PhotoPutZoomedBlock(Tk_PhotoHandle handle,
+ void Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr, int x, int y,
int width, int height, int zoomX, int zoomY,
int subsampleX, int subsampleY, int compRule)
@@ -1018,6 +1019,54 @@ declare 264 {
int width, int height, int state)
}
+# TIP#116
+declare 265 {
+ int Tk_PhotoExpand(Tcl_Interp *interp, Tk_PhotoHandle handle,
+ int width, int height)
+}
+declare 266 {
+ int Tk_PhotoPutBlock(Tcl_Interp *interp, Tk_PhotoHandle handle,
+ Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height,
+ int compRule)
+}
+declare 267 {
+ int Tk_PhotoPutZoomedBlock(Tcl_Interp *interp, Tk_PhotoHandle handle,
+ Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height,
+ int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule)
+}
+declare 268 {
+ int Tk_PhotoSetSize(Tcl_Interp *interp, Tk_PhotoHandle handle,
+ int width, int height)
+}
+# TIP#245
+declare 269 {
+ long Tk_GetUserInactiveTime(Display *dpy)
+}
+declare 270 {
+ void Tk_ResetUserInactiveTime(Display *dpy)
+}
+
+# TIP #264
+declare 271 {
+ Tcl_Interp *Tk_Interp(Tk_Window tkwin)
+}
+
+# Now that the Tk 8.2 -> 8.3 transition is long past, use more conventional
+# means to continue support for extensions using the USE_OLD_IMAGE to
+# continue use of their string-based Tcl_ImageTypes and Tcl_PhotoImageFormats.
+#
+# Note that this restores the usual rules for stub compatibility. Stub-enabled
+# extensions compiled against 8.5 headers and linked to the 8.5 stub library
+# will produce a file [load]able into an interp with Tk 8.X, for X >= 5.
+# It will *not* be [load]able into interps with Tk 8.4 (or Tk 8.2!).
+# Developers who need to produce a file [load]able into legacy interps must
+# build against legacy sources.
+declare 272 {
+ void Tk_CreateOldImageType(Tk_ImageType *typePtr)
+}
+declare 273 {
+ void Tk_CreateOldPhotoImageFormat(Tk_PhotoImageFormat *formatPtr)
+}
# Define the platform specific public Tk interface. These functions are
# only available on the designated platform.
@@ -1047,7 +1096,8 @@ declare 5 win {
UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
}
-# Mac OS X specific functions
+################################
+# Aqua specific functions
declare 0 aqua {
void Tk_MacOSXSetEmbedHandler(
@@ -1077,10 +1127,10 @@ declare 6 aqua {
void TkMacOSXInvalClipRgns(Tk_Window tkwin)
}
declare 7 aqua {
- GWorldPtr TkMacOSXGetDrawablePort(Drawable drawable)
+ void *TkMacOSXGetDrawablePort(Drawable drawable)
}
declare 8 aqua {
- ControlRef TkMacOSXGetRootControl(Drawable drawable)
+ void *TkMacOSXGetRootControl(Drawable drawable)
}
declare 9 aqua {
void Tk_MacOSXSetupTkNotifier(void)
@@ -1088,6 +1138,37 @@ declare 9 aqua {
declare 10 aqua {
int Tk_MacOSXIsAppInFront(void)
}
+
+##############################################################################
+
+# Public functions that are not accessible via the stubs table.
+
+export {
+ const char *Tk_InitStubs(Tcl_Interp *interp, const char *version,
+ int exact)
+}
+export {
+ const char *Tk_PkgInitStubsCheck(Tcl_Interp *interp, const char *version,
+ int exact)
+}
+
+# Global variables that need to be exported from the tcl shared library.
+
+export {
+ TkStubs *tkStubsPtr (fool checkstubs)
+}
+export {
+ TkPlatStubs *tkPlatStubsPtr (fool checkstubs)
+}
+export {
+ TkIntStubs *tkIntStubsPtr (fool checkstubs)
+}
+export {
+ TkIntPlatStubs *tkIntPlatStubsPtr (fool checkstubs)
+}
+export {
+ TkIntXlibStubs *tkIntXlibStubsPtr (fool checkstubs)
+}
# Local Variables:
# mode: tcl
diff --git a/generic/tk.h b/generic/tk.h
index 4a5b371..f1f81cd 100644
--- a/generic/tk.h
+++ b/generic/tk.h
@@ -1,26 +1,32 @@
/*
* tk.h --
*
- * Declarations for Tk-related things that are visible
- * outside of the Tk module itself.
+ * Declarations for Tk-related things that are visible outside of the Tk
+ * module itself.
*
* Copyright (c) 1989-1994 The Regents of the University of California.
* Copyright (c) 1994 The Australian National University.
* Copyright (c) 1994-1998 Sun Microsystems, Inc.
* Copyright (c) 1998-2000 Ajuba Solutions.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TK
#define _TK
-#ifndef _TCL
#include <tcl.h>
-#if (TCL_MAJOR_VERSION != 8) || (TCL_MINOR_VERSION != 4)
-# error Tk 8.4 must be compiled with tcl.h from Tcl 8.4
+#if (TCL_MAJOR_VERSION != 8) || (TCL_MINOR_VERSION < 5)
+# error Tk 8.5 must be compiled with tcl.h from Tcl 8.5
#endif
+
+#ifndef _ANSI_ARGS_
+# ifndef NO_PROTOTYPES
+# define _ANSI_ARGS_(x) x
+# else
+# define _ANSI_ARGS_(x) ()
+# endif
#endif
/*
@@ -35,40 +41,41 @@ extern "C" {
* When version numbers change here, you must also go into the following files
* and update the version numbers:
*
- * library/tk.tcl (only if Major.minor changes, not patchlevel)
+ * library/tk.tcl (2 LOC patch)
* unix/configure.in (2 LOC Major, 2 LOC minor, 1 LOC patch)
* win/configure.in (as above)
- * win/makefile.vc (not patchlevel)
* README (sections 0 and 1)
- * mac/README (not patchlevel)
+ * macosx/Wish.xcode/project.pbxproj (not patchlevel) 1 LOC
+ * macosx/Wish-Common.xcconfig (not patchlevel) 1 LOC
* win/README (not patchlevel)
* unix/README (not patchlevel)
- * unix/tk.spec (3 LOC Major/Minor, 2 LOC patch)
+ * unix/tk.spec (1 LOC patch)
* win/tcl.m4 (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.
+ * 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 4
-#define TK_RELEASE_LEVEL TCL_FINAL_RELEASE
-#define TK_RELEASE_SERIAL 19
+#define TK_MAJOR_VERSION 8
+#define TK_MINOR_VERSION 5
+#define TK_RELEASE_LEVEL TCL_FINAL_RELEASE
+#define TK_RELEASE_SERIAL 13
-#define TK_VERSION "8.4"
-#define TK_PATCH_LEVEL "8.4.19"
+#define TK_VERSION "8.5"
+#define TK_PATCH_LEVEL "8.5.13"
-/*
- * A special definition used to allow this header file to be included
- * from windows resource files so that they can obtain version
- * information. RC_INVOKED is defined by default by the windows RC tool.
+/*
+ * A special definition used to allow this header file to be included from
+ * windows or mac resource files so that they can obtain version information.
+ * RC_INVOKED is defined by default by the windows RC tool and manually set
+ * for macintosh.
*
- * Resource compilers don't like all the C stuff, like typedefs and
- * procedure declarations, that occur below, so block them out.
+ * Resource compilers don't like all the C stuff, like typedefs and procedure
+ * declarations, that occur below, so block them out.
*/
-
+
#ifndef RC_INVOKED
-
+
#ifndef _XLIB_H
# if defined(MAC_OSX_TK)
# include <X11/Xlib.h>
@@ -85,7 +92,7 @@ extern "C" {
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif
-
+
/*
* Decide whether or not to use input methods.
*/
@@ -118,11 +125,11 @@ typedef struct Tk_StyledElement_ *Tk_StyledElement;
* Additional types exported to clients.
*/
-typedef CONST char *Tk_Uid;
+typedef const char *Tk_Uid;
/*
- * The enum below defines the valid types for Tk configuration options
- * as implemented by Tk_InitOptions, Tk_SetOptions, etc.
+ * The enum below defines the valid types for Tk configuration options as
+ * implemented by Tk_InitOptions, Tk_SetOptions, etc.
*/
typedef enum {
@@ -148,56 +155,54 @@ typedef enum {
} Tk_OptionType;
/*
- * 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.
+ * 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.
*/
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
+ Tk_OptionType type; /* Type of option, such as TK_OPTION_COLOR;
+ * see definitions above. Last option in table
+ * must have type TK_OPTION_END. */
+ const 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. */
+ const char *dbName; /* Name for option in option database. */
+ const char *dbClass; /* Class for option in database. */
+ const 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. */
+ * 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. */
+ * 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
+ * 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. */
+ 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 values for Tk_OptionSpec structures. These flags are shared by
- * Tk_ConfigSpec structures, so be sure to coordinate any changes
- * carefully.
+ * Flag values for Tk_OptionSpec structures. These flags are shared by
+ * Tk_ConfigSpec structures, so be sure to coordinate any changes carefully.
*/
#define TK_OPTION_NULL_OK (1 << 0)
@@ -218,28 +223,29 @@ typedef void (Tk_CustomOptionRestoreProc) _ANSI_ARGS_((ClientData clientData,
Tk_Window tkwin, char *internalPtr, char *saveInternalPtr));
typedef void (Tk_CustomOptionFreeProc) _ANSI_ARGS_((ClientData clientData,
Tk_Window tkwin, char *internalPtr));
-
+
typedef struct Tk_ObjCustomOption {
- char *name; /* Name of the custom option. */
- Tk_CustomOptionSetProc *setProc; /* Function to use to set a record's
- * option value from a Tcl_Obj */
- Tk_CustomOptionGetProc *getProc; /* Function to use to get a Tcl_Obj
- * representation from an internal
- * representation of an option. */
- Tk_CustomOptionRestoreProc *restoreProc; /* Function to use to restore a
- * saved value for the internal
- * representation. */
- Tk_CustomOptionFreeProc *freeProc; /* Function to use to free the internal
- * representation of an option. */
- ClientData clientData; /* Arbitrary one-word value passed to
- * the handling procs. */
+ const char *name; /* Name of the custom option. */
+ Tk_CustomOptionSetProc *setProc;
+ /* Function to use to set a record's option
+ * value from a Tcl_Obj */
+ Tk_CustomOptionGetProc *getProc;
+ /* Function to use to get a Tcl_Obj
+ * representation from an internal
+ * representation of an option. */
+ Tk_CustomOptionRestoreProc *restoreProc;
+ /* Function to use to restore a saved value
+ * for the internal representation. */
+ Tk_CustomOptionFreeProc *freeProc;
+ /* Function to use to free the internal
+ * representation of an option. */
+ ClientData clientData; /* Arbitrary one-word value passed to the
+ * handling procs. */
} Tk_ObjCustomOption;
-
/*
- * Macro to use to fill in "offset" fields of the Tk_OptionSpec.
- * struct. Computes number of bytes from beginning of structure
- * to a given field.
+ * Macro to use to fill in "offset" fields of the Tk_OptionSpec structure.
+ * Computes number of bytes from beginning of structure to a given field.
*/
#ifdef offsetof
@@ -249,34 +255,30 @@ typedef struct Tk_ObjCustomOption {
#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.
+ * The following two structures are used for error handling. When config
+ * 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. */
+ 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 was
+ * not 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 the field
+ * 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 (i.e., 8 bytes) is big
+ * enough. Also, using a double guarantees
+ * that the field is properly aligned for
+ * storing large values. */
} Tk_SavedOption;
#ifdef TCL_MEM_DEBUG
@@ -286,31 +288,30 @@ typedef struct Tk_SavedOption {
#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. */
+ 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. */
+ /* 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. THESE ARE
- * DEPRECATED; PLEASE USE THE NEW STRUCTURES LISTED ABOVE.
+ * 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. THESE ARE DEPRECATED; PLEASE USE THE NEW STRUCTURES
+ * LISTED ABOVE.
*/
/*
- * This is a temporary flag used while tkObjConfig and new widgets
- * are in development.
+ * This is a temporary flag used while tkObjConfig and new widgets are in
+ * development.
*/
#ifndef __NO_OLD_CONFIG
@@ -323,58 +324,58 @@ typedef char *(Tk_OptionPrintProc) _ANSI_ARGS_((ClientData clientData,
Tcl_FreeProc **freeProcPtr));
typedef struct Tk_CustomOption {
- Tk_OptionParseProc *parseProc; /* Procedure to call to parse an
- * option and store it in converted
- * form. */
- Tk_OptionPrintProc *printProc; /* Procedure to return a printable
- * string describing an existing
- * option. */
- ClientData clientData; /* Arbitrary one-word value used by
- * option parser: passed to
- * parseProc and printProc. */
+ Tk_OptionParseProc *parseProc;
+ /* Procedure to call to parse an option and
+ * store it in converted form. */
+ Tk_OptionPrintProc *printProc;
+ /* Procedure to return a printable string
+ * describing an existing option. */
+ ClientData clientData; /* Arbitrary one-word value used by option
+ * parser: passed to parseProc and
+ * printProc. */
} Tk_CustomOption;
/*
- * Structure used to specify information for Tk_ConfigureWidget. Each
- * structure gives complete information for one option, including
- * how the option is specified on the command line, where it appears
- * in the option database, etc.
+ * Structure used to specify information for Tk_ConfigureWidget. Each
+ * structure gives complete information for one option, including how the
+ * option is specified on the command line, where it appears in the option
+ * database, etc.
*/
typedef struct Tk_ConfigSpec {
int type; /* Type of option, such as TK_CONFIG_COLOR;
- * see definitions below. Last option in
- * table must have type TK_CONFIG_END. */
- char *argvName; /* Switch used to specify option in argv.
- * NULL means this spec is part of a group. */
+ * see definitions below. Last option in table
+ * must have type TK_CONFIG_END. */
+ char *argvName; /* Switch used to specify option in argv. NULL
+ * means this spec is part of a group. */
Tk_Uid dbName; /* Name for option in option database. */
Tk_Uid dbClass; /* Class for option in database. */
- Tk_Uid defValue; /* Default value for option if not
- * specified in command line or database. */
- int offset; /* Where in widget record to store value;
- * use Tk_Offset macro to generate values
- * for this. */
+ Tk_Uid defValue; /* Default value for option if not specified
+ * in command line or database. */
+ int offset; /* Where in widget record to store value; use
+ * Tk_Offset macro to generate values for
+ * this. */
int specFlags; /* Any combination of the values defined
- * below; other bits are used internally
- * by tkConfig.c. */
- Tk_CustomOption *customPtr; /* If type is TK_CONFIG_CUSTOM then this is
- * a pointer to info about how to parse and
- * print the option. Otherwise it is
+ * below; other bits are used internally by
+ * tkConfig.c. */
+ Tk_CustomOption *customPtr; /* If type is TK_CONFIG_CUSTOM then this is a
+ * pointer to info about how to parse and
+ * print the option. Otherwise it is
* irrelevant. */
} Tk_ConfigSpec;
/*
- * Type values for Tk_ConfigSpec structures. See the user
- * documentation for details.
+ * Type values for Tk_ConfigSpec structures. See the user documentation for
+ * details.
*/
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_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_PIXELS, TK_CONFIG_MM, TK_CONFIG_WINDOW, TK_CONFIG_CUSTOM,
TK_CONFIG_END
} Tk_ConfigTypes;
@@ -386,10 +387,10 @@ typedef enum {
#define TK_CONFIG_OBJS 0x80
/*
- * 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
- * tkOldConfig.c (internal-use-only flags are defined there).
+ * 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 tkOldConfig.c
+ * (internal-use-only flags are defined there).
*/
#define TK_CONFIG_NULL_OK (1 << 0)
@@ -405,14 +406,15 @@ typedef enum {
*/
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. */
+ 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;
/*
@@ -444,8 +446,8 @@ typedef struct {
#define TK_ARGV_DONT_SKIP_FIRST_ARG 0x8
/*
- * Enumerated type for describing actions to be taken in response
- * to a restrictProc established by Tk_RestrictEvents.
+ * Enumerated type for describing actions to be taken in response to a
+ * restrictProc established by Tk_RestrictEvents.
*/
typedef enum {
@@ -483,10 +485,10 @@ typedef enum {
#define TK_3D_DARK_GC 3
/*
- * Special EnterNotify/LeaveNotify "mode" for use in events
- * generated by tkShare.c. Pick a high enough value that it's
- * unlikely to conflict with existing values (like NotifyNormal)
- * or any new values defined in the future.
+ * Special EnterNotify/LeaveNotify "mode" for use in events generated by
+ * tkShare.c. Pick a high enough value that it's unlikely to conflict with
+ * existing values (like NotifyNormal) or any new values defined in the
+ * future.
*/
#define TK_NOTIFY_SHARE 20
@@ -511,7 +513,7 @@ typedef enum {
/*
* The following structure is used by Tk_GetFontMetrics() to return
- * information about the properties of a Tk_Font.
+ * information about the properties of a Tk_Font.
*/
typedef struct Tk_FontMetrics {
@@ -523,9 +525,9 @@ typedef struct Tk_FontMetrics {
* letter sticks below the baseline, plus any
* extra blank space added by the designer of
* the font. */
- int linespace; /* The sum of the ascent and descent. How
- * far apart two lines of text in the same
- * font should be placed so that none of the
+ int linespace; /* The sum of the ascent and descent. How far
+ * apart two lines of text in the same font
+ * should be placed so that none of the
* characters in one line overlap any of the
* characters in the other line. */
} Tk_FontMetrics;
@@ -559,13 +561,12 @@ typedef void (Tk_ClassModalProc) _ANSI_ARGS_((Tk_Window tkwin,
typedef struct Tk_ClassProcs {
unsigned int size;
Tk_ClassWorldChangedProc *worldChangedProc;
- /* Procedure to invoke when the widget needs to
- * respond in some way to a change in the
+ /* Procedure to invoke when the widget needs
+ * to respond in some way to a change in the
* world (font changes, etc.) */
Tk_ClassCreateProc *createProc;
- /* Procedure to invoke when the
- * platform-dependent window needs to be
- * created. */
+ /* Procedure to invoke when the platform-
+ * dependent window needs to be created. */
Tk_ClassModalProc *modalProc;
/* Procedure to invoke after all bindings on a
* widget have been triggered in order to
@@ -573,8 +574,8 @@ typedef struct Tk_ClassProcs {
} Tk_ClassProcs;
/*
- * Simple accessor for Tk_ClassProcs structure. Checks that the structure
- * is not NULL, then checks the size field and returns either the requested
+ * Simple accessor for Tk_ClassProcs structure. Checks that the structure is
+ * not NULL, then checks the size field and returns either the requested
* field, if present, or NULL if the structure is too small to have the field
* (or NULL if the structure is NULL).
*
@@ -591,9 +592,9 @@ typedef struct Tk_ClassProcs {
(((procs)->size <= Tk_Offset(Tk_ClassProcs, which)) ? NULL:(procs)->which))
/*
- * Each geometry manager (the packer, the placer, etc.) is represented
- * by a structure of the following form, which indicates procedures
- * to invoke in the geometry manager to carry out certain functions.
+ * Each geometry manager (the packer, the placer, etc.) is represented by a
+ * structure of the following form, which indicates procedures to invoke in
+ * the geometry manager to carry out certain functions.
*/
typedef void (Tk_GeomRequestProc) _ANSI_ARGS_((ClientData clientData,
@@ -602,17 +603,17 @@ typedef void (Tk_GeomLostSlaveProc) _ANSI_ARGS_((ClientData clientData,
Tk_Window tkwin));
typedef struct Tk_GeomMgr {
- char *name; /* Name of the geometry manager (command
- * used to invoke it, or name of widget
- * class that allows embedded widgets). */
+ const char *name; /* Name of the geometry manager (command used
+ * to invoke it, or name of widget class that
+ * allows embedded widgets). */
Tk_GeomRequestProc *requestProc;
/* Procedure to invoke when a slave's
* requested geometry changes. */
Tk_GeomLostSlaveProc *lostSlaveProc;
- /* Procedure to invoke when a slave is
- * taken away from one geometry manager
- * by another. NULL means geometry manager
- * doesn't care when slaves are lost. */
+ /* Procedure to invoke when a slave is taken
+ * away from one geometry manager by another.
+ * NULL means geometry manager doesn't care
+ * when slaves are lost. */
} Tk_GeomMgr;
/*
@@ -644,40 +645,45 @@ typedef struct Tk_GeomMgr {
/*
* A virtual event shares most of its fields with the XKeyEvent and
- * XButtonEvent structures. 99% of the time a virtual event will be
- * an abstraction of a key or button event, so this structure provides
- * the most information to the user. The only difference is the changing
- * of the detail field for a virtual event so that it holds the name of the
- * virtual event being triggered.
+ * XButtonEvent structures. 99% of the time a virtual event will be an
+ * abstraction of a key or button event, so this structure provides the most
+ * information to the user. The only difference is the changing of the detail
+ * field for a virtual event so that it holds the name of the virtual event
+ * being triggered.
*
- * When using this structure, if you want your code to work correctly
- * in Tk 8.5 as well, you should ensure that you zero out all the
+ * When using this structure, you should ensure that you zero out all the
* fields first using memset() or bzero().
*/
typedef struct {
int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* True if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window event; /* Window on which event was requested. */
- Window root; /* root window that the event occured on */
- Window subwindow; /* child window */
- Time time; /* milliseconds */
- int x, y; /* pointer x, y coordinates in event window */
- int x_root, y_root; /* coordinates relative to root */
- unsigned int state; /* key or button mask */
- Tk_Uid name; /* Name of virtual event. */
- Bool same_screen; /* same screen flag */
- Tcl_Obj *user_data; /* not used in Tk 8.4 */
+ unsigned long serial; /* # of last request processed by server. */
+ Bool send_event; /* True if this came from a SendEvent
+ * request. */
+ Display *display; /* Display the event was read from. */
+ Window event; /* Window on which event was requested. */
+ Window root; /* Root window that the event occured on. */
+ Window subwindow; /* Child window. */
+ Time time; /* Milliseconds. */
+ int x, y; /* Pointer x, y coordinates in event
+ * window. */
+ int x_root, y_root; /* Coordinates relative to root. */
+ unsigned int state; /* Key or button mask */
+ Tk_Uid name; /* Name of virtual event. */
+ Bool same_screen; /* Same screen flag. */
+ Tcl_Obj *user_data; /* Application-specific data reference; Tk
+ * will decrement the reference count *once*
+ * when it has finished processing the
+ * event. */
} XVirtualEvent;
typedef struct {
int type;
- unsigned long serial; /* # of last request processed by server */
- Bool send_event; /* True if this came from a SendEvent request */
- Display *display; /* Display the event was read from */
- Window window; /* Window in which event occurred. */
+ unsigned long serial; /* # of last request processed by server. */
+ Bool send_event; /* True if this came from a SendEvent
+ * request. */
+ Display *display; /* Display the event was read from. */
+ Window window; /* Window in which event occurred. */
} XActivateDeactivateEvent;
typedef XActivateDeactivateEvent XActivateEvent;
typedef XActivateDeactivateEvent XDeactivateEvent;
@@ -685,29 +691,29 @@ typedef XActivateDeactivateEvent XDeactivateEvent;
/*
*--------------------------------------------------------------
*
- * Macros for querying Tk_Window structures. See the
- * manual entries for documentation.
+ * Macros for querying Tk_Window structures. See the manual entries for
+ * documentation.
*
*--------------------------------------------------------------
*/
-#define Tk_Display(tkwin) (((Tk_FakeWin *) (tkwin))->display)
-#define Tk_ScreenNumber(tkwin) (((Tk_FakeWin *) (tkwin))->screenNum)
-#define Tk_Screen(tkwin) (ScreenOfDisplay(Tk_Display(tkwin), \
- Tk_ScreenNumber(tkwin)))
-#define Tk_Depth(tkwin) (((Tk_FakeWin *) (tkwin))->depth)
-#define Tk_Visual(tkwin) (((Tk_FakeWin *) (tkwin))->visual)
-#define Tk_WindowId(tkwin) (((Tk_FakeWin *) (tkwin))->window)
-#define Tk_PathName(tkwin) (((Tk_FakeWin *) (tkwin))->pathName)
-#define Tk_Name(tkwin) (((Tk_FakeWin *) (tkwin))->nameUid)
-#define Tk_Class(tkwin) (((Tk_FakeWin *) (tkwin))->classUid)
-#define Tk_X(tkwin) (((Tk_FakeWin *) (tkwin))->changes.x)
-#define Tk_Y(tkwin) (((Tk_FakeWin *) (tkwin))->changes.y)
-#define Tk_Width(tkwin) (((Tk_FakeWin *) (tkwin))->changes.width)
+#define Tk_Display(tkwin) (((Tk_FakeWin *) (tkwin))->display)
+#define Tk_ScreenNumber(tkwin) (((Tk_FakeWin *) (tkwin))->screenNum)
+#define Tk_Screen(tkwin) \
+ (ScreenOfDisplay(Tk_Display(tkwin), Tk_ScreenNumber(tkwin)))
+#define Tk_Depth(tkwin) (((Tk_FakeWin *) (tkwin))->depth)
+#define Tk_Visual(tkwin) (((Tk_FakeWin *) (tkwin))->visual)
+#define Tk_WindowId(tkwin) (((Tk_FakeWin *) (tkwin))->window)
+#define Tk_PathName(tkwin) (((Tk_FakeWin *) (tkwin))->pathName)
+#define Tk_Name(tkwin) (((Tk_FakeWin *) (tkwin))->nameUid)
+#define Tk_Class(tkwin) (((Tk_FakeWin *) (tkwin))->classUid)
+#define Tk_X(tkwin) (((Tk_FakeWin *) (tkwin))->changes.x)
+#define Tk_Y(tkwin) (((Tk_FakeWin *) (tkwin))->changes.y)
+#define Tk_Width(tkwin) (((Tk_FakeWin *) (tkwin))->changes.width)
#define Tk_Height(tkwin) \
(((Tk_FakeWin *) (tkwin))->changes.height)
-#define Tk_Changes(tkwin) (&((Tk_FakeWin *) (tkwin))->changes)
-#define Tk_Attributes(tkwin) (&((Tk_FakeWin *) (tkwin))->atts)
+#define Tk_Changes(tkwin) (&((Tk_FakeWin *) (tkwin))->changes)
+#define Tk_Attributes(tkwin) (&((Tk_FakeWin *) (tkwin))->atts)
#define Tk_IsEmbedded(tkwin) \
(((Tk_FakeWin *) (tkwin))->flags & TK_EMBEDDED)
#define Tk_IsContainer(tkwin) \
@@ -722,8 +728,10 @@ typedef XActivateDeactivateEvent XDeactivateEvent;
(((Tk_FakeWin *) (tkwin))->flags & TK_WIN_MANAGED)
#define Tk_TopWinHierarchy(tkwin) \
(((Tk_FakeWin *) (tkwin))->flags & TK_TOP_HIERARCHY)
-#define Tk_ReqWidth(tkwin) (((Tk_FakeWin *) (tkwin))->reqWidth)
-#define Tk_ReqHeight(tkwin) (((Tk_FakeWin *) (tkwin))->reqHeight)
+#define Tk_IsManageable(tkwin) \
+ (((Tk_FakeWin *) (tkwin))->flags & TK_WM_MANAGEABLE)
+#define Tk_ReqWidth(tkwin) (((Tk_FakeWin *) (tkwin))->reqWidth)
+#define Tk_ReqHeight(tkwin) (((Tk_FakeWin *) (tkwin))->reqHeight)
/* Tk_InternalBorderWidth is deprecated */
#define Tk_InternalBorderWidth(tkwin) \
(((Tk_FakeWin *) (tkwin))->internalBorderLeft)
@@ -735,20 +743,19 @@ typedef XActivateDeactivateEvent XDeactivateEvent;
(((Tk_FakeWin *) (tkwin))->internalBorderTop)
#define Tk_InternalBorderBottom(tkwin) \
(((Tk_FakeWin *) (tkwin))->internalBorderBottom)
-#define Tk_MinReqWidth(tkwin) (((Tk_FakeWin *) (tkwin))->minReqWidth)
-#define Tk_MinReqHeight(tkwin) (((Tk_FakeWin *) (tkwin))->minReqHeight)
-#define Tk_Parent(tkwin) (((Tk_FakeWin *) (tkwin))->parentPtr)
-#define Tk_Colormap(tkwin) (((Tk_FakeWin *) (tkwin))->atts.colormap)
+#define Tk_MinReqWidth(tkwin) (((Tk_FakeWin *) (tkwin))->minReqWidth)
+#define Tk_MinReqHeight(tkwin) (((Tk_FakeWin *) (tkwin))->minReqHeight)
+#define Tk_Parent(tkwin) (((Tk_FakeWin *) (tkwin))->parentPtr)
+#define Tk_Colormap(tkwin) (((Tk_FakeWin *) (tkwin))->atts.colormap)
/*
- * The structure below is needed by the macros above so that they can
- * access the fields of a Tk_Window. The fields not needed by the macros
- * are declared as "dummyX". The structure has its own type in order to
- * prevent applications from accessing Tk_Window fields except using
- * official macros. WARNING!! The structure definition must be kept
- * consistent with the TkWindow structure in tkInt.h. If you change one,
- * then change the other. See the declaration in tkInt.h for
- * documentation on what the fields are used for internally.
+ * The structure below is needed by the macros above so that they can access
+ * the fields of a Tk_Window. The fields not needed by the macros are declared
+ * as "dummyX". The structure has its own type in order to prevent apps from
+ * accessing Tk_Window fields except using official macros. WARNING!! The
+ * structure definition must be kept consistent with the TkWindow structure in
+ * tkInt.h. If you change one, then change the other. See the declaration in
+ * tkInt.h for documentation on what the fields are used for internally.
*/
typedef struct Tk_FakeWin {
@@ -803,69 +810,65 @@ typedef struct Tk_FakeWin {
* TK_ALREADY_DEAD: 1 means the window is in the process of
* being destroyed already.
* TK_NEED_CONFIG_NOTIFY: 1 means that the window has been reconfigured
- * before it was made to exist. At the time of
+ * before it was made to exist. At the time of
* making it exist a ConfigureNotify event needs
* to be generated.
- * TK_GRAB_FLAG: Used to manage grabs. See tkGrab.c for
- * details.
+ * TK_GRAB_FLAG: Used to manage grabs. See tkGrab.c for details
* TK_CHECKED_IC: 1 means we've already tried to get an input
- * context for this window; if the ic field
- * is NULL it means that there isn't a context
- * for the field.
+ * context for this window; if the ic field is
+ * NULL it means that there isn't a context for
+ * the field.
* TK_DONT_DESTROY_WINDOW: 1 means that Tk_DestroyWindow should not
* invoke XDestroyWindow to destroy this widget's
- * X window. The flag is set when the window
- * has already been destroyed elsewhere (e.g.
- * by another application) or when it will be
- * destroyed later (e.g. by destroying its
- * parent).
+ * X window. The flag is set when the window has
+ * already been destroyed elsewhere (e.g. by
+ * another application) or when it will be
+ * destroyed later (e.g. by destroying its parent)
* TK_WM_COLORMAP_WINDOW: 1 means that this window has at some time
* appeared in the WM_COLORMAP_WINDOWS property
- * for its toplevel, so we have to remove it
- * from that property if the window is
- * deleted and the toplevel isn't.
+ * for its toplevel, so we have to remove it from
+ * that property if the window is deleted and the
+ * toplevel isn't.
* TK_EMBEDDED: 1 means that this window (which must be a
* toplevel) is not a free-standing window but
* rather is embedded in some other application.
* TK_CONTAINER: 1 means that this window is a container, and
- * that some other application (either in
- * this process or elsewhere) may be
- * embedding itself inside the window.
+ * that some other application (either in this
+ * process or elsewhere) may be embedding itself
+ * inside the window.
* TK_BOTH_HALVES: 1 means that this window is used for
- * application embedding (either as
- * container or embedded application), and
- * both the containing and embedded halves
- * are associated with windows in this
- * particular process.
+ * application embedding (either as container or
+ * embedded application), and both the containing
+ * and embedded halves are associated with
+ * windows in this particular process.
* TK_DEFER_MODAL: 1 means that this window has deferred a modal
* loop until all of the bindings for the current
* event have been invoked.
- * TK_WRAPPER: 1 means that this window is the extra
- * wrapper window created around a toplevel
- * to hold the menubar under Unix. See
- * tkUnixWm.c for more information.
+ * TK_WRAPPER: 1 means that this window is the extra wrapper
+ * window created around a toplevel to hold the
+ * menubar under Unix. See tkUnixWm.c for more
+ * information.
* TK_REPARENTED: 1 means that this window has been reparented
* so that as far as the window system is
- * concerned it isn't a child of its Tk
- * parent. Initially this is used only for
- * special Unix menubar windows.
+ * concerned it isn't a child of its Tk parent.
+ * Initially this is used only for special Unix
+ * menubar windows.
* TK_ANONYMOUS_WINDOW: 1 means that this window has no name, and is
* thus not accessible from Tk.
* TK_HAS_WRAPPER 1 means that this window has a wrapper window
- * TK_WIN_MANAGED 1 means that this window is a child of the
- * root window, and is managed by the window
- * manager.
- * TK_TOP_HIERARCHY 1 means this window is at the top of a
- * physical window hierarchy within this
- * process, i.e. the window's parent
- * either doesn't exist or is not owned by
- * this Tk application.
- * TK_PROP_PROPCHANGE 1 means that PropertyNotify events in
- * this window's children should propagate
- * up to this window.
+ * TK_WIN_MANAGED 1 means that this window is a child of the root
+ * window, and is managed by the window manager.
+ * TK_TOP_HIERARCHY 1 means this window is at the top of a physical
+ * window hierarchy within this process, i.e. the
+ * window's parent either doesn't exist or is not
+ * owned by this Tk application.
+ * TK_PROP_PROPCHANGE 1 means that PropertyNotify events in the
+ * window's children should propagate up to this
+ * window.
+ * TK_WM_MANAGEABLE 1 marks a window as capable of being converted
+ * into a toplevel using [wm manage].
*/
-
#define TK_MAPPED 1
#define TK_TOP_LEVEL 2
#define TK_ALREADY_DEAD 4
@@ -885,12 +888,12 @@ typedef struct Tk_FakeWin {
#define TK_WIN_MANAGED 0x10000
#define TK_TOP_HIERARCHY 0x20000
#define TK_PROP_PROPCHANGE 0x40000
+#define TK_WM_MANAGEABLE 0x80000
/*
*--------------------------------------------------------------
*
- * Procedure prototypes and structures used for defining new canvas
- * items:
+ * Procedure prototypes and structures used for defining new canvas items:
*
*--------------------------------------------------------------
*/
@@ -911,54 +914,48 @@ typedef struct Tk_SmoothMethod {
} Tk_SmoothMethod;
/*
- * For each item in a canvas widget there exists one record with
- * the following structure. Each actual item is represented by
- * a record with the following stuff at its beginning, plus additional
- * type-specific stuff after that.
+ * For each item in a canvas widget there exists one record with the following
+ * structure. Each actual item is represented by a record with the following
+ * stuff at its beginning, plus additional type-specific stuff after that.
*/
#define TK_TAG_SPACE 3
-typedef struct Tk_Item {
- int id; /* Unique identifier for this item
- * (also serves as first tag for
- * item). */
- struct Tk_Item *nextPtr; /* Next in display list of all
- * items in this canvas. Later items
- * in list are drawn on top of earlier
- * ones. */
- Tk_Uid staticTagSpace[TK_TAG_SPACE];/* Built-in space for limited # of
- * tags. */
- Tk_Uid *tagPtr; /* Pointer to array of tags. Usually
- * points to staticTagSpace, but
- * may point to malloc-ed space if
- * there are lots of tags. */
- int tagSpace; /* Total amount of tag space available
- * at tagPtr. */
- int numTags; /* Number of tag slots actually used
- * at *tagPtr. */
- struct Tk_ItemType *typePtr; /* Table of procedures that implement
- * this type of item. */
- int x1, y1, x2, y2; /* Bounding box for item, in integer
- * canvas units. Set by item-specific
- * code and guaranteed to contain every
- * pixel drawn in item. Item area
- * includes x1 and y1 but not x2
- * and y2. */
- struct Tk_Item *prevPtr; /* Previous in display list of all
- * items in this canvas. Later items
- * in list are drawn just below earlier
- * ones. */
- Tk_State state; /* state of item */
- char *reserved1; /* reserved for future use */
- int redraw_flags; /* some flags used in the canvas */
+typedef struct Tk_Item {
+ int id; /* Unique identifier for this item (also
+ * serves as first tag for item). */
+ struct Tk_Item *nextPtr; /* Next in display list of all items in this
+ * canvas. Later items in list are drawn on
+ * top of earlier ones. */
+ Tk_Uid staticTagSpace[TK_TAG_SPACE];
+ /* Built-in space for limited # of tags. */
+ Tk_Uid *tagPtr; /* Pointer to array of tags. Usually points to
+ * staticTagSpace, but may point to malloc-ed
+ * space if there are lots of tags. */
+ int tagSpace; /* Total amount of tag space available at
+ * tagPtr. */
+ int numTags; /* Number of tag slots actually used at
+ * *tagPtr. */
+ struct Tk_ItemType *typePtr;/* Table of procedures that implement this
+ * type of item. */
+ int x1, y1, x2, y2; /* Bounding box for item, in integer canvas
+ * units. Set by item-specific code and
+ * guaranteed to contain every pixel drawn in
+ * item. Item area includes x1 and y1 but not
+ * x2 and y2. */
+ struct Tk_Item *prevPtr; /* Previous in display list of all items in
+ * this canvas. Later items in list are drawn
+ * just below earlier ones. */
+ Tk_State state; /* State of item. */
+ char *reserved1; /* reserved for future use */
+ int redraw_flags; /* Some flags used in the canvas */
/*
*------------------------------------------------------------------
- * Starting here is additional type-specific stuff; see the
- * declarations for individual types to see what is part of
- * each type. The actual space below is determined by the
- * "itemInfoSize" of the type's Tk_ItemType record.
+ * Starting here is additional type-specific stuff; see the declarations
+ * for individual types to see what is part of each type. The actual space
+ * below is determined by the "itemInfoSize" of the type's Tk_ItemType
+ * record.
*------------------------------------------------------------------
*/
} Tk_Item;
@@ -966,20 +963,19 @@ typedef struct Tk_Item {
/*
* Flag bits for canvases (redraw_flags):
*
- * TK_ITEM_STATE_DEPENDANT - 1 means that object needs to be
- * redrawn if the canvas state changes.
- * TK_ITEM_DONT_REDRAW - 1 means that the object redraw is already
- * been prepared, so the general canvas code
- * doesn't need to do that any more.
+ * TK_ITEM_STATE_DEPENDANT - 1 means that object needs to be redrawn if the
+ * canvas state changes.
+ * TK_ITEM_DONT_REDRAW - 1 means that the object redraw is already been
+ * prepared, so the general canvas code doesn't
+ * need to do that any more.
*/
#define TK_ITEM_STATE_DEPENDANT 1
#define TK_ITEM_DONT_REDRAW 2
/*
- * Records of the following type are used to describe a type of
- * item (e.g. lines, circles, etc.) that can form part of a
- * canvas widget.
+ * Records of the following type are used to describe a type of item (e.g.
+ * lines, circles, etc.) that can form part of a canvas widget.
*/
#ifdef USE_OLD_CANVAS
@@ -995,13 +991,13 @@ typedef int Tk_ItemCoordProc _ANSI_ARGS_((Tcl_Interp *interp,
#else
typedef int Tk_ItemCreateProc _ANSI_ARGS_((Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
- Tcl_Obj *CONST objv[]));
+ Tcl_Obj *const objv[]));
typedef int Tk_ItemConfigureProc _ANSI_ARGS_((Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
- Tcl_Obj *CONST objv[], int flags));
+ Tcl_Obj *const objv[], int flags));
typedef int Tk_ItemCoordProc _ANSI_ARGS_((Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
- Tcl_Obj *CONST argv[]));
+ Tcl_Obj *const argv[]));
#endif
typedef void Tk_ItemDeleteProc _ANSI_ARGS_((Tk_Canvas canvas,
Tk_Item *itemPtr, Display *display));
@@ -1035,100 +1031,103 @@ typedef void Tk_ItemDCharsProc _ANSI_ARGS_((Tk_Canvas canvas,
#ifndef __NO_OLD_CONFIG
typedef struct Tk_ItemType {
- char *name; /* The name of this type of item, such
- * as "line". */
- int itemSize; /* Total amount of space needed for
- * item's record. */
- Tk_ItemCreateProc *createProc; /* Procedure to create a new item of
- * this type. */
- Tk_ConfigSpec *configSpecs; /* Pointer to array of configuration
- * specs for this type. Used for
- * returning configuration info. */
- Tk_ItemConfigureProc *configProc; /* Procedure to call to change
- * configuration options. */
- Tk_ItemCoordProc *coordProc; /* Procedure to call to get and set
- * the item's coordinates. */
- Tk_ItemDeleteProc *deleteProc; /* Procedure to delete existing item of
- * this type. */
- Tk_ItemDisplayProc *displayProc; /* Procedure to display items of
- * this type. */
- int alwaysRedraw; /* Non-zero means displayProc should
- * be called even when the item has
- * been moved off-screen. */
- Tk_ItemPointProc *pointProc; /* Computes distance from item to
- * a given point. */
- Tk_ItemAreaProc *areaProc; /* Computes whether item is inside,
- * outside, or overlapping an area. */
+ char *name; /* The name of this type of item, such as
+ * "line". */
+ int itemSize; /* Total amount of space needed for item's
+ * record. */
+ Tk_ItemCreateProc *createProc;
+ /* Procedure to create a new item of this
+ * type. */
+ Tk_ConfigSpec *configSpecs; /* Pointer to array of configuration specs for
+ * this type. Used for returning configuration
+ * info. */
+ Tk_ItemConfigureProc *configProc;
+ /* Procedure to call to change configuration
+ * options. */
+ Tk_ItemCoordProc *coordProc;/* Procedure to call to get and set the item's
+ * coordinates. */
+ Tk_ItemDeleteProc *deleteProc;
+ /* Procedure to delete existing item of this
+ * type. */
+ Tk_ItemDisplayProc *displayProc;
+ /* Procedure to display items of this type. */
+ int alwaysRedraw; /* Non-zero means displayProc should be called
+ * even when the item has been moved
+ * off-screen. */
+ Tk_ItemPointProc *pointProc;/* Computes distance from item to a given
+ * point. */
+ Tk_ItemAreaProc *areaProc; /* Computes whether item is inside, outside,
+ * or overlapping an area. */
Tk_ItemPostscriptProc *postscriptProc;
- /* Procedure to write a Postscript
- * description for items of this
- * type. */
- Tk_ItemScaleProc *scaleProc; /* Procedure to rescale items of
- * this type. */
- Tk_ItemTranslateProc *translateProc;/* Procedure to translate items of
- * this type. */
- Tk_ItemIndexProc *indexProc; /* Procedure to determine index of
- * indicated character. NULL if
- * item doesn't support indexing. */
- Tk_ItemCursorProc *icursorProc; /* Procedure to set insert cursor pos.
- * to just before a given position. */
- Tk_ItemSelectionProc *selectionProc;/* Procedure to return selection (in
- * STRING format) when it is in this
- * item. */
- Tk_ItemInsertProc *insertProc; /* Procedure to insert something into
- * an item. */
- Tk_ItemDCharsProc *dCharsProc; /* Procedure to delete characters
- * from an item. */
- struct Tk_ItemType *nextPtr; /* Used to link types together into
- * a list. */
- char *reserved1; /* Reserved for future extension. */
- int reserved2; /* Carefully compatible with */
- char *reserved3; /* Jan Nijtmans dash patch */
+ /* Procedure to write a Postscript description
+ * for items of this type. */
+ Tk_ItemScaleProc *scaleProc;/* Procedure to rescale items of this type. */
+ Tk_ItemTranslateProc *translateProc;
+ /* Procedure to translate items of this
+ * type. */
+ Tk_ItemIndexProc *indexProc;/* Procedure to determine index of indicated
+ * character. NULL if item doesn't support
+ * indexing. */
+ Tk_ItemCursorProc *icursorProc;
+ /* Procedure to set insert cursor posn to just
+ * before a given position. */
+ Tk_ItemSelectionProc *selectionProc;
+ /* Procedure to return selection (in STRING
+ * format) when it is in this item. */
+ Tk_ItemInsertProc *insertProc;
+ /* Procedure to insert something into an
+ * item. */
+ Tk_ItemDCharsProc *dCharsProc;
+ /* Procedure to delete characters from an
+ * item. */
+ struct Tk_ItemType *nextPtr;/* Used to link types together into a list. */
+ char *reserved1; /* Reserved for future extension. */
+ int reserved2; /* Carefully compatible with */
+ char *reserved3; /* Jan Nijtmans dash patch */
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
- * those that display text. It is shared by the generic canvas code
- * and the item-specific code, but most of the fields should be written
- * only by the canvas generic code.
+ * The following structure provides information about the selection and the
+ * insertion cursor. It is needed by only a few items, such as those that
+ * display text. It is shared by the generic canvas code and the item-specific
+ * code, but most of the fields should be written only by the canvas generic
+ * code.
*/
typedef struct Tk_CanvasTextInfo {
Tk_3DBorder selBorder; /* Border and background for selected
- * characters. Read-only to items.*/
- int selBorderWidth; /* Width of border around selection.
- * Read-only to items. */
+ * characters. Read-only to items.*/
+ int selBorderWidth; /* Width of border around selection. Read-only
+ * to items. */
XColor *selFgColorPtr; /* Foreground color for selected text.
* Read-only to items. */
- Tk_Item *selItemPtr; /* Pointer to selected item. NULL means
- * selection isn't in this canvas.
- * Writable by items. */
+ Tk_Item *selItemPtr; /* Pointer to selected item. NULL means
+ * selection isn't in this canvas. 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; /* Character index of fixed end of
- * selection (i.e. "select to" operation will
- * use this as one end of the selection).
+ * 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; /* 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
+ * cursor. Read-only to items. */
+ int insertWidth; /* Total width of insertion cursor. Read-only
* to items. */
int insertBorderWidth; /* Width of 3-D border around insert cursor.
* Read-only to items. */
- Tk_Item *focusItemPtr; /* Item that currently has the input focus,
- * or NULL if no such item. Read-only to
- * items. */
+ Tk_Item *focusItemPtr; /* Item that currently has the input focus, or
+ * NULL if no such item. Read-only to items. */
int gotFocus; /* Non-zero means that the canvas widget has
- * the input focus. Read-only to items.*/
+ * the input focus. Read-only to items.*/
int cursorOn; /* Non-zero means that an insertion cursor
* should be displayed in focusItemPtr.
* Read-only to items.*/
@@ -1147,7 +1146,7 @@ typedef struct Tk_Dash {
} Tk_Dash;
typedef struct Tk_TSOffset {
- int flags; /* flags; see below for possible values */
+ int flags; /* Flags; see below for possible values */
int xoffset; /* x offset */
int yoffset; /* y offset */
} Tk_TSOffset;
@@ -1170,22 +1169,23 @@ typedef struct Tk_Outline {
double width; /* Width of outline. */
double activeWidth; /* Width of outline. */
double disabledWidth; /* Width of outline. */
- int offset; /* Dash offset */
- Tk_Dash dash; /* Dash pattern */
- Tk_Dash activeDash; /* Dash pattern if state is active*/
- Tk_Dash disabledDash; /* Dash pattern if state is disabled*/
- VOID *reserved1; /* reserved for future expansion */
+ int offset; /* Dash offset. */
+ Tk_Dash dash; /* Dash pattern. */
+ Tk_Dash activeDash; /* Dash pattern if state is active. */
+ Tk_Dash disabledDash; /* Dash pattern if state is disabled. */
+ VOID *reserved1; /* Reserved for future expansion. */
VOID *reserved2;
VOID *reserved3;
- Tk_TSOffset tsoffset; /* stipple offset for outline*/
+ Tk_TSOffset tsoffset; /* Stipple offset for outline. */
XColor *color; /* Outline color. */
XColor *activeColor; /* Outline color if state is active. */
XColor *disabledColor; /* Outline color if state is disabled. */
Pixmap stipple; /* Outline Stipple pattern. */
- Pixmap activeStipple; /* Outline Stipple pattern if state is active. */
- Pixmap disabledStipple; /* Outline Stipple pattern if state is disabled. */
+ Pixmap activeStipple; /* Outline Stipple pattern if state is
+ * active. */
+ Pixmap disabledStipple; /* Outline Stipple pattern if state is
+ * disabled. */
} Tk_Outline;
-
/*
*--------------------------------------------------------------
@@ -1202,7 +1202,7 @@ typedef int (Tk_ImageCreateProc) _ANSI_ARGS_((Tcl_Interp *interp,
Tk_ImageMaster master, ClientData *masterDataPtr));
#else
typedef int (Tk_ImageCreateProc) _ANSI_ARGS_((Tcl_Interp *interp,
- char *name, int objc, Tcl_Obj *CONST objv[], Tk_ImageType *typePtr,
+ char *name, int objc, Tcl_Obj *const objv[], Tk_ImageType *typePtr,
Tk_ImageMaster master, ClientData *masterDataPtr));
#endif
typedef ClientData (Tk_ImageGetProc) _ANSI_ARGS_((Tk_Window tkwin,
@@ -1221,39 +1221,37 @@ typedef int (Tk_ImagePostscriptProc) _ANSI_ARGS_((ClientData clientData,
int x, int y, int width, int height, int prepass));
/*
- * The following structure represents a particular type of image
- * (bitmap, xpm image, etc.). It provides information common to
- * all images of that type, such as the type name and a collection
- * of procedures in the image manager that respond to various
- * events. Each image manager is represented by one of these
- * structures.
+ * The following structure represents a particular type of image (bitmap, xpm
+ * image, etc.). It provides information common to all images of that type,
+ * such as the type name and a collection of procedures in the image manager
+ * that respond to various events. Each image manager is represented by one of
+ * these structures.
*/
struct Tk_ImageType {
char *name; /* Name of image type. */
Tk_ImageCreateProc *createProc;
- /* Procedure to call to create a new image
- * of this type. */
+ /* Procedure to call to create a new image of
+ * this type. */
Tk_ImageGetProc *getProc; /* Procedure to call the first time
- * Tk_GetImage is called in a new way
- * (new visual or screen). */
+ * Tk_GetImage is called in a new way (new
+ * visual or screen). */
Tk_ImageDisplayProc *displayProc;
/* Call to draw image, in response to
* Tk_RedrawImage calls. */
- Tk_ImageFreeProc *freeProc; /* Procedure to call whenever Tk_FreeImage
- * is called to release an instance of an
+ Tk_ImageFreeProc *freeProc; /* Procedure to call whenever Tk_FreeImage is
+ * called to release an instance of an
* image. */
Tk_ImageDeleteProc *deleteProc;
- /* Procedure to call to delete image. It
- * will not be called until after freeProc
- * has been called for each instance of the
- * image. */
+ /* Procedure to call to delete image. It will
+ * not be called until after freeProc has been
+ * called for each instance of the image. */
Tk_ImagePostscriptProc *postscriptProc;
/* Procedure to call to produce postscript
* output for the image. */
struct Tk_ImageType *nextPtr;
/* Next in list of all image types currently
- * known. Filled in by Tk, not by image
+ * known. Filled in by Tk, not by image
* manager. */
char *reserved; /* reserved for future expansion */
};
@@ -1267,8 +1265,8 @@ struct Tk_ImageType {
*/
/*
- * The following type is used to identify a particular photo image
- * to be manipulated:
+ * The following type is used to identify a particular photo image to be
+ * manipulated:
*/
typedef void *Tk_PhotoHandle;
@@ -1279,29 +1277,28 @@ typedef void *Tk_PhotoHandle;
typedef struct Tk_PhotoImageBlock {
unsigned char *pixelPtr; /* Pointer to the first pixel. */
- int width; /* Width of block, in pixels. */
- int height; /* Height of block, in pixels. */
- int pitch; /* Address difference between corresponding
+ int width; /* Width of block, in pixels. */
+ int height; /* Height of block, in pixels. */
+ int pitch; /* Address difference between corresponding
* pixels in successive lines. */
- int pixelSize; /* Address difference between successive
+ int pixelSize; /* Address difference between successive
* pixels in the same line. */
- int offset[4]; /* Address differences between the red, green,
+ int offset[4]; /* Address differences between the red, green,
* blue and alpha components of the pixel and
* the pixel as a whole. */
} Tk_PhotoImageBlock;
/*
- * The following values control how blocks are combined into photo
- * images when the alpha component of a pixel is not 255, a.k.a. the
- * compositing rule.
+ * The following values control how blocks are combined into photo images when
+ * the alpha component of a pixel is not 255, a.k.a. the compositing rule.
*/
#define TK_PHOTO_COMPOSITE_OVERLAY 0
#define TK_PHOTO_COMPOSITE_SET 1
/*
- * Procedure prototypes and structures used in reading and
- * writing photo images:
+ * Procedure prototypes and structures used in reading and writing photo
+ * images:
*/
typedef struct Tk_PhotoImageFormat Tk_PhotoImageFormat;
@@ -1324,68 +1321,61 @@ typedef int (Tk_ImageStringWriteProc) _ANSI_ARGS_((Tcl_Interp *interp,
Tk_PhotoImageBlock *blockPtr));
#else
typedef int (Tk_ImageFileMatchProc) _ANSI_ARGS_((Tcl_Channel chan,
- CONST char *fileName, Tcl_Obj *format, int *widthPtr,
+ const char *fileName, Tcl_Obj *format, int *widthPtr,
int *heightPtr, Tcl_Interp *interp));
typedef int (Tk_ImageStringMatchProc) _ANSI_ARGS_((Tcl_Obj *dataObj,
Tcl_Obj *format, int *widthPtr, int *heightPtr,
Tcl_Interp *interp));
typedef int (Tk_ImageFileReadProc) _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Channel chan, CONST char *fileName, Tcl_Obj *format,
+ Tcl_Channel chan, const char *fileName, Tcl_Obj *format,
Tk_PhotoHandle imageHandle, int destX, int destY,
int width, int height, int srcX, int srcY));
typedef int (Tk_ImageStringReadProc) _ANSI_ARGS_((Tcl_Interp *interp,
Tcl_Obj *dataObj, Tcl_Obj *format, Tk_PhotoHandle imageHandle,
int destX, int destY, int width, int height, int srcX, int srcY));
typedef int (Tk_ImageFileWriteProc) _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *fileName, Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr));
+ const char *fileName, Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr));
typedef int (Tk_ImageStringWriteProc) _ANSI_ARGS_((Tcl_Interp *interp,
Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr));
#endif
/*
- * The following structure represents a particular file format for
- * storing images (e.g., PPM, GIF, JPEG, etc.). It provides information
- * to allow image files of that format to be recognized and read into
- * a photo image.
+ * The following structure represents a particular file format for storing
+ * images (e.g., PPM, GIF, JPEG, etc.). It provides information to allow image
+ * files of that format to be recognized and read into a photo image.
*/
struct Tk_PhotoImageFormat {
char *name; /* Name of image file format */
Tk_ImageFileMatchProc *fileMatchProc;
- /* Procedure to call to determine whether
- * an image file matches this format. */
+ /* Procedure to call to determine whether an
+ * image file matches this format. */
Tk_ImageStringMatchProc *stringMatchProc;
- /* Procedure to call to determine whether
- * the data in a string matches this format. */
+ /* Procedure to call to determine whether the
+ * data in a string matches this format. */
Tk_ImageFileReadProc *fileReadProc;
- /* Procedure to call to read data from
- * an image file into a photo image. */
+ /* Procedure to call to read data from an
+ * image file into a photo image. */
Tk_ImageStringReadProc *stringReadProc;
- /* Procedure to call to read data from
- * a string into a photo image. */
+ /* Procedure to call to read data from a
+ * string into a photo image. */
Tk_ImageFileWriteProc *fileWriteProc;
- /* Procedure to call to write data from
- * a photo image to a file. */
+ /* Procedure to call to write data from a
+ * photo image to a file. */
Tk_ImageStringWriteProc *stringWriteProc;
/* Procedure to call to obtain a string
* representation of the data in a photo
* image.*/
struct Tk_PhotoImageFormat *nextPtr;
/* Next in list of all photo image formats
- * currently known. Filled in by Tk, not
- * by image format handler. */
+ * currently known. Filled in by Tk, not by
+ * image format handler. */
};
-EXTERN void Tk_CreateOldImageType _ANSI_ARGS_((
- Tk_ImageType *typePtr));
-EXTERN void Tk_CreateOldPhotoImageFormat _ANSI_ARGS_((
- Tk_PhotoImageFormat *formatPtr));
-
-#if !defined(USE_TK_STUBS) && defined(USE_OLD_IMAGE)
+#ifdef USE_OLD_IMAGE
#define Tk_CreateImageType Tk_CreateOldImageType
#define Tk_CreatePhotoImageFormat Tk_CreateOldPhotoImageFormat
#endif
-
/*
*--------------------------------------------------------------
@@ -1398,6 +1388,7 @@ EXTERN void Tk_CreateOldPhotoImageFormat _ANSI_ARGS_((
/*
* Style support version tag.
*/
+
#define TK_STYLE_VERSION_1 0x1
#define TK_STYLE_VERSION TK_STYLE_VERSION_1
@@ -1407,16 +1398,16 @@ EXTERN void Tk_CreateOldPhotoImageFormat _ANSI_ARGS_((
*/
typedef void (Tk_GetElementSizeProc) _ANSI_ARGS_((ClientData clientData,
- char *recordPtr, CONST Tk_OptionSpec **optionsPtr, Tk_Window tkwin,
+ char *recordPtr, const Tk_OptionSpec **optionsPtr, Tk_Window tkwin,
int width, int height, int inner, int *widthPtr, int *heightPtr));
typedef void (Tk_GetElementBoxProc) _ANSI_ARGS_((ClientData clientData,
- char *recordPtr, CONST Tk_OptionSpec **optionsPtr, Tk_Window tkwin,
+ char *recordPtr, const Tk_OptionSpec **optionsPtr, Tk_Window tkwin,
int x, int y, int width, int height, int inner, int *xPtr, int *yPtr,
int *widthPtr, int *heightPtr));
typedef int (Tk_GetElementBorderWidthProc) _ANSI_ARGS_((ClientData clientData,
- char *recordPtr, CONST Tk_OptionSpec **optionsPtr, Tk_Window tkwin));
+ char *recordPtr, const Tk_OptionSpec **optionsPtr, Tk_Window tkwin));
typedef void (Tk_DrawElementProc) _ANSI_ARGS_((ClientData clientData,
- char *recordPtr, CONST Tk_OptionSpec **optionsPtr, Tk_Window tkwin,
+ char *recordPtr, const Tk_OptionSpec **optionsPtr, Tk_Window tkwin,
Drawable d, int x, int y, int width, int height, int state));
typedef struct Tk_ElementOptionSpec {
@@ -1431,22 +1422,18 @@ typedef struct Tk_ElementSpec {
Tk_ElementOptionSpec *options;
/* List of required options. Last one's name
* must be NULL. */
-
- /*
- * Hooks
- */
-
Tk_GetElementSizeProc *getSize;
- /* Compute the external (resp. internal) size of
- * the element from its desired internal (resp.
- * external) size. */
+ /* Compute the external (resp. internal) size
+ * of the element from its desired internal
+ * (resp. external) size. */
Tk_GetElementBoxProc *getBox;
/* Compute the inscribed or bounding boxes
* within a given area. */
Tk_GetElementBorderWidthProc *getBorderWidth;
/* Return the element's internal border width.
* Mostly useful for widgets. */
- Tk_DrawElementProc *draw; /* Draw the element in the given bounding box.*/
+ Tk_DrawElementProc *draw; /* Draw the element in the given bounding
+ * box. */
} Tk_ElementSpec;
/*
@@ -1461,9 +1448,9 @@ typedef struct Tk_ElementSpec {
/*
*--------------------------------------------------------------
*
- * The definitions below provide backward compatibility for
- * functions and types related to event handling that used to
- * be in Tk but have moved to Tcl.
+ * The definitions below provide backward compatibility for functions and
+ * types related to event handling that used to be in Tk but have moved to
+ * Tcl.
*
*--------------------------------------------------------------
*/
@@ -1506,23 +1493,20 @@ typedef struct Tk_ElementSpec {
#define Tk_Main(argc, argv, proc) \
Tk_MainEx(argc, argv, proc, Tcl_CreateInterp())
-CONST char *Tk_InitStubs _ANSI_ARGS_((Tcl_Interp *interp, char *version, int exact));
+const char * Tk_InitStubs _ANSI_ARGS_((Tcl_Interp *interp,
+ const char *version, int exact));
+EXTERN const char * Tk_PkgInitStubsCheck _ANSI_ARGS_((Tcl_Interp *interp,
+ const char *version, int exact));
#ifndef USE_TK_STUBS
#define Tk_InitStubs(interp, version, exact) \
- Tcl_PkgRequire(interp, "Tk", version, exact)
+ Tk_PkgInitStubsCheck(interp, version, exact)
#endif
-void Tk_InitImageArgs _ANSI_ARGS_((Tcl_Interp *interp, int argc, char ***argv));
-
-#if !defined(USE_TK_STUBS) || !defined(USE_OLD_IMAGE)
-
#define Tk_InitImageArgs(interp, argc, argv) /**/
-#endif
-
/*
*--------------------------------------------------------------
@@ -1548,7 +1532,6 @@ typedef Tk_RestrictAction (Tk_RestrictProc) _ANSI_ARGS_((
typedef int (Tk_SelectionProc) _ANSI_ARGS_((ClientData clientData,
int offset, char *buffer, int maxBytes));
-
/*
*--------------------------------------------------------------
*
@@ -1560,12 +1543,11 @@ typedef int (Tk_SelectionProc) _ANSI_ARGS_((ClientData clientData,
#include "tkDecls.h"
/*
- * Allow users to say that they don't want to alter their source to
- * add the extra argument to Tk_PhotoPutBlock(); DO NOT DEFINE THIS
- * WHEN BUILDING TK.
+ * Allow users to say that they don't want to alter their source to add extra
+ * arguments to Tk_PhotoPutBlock() et al; DO NOT DEFINE THIS WHEN BUILDING TK.
*
- * This goes after the inclusion of the stubbed-decls so that the
- * declarations of what is actually there can be correct.
+ * This goes after the inclusion of the stubbed-decls so that the declarations
+ * of what is actually there can be correct.
*/
#ifdef USE_COMPOSITELESS_PHOTO_PUT_BLOCK
@@ -1577,13 +1559,34 @@ typedef int (Tk_SelectionProc) _ANSI_ARGS_((ClientData clientData,
# undef Tk_PhotoPutZoomedBlock
# endif
# define Tk_PhotoPutZoomedBlock Tk_PhotoPutZoomedBlock_NoComposite
+# define USE_PANIC_ON_PHOTO_ALLOC_FAILURE
+#else /* !USE_COMPOSITELESS_PHOTO_PUT_BLOCK */
+# ifdef USE_PANIC_ON_PHOTO_ALLOC_FAILURE
+# ifdef Tk_PhotoPutBlock
+# undef Tk_PhotoPutBlock
+# endif
+# define Tk_PhotoPutBlock Tk_PhotoPutBlock_Panic
+# ifdef Tk_PhotoPutZoomedBlock
+# undef Tk_PhotoPutZoomedBlock
+# endif
+# define Tk_PhotoPutZoomedBlock Tk_PhotoPutZoomedBlock_Panic
+# endif /* USE_PANIC_ON_PHOTO_ALLOC_FAILURE */
#endif /* USE_COMPOSITELESS_PHOTO_PUT_BLOCK */
+#ifdef USE_PANIC_ON_PHOTO_ALLOC_FAILURE
+# ifdef Tk_PhotoExpand
+# undef Tk_PhotoExpand
+# endif
+# define Tk_PhotoExpand Tk_PhotoExpand_Panic
+# ifdef Tk_PhotoSetSize
+# undef Tk_PhotoSetSize
+# endif
+# define Tk_PhotoSetSize Tk_PhotoSetSize_Panic
+#endif /* USE_PANIC_ON_PHOTO_ALLOC_FAILURE */
/*
* Tcl commands exported by Tk:
*/
-
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
@@ -1592,9 +1595,17 @@ typedef int (Tk_SelectionProc) _ANSI_ARGS_((ClientData clientData,
/*
* end block for C++
*/
-
+
#ifdef __cplusplus
}
#endif
-
+
#endif /* _TK */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tk3d.c b/generic/tk3d.c
index 4d9d163..caa40dd 100644
--- a/generic/tk3d.c
+++ b/generic/tk3d.c
@@ -1,40 +1,41 @@
-/*
+/*
* tk3d.c --
*
- * This module provides procedures to draw borders in
- * the three-dimensional Motif style.
+ * This module provides procedures to draw borders in the
+ * three-dimensional Motif style.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
+#include "tkInt.h"
#include "tk3d.h"
/*
- * The following table defines the string values for reliefs, which are
- * used by Tk_GetReliefFromObj.
+ * The following table defines the string values for reliefs, which are used
+ * by Tk_GetReliefFromObj.
*/
-static CONST char *reliefStrings[] = {"flat", "groove", "raised",
- "ridge", "solid", "sunken",
- (char *) NULL};
+static CONST char *reliefStrings[] = {
+ "flat", "groove", "raised", "ridge", "solid", "sunken", NULL
+};
/*
- * Forward declarations for procedures defined in this file:
+ * Forward declarations for functions defined in this file:
*/
-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));
+static void BorderInit(TkDisplay *dispPtr);
+static void DupBorderObjProc(Tcl_Obj *srcObjPtr,
+ Tcl_Obj *dupObjPtr);
+static void FreeBorderObjProc(Tcl_Obj *objPtr);
+static int Intersect(XPoint *a1Ptr, XPoint *a2Ptr,
+ XPoint *b1Ptr, XPoint *b2Ptr, XPoint *iPtr);
+static void InitBorderObj(Tcl_Obj *objPtr);
+static void ShiftLine(XPoint *p1Ptr, XPoint *p2Ptr,
+ int distance, XPoint *p3Ptr);
/*
* The following structure defines the implementation of the "border" Tcl
@@ -57,30 +58,30 @@ Tcl_ObjType tkBorderObjType = {
*
* Tk_Alloc3DBorderFromObj --
*
- * Given a Tcl_Obj *, map the value to a corresponding
- * Tk_3DBorder structure based on the tkwin given.
+ * 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.
+ * The return value is a token for a data structure describing a 3-D
+ * border. This token may be passed to functions 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 FreeBorderObjProc so that the database is
- * cleaned up when borders aren't in use anymore.
+ * The border is added to an internal database with a reference count.
+ * For each call to this function, there should eventually be a call to
+ * FreeBorderObjProc 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
+Tk_Alloc3DBorderFromObj(
+ 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;
@@ -91,15 +92,15 @@ Tk_Alloc3DBorderFromObj(interp, tkwin, 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 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.
+ * This is a stale reference: it refers to a border that's no
+ * longer in use. Clear the reference.
*/
FreeBorderObjProc(objPtr);
@@ -112,24 +113,22 @@ Tk_Alloc3DBorderFromObj(interp, tkwin, objPtr)
}
/*
- * 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.
+ * 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 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 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 *firstBorderPtr =
(TkBorder *) Tcl_GetHashValue(borderPtr->hashPtr);
FreeBorderObjProc(objPtr);
for (borderPtr = firstBorderPtr ; borderPtr != NULL;
@@ -138,19 +137,19 @@ Tk_Alloc3DBorderFromObj(interp, tkwin, objPtr)
&& (Tk_Colormap(tkwin) == borderPtr->colormap)) {
borderPtr->resourceRefCount++;
borderPtr->objRefCount++;
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) borderPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr;
return (Tk_3DBorder) borderPtr;
}
}
}
/*
- * Still no luck. Call Tk_Get3DBorder to allocate a new border.
+ * 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;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr;
if (borderPtr != NULL) {
borderPtr->objRefCount++;
}
@@ -165,31 +164,31 @@ Tk_Alloc3DBorderFromObj(interp, tkwin, objPtr)
* 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 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.
+ * The return value is a token for a data structure describing a 3-D
+ * border. This token may be passed to functions 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.
- * It is the caller's responsibility to eventually call
- * Tk_Free3DBorder to release the resources.
+ * Data structures, graphics contexts, etc. are allocated. It is the
+ * caller's responsibility to eventually call Tk_Free3DBorder to release
+ * the resources.
*
*--------------------------------------------------------------
*/
Tk_3DBorder
-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
- * for window background. */
+Tk_Get3DBorder(
+ 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 for window
+ * background. */
{
Tcl_HashEntry *hashPtr;
TkBorder *borderPtr, *existingBorderPtr;
- int new;
+ int isNew;
XGCValues gcValues;
XColor *bgColorPtr;
TkDisplay *dispPtr;
@@ -200,8 +199,8 @@ Tk_Get3DBorder(interp, tkwin, colorName)
BorderInit(dispPtr);
}
- hashPtr = Tcl_CreateHashEntry(&dispPtr->borderTable, colorName, &new);
- if (!new) {
+ hashPtr = Tcl_CreateHashEntry(&dispPtr->borderTable, colorName, &isNew);
+ if (!isNew) {
existingBorderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr);
for (borderPtr = existingBorderPtr; borderPtr != NULL;
borderPtr = borderPtr->nextPtr) {
@@ -216,12 +215,12 @@ Tk_Get3DBorder(interp, tkwin, colorName)
}
/*
- * No satisfactory border exists yet. Initialize a new one.
+ * No satisfactory border exists yet. Initialize a new one.
*/
bgColorPtr = Tk_GetColor(interp, tkwin, colorName);
if (bgColorPtr == NULL) {
- if (new) {
+ if (isNew) {
Tcl_DeleteHashEntry(hashPtr);
}
return NULL;
@@ -246,9 +245,8 @@ Tk_Get3DBorder(interp, tkwin, colorName)
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.
+ * 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;
@@ -267,25 +265,24 @@ Tk_Get3DBorder(interp, tkwin, colorName)
* None.
*
* Side effects:
- * A 3-D border will be drawn in the indicated drawable.
- * The outside edges of the border will be determined by x,
- * y, width, and height. The inside edges of the border
- * will be determined by the borderWidth argument.
+ * A 3-D border will be drawn in the indicated drawable. The outside
+ * edges of the border will be determined by x, y, width, and height. The
+ * inside edges of the border will be determined by the borderWidth
+ * argument.
*
*--------------------------------------------------------------
*/
void
-Tk_Draw3DRectangle(tkwin, drawable, border, x, y, width, height,
- borderWidth, relief)
- Tk_Window tkwin; /* Window for which border was allocated. */
- Drawable drawable; /* X window or pixmap in which to draw. */
- Tk_3DBorder border; /* Token for border to draw. */
- int x, y, width, height; /* Outside area of region in
- * which border will be drawn. */
- int borderWidth; /* Desired width for border, in
- * pixels. */
- int relief; /* Type of relief: TK_RELIEF_RAISED,
+Tk_Draw3DRectangle(
+ Tk_Window tkwin, /* Window for which border was allocated. */
+ Drawable drawable, /* X window or pixmap in which to draw. */
+ Tk_3DBorder border, /* Token for border to draw. */
+ int x, int y, int width, int height,
+ /* Outside area of region in which border will
+ * be drawn. */
+ int borderWidth, /* Desired width for border, in pixels. */
+ int relief) /* Type of relief: TK_RELIEF_RAISED,
* TK_RELIEF_SUNKEN, TK_RELIEF_GROOVE, etc. */
{
if (width < 2*borderWidth) {
@@ -309,12 +306,11 @@ Tk_Draw3DRectangle(tkwin, drawable, border, x, y, width, height,
*
* Tk_NameOf3DBorder --
*
- * Given a border, return a textual string identifying the
- * border's color.
+ * Given a border, return a textual string identifying the border's
+ * color.
*
* Results:
- * The return value is the string that was used to create
- * the border.
+ * The return value is the string that was used to create the border.
*
* Side effects:
* None.
@@ -323,8 +319,8 @@ Tk_Draw3DRectangle(tkwin, drawable, border, x, y, width, height,
*/
CONST char *
-Tk_NameOf3DBorder(border)
- Tk_3DBorder border; /* Token for border. */
+Tk_NameOf3DBorder(
+ Tk_3DBorder border) /* Token for border. */
{
TkBorder *borderPtr = (TkBorder *) border;
@@ -336,8 +332,7 @@ Tk_NameOf3DBorder(border)
*
* Tk_3DBorderColor --
*
- * Given a 3D border, return the X color used for the "flat"
- * surfaces.
+ * Given a 3D border, return the X color used for the "flat" surfaces.
*
* Results:
* Returns the color used drawing flat surfaces with the border.
@@ -348,10 +343,10 @@ Tk_NameOf3DBorder(border)
*--------------------------------------------------------------------
*/
XColor *
-Tk_3DBorderColor(border)
- Tk_3DBorder border; /* Border whose color is wanted. */
+Tk_3DBorderColor(
+ Tk_3DBorder border) /* Border whose color is wanted. */
{
- return(((TkBorder *) border)->bgColorPtr);
+ return ((TkBorder *) border)->bgColorPtr;
}
/*
@@ -359,8 +354,8 @@ Tk_3DBorderColor(border)
*
* Tk_3DBorderGC --
*
- * Given a 3D border, returns one of the graphics contexts used to
- * draw the border.
+ * Given a 3D border, returns one of the graphics contexts used to draw
+ * the border.
*
* Results:
* Returns the graphics context given by the "which" argument.
@@ -371,10 +366,10 @@ Tk_3DBorderColor(border)
*--------------------------------------------------------------------
*/
GC
-Tk_3DBorderGC(tkwin, border, which)
- Tk_Window tkwin; /* Window for which border was allocated. */
- Tk_3DBorder border; /* Border whose GC is wanted. */
- int which; /* Selects one of the border's 3 GC's:
+Tk_3DBorderGC(
+ Tk_Window tkwin, /* Window for which border was allocated. */
+ Tk_3DBorder border, /* Border whose GC is wanted. */
+ int which) /* Selects one of the border's 3 GC's:
* TK_3D_FLAT_GC, TK_3D_LIGHT_GC, or
* TK_3D_DARK_GC. */
{
@@ -390,11 +385,11 @@ Tk_3DBorderGC(tkwin, border, which)
} else if (which == TK_3D_DARK_GC){
return borderPtr->darkGC;
}
- panic("bogus \"which\" value in Tk_3DBorderGC");
+ Tcl_Panic("bogus \"which\" value in Tk_3DBorderGC");
/*
- * The code below will never be executed, but it's needed to
- * keep compilers happy.
+ * The code below will never be executed, but it's needed to keep
+ * compilers happy.
*/
return (GC) None;
@@ -405,10 +400,9 @@ Tk_3DBorderGC(tkwin, border, which)
*
* Tk_Free3DBorder --
*
- * This procedure is called when a 3D border is no longer
- * needed. It frees the resources associated with the
- * border. After this call, the caller should never again
- * use the "border" token.
+ * This function is called when a 3D border is no longer needed. It frees
+ * the resources associated with the border. After this call, the caller
+ * should never again use the "border" token.
*
* Results:
* None.
@@ -420,8 +414,8 @@ Tk_3DBorderGC(tkwin, border, which)
*/
void
-Tk_Free3DBorder(border)
- Tk_3DBorder border; /* Token for border to be released. */
+Tk_Free3DBorder(
+ Tk_3DBorder border) /* Token for border to be released. */
{
TkBorder *borderPtr = (TkBorder *) border;
Display *display = DisplayOfScreen(borderPtr->screen);
@@ -477,27 +471,27 @@ 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.
+ * This function 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.
+ * 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_Free3DBorderFromObj(
+ 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(objPtr);
@@ -506,66 +500,65 @@ Tk_Free3DBorderFromObj(tkwin, objPtr)
/*
*---------------------------------------------------------------------------
*
- * FreeBorderObjProc --
+ * 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.
+ * 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.
+ * 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. */
+FreeBorderObjProc(
+ Tcl_Obj *objPtr) /* The object we are releasing. */
{
TkBorder *borderPtr = (TkBorder *) objPtr->internalRep.twoPtrValue.ptr1;
if (borderPtr != NULL) {
borderPtr->objRefCount--;
- if ((borderPtr->objRefCount == 0)
+ if ((borderPtr->objRefCount == 0)
&& (borderPtr->resourceRefCount == 0)) {
ckfree((char *) borderPtr);
}
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
+ objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}
}
/*
*---------------------------------------------------------------------------
*
- * DupBorderObjProc --
+ * DupBorderObjProc --
*
- * When a cached border object is duplicated, this is called to
- * update the internal reps.
+ * 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.
+ * 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. */
+DupBorderObjProc(
+ 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;
+ dupObjPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr;
if (borderPtr != NULL) {
borderPtr->objRefCount++;
@@ -577,8 +570,8 @@ DupBorderObjProc(srcObjPtr, dupObjPtr)
*
* Tk_SetBackgroundFromBorder --
*
- * Change the background of a window to one appropriate for a given
- * 3-D border.
+ * Change the background of a window to one appropriate for a given 3-D
+ * border.
*
* Results:
* None.
@@ -590,9 +583,9 @@ DupBorderObjProc(srcObjPtr, dupObjPtr)
*/
void
-Tk_SetBackgroundFromBorder(tkwin, border)
- Tk_Window tkwin; /* Window whose background is to be set. */
- Tk_3DBorder border; /* Token for border. */
+Tk_SetBackgroundFromBorder(
+ Tk_Window tkwin, /* Window whose background is to be set. */
+ Tk_3DBorder border) /* Token for border. */
{
register TkBorder *borderPtr = (TkBorder *) border;
@@ -618,13 +611,13 @@ Tk_SetBackgroundFromBorder(tkwin, border)
*/
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. */
+Tk_GetReliefFromObj(
+ 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,
+ return Tcl_GetIndexFromObj(interp, objPtr, reliefStrings, "relief", 0,
resultPtr);
}
@@ -633,13 +626,13 @@ Tk_GetReliefFromObj(interp, objPtr, resultPtr)
*
* Tk_GetRelief --
*
- * Parse a relief description and return the corresponding
- * relief value, or an error.
+ * Parse a relief description and return the corresponding relief value,
+ * or an error.
*
* Results:
- * A standard Tcl return value. If all goes well then
- * *reliefPtr is filled in with one of the values
- * TK_RELIEF_RAISED, TK_RELIEF_FLAT, or TK_RELIEF_SUNKEN.
+ * A standard Tcl return value. If all goes well then *reliefPtr is
+ * filled in with one of the values TK_RELIEF_RAISED, TK_RELIEF_FLAT, or
+ * TK_RELIEF_SUNKEN.
*
* Side effects:
* None.
@@ -648,10 +641,10 @@ Tk_GetReliefFromObj(interp, objPtr, resultPtr)
*/
int
-Tk_GetRelief(interp, name, reliefPtr)
- Tcl_Interp *interp; /* For error messages. */
- CONST char *name; /* Name of a relief type. */
- int *reliefPtr; /* Where to store converted relief. */
+Tk_GetRelief(
+ Tcl_Interp *interp, /* For error messages. */
+ CONST char *name, /* Name of a relief type. */
+ int *reliefPtr) /* Where to store converted relief. */
{
char c;
size_t length;
@@ -688,12 +681,10 @@ Tk_GetRelief(interp, name, reliefPtr)
*
* Tk_NameOfRelief --
*
- * Given a relief value, produce a string describing that
- * relief value.
+ * Given a relief value, produce a string describing that relief value.
*
* Results:
- * The return value is a static string that is equivalent
- * to relief.
+ * The return value is a static string that is equivalent to relief.
*
* Side effects:
* None.
@@ -702,9 +693,9 @@ Tk_GetRelief(interp, name, reliefPtr)
*/
CONST char *
-Tk_NameOfRelief(relief)
- int relief; /* One of TK_RELIEF_FLAT, TK_RELIEF_RAISED,
- * or TK_RELIEF_SUNKEN. */
+Tk_NameOfRelief(
+ int relief) /* One of TK_RELIEF_FLAT, TK_RELIEF_RAISED, or
+ * TK_RELIEF_SUNKEN. */
{
if (relief == TK_RELIEF_FLAT) {
return "flat";
@@ -730,39 +721,35 @@ Tk_NameOfRelief(relief)
*
* Tk_Draw3DPolygon --
*
- * Draw a border with 3-D appearance around the edge of a
- * given polygon.
+ * Draw a border with 3-D appearance around the edge of a given polygon.
*
* Results:
* None.
*
* Side effects:
- * Information is drawn in "drawable" in the form of a
- * 3-D border borderWidth units width wide on the left
- * of the trajectory given by pointPtr and numPoints (or
- * -borderWidth units wide on the right side, if borderWidth
- * is negative).
+ * Information is drawn in "drawable" in the form of a 3-D border
+ * borderWidth units width wide on the left of the trajectory given by
+ * pointPtr and numPoints (or -borderWidth units wide on the right side,
+ * if borderWidth is negative).
*
*--------------------------------------------------------------
*/
void
-Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
- borderWidth, leftRelief)
- Tk_Window tkwin; /* Window for which border was allocated. */
- Drawable drawable; /* X window or pixmap in which to draw. */
- Tk_3DBorder border; /* Token for border to draw. */
- XPoint *pointPtr; /* Array of points describing
- * polygon. All points must be
- * absolute (CoordModeOrigin). */
- int numPoints; /* Number of points at *pointPtr. */
- int borderWidth; /* Width of border, measured in
- * pixels to the left of the polygon's
- * trajectory. May be negative. */
- int leftRelief; /* TK_RELIEF_RAISED or
- * TK_RELIEF_SUNKEN: indicates how
- * stuff to left of trajectory looks
- * relative to stuff on right. */
+Tk_Draw3DPolygon(
+ Tk_Window tkwin, /* Window for which border was allocated. */
+ Drawable drawable, /* X window or pixmap in which to draw. */
+ Tk_3DBorder border, /* Token for border to draw. */
+ XPoint *pointPtr, /* Array of points describing polygon. All
+ * points must be absolute
+ * (CoordModeOrigin). */
+ int numPoints, /* Number of points at *pointPtr. */
+ int borderWidth, /* Width of border, measured in pixels to the
+ * left of the polygon's trajectory. May be
+ * negative. */
+ int leftRelief) /* TK_RELIEF_RAISED or TK_RELIEF_SUNKEN:
+ * indicates how stuff to left of trajectory
+ * looks relative to stuff on right. */
{
XPoint poly[4], b1, b2, newB1, newB2;
XPoint perp, c, shift1, shift2; /* Used for handling parallel lines. */
@@ -794,8 +781,8 @@ Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
}
/*
- * If the polygon is already closed, drop the last point from it
- * (we'll close it automatically).
+ * If the polygon is already closed, drop the last point from it (we'll
+ * close it automatically).
*/
p1Ptr = &pointPtr[numPoints-1];
@@ -805,8 +792,8 @@ Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
}
/*
- * The loop below is executed once for each vertex in the polgon.
- * At the beginning of each iteration things look like this:
+ * The loop below is executed once for each vertex in the polgon. At the
+ * beginning of each iteration things look like this:
*
* poly[1] /
* * /
@@ -824,23 +811,21 @@ Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
* x-------------------------
*
* The job of this iteration is to do the following:
- * (a) Compute x (the border corner corresponding to
- * pointPtr[i]) and put it in poly[2]. As part of
- * this, compute a new b1 and b2 value for the next
- * side of the polygon.
+ * (a) Compute x (the border corner corresponding to pointPtr[i]) and put
+ * it in poly[2]. As part of this, compute a new b1 and b2 value for
+ * the next side of the polygon.
* (b) Put pointPtr[i] into poly[3].
* (c) Draw the polygon given by poly[0..3].
- * (d) Advance poly[0], poly[1], b1, and b2 for the
- * next side of the polygon.
+ * (d) Advance poly[0], poly[1], b1, and b2 for the next side of the
+ * polygon.
*/
/*
- * The above situation doesn't first come into existence until
- * two points have been processed; the first two points are
- * used to "prime the pump", so some parts of the processing
- * are ommitted for these points. The variable "pointsSeen"
- * keeps track of the priming process; it has to be separate
- * from i in order to be able to ignore duplicate points in the
+ * The above situation doesn't first come into existence until two points
+ * have been processed; the first two points are used to "prime the pump",
+ * so some parts of the processing are ommitted for these points. The
+ * variable "pointsSeen" keeps track of the priming process; it has to be
+ * separate from i in order to be able to ignore duplicate points in the
* polygon.
*/
@@ -852,9 +837,10 @@ Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
}
if ((p2Ptr->x == p1Ptr->x) && (p2Ptr->y == p1Ptr->y)) {
/*
- * Ignore duplicate points (they'd cause core dumps in
- * ShiftLine calls below).
+ * Ignore duplicate points (they'd cause core dumps in ShiftLine
+ * calls below).
*/
+
continue;
}
ShiftLine(p1Ptr, p2Ptr, borderWidth, &newB1);
@@ -866,9 +852,8 @@ Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
parallel = Intersect(&newB1, &newB2, &b1, &b2, &poly[2]);
/*
- * If two consecutive segments of the polygon are parallel,
- * then things get more complex. Consider the following
- * diagram:
+ * If two consecutive segments of the polygon are parallel, then
+ * things get more complex. Consider the following diagram:
*
* poly[1]
* *----b1-----------b2------a
@@ -880,16 +865,16 @@ Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
* --*--------*----c
* newB1 newB2
*
- * Instead of using x and *p1Ptr for poly[2] and poly[3], as
- * in the original diagram, use a and b as above. Then instead
- * of using x and *p1Ptr for the new poly[0] and poly[1], use
- * b and c as above.
+ * Instead of using x and *p1Ptr for poly[2] and poly[3], as in
+ * the original diagram, use a and b as above. Then instead of
+ * using x and *p1Ptr for the new poly[0] and poly[1], use b and c
+ * as above.
*
* Do the computation in three stages:
- * 1. Compute a point "perp" such that the line p1Ptr-perp
- * is perpendicular to p1Ptr-p2Ptr.
- * 2. Compute the points a and c by intersecting the lines
- * b1-b2 and newB1-newB2 with p1Ptr-perp.
+ * 1. Compute a point "perp" such that the line p1Ptr-perp is
+ * perpendicular to p1Ptr-p2Ptr.
+ * 2. Compute the points a and c by intersecting the lines b1-b2
+ * and newB1-newB2 with p1Ptr-perp.
* 3. Compute b by shifting p1Ptr-perp to the right and
* intersecting it with p1Ptr-p2Ptr.
*/
@@ -955,33 +940,34 @@ Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
*/
void
-Tk_Fill3DRectangle(tkwin, drawable, border, x, y, width,
- height, borderWidth, relief)
- Tk_Window tkwin; /* Window for which border was allocated. */
- Drawable drawable; /* X window or pixmap in which to draw. */
- Tk_3DBorder border; /* Token for border to draw. */
- int x, y, width, height; /* Outside area of rectangular region. */
- int borderWidth; /* Desired width for border, in
- * pixels. Border will be *inside* region. */
- int relief; /* Indicates 3D effect: TK_RELIEF_FLAT,
+Tk_Fill3DRectangle(
+ Tk_Window tkwin, /* Window for which border was allocated. */
+ Drawable drawable, /* X window or pixmap in which to draw. */
+ Tk_3DBorder border, /* Token for border to draw. */
+ int x, int y, int width, int height,
+ /* Outside area of rectangular region. */
+ int borderWidth, /* Desired width for border, in pixels. Border
+ * will be *inside* region. */
+ int relief) /* Indicates 3D effect: TK_RELIEF_FLAT,
* TK_RELIEF_RAISED, or TK_RELIEF_SUNKEN. */
{
register TkBorder *borderPtr = (TkBorder *) border;
int doubleBorder;
/*
- * This code is slightly tricky because it only draws the background
- * in areas not covered by the 3D border. This avoids flashing
- * effects on the screen for the border region.
+ * This code is slightly tricky because it only draws the background in
+ * areas not covered by the 3D border. This avoids flashing effects on the
+ * screen for the border region.
*/
-
+
if (relief == TK_RELIEF_FLAT) {
borderWidth = 0;
} else {
/*
- * We need to make this extra check, otherwise we will leave
- * garbage in thin frames [Bug: 3596]
+ * We need to make this extra check, otherwise we will leave garbage
+ * in thin frames [Bug: 3596]
*/
+
if (width < 2*borderWidth) {
borderWidth = width/2;
}
@@ -1020,22 +1006,21 @@ Tk_Fill3DRectangle(tkwin, drawable, border, x, y, width,
*/
void
-Tk_Fill3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
- borderWidth, leftRelief)
- Tk_Window tkwin; /* Window for which border was allocated. */
- Drawable drawable; /* X window or pixmap in which to draw. */
- Tk_3DBorder border; /* Token for border to draw. */
- XPoint *pointPtr; /* Array of points describing
- * polygon. All points must be
- * absolute (CoordModeOrigin). */
- int numPoints; /* Number of points at *pointPtr. */
- int borderWidth; /* Width of border, measured in
- * pixels to the left of the polygon's
- * trajectory. May be negative. */
- int leftRelief; /* Indicates 3D effect of left side of
+Tk_Fill3DPolygon(
+ Tk_Window tkwin, /* Window for which border was allocated. */
+ Drawable drawable, /* X window or pixmap in which to draw. */
+ Tk_3DBorder border, /* Token for border to draw. */
+ XPoint *pointPtr, /* Array of points describing polygon. All
+ * points must be absolute
+ * (CoordModeOrigin). */
+ int numPoints, /* Number of points at *pointPtr. */
+ int borderWidth, /* Width of border, measured in pixels to the
+ * left of the polygon's trajectory. May be
+ * negative. */
+ int leftRelief) /* Indicates 3D effect of left side of
* trajectory relative to right:
- * TK_RELIEF_FLAT, TK_RELIEF_RAISED,
- * or TK_RELIEF_SUNKEN. */
+ * TK_RELIEF_FLAT, TK_RELIEF_RAISED, or
+ * TK_RELIEF_SUNKEN. */
{
register TkBorder *borderPtr = (TkBorder *) border;
@@ -1064,8 +1049,8 @@ Tk_Fill3DPolygon(tkwin, drawable, border, pointPtr, numPoints,
*/
static void
-BorderInit(dispPtr)
- TkDisplay * dispPtr; /* Used to access thread-specific data. */
+BorderInit(
+ TkDisplay *dispPtr) /* Used to access thread-specific data. */
{
dispPtr->borderInit = 1;
Tcl_InitHashTable(&dispPtr->borderTable, TCL_STRING_KEYS);
@@ -1076,9 +1061,8 @@ BorderInit(dispPtr)
*
* ShiftLine --
*
- * Given two points on a line, compute a point on a
- * new line that is parallel to the given line and
- * a given distance away from it.
+ * Given two points on a line, compute a point on a new line that is
+ * parallel to the given line and a given distance away from it.
*
* Results:
* None.
@@ -1090,36 +1074,31 @@ BorderInit(dispPtr)
*/
static void
-ShiftLine(p1Ptr, p2Ptr, distance, p3Ptr)
- XPoint *p1Ptr; /* First point on line. */
- XPoint *p2Ptr; /* Second point on line. */
- int distance; /* New line is to be this many
- * units to the left of original
- * line, when looking from p1 to
- * p2. May be negative. */
- XPoint *p3Ptr; /* Store coords of point on new
- * line here. */
+ShiftLine(
+ XPoint *p1Ptr, /* First point on line. */
+ XPoint *p2Ptr, /* Second point on line. */
+ int distance, /* New line is to be this many units to the
+ * left of original line, when looking from p1
+ * to p2. May be negative. */
+ XPoint *p3Ptr) /* Store coords of point on new line here. */
{
int dx, dy, dxNeg, dyNeg;
/*
- * The table below is used for a quick approximation in
- * computing the new point. An index into the table
- * is 128 times the slope of the original line (the slope
- * must always be between 0 and 1). The value of the table
- * entry is 128 times the amount to displace the new line
- * in y for each unit of perpendicular distance. In other
- * words, the table maps from the tangent of an angle to
- * the inverse of its cosine. If the slope of the original
- * line is greater than 1, then the displacement is done in
- * x rather than in y.
+ * The table below is used for a quick approximation in computing the new
+ * point. An index into the table is 128 times the slope of the original
+ * line (the slope must always be between 0 and 1). The value of the table
+ * entry is 128 times the amount to displace the new line in y for each
+ * unit of perpendicular distance. In other words, the table maps from the
+ * tangent of an angle to the inverse of its cosine. If the slope of the
+ * original line is greater than 1, then the displacement is done in x
+ * rather than in y.
*/
static int shiftTable[129];
/*
- * Initialize the table if this is the first time it is
- * used.
+ * Initialize the table if this is the first time it is used.
*/
if (shiftTable[0] == 0) {
@@ -1171,10 +1150,9 @@ ShiftLine(p1Ptr, p2Ptr, distance, p3Ptr)
* Find the intersection point between two lines.
*
* Results:
- * Under normal conditions 0 is returned and the point
- * at *iPtr is filled in with the intersection between
- * the two lines. If the two lines are parallel, then
- * -1 is returned and *iPtr isn't modified.
+ * Under normal conditions 0 is returned and the point at *iPtr is filled
+ * in with the intersection between the two lines. If the two lines are
+ * parallel, then -1 is returned and *iPtr isn't modified.
*
* Side effects:
* None.
@@ -1183,19 +1161,19 @@ ShiftLine(p1Ptr, p2Ptr, distance, p3Ptr)
*/
static int
-Intersect(a1Ptr, a2Ptr, b1Ptr, b2Ptr, iPtr)
- XPoint *a1Ptr; /* First point of first line. */
- XPoint *a2Ptr; /* Second point of first line. */
- XPoint *b1Ptr; /* First point of second line. */
- XPoint *b2Ptr; /* Second point of second line. */
- XPoint *iPtr; /* Filled in with intersection point. */
+Intersect(
+ XPoint *a1Ptr, /* First point of first line. */
+ XPoint *a2Ptr, /* Second point of first line. */
+ XPoint *b1Ptr, /* First point of second line. */
+ XPoint *b2Ptr, /* Second point of second line. */
+ XPoint *iPtr) /* Filled in with intersection point. */
{
int dxadyb, dxbdya, dxadxb, dyadyb, p, q;
/*
- * The code below is just a straightforward manipulation of two
- * equations of the form y = (x-x1)*(y2-y1)/(x2-x1) + y1 to solve
- * for the x-coordinate of intersection, then the y-coordinate.
+ * The code below is just a straightforward manipulation of two equations
+ * of the form y = (x-x1)*(y2-y1)/(x2-x1) + y1 to solve for the
+ * x-coordinate of intersection, then the y-coordinate.
*/
dxadyb = (a2Ptr->x - a1Ptr->x)*(b2Ptr->y - b1Ptr->y);
@@ -1236,26 +1214,26 @@ Intersect(a1Ptr, a2Ptr, b1Ptr, b2Ptr, iPtr)
*
* 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.
+ * 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.
+ * 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.
+ * 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. */
+Tk_Get3DBorderFromObj(
+ Tk_Window tkwin,
+ Tcl_Obj *objPtr) /* The object whose string value selects a
+ * border. */
{
TkBorder *borderPtr = NULL;
Tcl_HashEntry *hashPtr;
@@ -1266,10 +1244,9 @@ Tk_Get3DBorderFromObj(tkwin, objPtr)
}
/*
- * If we are lucky (and the user doesn't use too many different
- * displays, screens, or colormaps...) then the TkBorder
- * structure we need will be cached in the internal
- * representation of the Tcl_Obj. Check it out...
+ * If we are lucky (and the user doesn't use too many different displays,
+ * screens, or colormaps...) then the TkBorder structure we need will be
+ * cached in the internal representation of the Tcl_Obj. Check it out...
*/
borderPtr = (TkBorder *) objPtr->internalRep.twoPtrValue.ptr1;
@@ -1278,22 +1255,22 @@ Tk_Get3DBorderFromObj(tkwin, objPtr)
&& (Tk_Screen(tkwin) == borderPtr->screen)
&& (Tk_Colormap(tkwin) == borderPtr->colormap)) {
/*
- * The object already points to the right border structure.
- * Just return it.
+ * The object already points to the right border structure. Just
+ * return it.
*/
+
return (Tk_3DBorder) borderPtr;
}
/*
- * If we make it here, it means we aren't so lucky. Either there
- * was no cached TkBorder in the Tcl_Obj, or the TkBorder that was
- * there is for the wrong screen/colormap. Either way, we have
- * to search for the right TkBorder. For each color name, there is
- * linked list of TkBorder structures, one structure for each
- * screen/colormap combination. The head of the linked list is
- * recorded in a hash table (where the key is the color name)
- * attached to the TkDisplay structure. Walk this list to find
- * the right TkBorder structure.
+ * If we make it here, it means we aren't so lucky. Either there was no
+ * cached TkBorder in the Tcl_Obj, or the TkBorder that was there is for
+ * the wrong screen/colormap. Either way, we have to search for the right
+ * TkBorder. For each color name, there is linked list of TkBorder
+ * structures, one structure for each screen/colormap combination. The
+ * head of the linked list is recorded in a hash table (where the key is
+ * the color name) attached to the TkDisplay structure. Walk this list to
+ * find the right TkBorder structure.
*/
hashPtr = Tcl_FindHashEntry(&dispPtr->borderTable, Tcl_GetString(objPtr));
@@ -1305,14 +1282,14 @@ Tk_Get3DBorderFromObj(tkwin, objPtr)
if ((Tk_Screen(tkwin) == borderPtr->screen)
&& (Tk_Colormap(tkwin) == borderPtr->colormap)) {
FreeBorderObjProc(objPtr);
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) borderPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr;
borderPtr->objRefCount++;
return (Tk_3DBorder) borderPtr;
}
}
- error:
- panic("Tk_Get3DBorderFromObj called with non-existent border!");
+ error:
+ Tcl_Panic("Tk_Get3DBorderFromObj called with non-existent border!");
/*
* The following code isn't reached; it's just there to please compilers.
*/
@@ -1333,20 +1310,20 @@ Tk_Get3DBorderFromObj(tkwin, objPtr)
* 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.
+ * 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. */
+InitBorderObj(
+ Tcl_Obj *objPtr) /* The object to convert. */
{
- Tcl_ObjType *typePtr;
+ const Tcl_ObjType *typePtr;
/*
- * Free the old internalRep before setting the new one.
+ * Free the old internalRep before setting the new one.
*/
Tcl_GetString(objPtr);
@@ -1355,7 +1332,7 @@ InitBorderObj(objPtr)
(*typePtr->freeIntRepProc)(objPtr);
}
objPtr->typePtr = &tkBorderObjType;
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
+ objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}
/*
@@ -1363,13 +1340,13 @@ InitBorderObj(objPtr)
*
* TkDebugBorder --
*
- * This procedure returns debugging information about a border.
+ * This function 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.
+ * corresponding to "name". Each sublist has two elements that contain
+ * the resourceRefCount and objRefCount fields from the TkBorder
+ * structure.
*
* Side effects:
* None.
@@ -1378,10 +1355,10 @@ InitBorderObj(objPtr)
*/
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. */
+TkDebugBorder(
+ 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;
@@ -1393,16 +1370,24 @@ TkDebugBorder(tkwin, name)
if (hashPtr != NULL) {
borderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr);
if (borderPtr == NULL) {
- panic("TkDebugBorder found empty hash table entry");
+ Tcl_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_NewIntObj(borderPtr->objRefCount));
Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
}
}
return resultPtr;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tk3d.h b/generic/tk3d.h
index 2905ff5..5e0a0cf 100644
--- a/generic/tk3d.h
+++ b/generic/tk3d.h
@@ -1,13 +1,12 @@
/*
* tk3d.h --
*
- * Declarations of types and functions shared by the 3d border
- * module.
+ * Declarations of types and functions shared by the 3d border module.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TK3D
@@ -22,9 +21,8 @@
/*
* 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.
+ * currently in use. Structures of this type are indexed by borderTable, so
+ * that a single structure can be shared for several uses.
*/
typedef struct TkBorder {
@@ -38,18 +36,17 @@ typedef struct TkBorder {
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. */
+ * 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). */
+ XColor *bgColorPtr; /* Background color (intensity between
+ * lightColorPtr and darkColorPtr). */
XColor *darkColorPtr; /* Color for darker areas (must free when
* deleting structure). NULL means shadows
* haven't been allocated yet.*/
@@ -57,28 +54,26 @@ typedef struct TkBorder {
* (must free this when deleting structure).
* NULL means shadows haven't been allocated
* yet. */
- Pixmap shadow; /* Stipple pattern to use for drawing
- * shadows areas. Used for displays with
- * <= 64 colors or where colormap has filled
- * up. */
- GC bgGC; /* Used (if necessary) to draw areas in
- * the background color. */
- GC darkGC; /* Used to draw darker parts of the
- * border. None means the shadow colors
- * haven't been allocated yet.*/
- GC lightGC; /* Used to draw lighter parts of
- * the border. None means the shadow colors
- * haven't been allocated yet. */
- Tcl_HashEntry *hashPtr; /* Entry in borderTable (needed in
- * order to delete structure). */
+ Pixmap shadow; /* Stipple pattern to use for drawing shadows
+ * areas. Used for displays with <= 64 colors
+ * or where colormap has filled up. */
+ GC bgGC; /* Used (if necessary) to draw areas in the
+ * background color. */
+ GC darkGC; /* Used to draw darker parts of the border.
+ * None means the shadow colors haven't been
+ * allocated yet.*/
+ GC lightGC; /* Used to draw lighter parts of the border.
+ * None means the shadow colors 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. */
+ * the same color name. Borders with the same
+ * name but different screens or colormaps are
+ * chained together off a single entry in
+ * borderTable. */
} TkBorder;
-
/*
* Maximum intensity for a color:
*/
@@ -89,10 +84,9 @@ typedef struct TkBorder {
* Declarations for platform specific interfaces used by this module.
*/
-EXTERN TkBorder * TkpGetBorder _ANSI_ARGS_((void));
-EXTERN void TkpGetShadows _ANSI_ARGS_((TkBorder *borderPtr,
- Tk_Window tkwin));
-EXTERN void TkpFreeBorder _ANSI_ARGS_((TkBorder *borderPtr));
+MODULE_SCOPE TkBorder *TkpGetBorder(void);
+MODULE_SCOPE void TkpGetShadows(TkBorder *borderPtr, Tk_Window tkwin);
+MODULE_SCOPE void TkpFreeBorder(TkBorder *borderPtr);
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLIMPORT
diff --git a/generic/tkArgv.c b/generic/tkArgv.c
index 4ee3b78..a338e45 100644
--- a/generic/tkArgv.c
+++ b/generic/tkArgv.c
@@ -1,85 +1,81 @@
/*
* tkArgv.c --
*
- * This file contains a procedure that handles table-based
- * argv-argc parsing.
+ * This file contains a function that handles table-based argv-argc
+ * parsing.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
-#include "tk.h"
+#include "tkInt.h"
/*
- * Default table of argument descriptors. These are normally available
- * in every application.
+ * Default table of argument descriptors. These are normally available in
+ * every application.
*/
static Tk_ArgvInfo defaultTable[] = {
- {"-help", TK_ARGV_HELP, (char *) NULL, (char *) NULL,
+ {"-help", TK_ARGV_HELP, NULL, NULL,
"Print summary of command-line options and abort"},
- {NULL, TK_ARGV_END, (char *) NULL, (char *) NULL,
- (char *) NULL}
+ {NULL, TK_ARGV_END, NULL, NULL, NULL}
};
/*
- * Forward declarations for procedures defined in this file:
+ * Forward declarations for functions defined in this file:
*/
-static void PrintUsage _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_ArgvInfo *argTable, int flags));
+static void PrintUsage(Tcl_Interp *interp, Tk_ArgvInfo *argTable,
+ int flags);
/*
*----------------------------------------------------------------------
*
* Tk_ParseArgv --
*
- * Process an argv array according to a table of expected
- * command-line options. See the manual page for more details.
+ * Process an argv array according to a table of expected command-line
+ * options. See the manual page for more details.
*
* Results:
- * The return value is a standard Tcl return value. If an
- * 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
- * argument).
+ * The return value is a standard Tcl return value. If an 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 argument).
*
* Side effects:
- * Variables may be modified, resources may be entered for tkwin,
- * or procedures may be called. It all depends on the arguments
- * and their entries in argTable. See the user documentation
- * for details.
+ * Variables may be modified, resources may be entered for tkwin, or
+ * functions may be called. It all depends on the arguments and their
+ * entries in argTable. See the user documentation for details.
*
*----------------------------------------------------------------------
*/
int
-Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags)
- Tcl_Interp *interp; /* Place to store error message. */
- Tk_Window tkwin; /* Window to use for setting Tk options.
- * NULL means ignore Tk option specs. */
- int *argcPtr; /* Number of arguments in argv. Modified
- * to hold # args left in argv at end. */
- CONST char **argv; /* Array of arguments. Modified to hold
- * those that couldn't be processed here. */
- Tk_ArgvInfo *argTable; /* Array of option descriptions */
- int flags; /* Or'ed combination of various flag bits,
+Tk_ParseArgv(
+ Tcl_Interp *interp, /* Place to store error message. */
+ Tk_Window tkwin, /* Window to use for setting Tk options. NULL
+ * means ignore Tk option specs. */
+ int *argcPtr, /* Number of arguments in argv. Modified to
+ * hold # args left in argv at end. */
+ CONST char **argv, /* Array of arguments. Modified to hold those
+ * that couldn't be processed here. */
+ Tk_ArgvInfo *argTable, /* Array of option descriptions */
+ int flags) /* Or'ed combination of various flag bits,
* such as TK_ARGV_NO_DEFAULTS. */
{
register Tk_ArgvInfo *infoPtr;
- /* Pointer to the current entry in the
- * table of argument descriptions. */
+ /* Pointer to the current entry in the table
+ * of argument descriptions. */
Tk_ArgvInfo *matchPtr; /* Descriptor that matches current argument. */
CONST char *curArg; /* Current argument */
register char c; /* Second character of current arg (used for
- * quick check for matching; use 2nd char.
- * because first char. will almost always
- * be '-'). */
+ * quick check for matching; use 2nd char.
+ * because first char. will almost always be
+ * '-'). */
int srcIndex; /* Location from which to read next argument
* from argv. */
int dstIndex; /* Index into argv to which next unused
@@ -109,9 +105,8 @@ Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags)
}
/*
- * Loop throught the argument descriptors searching for one with
- * the matching key string. If found, leave a pointer to it in
- * matchPtr.
+ * Loop throught the argument descriptors searching for one with the
+ * matching key string. If found, leave a pointer to it in matchPtr.
*/
matchPtr = NULL;
@@ -123,44 +118,43 @@ Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags)
}
for (; (infoPtr != NULL) && (infoPtr->type != TK_ARGV_END);
infoPtr++) {
- if (infoPtr->key == NULL) {
- continue;
- }
- if ((infoPtr->key[1] != c)
- || (strncmp(infoPtr->key, curArg, length) != 0)) {
- continue;
- }
- if ((tkwin == NULL)
- && ((infoPtr->type == TK_ARGV_CONST_OPTION)
- || (infoPtr->type == TK_ARGV_OPTION_VALUE)
- || (infoPtr->type == TK_ARGV_OPTION_NAME_VALUE))) {
- continue;
- }
- if (infoPtr->key[length] == 0) {
- matchPtr = infoPtr;
- goto gotMatch;
- }
- if (flags & TK_ARGV_NO_ABBREV) {
- continue;
- }
- if (matchPtr != NULL) {
- Tcl_AppendResult(interp, "ambiguous option \"", curArg,
- "\"", (char *) NULL);
- return TCL_ERROR;
- }
- matchPtr = infoPtr;
+ if (infoPtr->key == NULL) {
+ continue;
+ }
+ if ((infoPtr->key[1] != c)
+ || (strncmp(infoPtr->key, curArg, length) != 0)) {
+ continue;
+ }
+ if ((tkwin == NULL)
+ && ((infoPtr->type == TK_ARGV_CONST_OPTION)
+ || (infoPtr->type == TK_ARGV_OPTION_VALUE)
+ || (infoPtr->type == TK_ARGV_OPTION_NAME_VALUE))) {
+ continue;
+ }
+ if (infoPtr->key[length] == 0) {
+ matchPtr = infoPtr;
+ goto gotMatch;
+ }
+ if (flags & TK_ARGV_NO_ABBREV) {
+ continue;
+ }
+ if (matchPtr != NULL) {
+ Tcl_AppendResult(interp, "ambiguous option \"", curArg,
+ "\"", NULL);
+ return TCL_ERROR;
+ }
+ matchPtr = infoPtr;
}
}
if (matchPtr == NULL) {
-
/*
- * Unrecognized argument. Just copy it down, unless the caller
+ * Unrecognized argument. Just copy it down, unless the caller
* prefers an error to be registered.
*/
if (flags & TK_ARGV_NO_LEFTOVERS) {
Tcl_AppendResult(interp, "unrecognized argument \"",
- curArg, "\"", (char *) NULL);
+ curArg, "\"", NULL);
return TCL_ERROR;
}
argv[dstIndex] = curArg;
@@ -172,154 +166,143 @@ Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags)
* Take the appropriate action based on the option type
*/
- gotMatch:
+ gotMatch:
infoPtr = matchPtr;
switch (infoPtr->type) {
- case TK_ARGV_CONSTANT:
- *((int *) infoPtr->dst) = (int) infoPtr->src;
- break;
- case TK_ARGV_INT:
- if (argc == 0) {
- goto missingArg;
- } else {
- char *endPtr;
-
- *((int *) infoPtr->dst) =
- strtol(argv[srcIndex], &endPtr, 0);
- if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) {
- Tcl_AppendResult(interp, "expected integer argument ",
- "for \"", infoPtr->key, "\" but got \"",
- argv[srcIndex], "\"", (char *) NULL);
- return TCL_ERROR;
- }
- srcIndex++;
- argc--;
- }
- break;
- case TK_ARGV_STRING:
- if (argc == 0) {
- goto missingArg;
- } else {
- *((CONST char **)infoPtr->dst) = argv[srcIndex];
- srcIndex++;
- argc--;
- }
- break;
- case TK_ARGV_UID:
- if (argc == 0) {
- goto missingArg;
- } else {
- *((Tk_Uid *)infoPtr->dst) = Tk_GetUid(argv[srcIndex]);
- srcIndex++;
- argc--;
- }
- break;
- case TK_ARGV_REST:
- *((int *) infoPtr->dst) = dstIndex;
- goto argsDone;
- case TK_ARGV_FLOAT:
- if (argc == 0) {
- goto missingArg;
- } else {
- char *endPtr;
-
- *((double *) infoPtr->dst) =
- strtod(argv[srcIndex], &endPtr);
- if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) {
- Tcl_AppendResult(interp, "expected floating-point ",
- "argument for \"", infoPtr->key,
- "\" but got \"", argv[srcIndex], "\"",
- (char *) NULL);
- return TCL_ERROR;
- }
- srcIndex++;
- argc--;
- }
- break;
- case TK_ARGV_FUNC: {
- typedef int (ArgvFunc) _ANSI_ARGS_ ((char *, char *,
- CONST char *));
- ArgvFunc *handlerProc;
+ case TK_ARGV_CONSTANT:
+ *((int *) infoPtr->dst) = PTR2INT(infoPtr->src);
+ break;
+ case TK_ARGV_INT:
+ if (argc == 0) {
+ goto missingArg;
+ } else {
+ char *endPtr;
- handlerProc = (ArgvFunc *) infoPtr->src;
- if ((*handlerProc)(infoPtr->dst, infoPtr->key,
- argv[srcIndex])) {
- srcIndex += 1;
- argc -= 1;
+ *((int *) infoPtr->dst) = strtol(argv[srcIndex], &endPtr, 0);
+ if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) {
+ Tcl_AppendResult(interp,"expected integer argument for \"",
+ infoPtr->key, "\" but got \"", argv[srcIndex],
+ "\"", NULL);
+ return TCL_ERROR;
}
- break;
+ srcIndex++;
+ argc--;
+ }
+ break;
+ case TK_ARGV_STRING:
+ if (argc == 0) {
+ goto missingArg;
+ }
+ *((CONST char **)infoPtr->dst) = argv[srcIndex];
+ srcIndex++;
+ argc--;
+ break;
+ case TK_ARGV_UID:
+ if (argc == 0) {
+ goto missingArg;
}
- case TK_ARGV_GENFUNC: {
- typedef int (ArgvGenFunc)_ANSI_ARGS_((char *, Tcl_Interp *,
- char *, int, CONST char **));
- ArgvGenFunc *handlerProc;
+ *((Tk_Uid *)infoPtr->dst) = Tk_GetUid(argv[srcIndex]);
+ srcIndex++;
+ argc--;
+ break;
+ case TK_ARGV_REST:
+ *((int *) infoPtr->dst) = dstIndex;
+ goto argsDone;
+ case TK_ARGV_FLOAT:
+ if (argc == 0) {
+ goto missingArg;
+ } else {
+ char *endPtr;
- handlerProc = (ArgvGenFunc *) infoPtr->src;
- argc = (*handlerProc)(infoPtr->dst, interp, infoPtr->key,
- argc, argv+srcIndex);
- if (argc < 0) {
+ *((double *) infoPtr->dst) = strtod(argv[srcIndex], &endPtr);
+ if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) {
+ Tcl_AppendResult(interp, "expected floating-point ",
+ "argument for \"", infoPtr->key, "\" but got \"",
+ argv[srcIndex], "\"", NULL);
return TCL_ERROR;
}
- break;
+ srcIndex++;
+ argc--;
}
- case TK_ARGV_HELP:
- PrintUsage (interp, argTable, flags);
- return TCL_ERROR;
- case TK_ARGV_CONST_OPTION:
- Tk_AddOption(tkwin, infoPtr->dst, infoPtr->src,
- TK_INTERACTIVE_PRIO);
- break;
- case TK_ARGV_OPTION_VALUE:
- if (argc < 1) {
- goto missingArg;
- }
- Tk_AddOption(tkwin, infoPtr->dst, argv[srcIndex],
- TK_INTERACTIVE_PRIO);
+ break;
+ case TK_ARGV_FUNC: {
+ typedef int (ArgvFunc)(char *, char *, CONST char *);
+ ArgvFunc *handlerProc = (ArgvFunc *) infoPtr->src;
+
+ if ((*handlerProc)(infoPtr->dst, infoPtr->key, argv[srcIndex])) {
srcIndex++;
argc--;
- break;
- case TK_ARGV_OPTION_NAME_VALUE:
- if (argc < 2) {
- Tcl_AppendResult(interp, "\"", curArg,
- "\" option requires two following arguments",
- (char *) NULL);
- return TCL_ERROR;
- }
- Tk_AddOption(tkwin, argv[srcIndex], argv[srcIndex+1],
- TK_INTERACTIVE_PRIO);
- srcIndex += 2;
- argc -= 2;
- break;
- default: {
- char buf[64 + TCL_INTEGER_SPACE];
-
- sprintf(buf, "bad argument type %d in Tk_ArgvInfo",
- infoPtr->type);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ break;
+ }
+ case TK_ARGV_GENFUNC: {
+ typedef int (ArgvGenFunc)(char *, Tcl_Interp *, char *, int,
+ CONST char **);
+ ArgvGenFunc *handlerProc = (ArgvGenFunc *) infoPtr->src;
+
+ argc = (*handlerProc)(infoPtr->dst, interp, infoPtr->key,
+ argc, argv+srcIndex);
+ if (argc < 0) {
+ return TCL_ERROR;
+ }
+ break;
+ }
+ case TK_ARGV_HELP:
+ PrintUsage(interp, argTable, flags);
+ return TCL_ERROR;
+ case TK_ARGV_CONST_OPTION:
+ Tk_AddOption(tkwin, infoPtr->dst, infoPtr->src,
+ TK_INTERACTIVE_PRIO);
+ break;
+ case TK_ARGV_OPTION_VALUE:
+ if (argc < 1) {
+ goto missingArg;
+ }
+ Tk_AddOption(tkwin, infoPtr->dst, argv[srcIndex],
+ TK_INTERACTIVE_PRIO);
+ srcIndex++;
+ argc--;
+ break;
+ case TK_ARGV_OPTION_NAME_VALUE:
+ if (argc < 2) {
+ Tcl_AppendResult(interp, "\"", curArg,
+ "\" option requires two following arguments", NULL);
return TCL_ERROR;
}
+ Tk_AddOption(tkwin, argv[srcIndex], argv[srcIndex+1],
+ TK_INTERACTIVE_PRIO);
+ srcIndex += 2;
+ argc -= 2;
+ break;
+ 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;
+ }
}
}
/*
- * If we broke out of the loop because of an OPT_REST argument,
- * copy the remaining arguments down.
+ * If we broke out of the loop because of an OPT_REST argument, copy the
+ * remaining arguments down.
*/
- argsDone:
+ argsDone:
while (argc) {
argv[dstIndex] = argv[srcIndex];
srcIndex++;
dstIndex++;
argc--;
}
- argv[dstIndex] = (char *) NULL;
+ argv[dstIndex] = NULL;
*argcPtr = dstIndex;
return TCL_OK;
- missingArg:
+ missingArg:
Tcl_AppendResult(interp, "\"", curArg,
- "\" option requires an additional argument", (char *) NULL);
+ "\" option requires an additional argument", NULL);
return TCL_ERROR;
}
@@ -331,10 +314,9 @@ Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags)
* Generate a help string describing command-line options.
*
* Results:
- * 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.
+ * 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.
*
* Side effects:
* None.
@@ -343,31 +325,29 @@ Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags)
*/
static void
-PrintUsage(interp, argTable, flags)
- Tcl_Interp *interp; /* Place information in this interp's
- * result area. */
- Tk_ArgvInfo *argTable; /* Array of command-specific argument
+PrintUsage(
+ Tcl_Interp *interp, /* Place information in this interp's result
+ * area. */
+ Tk_ArgvInfo *argTable, /* Array of command-specific argument
* descriptions. */
- int flags; /* If the TK_ARGV_NO_DEFAULTS bit is set
- * in this word, then don't generate
- * information for default options. */
+ int flags) /* If the TK_ARGV_NO_DEFAULTS bit is set in
+ * this word, then don't generate information
+ * for default options. */
{
register Tk_ArgvInfo *infoPtr;
- int width, i, numSpaces;
-#define NUM_SPACES 20
- static CONST char spaces[] = " ";
+ size_t width, i, numSpaces;
char tmp[TCL_DOUBLE_SPACE];
/*
- * First, compute the width of the widest option key, so that we
- * can make everything line up.
+ * First, compute the width of the widest option key, so that we can make
+ * everything line up.
*/
width = 4;
for (i = 0; i < 2; i++) {
for (infoPtr = i ? defaultTable : argTable;
infoPtr->type != TK_ARGV_END; infoPtr++) {
- int length;
+ size_t length;
if (infoPtr->key == NULL) {
continue;
}
@@ -378,59 +358,54 @@ PrintUsage(interp, argTable, flags)
}
}
- Tcl_AppendResult(interp, "Command-specific options:", (char *) NULL);
+ Tcl_AppendResult(interp, "Command-specific options:", NULL);
for (i = 0; ; i++) {
for (infoPtr = i ? defaultTable : argTable;
infoPtr->type != TK_ARGV_END; infoPtr++) {
if ((infoPtr->type == TK_ARGV_HELP) && (infoPtr->key == NULL)) {
- Tcl_AppendResult(interp, "\n", infoPtr->help, (char *) NULL);
+ Tcl_AppendResult(interp, "\n", infoPtr->help, NULL);
continue;
}
- Tcl_AppendResult(interp, "\n ", infoPtr->key, ":", (char *) NULL);
+ Tcl_AppendResult(interp, "\n ", infoPtr->key, ":", NULL);
numSpaces = width + 1 - strlen(infoPtr->key);
- while (numSpaces > 0) {
- if (numSpaces >= NUM_SPACES) {
- Tcl_AppendResult(interp, spaces, (char *) NULL);
- } else {
- Tcl_AppendResult(interp, spaces+NUM_SPACES-numSpaces,
- (char *) NULL);
- }
- numSpaces -= NUM_SPACES;
+ while (numSpaces-- > 0) {
+ Tcl_AppendResult(interp, " ", NULL);
}
- Tcl_AppendResult(interp, infoPtr->help, (char *) NULL);
+ Tcl_AppendResult(interp, infoPtr->help, NULL);
switch (infoPtr->type) {
- case TK_ARGV_INT: {
- sprintf(tmp, "%d", *((int *) infoPtr->dst));
- Tcl_AppendResult(interp, "\n\t\tDefault value: ",
- tmp, (char *) NULL);
- break;
- }
- case TK_ARGV_FLOAT: {
- sprintf(tmp, "%g", *((double *) infoPtr->dst));
- Tcl_AppendResult(interp, "\n\t\tDefault value: ",
- tmp, (char *) NULL);
- break;
- }
- case TK_ARGV_STRING: {
- char *string;
+ case TK_ARGV_INT:
+ sprintf(tmp, "%d", *((int *) infoPtr->dst));
+ Tcl_AppendResult(interp, "\n\t\tDefault value: ", tmp, NULL);
+ break;
+ case TK_ARGV_FLOAT:
+ Tcl_PrintDouble(NULL, *((double *) infoPtr->dst), tmp);
+ Tcl_AppendResult(interp, "\n\t\tDefault value: ", tmp, NULL);
+ break;
+ case TK_ARGV_STRING: {
+ char *string = *((char **) infoPtr->dst);
- string = *((char **) infoPtr->dst);
- if (string != NULL) {
- Tcl_AppendResult(interp, "\n\t\tDefault value: \"",
- string, "\"", (char *) NULL);
- }
- break;
- }
- default: {
- break;
+ if (string != NULL) {
+ Tcl_AppendResult(interp, "\n\t\tDefault value: \"", string,
+ "\"", NULL);
}
+ break;
+ }
+ default:
+ break;
}
}
if ((flags & TK_ARGV_NO_DEFAULTS) || (i > 0)) {
break;
}
- Tcl_AppendResult(interp, "\nGeneric options for all commands:",
- (char *) NULL);
+ Tcl_AppendResult(interp, "\nGeneric options for all commands:", NULL);
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkAtom.c b/generic/tkAtom.c
index 108e989..fe1b5b3 100644
--- a/generic/tkAtom.c
+++ b/generic/tkAtom.c
@@ -1,28 +1,26 @@
-/*
+/*
* tkAtom.c --
*
- * This file manages a cache of X Atoms in order to avoid
- * interactions with the X server. It's much like the Xmu
- * routines, except it has a cleaner interface (caller
- * doesn't have to provide permanent storage for atom names,
- * for example).
+ * This file manages a cache of X Atoms in order to avoid interactions
+ * with the X server. It's much like the Xmu routines, except it has a
+ * cleaner interface (caller doesn't have to provide permanent storage
+ * for atom names, for example).
*
* Copyright (c) 1990-1994 The Regents of the University of California.
* Copyright (c) 1994 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
/*
- * The following are a list of the predefined atom strings.
- * They should match those found in xatom.h
+ * The following are a list of the predefined atom strings. They should match
+ * those found in xatom.h
*/
-static CONST char *atomNameArray[] = {
+static const char *atomNameArray[] = {
"PRIMARY", "SECONDARY", "ARC",
"ATOM", "BITMAP", "CARDINAL",
"COLORMAP", "CURSOR", "CUT_BUFFER0",
@@ -46,24 +44,24 @@ static CONST char *atomNameArray[] = {
"COPYRIGHT", "NOTICE", "FONT_NAME",
"FAMILY_NAME", "FULL_NAME", "CAP_HEIGHT",
"WM_CLASS", "WM_TRANSIENT_FOR",
- (char *) NULL
+ NULL
};
/*
- * Forward references to procedures defined in this file:
+ * Forward references to functions defined in this file:
*/
-static void AtomInit _ANSI_ARGS_((TkDisplay *dispPtr));
+static void AtomInit(TkDisplay *dispPtr);
/*
*--------------------------------------------------------------
*
* Tk_InternAtom --
*
- * Given a string, produce the equivalent X atom. This
- * procedure is equivalent to XInternAtom, except that it
- * keeps a local cache of atoms. Once a name is known,
- * the server need not be contacted again for that name.
+ * Given a string, produce the equivalent X atom. This function is
+ * equivalent to XInternAtom, except that it keeps a local cache of
+ * atoms. Once a name is known, the server need not be contacted again
+ * for that name.
*
* Results:
* The return value is the Atom corresponding to name.
@@ -75,32 +73,31 @@ static void AtomInit _ANSI_ARGS_((TkDisplay *dispPtr));
*/
Atom
-Tk_InternAtom(tkwin, name)
- Tk_Window tkwin; /* Window token; map name to atom
- * for this window's display. */
- CONST char *name; /* Name to turn into atom. */
+Tk_InternAtom(
+ Tk_Window tkwin, /* Window token; map name to atom for this
+ * window's display. */
+ CONST char *name) /* Name to turn into atom. */
{
register TkDisplay *dispPtr;
register Tcl_HashEntry *hPtr;
- int new;
+ int isNew;
dispPtr = ((TkWindow *) tkwin)->dispPtr;
if (!dispPtr->atomInit) {
AtomInit(dispPtr);
}
- hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &new);
- if (new) {
+ hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew);
+ if (isNew) {
Tcl_HashEntry *hPtr2;
Atom atom;
atom = XInternAtom(dispPtr->display, name, False);
- Tcl_SetHashValue(hPtr, atom);
- hPtr2 = Tcl_CreateHashEntry(&dispPtr->atomTable, (char *) atom,
- &new);
+ Tcl_SetHashValue(hPtr, INT2PTR(atom));
+ hPtr2 = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew);
Tcl_SetHashValue(hPtr2, Tcl_GetHashKey(&dispPtr->nameTable, hPtr));
}
- return (Atom) Tcl_GetHashValue(hPtr);
+ return (Atom) PTR2INT(Tcl_GetHashValue(hPtr));
}
/*
@@ -108,16 +105,15 @@ Tk_InternAtom(tkwin, name)
*
* Tk_GetAtomName --
*
- * This procedure is equivalent to XGetAtomName except that
- * it uses the local atom cache to avoid contacting the
- * server.
+ * This function is equivalent to XGetAtomName except that it uses the
+ * local atom cache to avoid contacting the server.
*
* Results:
- * The return value is a character string corresponding to
- * the atom given by "atom". This string's storage space
- * is static: it need not be freed by the caller, and should
- * not be modified by the caller. If "atom" doesn't exist
- * on tkwin's display, then the string "?bad atom?" is returned.
+ * The return value is a character string corresponding to the atom given
+ * by "atom". This string's storage space is static: it need not be freed
+ * by the caller, and should not be modified by the caller. If "atom"
+ * doesn't exist on tkwin's display, then the string "?bad atom?" is
+ * returned.
*
* Side effects:
* None.
@@ -126,11 +122,10 @@ Tk_InternAtom(tkwin, name)
*/
CONST char *
-Tk_GetAtomName(tkwin, atom)
- Tk_Window tkwin; /* Window token; map atom to name
- * relative to this window's
- * display. */
- Atom atom; /* Atom whose name is wanted. */
+Tk_GetAtomName(
+ Tk_Window tkwin, /* Window token; map atom to name relative to
+ * this window's display. */
+ Atom atom) /* Atom whose name is wanted. */
{
register TkDisplay *dispPtr;
register Tcl_HashEntry *hPtr;
@@ -140,14 +135,14 @@ Tk_GetAtomName(tkwin, atom)
AtomInit(dispPtr);
}
- hPtr = Tcl_FindHashEntry(&dispPtr->atomTable, (char *) atom);
+ hPtr = Tcl_FindHashEntry(&dispPtr->atomTable, INT2PTR(atom));
if (hPtr == NULL) {
char *name;
Tk_ErrorHandler handler;
- int new, mustFree;
+ int isNew, mustFree;
- handler= Tk_CreateErrorHandler(dispPtr->display, BadAtom,
- -1, -1, (Tk_ErrorProc *) NULL, (ClientData) NULL);
+ handler = Tk_CreateErrorHandler(dispPtr->display, BadAtom, -1, -1,
+ NULL, (ClientData) NULL);
name = XGetAtomName(dispPtr->display, atom);
mustFree = 1;
if (name == NULL) {
@@ -155,15 +150,13 @@ Tk_GetAtomName(tkwin, atom)
mustFree = 0;
}
Tk_DeleteErrorHandler(handler);
- hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, (char *) name,
- &new);
- Tcl_SetHashValue(hPtr, atom);
+ hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew);
+ Tcl_SetHashValue(hPtr, INT2PTR(atom));
if (mustFree) {
XFree(name);
}
name = Tcl_GetHashKey(&dispPtr->nameTable, hPtr);
- hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, (char *) atom,
- &new);
+ hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew);
Tcl_SetHashValue(hPtr, name);
}
return Tcl_GetHashValue(hPtr);
@@ -186,8 +179,8 @@ Tk_GetAtomName(tkwin, atom)
*/
static void
-AtomInit(dispPtr)
- register TkDisplay *dispPtr; /* Display to initialize. */
+AtomInit(
+ register TkDisplay *dispPtr)/* Display to initialize. */
{
Tcl_HashEntry *hPtr;
Atom atom;
@@ -197,19 +190,27 @@ AtomInit(dispPtr)
Tcl_InitHashTable(&dispPtr->atomTable, TCL_ONE_WORD_KEYS);
for (atom = 1; atom <= XA_LAST_PREDEFINED; atom++) {
- hPtr = Tcl_FindHashEntry(&dispPtr->atomTable, (char *) atom);
- if (hPtr == NULL) {
- CONST char *name;
- int new;
-
- name = atomNameArray[atom - 1];
- hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, (char *) name,
- &new);
- Tcl_SetHashValue(hPtr, atom);
- name = Tcl_GetHashKey(&dispPtr->nameTable, hPtr);
- hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, (char *) atom,
- &new);
- Tcl_SetHashValue(hPtr, name);
+ const char *name;
+ int isNew;
+
+ hPtr = Tcl_FindHashEntry(&dispPtr->atomTable, INT2PTR(atom));
+ if (hPtr != NULL) {
+ continue;
}
+
+ name = atomNameArray[atom - 1];
+ hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew);
+ Tcl_SetHashValue(hPtr, INT2PTR(atom));
+ name = Tcl_GetHashKey(&dispPtr->nameTable, hPtr);
+ hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew);
+ Tcl_SetHashValue(hPtr, name);
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkBind.c b/generic/tkBind.c
index 3d617d4..8d20fa9 100644
--- a/generic/tkBind.c
+++ b/generic/tkBind.c
@@ -1,18 +1,17 @@
-/*
+/*
* tkBind.c --
*
- * This file provides procedures that associate Tcl commands
- * with X events or sequences of X events.
+ * This file provides functions that associate Tcl commands with X events
+ * or sequences of X events.
*
* Copyright (c) 1989-1994 The Regents of the University of California.
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
#ifdef __WIN32__
@@ -23,7 +22,6 @@
#include "tkUnixInt.h"
#endif
-
/*
* File structure:
*
@@ -44,111 +42,109 @@
* Non-package-specific helpers.
*/
-
/*
- * The following union is used to hold the detail information from an
- * XEvent (including Tk's XVirtualEvent extension).
+ * The following union is used to hold the detail information from an XEvent
+ * (including Tk's XVirtualEvent extension).
*/
+
typedef union {
- KeySym keySym; /* KeySym that corresponds to xkey.keycode. */
- int button; /* Button that was pressed (xbutton.button). */
- Tk_Uid name; /* Tk_Uid of virtual event. */
- ClientData clientData; /* Used when type of Detail is unknown, and to
- * ensure that all bytes of Detail are initialized
- * when this structure is used in a hash key. */
+ KeySym keySym; /* KeySym that corresponds to xkey.keycode. */
+ int button; /* Button that was pressed (xbutton.button). */
+ Tk_Uid name; /* Tk_Uid of virtual event. */
+ ClientData clientData; /* Used when type of Detail is unknown, and to
+ * ensure that all bytes of Detail are
+ * initialized when this structure is used in
+ * a hash key. */
} Detail;
/*
- * The structure below represents a binding table. A binding table
- * represents a domain in which event bindings may occur. It includes
- * a space of objects relative to which events occur (usually windows,
- * but not always), a history of recent events in the domain, and
- * a set of mappings that associate particular Tcl commands with sequences
- * of events in the domain. Multiple binding tables may exist at once,
- * either because there are multiple applications open, or because there
- * are multiple domains within an application with separate event
- * bindings for each (for example, each canvas widget has a separate
- * binding table for associating events with the items in the canvas).
- *
- * Note: it is probably a bad idea to reduce EVENT_BUFFER_SIZE much
- * below 30. To see this, consider a triple mouse button click while
- * the Shift key is down (and auto-repeating). There may be as many
- * as 3 auto-repeat events after each mouse button press or release
- * (see the first large comment block within Tk_BindEvent for more on
- * this), for a total of 20 events to cover the three button presses
- * and two intervening releases. If you reduce EVENT_BUFFER_SIZE too
- * much, shift multi-clicks will be lost.
- *
+ * The structure below represents a binding table. A binding table represents
+ * a domain in which event bindings may occur. It includes a space of objects
+ * relative to which events occur (usually windows, but not always), a history
+ * of recent events in the domain, and a set of mappings that associate
+ * particular Tcl commands with sequences of events in the domain. Multiple
+ * binding tables may exist at once, either because there are multiple
+ * applications open, or because there are multiple domains within an
+ * application with separate event bindings for each (for example, each canvas
+ * widget has a separate binding table for associating events with the items
+ * in the canvas).
+ *
+ * Note: it is probably a bad idea to reduce EVENT_BUFFER_SIZE much below 30.
+ * To see this, consider a triple mouse button click while the Shift key is
+ * down (and auto-repeating). There may be as many as 3 auto-repeat events
+ * after each mouse button press or release (see the first large comment block
+ * within Tk_BindEvent for more on this), for a total of 20 events to cover
+ * the three button presses and two intervening releases. If you reduce
+ * EVENT_BUFFER_SIZE too much, shift multi-clicks will be lost.
*/
#define EVENT_BUFFER_SIZE 30
typedef struct BindingTable {
- XEvent eventRing[EVENT_BUFFER_SIZE];/* Circular queue of recent events
- * (higher indices are for more recent
- * events). */
- Detail detailRing[EVENT_BUFFER_SIZE];/* "Detail" information (keySym,
- * button, Tk_Uid, or 0) for each
- * entry in eventRing. */
- int curEvent; /* Index in eventRing of most recent
- * event. Newer events have higher
- * indices. */
- Tcl_HashTable patternTable; /* Used to map from an event to a
- * list of patterns that may match that
- * event. Keys are PatternTableKey
- * structs, values are (PatSeq *). */
- Tcl_HashTable objectTable; /* Used to map from an object to a
- * list of patterns associated with
- * that object. Keys are ClientData,
- * values are (PatSeq *). */
- Tcl_Interp *interp; /* Interpreter in which commands are
- * executed. */
+ XEvent eventRing[EVENT_BUFFER_SIZE];
+ /* Circular queue of recent events (higher
+ * indices are for more recent events). */
+ Detail detailRing[EVENT_BUFFER_SIZE];
+ /* "Detail" information (keySym, button,
+ * Tk_Uid, or 0) for each entry in
+ * eventRing. */
+ int curEvent; /* Index in eventRing of most recent event.
+ * Newer events have higher indices. */
+ Tcl_HashTable patternTable; /* Used to map from an event to a list of
+ * patterns that may match that event. Keys
+ * are PatternTableKey structs, values are
+ * (PatSeq *). */
+ Tcl_HashTable objectTable; /* Used to map from an object to a list of
+ * patterns associated with that object. Keys
+ * are ClientData, values are (PatSeq *). */
+ Tcl_Interp *interp; /* Interpreter in which commands are
+ * executed. */
} BindingTable;
/*
- * The following structure represents virtual event table. A virtual event
- * table provides a way to map from platform-specific physical events such
- * as button clicks or key presses to virtual events such as <<Paste>>,
+ * The following structure represents virtual event table. A virtual event
+ * table provides a way to map from platform-specific physical events such as
+ * button clicks or key presses to virtual events such as <<Paste>>,
* <<Close>>, or <<ScrollWindow>>.
*
* A virtual event is usually never part of the event stream, but instead is
- * synthesized inline by matching low-level events. However, a virtual
- * event may be generated by platform-specific code or by Tcl scripts. In
- * that case, no lookup of the virtual event will need to be done using
- * this table, because the virtual event is actually in the event stream.
+ * synthesized inline by matching low-level events. However, a virtual event
+ * may be generated by platform-specific code or by Tcl scripts. In that case,
+ * no lookup of the virtual event will need to be done using this table,
+ * because the virtual event is actually in the event stream.
*/
typedef struct VirtualEventTable {
- Tcl_HashTable patternTable; /* Used to map from a physical event to
- * a list of patterns that may match that
- * event. Keys are PatternTableKey
- * structs, values are (PatSeq *). */
- Tcl_HashTable nameTable; /* Used to map a virtual event name to
- * the array of physical events that can
- * trigger it. Keys are the Tk_Uid names
- * of the virtual events, values are
- * PhysicalsOwned structs. */
+ Tcl_HashTable patternTable; /* Used to map from a physical event to a list
+ * of patterns that may match that event. Keys
+ * are PatternTableKey structs, values are
+ * (PatSeq *). */
+ Tcl_HashTable nameTable; /* Used to map a virtual event name to the
+ * array of physical events that can trigger
+ * it. Keys are the Tk_Uid names of the
+ * virtual events, values are PhysicalsOwned
+ * structs. */
} VirtualEventTable;
/*
- * The following structure is used as a key in a patternTable for both
- * binding tables and a virtual event tables.
+ * The following structure is used as a key in a patternTable for both binding
+ * tables and a virtual event tables.
*
- * In a binding table, the object field corresponds to the binding tag
- * for the widget whose bindings are being accessed.
+ * In a binding table, the object field corresponds to the binding tag for the
+ * widget whose bindings are being accessed.
*
- * In a virtual event table, the object field is always NULL. Virtual
- * events are a global definiton and are not tied to a particular
- * binding tag.
+ * In a virtual event table, the object field is always NULL. Virtual events
+ * are a global definiton and are not tied to a particular binding tag.
*
- * The same key is used for both types of pattern tables so that the
- * helper functions that traverse and match patterns will work for both
- * binding tables and virtual event tables.
+ * The same key is used for both types of pattern tables so that the helper
+ * functions that traverse and match patterns will work for both binding
+ * tables and virtual event tables.
*/
+
typedef struct PatternTableKey {
ClientData object; /* For binding table, identifies the binding
* tag of the object (or class of objects)
- * relative to which the event occurred.
- * For virtual event table, always NULL. */
+ * relative to which the event occurred. For
+ * virtual event table, always NULL. */
int type; /* Type of event (from X). */
Detail detail; /* Additional information, such as keysym,
* button, Tk_Uid, or 0 if nothing
@@ -162,37 +158,34 @@ typedef struct PatternTableKey {
typedef struct Pattern {
int eventType; /* Type of X event, e.g. ButtonPress. */
- int needMods; /* Mask of modifiers that must be
- * present (0 means no modifiers are
- * required). */
- Detail detail; /* Additional information that must
- * match event. Normally this is 0,
- * meaning no additional information
- * must match. For KeyPress and
- * KeyRelease events, a keySym may
- * be specified to select a
- * particular keystroke (0 means any
- * keystrokes). For button events,
- * specifies a particular button (0
- * means any buttons are OK). For virtual
- * events, specifies the Tk_Uid of the
+ int needMods; /* Mask of modifiers that must be present (0
+ * means no modifiers are required). */
+ Detail detail; /* Additional information that must match
+ * event. Normally this is 0, meaning no
+ * additional information must match. For
+ * KeyPress and KeyRelease events, a keySym
+ * may be specified to select a particular
+ * keystroke (0 means any keystrokes). For
+ * button events, specifies a particular
+ * button (0 means any buttons are OK). For
+ * virtual events, specifies the Tk_Uid of the
* virtual event name (never 0). */
} Pattern;
/*
* The following structure defines a pattern sequence, which consists of one
- * or more patterns. In order to trigger, a pattern sequence must match
- * the most recent X events (first pattern to most recent event, next
- * pattern to next event, and so on). It is used as the hash value in a
- * patternTable for both binding tables and virtual event tables.
- *
- * In a binding table, it is the sequence of physical events that make up
- * a binding for an object.
- *
- * In a virtual event table, it is the sequence of physical events that
- * define a virtual event.
- *
- * The same structure is used for both types of pattern tables so that the
+ * or more patterns. In order to trigger, a pattern sequence must match the
+ * most recent X events (first pattern to most recent event, next pattern to
+ * next event, and so on). It is used as the hash value in a patternTable for
+ * both binding tables and virtual event tables.
+ *
+ * In a binding table, it is the sequence of physical events that make up a
+ * binding for an object.
+ *
+ * In a virtual event table, it is the sequence of physical events that define
+ * a virtual event.
+ *
+ * The same structure is used for both types of pattern tables so that the
* helper functions that traverse and match patterns will work for both
* binding tables and virtual event tables.
*/
@@ -200,57 +193,56 @@ typedef struct Pattern {
typedef struct PatSeq {
int numPats; /* Number of patterns in sequence (usually
* 1). */
- TkBindEvalProc *eventProc; /* The procedure that will be invoked on
- * the clientData when this pattern sequence
+ TkBindEvalProc *eventProc; /* The function that will be invoked on the
+ * clientData when this pattern sequence
* matches. */
- TkBindFreeProc *freeProc; /* The procedure that will be invoked to
+ TkBindFreeProc *freeProc; /* The function that will be invoked to
* release the clientData when this pattern
* sequence is freed. */
ClientData clientData; /* Arbitray data passed to eventProc and
* freeProc when sequence matches. */
int flags; /* Miscellaneous flag values; see below for
* definitions. */
- int refCount; /* Number of times that this binding is in
- * the midst of executing. If greater than 1,
- * then a recursive invocation is happening.
- * Only when this is zero can the binding
- * actually be freed. */
- struct PatSeq *nextSeqPtr; /* Next in list of all pattern sequences
- * that have the same initial pattern. NULL
- * means end of list. */
- Tcl_HashEntry *hPtr; /* Pointer to hash table entry for the
- * initial pattern. This is the head of the
- * list of which nextSeqPtr forms a part. */
- struct VirtualOwners *voPtr;/* In a binding table, always NULL. In a
+ int refCount; /* Number of times that this binding is in the
+ * midst of executing. If greater than 1, then
+ * a recursive invocation is happening. Only
+ * when this is zero can the binding actually
+ * be freed. */
+ struct PatSeq *nextSeqPtr; /* Next in list of all pattern sequences that
+ * have the same initial pattern. NULL means
+ * end of list. */
+ Tcl_HashEntry *hPtr; /* Pointer to hash table entry for the initial
+ * pattern. This is the head of the list of
+ * which nextSeqPtr forms a part. */
+ struct VirtualOwners *voPtr;/* In a binding table, always NULL. In a
* virtual event table, identifies the array
* of virtual events that can be triggered by
* this event. */
- struct PatSeq *nextObjPtr; /* In a binding table, next in list of all
+ struct PatSeq *nextObjPtr; /* In a binding table, next in list of all
* pattern sequences for the same object (NULL
- * for end of list). Needed to implement
- * Tk_DeleteAllBindings. In a virtual event
+ * for end of list). Needed to implement
+ * Tk_DeleteAllBindings. In a virtual event
* table, always NULL. */
- Pattern pats[1]; /* Array of "numPats" patterns. Only one
+ Pattern pats[1]; /* Array of "numPats" patterns. Only one
* element is declared here but in actuality
- * enough space will be allocated for "numPats"
- * patterns. To match, pats[0] must match
- * event n, pats[1] must match event n-1, etc.
- */
+ * enough space will be allocated for
+ * "numPats" patterns. To match, pats[0] must
+ * match event n, pats[1] must match event
+ * n-1, etc. */
} PatSeq;
/*
* Flag values for PatSeq structures:
*
- * PAT_NEARBY 1 means that all of the events matching
- * this sequence must occur with nearby X
- * and Y mouse coordinates and close in time.
- * This is typically used to restrict multiple
- * button presses.
+ * PAT_NEARBY 1 means that all of the events matching this sequence
+ * must occur with nearby X and Y mouse coordinates and
+ * close in time. This is typically used to restrict
+ * multiple button presses.
* MARKED_DELETED 1 means that this binding has been marked as deleted
* and removed from the binding table, but its memory
- * could not be released because it was already queued for
- * execution. When the binding is actually about to be
- * executed, this flag will be checked and the binding
+ * could not be released because it was already queued
+ * for execution. When the binding is actually about to
+ * be executed, this flag will be checked and the binding
* skipped if set.
*/
@@ -258,52 +250,49 @@ typedef struct PatSeq {
#define MARKED_DELETED 0x2
/*
- * Constants that define how close together two events must be
- * in milliseconds or pixels to meet the PAT_NEARBY constraint:
+ * Constants that define how close together two events must be in milliseconds
+ * or pixels to meet the PAT_NEARBY constraint:
*/
#define NEARBY_PIXELS 5
#define NEARBY_MS 500
-
/*
* The following structure keeps track of all the virtual events that are
- * associated with a particular physical event. It is pointed to by the
- * voPtr field in a PatSeq in the patternTable of a virtual event table.
+ * associated with a particular physical event. It is pointed to by the voPtr
+ * field in a PatSeq in the patternTable of a virtual event table.
*/
typedef struct VirtualOwners {
- int numOwners; /* Number of virtual events to trigger. */
- Tcl_HashEntry *owners[1]; /* Array of pointers to entries in
- * nameTable. Enough space will
- * actually be allocated for numOwners
- * hash entries. */
+ int numOwners; /* Number of virtual events to trigger. */
+ Tcl_HashEntry *owners[1]; /* Array of pointers to entries in nameTable.
+ * Enough space will actually be allocated for
+ * numOwners hash entries. */
} VirtualOwners;
/*
- * The following structure is used in the nameTable of a virtual event
- * table to associate a virtual event with all the physical events that can
- * trigger it.
+ * The following structure is used in the nameTable of a virtual event table
+ * to associate a virtual event with all the physical events that can trigger
+ * it.
*/
typedef struct PhysicalsOwned {
- int numOwned; /* Number of physical events owned. */
- PatSeq *patSeqs[1]; /* Array of pointers to physical event
- * patterns. Enough space will actually
- * be allocated to hold numOwned. */
+ int numOwned; /* Number of physical events owned. */
+ PatSeq *patSeqs[1]; /* Array of pointers to physical event
+ * patterns. Enough space will actually be
+ * allocated to hold numOwned. */
} PhysicalsOwned;
/*
- * One of the following structures exists for each interpreter. This
- * structure keeps track of the current display and screen in the
- * interpreter, so that a script can be invoked whenever the display/screen
- * changes (the script does things like point tk::Priv at a display-specific
- * structure).
+ * One of the following structures exists for each interpreter. This structure
+ * keeps track of the current display and screen in the interpreter, so that a
+ * script can be invoked whenever the display/screen changes (the script does
+ * things like point tk::Priv at a display-specific structure).
*/
typedef struct {
- TkDisplay *curDispPtr; /* Display for last binding command invoked
- * in this application. */
- int curScreenIndex; /* Index of screen for last binding command. */
+ TkDisplay *curDispPtr; /* Display for last binding command invoked in
+ * this application. */
+ int curScreenIndex; /* Index of screen for last binding command */
int bindingDepth; /* Number of active instances of Tk_BindEvent
* in this application. */
} ScreenInfo;
@@ -311,21 +300,21 @@ typedef struct {
/*
* The following structure is used to keep track of all the C bindings that
* are awaiting invocation and whether the window they refer to has been
- * destroyed. If the window is destroyed, then all pending callbacks for
- * that window will be cancelled. The Tcl bindings will still all be
- * invoked, however.
+ * destroyed. If the window is destroyed, then all pending callbacks for that
+ * window will be cancelled. The Tcl bindings will still all be invoked,
+ * however.
*/
typedef struct PendingBinding {
struct PendingBinding *nextPtr;
- /* Next in chain of pending bindings, in
- * case a recursive binding evaluation is in
+ /* Next in chain of pending bindings, in case
+ * a recursive binding evaluation is in
* progress. */
Tk_Window tkwin; /* The window that the following bindings
* depend upon. */
- int deleted; /* Set to non-zero by window cleanup code
- * if tkwin is deleted. */
- PatSeq *matchArray[5]; /* Array of pending C bindings. The actual
+ int deleted; /* Set to non-zero by window cleanup code if
+ * tkwin is deleted. */
+ PatSeq *matchArray[5]; /* Array of pending C bindings. The actual
* size of this depends on how many C bindings
* matched the event passed to Tk_BindEvent.
* THIS FIELD MUST BE THE LAST IN THE
@@ -333,8 +322,8 @@ typedef struct PendingBinding {
} PendingBinding;
/*
- * The following structure keeps track of all the information local to
- * the binding package on a per interpreter basis.
+ * The following structure keeps track of all the information local to the
+ * binding package on a per interpreter basis.
*/
typedef struct BindInfo {
@@ -342,39 +331,38 @@ typedef struct BindInfo {
/* The virtual events that exist in this
* interpreter. */
ScreenInfo screenInfo; /* Keeps track of the current display and
- * screen, so it can be restored after
- * a binding has executed. */
+ * screen, so it can be restored after a
+ * binding has executed. */
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. */
+ int deleted; /* 1 the application has been deleted but the
+ * structure has been preserved. */
} BindInfo;
-
+
/*
- * In X11R4 and earlier versions, XStringToKeysym is ridiculously
- * slow. The data structure and hash table below, along with the
- * code that uses them, implement a fast mapping from strings to
- * keysyms. In X11R5 and later releases XStringToKeysym is plenty
- * fast so this stuff isn't needed. The #define REDO_KEYSYM_LOOKUP
- * is normally undefined, so that XStringToKeysym gets used. It
- * can be set in the Makefile to enable the use of the hash table
- * below.
+ * In X11R4 and earlier versions, XStringToKeysym is ridiculously slow. The
+ * data structure and hash table below, along with the code that uses them,
+ * implement a fast mapping from strings to keysyms. In X11R5 and later
+ * releases XStringToKeysym is plenty fast so this stuff isn't needed. The
+ * #define REDO_KEYSYM_LOOKUP is normally undefined, so that XStringToKeysym
+ * gets used. It can be set in the Makefile to enable the use of the hash
+ * table below.
*/
#ifdef REDO_KEYSYM_LOOKUP
typedef struct {
- char *name; /* Name of keysym. */
- KeySym value; /* Numeric identifier for keysym. */
+ char *name; /* Name of keysym. */
+ KeySym value; /* Numeric identifier for keysym. */
} KeySymInfo;
static KeySymInfo keyArray[] = {
#ifndef lint
#include "ks_names.h"
#endif
- {(char *) NULL, 0}
+ {NULL, 0}
};
-static Tcl_HashTable keySymTable; /* keyArray hashed by keysym value. */
-static Tcl_HashTable nameTable; /* keyArray hashed by keysym name. */
+static Tcl_HashTable keySymTable; /* keyArray hashed by keysym value. */
+static Tcl_HashTable nameTable; /* keyArray hashed by keysym name. */
#endif /* REDO_KEYSYM_LOOKUP */
/*
@@ -386,16 +374,17 @@ static int initialized = 0;
TCL_DECLARE_MUTEX(bindMutex)
/*
- * A hash table is kept to map from the string names of event
- * modifiers to information about those modifiers. The structure
- * for storing this information, and the hash table built at
- * initialization time, are defined below.
+ * A hash table is kept to map from the string names of event modifiers to
+ * information about those modifiers. The structure for storing this
+ * information, and the hash table built at initialization time, are defined
+ * below.
*/
typedef struct {
char *name; /* Name of modifier. */
- int mask; /* Button/modifier mask value, * such as Button1Mask. */
- int flags; /* Various flags; see below for
+ int mask; /* Button/modifier mask value, such as
+ * Button1Mask. */
+ int flags; /* Various flags; see below for
* definitions. */
} ModInfo;
@@ -423,6 +412,7 @@ static ModInfo modArray[] = {
{"Meta", META_MASK, 0},
{"M", META_MASK, 0},
{"Alt", ALT_MASK, 0},
+ {"Extended", EXTENDED_MASK, 0},
{"B1", Button1Mask, 0},
{"Button1", Button1Mask, 0},
{"B2", Button2Mask, 0},
@@ -448,32 +438,29 @@ static ModInfo modArray[] = {
{"Double", 0, DOUBLE},
{"Triple", 0, TRIPLE},
{"Quadruple", 0, QUADRUPLE},
- {"Any", 0, 0}, /* Ignored: historical relic. */
+ {"Any", 0, 0}, /* Ignored: historical relic */
{NULL, 0, 0}
};
static Tcl_HashTable modTable;
/*
- * This module also keeps a hash table mapping from event names
- * to information about those events. The structure, an array
- * to use to initialize the hash table, and the hash table are
- * all defined below.
+ * This module also keeps a hash table mapping from event names to information
+ * about those events. The structure, an array to use to initialize the hash
+ * table, and the hash table are all defined below.
*/
typedef struct {
char *name; /* Name of event. */
- int type; /* Event type for X, such as
- * ButtonPress. */
- int eventMask; /* Mask bits (for XSelectInput)
- * for this event type. */
+ int type; /* Event type for X, such as ButtonPress. */
+ int eventMask; /* Mask bits (for XSelectInput) for this event
+ * type. */
} EventInfo;
/*
- * Note: some of the masks below are an OR-ed combination of
- * several masks. This is necessary because X doesn't report
- * up events unless you also ask for down events. Also, X
- * doesn't report button state in motion events unless you've
- * asked about button events.
+ * Note: some of the masks below are an OR-ed combination of several masks.
+ * This is necessary because X doesn't report up events unless you also ask
+ * for down events. Also, X doesn't report button state in motion events
+ * unless you've asked about button events.
*/
static EventInfo eventArray[] = {
@@ -507,18 +494,18 @@ static EventInfo eventArray[] = {
{"CirculateRequest", CirculateRequest, SubstructureRedirectMask},
{"ConfigureRequest", ConfigureRequest, SubstructureRedirectMask},
{"Create", CreateNotify, SubstructureNotifyMask},
- {"MapRequest", MapRequest, SubstructureRedirectMask},
+ {"MapRequest", MapRequest, SubstructureRedirectMask},
{"ResizeRequest", ResizeRequest, ResizeRedirectMask},
- {(char *) NULL, 0, 0}
+ {NULL, 0, 0}
};
static Tcl_HashTable eventTable;
/*
- * The defines and table below are used to classify events into
- * various groups. The reason for this is that logically identical
- * fields (e.g. "state") appear at different places in different
- * types of events. The classification masks can be used to figure
- * out quickly where to extract information from events.
+ * The defines and table below are used to classify events into various
+ * groups. The reason for this is that logically identical fields (e.g.
+ * "state") appear at different places in different types of events. The
+ * classification masks can be used to figure out quickly where to extract
+ * information from events.
*/
#define KEY 0x1
@@ -546,7 +533,7 @@ static Tcl_HashTable eventTable;
#define CIRCREQ 0x400000
#define KEY_BUTTON_MOTION_VIRTUAL (KEY|BUTTON|MOTION|VIRTUAL)
-#define KEY_BUTTON_MOTION_CROSSING (KEY|BUTTON|MOTION|CROSSING|VIRTUAL)
+#define KEY_BUTTON_MOTION_CROSSING (KEY|BUTTON|MOTION|VIRTUAL|CROSSING)
static int flagArray[TK_LASTEVENT] = {
/* Not used */ 0,
@@ -585,18 +572,17 @@ static int flagArray[TK_LASTEVENT] = {
/* ClientMessage */ 0,
/* MappingNotify */ 0,
/* VirtualEvent */ VIRTUAL,
- /* Activate */ ACTIVATE,
+ /* Activate */ ACTIVATE,
/* Deactivate */ ACTIVATE,
/* MouseWheel */ KEY
};
/*
- * 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.
+ * 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[] = {
+
+static const TkStateMap queuePosition[] = {
{-1, "now"},
{TCL_QUEUE_HEAD, "head"},
{TCL_QUEUE_MARK, "mark"},
@@ -605,13 +591,13 @@ static TkStateMap queuePosition[] = {
};
/*
- * 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
- * when providing data from an XEvent to the user.
+ * 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 when providing
+ * data from an XEvent to the user.
*/
-static TkStateMap notifyMode[] = {
+static const TkStateMap notifyMode[] = {
{NotifyNormal, "NotifyNormal"},
{NotifyGrab, "NotifyGrab"},
{NotifyUngrab, "NotifyUngrab"},
@@ -619,7 +605,7 @@ static TkStateMap notifyMode[] = {
{-1, NULL}
};
-static TkStateMap notifyDetail[] = {
+static const TkStateMap notifyDetail[] = {
{NotifyAncestor, "NotifyAncestor"},
{NotifyVirtual, "NotifyVirtual"},
{NotifyInferior, "NotifyInferior"},
@@ -631,20 +617,20 @@ static TkStateMap notifyDetail[] = {
{-1, NULL}
};
-static TkStateMap circPlace[] = {
+static const TkStateMap circPlace[] = {
{PlaceOnTop, "PlaceOnTop"},
{PlaceOnBottom, "PlaceOnBottom"},
{-1, NULL}
};
-static TkStateMap visNotify[] = {
- {VisibilityUnobscured, "VisibilityUnobscured"},
- {VisibilityPartiallyObscured, "VisibilityPartiallyObscured"},
- {VisibilityFullyObscured, "VisibilityFullyObscured"},
+static const TkStateMap visNotify[] = {
+ {VisibilityUnobscured, "VisibilityUnobscured"},
+ {VisibilityPartiallyObscured, "VisibilityPartiallyObscured"},
+ {VisibilityFullyObscured, "VisibilityFullyObscured"},
{-1, NULL}
};
-static TkStateMap configureRequestDetail[] = {
+static const TkStateMap configureRequestDetail[] = {
{None, "None"},
{Above, "Above"},
{Below, "Below"},
@@ -654,79 +640,71 @@ static TkStateMap configureRequestDetail[] = {
{-1, NULL}
};
-static TkStateMap propNotify[] = {
+static const TkStateMap propNotify[] = {
{PropertyNewValue, "NewValue"},
{PropertyDelete, "Delete"},
{-1, NULL}
};
/*
- * Prototypes for local procedures defined in this file:
+ * Prototypes for local functions defined in this file:
*/
-static void ChangeScreen _ANSI_ARGS_((Tcl_Interp *interp,
- char *dispName, int screenIndex));
-static int CreateVirtualEvent _ANSI_ARGS_((Tcl_Interp *interp,
+static void ChangeScreen(Tcl_Interp *interp, char *dispName,
+ int screenIndex);
+static int CreateVirtualEvent(Tcl_Interp *interp,
VirtualEventTable *vetPtr, char *virtString,
- char *eventString));
-static int DeleteVirtualEvent _ANSI_ARGS_((Tcl_Interp *interp,
+ char *eventString);
+static int DeleteVirtualEvent(Tcl_Interp *interp,
VirtualEventTable *vetPtr, char *virtString,
- char *eventString));
-static void DeleteVirtualEventTable _ANSI_ARGS_((
- VirtualEventTable *vetPtr));
-static void ExpandPercents _ANSI_ARGS_((TkWindow *winPtr,
- CONST char *before, XEvent *eventPtr, KeySym keySym,
- Tcl_DString *dsPtr));
-static void FreeTclBinding _ANSI_ARGS_((ClientData clientData));
-static PatSeq * FindSequence _ANSI_ARGS_((Tcl_Interp *interp,
+ char *eventString);
+static void DeleteVirtualEventTable(VirtualEventTable *vetPtr);
+static void ExpandPercents(TkWindow *winPtr, const char *before,
+ XEvent *eventPtr,KeySym keySym,Tcl_DString *dsPtr);
+static void FreeTclBinding(ClientData clientData);
+static PatSeq * FindSequence(Tcl_Interp *interp,
Tcl_HashTable *patternTablePtr, ClientData object,
- CONST char *eventString, int create,
- int allowVirtual, unsigned long *maskPtr));
-static void GetAllVirtualEvents _ANSI_ARGS_((Tcl_Interp *interp,
- VirtualEventTable *vetPtr));
-static char * GetField _ANSI_ARGS_((char *p, char *copy, int size));
-static void GetPatternString _ANSI_ARGS_((PatSeq *psPtr,
- Tcl_DString *dsPtr));
-static int GetVirtualEvent _ANSI_ARGS_((Tcl_Interp *interp,
- VirtualEventTable *vetPtr, char *virtString));
-static Tk_Uid GetVirtualEventUid _ANSI_ARGS_((Tcl_Interp *interp,
- char *virtString));
-static int HandleEventGenerate _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window main, int objc,
- Tcl_Obj *CONST objv[]));
-static void InitVirtualEventTable _ANSI_ARGS_((
- VirtualEventTable *vetPtr));
-static PatSeq * MatchPatterns _ANSI_ARGS_((TkDisplay *dispPtr,
+ const char *eventString, int create,
+ int allowVirtual, unsigned long *maskPtr);
+static void GetAllVirtualEvents(Tcl_Interp *interp,
+ VirtualEventTable *vetPtr);
+static char * GetField(char *p, char *copy, int size);
+static void GetPatternString(PatSeq *psPtr, Tcl_DString *dsPtr);
+static int GetVirtualEvent(Tcl_Interp *interp,
+ VirtualEventTable *vetPtr, char *virtString);
+static Tk_Uid GetVirtualEventUid(Tcl_Interp *interp,
+ char *virtString);
+static int HandleEventGenerate(Tcl_Interp *interp, Tk_Window main,
+ int objc, Tcl_Obj *const objv[]);
+static void InitVirtualEventTable(VirtualEventTable *vetPtr);
+static PatSeq * MatchPatterns(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,
- CONST char **eventStringPtr, Pattern *patPtr,
- unsigned long *eventMaskPtr));
-static void DoWarp _ANSI_ARGS_((ClientData clientData));
+ PatSeq **sourcePtrPtr);
+static int NameToWindow(Tcl_Interp *interp, Tk_Window main,
+ Tcl_Obj *objPtr, Tk_Window *tkwinPtr);
+static int ParseEventDescription(Tcl_Interp *interp,
+ const char **eventStringPtr, Pattern *patPtr,
+ unsigned long *eventMaskPtr);
+static void DoWarp(ClientData clientData);
/*
- * The following define is used as a short circuit for the callback
- * procedure to evaluate a TclBinding. The actual evaluation of the
- * binding is handled inline, because special things have to be done
- * with a Tcl binding before evaluation time.
+ * The following define is used as a short circuit for the callback function
+ * to evaluate a TclBinding. The actual evaluation of the binding is handled
+ * inline, because special things have to be done with a Tcl binding before
+ * evaluation time.
*/
#define EvalTclBinding ((TkBindEvalProc *) 1)
-
/*
*---------------------------------------------------------------------------
*
* TkBindInit --
*
- * This procedure is called when an application is created. It
- * initializes all the structures used by bindings and virtual
- * events. It must be called before any other functions in this
- * file are called.
+ * This function is called when an application is created. It initializes
+ * all the structures used by bindings and virtual events. It must be
+ * called before any other functions in this file are called.
*
* Results:
* None.
@@ -738,39 +716,37 @@ static void DoWarp _ANSI_ARGS_((ClientData clientData));
*/
void
-TkBindInit(mainPtr)
- TkMainInfo *mainPtr; /* The newly created application. */
+TkBindInit(
+ TkMainInfo *mainPtr) /* The newly created application. */
{
BindInfo *bindInfoPtr;
if (sizeof(XEvent) < sizeof(XVirtualEvent)) {
- panic("TkBindInit: virtual events can't be supported");
+ Tcl_Panic("TkBindInit: virtual events can't be supported");
}
/*
- * Initialize the static data structures used by the binding package.
- * They are only initialized once, no matter how many interps are
- * created.
+ * Initialize the static data structures used by the binding package. They
+ * are only initialized once, no matter how many interps are created.
*/
if (!initialized) {
- Tcl_MutexLock(&bindMutex);
+ Tcl_MutexLock(&bindMutex);
if (!initialized) {
Tcl_HashEntry *hPtr;
ModInfo *modPtr;
EventInfo *eiPtr;
int newEntry;
-
#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, &newEntry);
+ hPtr = Tcl_CreateHashEntry(&keySymTable, kPtr->name, &newEntry);
Tcl_SetHashValue(hPtr, kPtr->value);
hPtr = Tcl_CreateHashEntry(&nameTable, (char *) kPtr->value,
- &newEntry);
+ &newEntry);
if (newEntry) {
Tcl_SetHashValue(hPtr, kPtr->name);
}
@@ -779,18 +755,18 @@ TkBindInit(mainPtr)
Tcl_InitHashTable(&modTable, TCL_STRING_KEYS);
for (modPtr = modArray; modPtr->name != NULL; modPtr++) {
- hPtr = Tcl_CreateHashEntry(&modTable, modPtr->name, &newEntry);
+ hPtr = Tcl_CreateHashEntry(&modTable, modPtr->name, &newEntry);
Tcl_SetHashValue(hPtr, modPtr);
}
-
+
Tcl_InitHashTable(&eventTable, TCL_STRING_KEYS);
for (eiPtr = eventArray; eiPtr->name != NULL; eiPtr++) {
- hPtr = Tcl_CreateHashEntry(&eventTable, eiPtr->name, &newEntry);
+ hPtr = Tcl_CreateHashEntry(&eventTable, eiPtr->name, &newEntry);
Tcl_SetHashValue(hPtr, eiPtr);
}
initialized = 1;
}
- Tcl_MutexUnlock(&bindMutex);
+ Tcl_MutexUnlock(&bindMutex);
}
mainPtr->bindingTable = Tk_CreateBindingTable(mainPtr->interp);
@@ -812,8 +788,8 @@ TkBindInit(mainPtr)
*
* TkBindFree --
*
- * This procedure is called when an application is deleted. It
- * deletes all the structures used by bindings and virtual events.
+ * This function is called when an application is deleted. It deletes all
+ * the structures used by bindings and virtual events.
*
* Results:
* None.
@@ -825,11 +801,11 @@ TkBindInit(mainPtr)
*/
void
-TkBindFree(mainPtr)
- TkMainInfo *mainPtr; /* The newly created application. */
+TkBindFree(
+ TkMainInfo *mainPtr) /* The newly created application. */
{
BindInfo *bindInfoPtr;
-
+
Tk_DeleteBindingTable(mainPtr->bindingTable);
mainPtr->bindingTable = NULL;
@@ -848,8 +824,8 @@ TkBindFree(mainPtr)
* Set up a new domain in which event bindings may be created.
*
* Results:
- * The return value is a token for the new table, which must
- * be passed to procedures like Tk_CreateBinding.
+ * The return value is a token for the new table, which must be passed to
+ * functions like Tk_CreateBinding.
*
* Side effects:
* Memory is allocated for the new table.
@@ -858,9 +834,9 @@ TkBindFree(mainPtr)
*/
Tk_BindingTable
-Tk_CreateBindingTable(interp)
- Tcl_Interp *interp; /* Interpreter to associate with the binding
- * table: commands are executed in this
+Tk_CreateBindingTable(
+ Tcl_Interp *interp) /* Interpreter to associate with the binding
+ * table: commands are executed in this
* interpreter. */
{
BindingTable *bindPtr;
@@ -887,9 +863,8 @@ Tk_CreateBindingTable(interp)
*
* Tk_DeleteBindingTable --
*
- * Destroy a binding table and free up all its memory.
- * The caller should not use bindingTable again after
- * this procedure returns.
+ * Destroy a binding table and free up all its memory. The caller should
+ * not use bindingTable again after this function returns.
*
* Results:
* None.
@@ -901,9 +876,9 @@ Tk_CreateBindingTable(interp)
*/
void
-Tk_DeleteBindingTable(bindingTable)
- Tk_BindingTable bindingTable; /* Token for the binding table to
- * destroy. */
+Tk_DeleteBindingTable(
+ Tk_BindingTable bindingTable)
+ /* Token for the binding table to destroy. */
{
BindingTable *bindPtr = (BindingTable *) bindingTable;
PatSeq *psPtr, *nextPtr;
@@ -911,8 +886,7 @@ Tk_DeleteBindingTable(bindingTable)
Tcl_HashSearch search;
/*
- * Find and delete all of the patterns associated with the binding
- * table.
+ * Find and delete all of the patterns associated with the binding table.
*/
for (hPtr = Tcl_FirstHashEntry(&bindPtr->patternTable, &search);
@@ -931,8 +905,7 @@ Tk_DeleteBindingTable(bindingTable)
}
/*
- * Clean up the rest of the information associated with the
- * binding table.
+ * Clean up the rest of the information associated with the binding table.
*/
Tcl_DeleteHashTable(&bindPtr->patternTable);
@@ -945,41 +918,39 @@ Tk_DeleteBindingTable(bindingTable)
*
* Tk_CreateBinding --
*
- * Add a binding to a binding table, so that future calls to
- * Tk_BindEvent may execute the command in the binding.
+ * Add a binding to a binding table, so that future calls to Tk_BindEvent
+ * may execute the command in the binding.
*
* 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 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
+ * The return value is 0 if an error occurred while setting up the
+ * binding. In this case, an error message will be 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
* what events to select for in a window, for example.
*
* Side effects:
- * An existing binding on the same event sequence may be
- * replaced.
- * The new binding may cause future calls to Tk_BindEvent to
- * behave differently than they did previously.
+ * An existing binding on the same event sequence may be replaced. The
+ * new binding may cause future calls to Tk_BindEvent to behave
+ * differently than they did previously.
*
*--------------------------------------------------------------
*/
unsigned long
-Tk_CreateBinding(interp, bindingTable, object, eventString, command, append)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_BindingTable bindingTable;
+Tk_CreateBinding(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_BindingTable bindingTable,
/* Table in which to create binding. */
- ClientData object; /* Token for object with which binding is
+ ClientData object, /* Token for object with which binding is
* associated. */
- CONST char *eventString; /* String describing event sequence that
+ const char *eventString, /* String describing event sequence that
* triggers binding. */
- CONST char *command; /* Contains Tcl command to execute when
+ const char *command, /* Contains Tcl command to execute when
* binding triggers. */
- int append; /* 0 means replace any existing binding for
+ int append) /* 0 means replace any existing binding for
* eventString; 1 means append to that
- * binding. If the existing binding is for a
+ * binding. If the existing binding is for a
* callback function and not a Tcl command
* string, the existing binding will always be
* replaced. */
@@ -987,27 +958,30 @@ Tk_CreateBinding(interp, bindingTable, object, eventString, command, append)
BindingTable *bindPtr = (BindingTable *) bindingTable;
PatSeq *psPtr;
unsigned long eventMask;
- char *new, *old;
+ char *newStr, *oldStr;
+ if (!*command) {
+ /* Silently ignore empty scripts -- see SF#3006842 */
+ return 1;
+ }
psPtr = FindSequence(interp, &bindPtr->patternTable, object, eventString,
1, 1, &eventMask);
if (psPtr == NULL) {
return 0;
}
if (psPtr->eventProc == NULL) {
- int new;
+ int isNew;
Tcl_HashEntry *hPtr;
-
+
/*
- * This pattern sequence was just created.
- * Link the pattern into the list associated with the object, so
- * that if the object goes away, these bindings will all
- * automatically be deleted.
+ * This pattern sequence was just created. Link the pattern into the
+ * list associated with the object, so that if the object goes away,
+ * these bindings will all automatically be deleted.
*/
hPtr = Tcl_CreateHashEntry(&bindPtr->objectTable, (char *) object,
- &new);
- if (new) {
+ &isNew);
+ if (isNew) {
psPtr->nextObjPtr = NULL;
} else {
psPtr->nextObjPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
@@ -1025,23 +999,23 @@ Tk_CreateBinding(interp, bindingTable, object, eventString, command, append)
append = 0;
}
- old = (char *) psPtr->clientData;
- if ((append != 0) && (old != NULL)) {
- int length;
+ oldStr = (char *) psPtr->clientData;
+ if ((append != 0) && (oldStr != NULL)) {
+ size_t length;
- length = strlen(old) + strlen(command) + 2;
- new = (char *) ckalloc((unsigned) length);
- sprintf(new, "%s\n%s", old, command);
+ length = strlen(oldStr) + strlen(command) + 2;
+ newStr = (char *) ckalloc((unsigned) length);
+ sprintf(newStr, "%s\n%s", oldStr, command);
} else {
- new = (char *) ckalloc((unsigned) strlen(command) + 1);
- strcpy(new, command);
+ newStr = (char *) ckalloc((unsigned) strlen(command) + 1);
+ strcpy(newStr, command);
}
- if (old != NULL) {
- ckfree(old);
+ if (oldStr != NULL) {
+ ckfree(oldStr);
}
psPtr->eventProc = EvalTclBinding;
psPtr->freeProc = FreeTclBinding;
- psPtr->clientData = (ClientData) new;
+ psPtr->clientData = (ClientData) newStr;
return eventMask;
}
@@ -1051,39 +1025,37 @@ Tk_CreateBinding(interp, bindingTable, object, eventString, command, append)
* TkCreateBindingProcedure --
*
* Add a C binding to a binding table, so that future calls to
- * Tk_BindEvent may callback the procedure in the binding.
+ * Tk_BindEvent may callback the function in the binding.
*
* 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 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
+
+ * The return value is 0 if an error occurred while setting up the
+ * binding. In this case, an error message will be 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
* what events to select for in a window, for example.
*
* Side effects:
- * Any existing binding on the same event sequence will be
- * replaced.
+ * Any existing binding on the same event sequence will be replaced.
*
*---------------------------------------------------------------------------
*/
unsigned long
-TkCreateBindingProcedure(interp, bindingTable, object, eventString,
- eventProc, freeProc, clientData)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_BindingTable bindingTable;
+TkCreateBindingProcedure(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_BindingTable bindingTable,
/* Table in which to create binding. */
- ClientData object; /* Token for object with which binding is
+ ClientData object, /* Token for object with which binding is
* associated. */
- CONST char *eventString; /* String describing event sequence that
+ const char *eventString, /* String describing event sequence that
* triggers binding. */
- TkBindEvalProc *eventProc; /* Procedure to invoke when binding
- * triggers. Must not be NULL. */
- TkBindFreeProc *freeProc; /* Procedure to invoke when binding is
- * freed. May be NULL for no procedure. */
- ClientData clientData; /* Arbitrary ClientData to pass to eventProc
+ TkBindEvalProc *eventProc, /* Function to invoke when binding triggers.
+ * Must not be NULL. */
+ TkBindFreeProc *freeProc, /* Function to invoke when binding is freed.
+ * May be NULL for no function. */
+ ClientData clientData) /* Arbitrary ClientData to pass to eventProc
* and freeProc. */
{
BindingTable *bindPtr = (BindingTable *) bindingTable;
@@ -1096,26 +1068,24 @@ TkCreateBindingProcedure(interp, bindingTable, object, eventString,
return 0;
}
if (psPtr->eventProc == NULL) {
- int new;
+ int isNew;
Tcl_HashEntry *hPtr;
-
+
/*
- * This pattern sequence was just created.
- * Link the pattern into the list associated with the object, so
- * that if the object goes away, these bindings will all
- * automatically be deleted.
+ * This pattern sequence was just created. Link the pattern into the
+ * list associated with the object, so that if the object goes away,
+ * these bindings will all automatically be deleted.
*/
hPtr = Tcl_CreateHashEntry(&bindPtr->objectTable, (char *) object,
- &new);
- if (new) {
+ &isNew);
+ if (isNew) {
psPtr->nextObjPtr = NULL;
} else {
psPtr->nextObjPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
}
Tcl_SetHashValue(hPtr, psPtr);
} else {
-
/*
* Free existing callback.
*/
@@ -1139,24 +1109,25 @@ TkCreateBindingProcedure(interp, bindingTable, object, eventString,
* Remove an event binding from a binding table.
*
* Results:
- * The result is a standard Tcl return value. If an error
- * occurs then the interp's result will contain an error message.
+ * The result is a standard Tcl return value. If an error occurs then the
+ * interp's result will contain an error message.
*
* Side effects:
- * The binding given by object and eventString is removed
- * from bindingTable.
+ * The binding given by object and eventString is removed from
+ * bindingTable.
*
*--------------------------------------------------------------
*/
int
-Tk_DeleteBinding(interp, bindingTable, object, eventString)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_BindingTable bindingTable; /* Table in which to delete binding. */
- ClientData object; /* Token for object with which binding
- * is associated. */
- CONST char *eventString; /* String describing event sequence
- * that triggers binding. */
+Tk_DeleteBinding(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_BindingTable bindingTable,
+ /* Table in which to delete binding. */
+ ClientData object, /* Token for object with which binding is
+ * associated. */
+ const char *eventString) /* String describing event sequence that
+ * triggers binding. */
{
BindingTable *bindPtr = (BindingTable *) bindingTable;
PatSeq *psPtr, *prevPtr;
@@ -1171,13 +1142,13 @@ Tk_DeleteBinding(interp, bindingTable, object, eventString)
}
/*
- * Unlink the binding from the list for its object, then from the
- * list for its pattern.
+ * Unlink the binding from the list for its object, then from the list for
+ * its pattern.
*/
hPtr = Tcl_FindHashEntry(&bindPtr->objectTable, (char *) object);
if (hPtr == NULL) {
- panic("Tk_DeleteBinding couldn't find object table entry");
+ Tcl_Panic("Tk_DeleteBinding couldn't find object table entry");
}
prevPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
if (prevPtr == psPtr) {
@@ -1185,7 +1156,7 @@ Tk_DeleteBinding(interp, bindingTable, object, eventString)
} else {
for ( ; ; prevPtr = prevPtr->nextObjPtr) {
if (prevPtr == NULL) {
- panic("Tk_DeleteBinding couldn't find on object list");
+ Tcl_Panic("Tk_DeleteBinding couldn't find on object list");
}
if (prevPtr->nextObjPtr == psPtr) {
prevPtr->nextObjPtr = psPtr->nextObjPtr;
@@ -1203,7 +1174,7 @@ Tk_DeleteBinding(interp, bindingTable, object, eventString)
} else {
for ( ; ; prevPtr = prevPtr->nextSeqPtr) {
if (prevPtr == NULL) {
- panic("Tk_DeleteBinding couldn't find on hash chain");
+ Tcl_Panic("Tk_DeleteBinding couldn't find on hash chain");
}
if (prevPtr->nextSeqPtr == psPtr) {
prevPtr->nextSeqPtr = psPtr->nextSeqPtr;
@@ -1230,13 +1201,12 @@ Tk_DeleteBinding(interp, bindingTable, object, eventString)
* Return the command associated with a given event string.
*
* Results:
- * The return value is a pointer to the command string
- * associated with eventString for object in the domain
- * 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
- * the interp's result. The return value is semi-static: it
- * will persist until the binding is changed or deleted.
+ * The return value is a pointer to the command string associated with
+ * eventString for object in the domain 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 the interp's
+ * result. The return value is semi-static: it will persist until the
+ * binding is changed or deleted.
*
* Side effects:
* None.
@@ -1244,15 +1214,15 @@ Tk_DeleteBinding(interp, bindingTable, object, eventString)
*--------------------------------------------------------------
*/
-CONST char *
-Tk_GetBinding(interp, bindingTable, object, eventString)
- Tcl_Interp *interp; /* Interpreter for error reporting. */
- Tk_BindingTable bindingTable; /* Table in which to look for
- * binding. */
- ClientData object; /* Token for object with which binding
- * is associated. */
- CONST char *eventString; /* String describing event sequence
- * that triggers binding. */
+const char *
+Tk_GetBinding(
+ Tcl_Interp *interp, /* Interpreter for error reporting. */
+ Tk_BindingTable bindingTable,
+ /* Table in which to look for binding. */
+ ClientData object, /* Token for object with which binding is
+ * associated. */
+ const char *eventString) /* String describing event sequence that
+ * triggers binding. */
{
BindingTable *bindPtr = (BindingTable *) bindingTable;
PatSeq *psPtr;
@@ -1264,7 +1234,7 @@ Tk_GetBinding(interp, bindingTable, object, eventString)
return NULL;
}
if (psPtr->eventProc == EvalTclBinding) {
- return (CONST char *) psPtr->clientData;
+ return (const char *) psPtr->clientData;
}
return "";
}
@@ -1274,14 +1244,14 @@ Tk_GetBinding(interp, bindingTable, object, eventString)
*
* Tk_GetAllBindings --
*
- * Return a list of event strings for all the bindings
- * associated with a given object.
+ * Return a list of event strings for all the bindings associated with a
+ * given object.
*
* Results:
- * 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.
+ * 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.
*
* Side effects:
* None.
@@ -1290,13 +1260,11 @@ Tk_GetBinding(interp, bindingTable, object, eventString)
*/
void
-Tk_GetAllBindings(interp, bindingTable, object)
- Tcl_Interp *interp; /* Interpreter returning result or
- * error. */
- Tk_BindingTable bindingTable; /* Table in which to look for
- * bindings. */
- ClientData object; /* Token for object. */
-
+Tk_GetAllBindings(
+ Tcl_Interp *interp, /* Interpreter returning result or error. */
+ Tk_BindingTable bindingTable,
+ /* Table in which to look for bindings. */
+ ClientData object) /* Token for object. */
{
BindingTable *bindPtr = (BindingTable *) bindingTable;
PatSeq *psPtr;
@@ -1310,11 +1278,11 @@ Tk_GetAllBindings(interp, bindingTable, object)
Tcl_DStringInit(&ds);
for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); psPtr != NULL;
psPtr = psPtr->nextObjPtr) {
- /*
- * For each binding, output information about each of the
- * patterns in its sequence.
+ /*
+ * For each binding, output information about each of the patterns in
+ * its sequence.
*/
-
+
Tcl_DStringSetLength(&ds, 0);
GetPatternString(psPtr, &ds);
Tcl_AppendElement(interp, Tcl_DStringValue(&ds));
@@ -1327,12 +1295,11 @@ Tk_GetAllBindings(interp, bindingTable, object)
*
* Tk_DeleteAllBindings --
*
- * Remove all bindings associated with a given object in a
- * given binding table.
+ * Remove all bindings associated with a given object in a given binding
+ * table.
*
* Results:
- * All bindings associated with object are removed from
- * bindingTable.
+ * All bindings associated with object are removed from bindingTable.
*
* Side effects:
* None.
@@ -1341,10 +1308,10 @@ Tk_GetAllBindings(interp, bindingTable, object)
*/
void
-Tk_DeleteAllBindings(bindingTable, object)
- Tk_BindingTable bindingTable; /* Table in which to delete
- * bindings. */
- ClientData object; /* Token for object. */
+Tk_DeleteAllBindings(
+ Tk_BindingTable bindingTable,
+ /* Table in which to delete bindings. */
+ ClientData object) /* Token for object. */
{
BindingTable *bindPtr = (BindingTable *) bindingTable;
PatSeq *psPtr, *prevPtr;
@@ -1357,12 +1324,12 @@ Tk_DeleteAllBindings(bindingTable, object)
}
for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); psPtr != NULL;
psPtr = nextPtr) {
- nextPtr = psPtr->nextObjPtr;
+ nextPtr = psPtr->nextObjPtr;
/*
- * Be sure to remove each binding from its hash chain in the
- * pattern table. If this is the last pattern in the chain,
- * then delete the hash entry too.
+ * Be sure to remove each binding from its hash chain in the pattern
+ * table. If this is the last pattern in the chain, then delete the
+ * hash entry too.
*/
prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr);
@@ -1375,7 +1342,7 @@ Tk_DeleteAllBindings(bindingTable, object)
} else {
for ( ; ; prevPtr = prevPtr->nextSeqPtr) {
if (prevPtr == NULL) {
- panic("Tk_DeleteAllBindings couldn't find on hash chain");
+ Tcl_Panic("Tk_DeleteAllBindings couldn't find on hash chain");
}
if (prevPtr->nextSeqPtr == psPtr) {
prevPtr->nextSeqPtr = psPtr->nextSeqPtr;
@@ -1400,11 +1367,10 @@ Tk_DeleteAllBindings(bindingTable, object)
*
* Tk_BindEvent --
*
- * This procedure is invoked to process an X event. The
- * event is added to those recorded for the binding table.
- * Then each of the objects at *objectPtr is checked in
- * order to see if it has a binding that matches the recent
- * events. If so, the most specific binding is invoked for
+ * This function is invoked to process an X event. The event is added to
+ * those recorded for the binding table. Then each of the objects at
+ * *objectPtr is checked in order to see if it has a binding that matches
+ * the recent events. If so, the most specific binding is invoked for
* each object.
*
* Results:
@@ -1413,32 +1379,32 @@ Tk_DeleteAllBindings(bindingTable, object)
* Side effects:
* Depends on the command associated with the matching binding.
*
- * All Tcl bindings scripts for each object are accumulated before
- * the first binding is evaluated. If the action of a Tcl binding
- * is to change or delete a binding, or delete the window associated
- * with the binding, all the original Tcl binding scripts will still
- * fire. Contrast this with C binding procedures. If a pending C
- * binding (one that hasn't fired yet, but is queued to be fired for
- * this window) is deleted, it will not be called, and if it is
- * changed, then the new binding procedure will be called. If the
- * window itself is deleted, no further C binding procedures will be
- * called for this window. When both Tcl binding scripts and C binding
- * procedures are interleaved, the above rules still apply.
+ * All Tcl bindings scripts for each object are accumulated before the
+ * first binding is evaluated. If the action of a Tcl binding is to
+ * change or delete a binding, or delete the window associated with the
+ * binding, all the original Tcl binding scripts will still fire.
+ * Contrast this with C binding functions. If a pending C binding (one
+ * that hasn't fired yet, but is queued to be fired for this window) is
+ * deleted, it will not be called, and if it is changed, then the new
+ * binding function will be called. If the window itself is deleted, no
+ * further C binding functions will be called for this window. When both
+ * Tcl binding scripts and C binding functions are interleaved, the above
+ * rules still apply.
*
*---------------------------------------------------------------------------
*/
void
-Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
- Tk_BindingTable bindingTable; /* Table in which to look for
- * bindings. */
- XEvent *eventPtr; /* What actually happened. */
- Tk_Window tkwin; /* Window on display where event
- * occurred (needed in order to
- * locate display information). */
- int numObjects; /* Number of objects at *objectPtr. */
- ClientData *objectPtr; /* Array of one or more objects
- * to check for a matching binding. */
+Tk_BindEvent(
+ Tk_BindingTable bindingTable,
+ /* Table in which to look for bindings. */
+ XEvent *eventPtr, /* What actually happened. */
+ Tk_Window tkwin, /* Window on display where event occurred
+ * (needed in order to locate display
+ * information). */
+ int numObjects, /* Number of objects at *objectPtr. */
+ ClientData *objectPtr) /* Array of one or more objects to check for a
+ * matching binding. */
{
BindingTable *bindPtr;
TkDisplay *dispPtr;
@@ -1453,15 +1419,14 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
Tcl_DString scripts, savedResult;
Detail detail;
char *p, *end;
- PendingBinding *pendingPtr;
- PendingBinding staticPending;
- TkWindow *winPtr = (TkWindow *)tkwin;
+ PendingBinding staticPending, *pendingPtr;
+ TkWindow *winPtr = (TkWindow *) tkwin;
PatternTableKey key;
Tk_ClassModalProc *modalProc;
+
/*
- * Ignore events on windows that don't have names: these are windows
- * like wrapper windows that shouldn't be visible to the
- * application.
+ * Ignore events on windows that don't have names: these are windows like
+ * wrapper windows that shouldn't be visible to the application.
*/
if (winPtr->pathName == NULL) {
@@ -1469,21 +1434,20 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
}
/*
- * Ignore the event completely if it is an Enter, Leave, FocusIn,
- * or FocusOut event with detail NotifyInferior. The reason for
- * ignoring these events is that we don't want transitions between
- * a window and its children to visible to bindings on the parent:
- * this would cause problems for mega-widgets, since the internal
- * structure of a mega-widget isn't supposed to be visible to
- * people watching the parent.
+ * Ignore the event completely if it is an Enter, Leave, FocusIn, or
+ * FocusOut event with detail NotifyInferior. The reason for ignoring
+ * these events is that we don't want transitions between a window and its
+ * children to visible to bindings on the parent: this would cause
+ * problems for mega-widgets, since the internal structure of a
+ * mega-widget isn't supposed to be visible to people watching the parent.
*/
- if ((eventPtr->type == EnterNotify) || (eventPtr->type == LeaveNotify)) {
+ if ((eventPtr->type == EnterNotify) || (eventPtr->type == LeaveNotify)) {
if (eventPtr->xcrossing.detail == NotifyInferior) {
return;
}
}
- if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) {
+ if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) {
if (eventPtr->xfocus.detail == NotifyInferior) {
return;
}
@@ -1494,20 +1458,19 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
bindInfoPtr = (BindInfo *) winPtr->mainPtr->bindInfo;
/*
- * Add the new event to the ring of saved events for the
- * binding table. Two tricky points:
+ * Add the new event to the ring of saved events for the binding table.
+ * Two tricky points:
*
- * 1. Combine consecutive MotionNotify events. Do this by putting
- * the new event *on top* of the previous event.
+ * 1. Combine consecutive MotionNotify events. Do this by putting the new
+ * event *on top* of the previous event.
* 2. If a modifier key is held down, it auto-repeats to generate
- * continuous KeyPress and KeyRelease events. These can flush
- * the event ring so that valuable information is lost (such
- * as repeated button clicks). To handle this, check for the
- * special case of a modifier KeyPress arriving when the previous
- * two events are a KeyRelease and KeyPress of the same key.
- * If this happens, mark the most recent event (the KeyRelease)
- * invalid and put the new event on top of the event before that
- * (the KeyPress).
+ * continuous KeyPress and KeyRelease events. These can flush the event
+ * ring so that valuable information is lost (such as repeated button
+ * clicks). To handle this, check for the special case of a modifier
+ * KeyPress arriving when the previous two events are a KeyRelease and
+ * KeyPress of the same key. If this happens, mark the most recent
+ * event (the KeyRelease) invalid and put the new event on top of the
+ * event before that (the KeyPress).
*/
if ((eventPtr->type == MotionNotify)
@@ -1517,6 +1480,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
*/
} else if (eventPtr->type == KeyPress) {
int i;
+
for (i = 0; ; i++) {
if (i >= dispPtr->numModKeyCodes) {
goto advanceRingPointer;
@@ -1543,14 +1507,15 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
bindPtr->eventRing[bindPtr->curEvent].type = -1;
bindPtr->curEvent = i;
} else {
- advanceRingPointer:
+
+ advanceRingPointer:
bindPtr->curEvent++;
if (bindPtr->curEvent >= EVENT_BUFFER_SIZE) {
bindPtr->curEvent = 0;
}
}
ringPtr = &bindPtr->eventRing[bindPtr->curEvent];
- memcpy((VOID *) ringPtr, (VOID *) eventPtr, sizeof(XEvent));
+ memcpy((void *) ringPtr, (void *) eventPtr, sizeof(XEvent));
detail.clientData = 0;
flags = flagArray[ringPtr->type];
if (flags & KEY) {
@@ -1575,14 +1540,12 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
memset(&key, 0, sizeof(key));
if (ringPtr->type != VirtualEvent) {
- Tcl_HashTable *veptPtr;
+ Tcl_HashTable *veptPtr = &bindInfoPtr->virtualEventTable.patternTable;
Tcl_HashEntry *hPtr;
- veptPtr = &bindInfoPtr->virtualEventTable.patternTable;
-
- key.object = NULL;
- key.type = ringPtr->type;
- key.detail = detail;
+ key.object = NULL;
+ key.type = ringPtr->type;
+ key.detail = detail;
hPtr = Tcl_FindHashEntry(veptPtr, (char *) &key);
if (hPtr != NULL) {
@@ -1593,37 +1556,34 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
key.detail.clientData = 0;
hPtr = Tcl_FindHashEntry(veptPtr, (char *) &key);
if (hPtr != NULL) {
- vMatchNoDetailList = (PatSeq *) Tcl_GetHashValue(hPtr);
+ vMatchNoDetailList = (PatSeq *) Tcl_GetHashValue(hPtr);
}
}
}
/*
- * Loop over all the binding tags, finding the binding script or
- * callback for each one. Append all of the binding scripts, with
- * %-sequences expanded, to "scripts", with null characters separating
- * the scripts for each object. Append all the callbacks to the array
- * of pending callbacks.
+ * Loop over all the binding tags, finding the binding script or callback
+ * for each one. Append all of the binding scripts, with %-sequences
+ * expanded, to "scripts", with null characters separating the scripts for
+ * each object. Append all the callbacks to the array of pending
+ * callbacks.
*/
-
+
pendingPtr = &staticPending;
matchCount = 0;
matchSpace = sizeof(staticPending.matchArray) / sizeof(PatSeq *);
Tcl_DStringInit(&scripts);
for ( ; numObjects > 0; numObjects--, objectPtr++) {
- PatSeq *matchPtr, *sourcePtr;
+ PatSeq *matchPtr = NULL, *sourcePtr = NULL;
Tcl_HashEntry *hPtr;
- matchPtr = NULL;
- sourcePtr = NULL;
-
/*
* Match the new event against those recorded in the pattern table,
- * saving the longest matching pattern. For events with details
- * (button and key events), look for a binding for the specific
- * key or button. First see if the event matches a physical event
- * that the object is interested in, then look for a virtual event.
+ * saving the longest matching pattern. For events with details
+ * (button and key events), look for a binding for the specific key or
+ * button. First see if the event matches a physical event that the
+ * object is interested in, then look for a virtual event.
*/
key.object = *objectPtr;
@@ -1631,7 +1591,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
key.detail = detail;
hPtr = Tcl_FindHashEntry(&bindPtr->patternTable, (char *) &key);
if (hPtr != NULL) {
- matchPtr = MatchPatterns(dispPtr, bindPtr,
+ matchPtr = MatchPatterns(dispPtr, bindPtr,
(PatSeq *) Tcl_GetHashValue(hPtr), matchPtr, NULL,
&sourcePtr);
}
@@ -1643,7 +1603,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
/*
* If no match was found, look for a binding for all keys or buttons
- * (detail of 0). Again, first match on a virtual event.
+ * (detail of 0). Again, first match on a virtual event.
*/
if ((detail.clientData != 0) && (matchPtr == NULL)) {
@@ -1656,24 +1616,24 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
}
if (vMatchNoDetailList != NULL) {
- matchPtr = MatchPatterns(dispPtr, bindPtr, vMatchNoDetailList,
+ matchPtr = MatchPatterns(dispPtr, bindPtr, vMatchNoDetailList,
matchPtr, objectPtr, &sourcePtr);
}
}
-
+
if (matchPtr != NULL) {
if (sourcePtr->eventProc == NULL) {
- panic("Tk_BindEvent: missing command");
+ Tcl_Panic("Tk_BindEvent: missing command");
}
if (sourcePtr->eventProc == EvalTclBinding) {
ExpandPercents(winPtr, (char *) sourcePtr->clientData,
eventPtr, detail.keySym, &scripts);
} else {
if (matchCount >= matchSpace) {
- PendingBinding *new;
+ PendingBinding *newPtr;
unsigned int oldSize, newSize;
-
+
oldSize = sizeof(staticPending)
- sizeof(staticPending.matchArray)
+ matchSpace * sizeof(PatSeq*);
@@ -1681,20 +1641,21 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
newSize = sizeof(staticPending)
- sizeof(staticPending.matchArray)
+ matchSpace * sizeof(PatSeq*);
- new = (PendingBinding *) ckalloc(newSize);
- memcpy((VOID *) new, (VOID *) pendingPtr, oldSize);
+ newPtr = (PendingBinding *) ckalloc(newSize);
+ memcpy((void *) newPtr, (void *) pendingPtr, oldSize);
if (pendingPtr != &staticPending) {
ckfree((char *) pendingPtr);
}
- pendingPtr = new;
+ pendingPtr = newPtr;
}
sourcePtr->refCount++;
pendingPtr->matchArray[matchCount] = sourcePtr;
matchCount++;
}
+
/*
- * A "" is added to the scripts string to separate the
- * various scripts that should be invoked.
+ * A "" is added to the scripts string to separate the various
+ * scripts that should be invoked.
*/
Tcl_DStringAppend(&scripts, "", 1);
@@ -1705,29 +1666,28 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
}
/*
- * Now go back through and evaluate the binding for each object,
- * in order, dealing with "break" and "continue" exceptions
- * appropriately.
+ * Now go back through and evaluate the binding for each object, in order,
+ * dealing with "break" and "continue" exceptions appropriately.
*
* There are two tricks here:
- * 1. Bindings can be invoked from in the middle of Tcl commands,
- * 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,
- * we save it in a dynamic string.
- * 2. The binding's action can potentially delete the binding,
- * so bindPtr may not point to anything valid once the action
- * completes. Thus we have to save bindPtr->interp in a
- * local variable in order to restore the result.
+ * 1. Bindings can be invoked from in the middle of Tcl commands, 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, we save it in a dynamic
+ * string.
+ * 2. The binding's action can potentially delete the binding, so bindPtr
+ * may not point to anything valid once the action completes. Thus we
+ * have to save bindPtr->interp in a local variable in order to restore
+ * the result.
*/
interp = bindPtr->interp;
Tcl_DStringInit(&savedResult);
/*
- * Save information about the current screen, then invoke a script
- * if the screen has changed.
+ * Save information about the current screen, then invoke a script if the
+ * screen has changed.
*/
Tcl_DStringGetResult(interp, &savedResult);
@@ -1744,9 +1704,8 @@ 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.
+ * 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;
@@ -1754,11 +1713,11 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
pendingPtr->deleted = 0;
bindInfoPtr->pendingList = pendingPtr;
}
-
+
/*
- * Save the current value of the TK_DEFER_MODAL flag so we can
- * restore it at the end of the loop. Clear the flag so we can
- * detect any recursive requests for a modal loop.
+ * Save the current value of the TK_DEFER_MODAL flag so we can restore it
+ * at the end of the loop. Clear the flag so we can detect any recursive
+ * requests for a modal loop.
*/
flags = winPtr->flags;
@@ -1769,16 +1728,15 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
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.
+ * 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;
-
+
if (!bindInfoPtr->deleted) {
screenPtr->bindingDepth++;
}
@@ -1786,7 +1744,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
if (*p == '\0') {
PatSeq *psPtr;
-
+
psPtr = pendingPtr->matchArray[i];
i++;
code = TCL_OK;
@@ -1804,6 +1762,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
}
} else {
int len = (int) strlen(p);
+
code = Tcl_EvalEx(interp, p, len, TCL_EVAL_GLOBAL);
p += len;
}
@@ -1815,7 +1774,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
if (code != TCL_OK) {
if (code == TCL_CONTINUE) {
/*
- * Do nothing: just go on to the next command.
+ * Do nothing: just go on to the next command.
*/
} else if (code == TCL_BREAK) {
break;
@@ -1829,13 +1788,13 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
if (matchCount > 0 && !pendingPtr->deleted) {
/*
- * Restore the original modal flag value and invoke the modal loop
- * if needed.
+ * Restore the original modal flag value and invoke the modal loop if
+ * needed.
*/
deferModal = winPtr->flags & TK_DEFER_MODAL;
- winPtr->flags = (winPtr->flags & (unsigned int) ~TK_DEFER_MODAL)
- | (flags & TK_DEFER_MODAL);
+ winPtr->flags = (winPtr->flags & (unsigned int) ~TK_DEFER_MODAL)
+ | (flags & TK_DEFER_MODAL);
if (deferModal) {
modalProc = Tk_GetClassProc(winPtr->classProcsPtr, modalProc);
if (modalProc != NULL) {
@@ -1846,12 +1805,10 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
if (!bindInfoPtr->deleted && (screenPtr->bindingDepth != 0)
&& ((oldDispPtr != screenPtr->curDispPtr)
- || (oldScreen != screenPtr->curScreenIndex))) {
-
+ || (oldScreen != screenPtr->curScreenIndex))) {
/*
- * Some other binding script is currently executing, but its
- * screen is no longer current. Change the current display
- * back again.
+ * Some other binding script is currently executing, but its screen is
+ * no longer current. Change the current display back again.
*/
screenPtr->curDispPtr = oldDispPtr;
@@ -1864,10 +1821,10 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
if (matchCount > 0) {
if (!bindInfoPtr->deleted) {
/*
- * Delete the pending list from the list of pending scripts
- * for this window.
+ * Delete the pending list from the list of pending scripts for
+ * this window.
*/
-
+
PendingBinding **curPtrPtr;
for (curPtrPtr = &bindInfoPtr->pendingList; ; ) {
@@ -1890,8 +1847,8 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
*
* TkBindDeadWindow --
*
- * This procedure is invoked when it is determined that a window is
- * dead. It cleans up bind-related information about the window
+ * This function is invoked when it is determined that a window is dead.
+ * It cleans up bind-related information about the window
*
* Results:
* None.
@@ -1901,20 +1858,22 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr)
*
*---------------------------------------------------------------------------
*/
-
+
void
-TkBindDeadWindow(winPtr)
- TkWindow *winPtr; /* The window that is being deleted. */
+TkBindDeadWindow(
+ TkWindow *winPtr) /* The window that is being deleted. */
{
BindInfo *bindInfoPtr;
PendingBinding *curPtr;
/*
- * Certain special windows like those used for send and clipboard
- * have no mainPtr.
+ * Certain special windows like those used for send and clipboard have no
+ * mainPtr.
*/
- if (winPtr->mainPtr == NULL)
- return;
+
+ if (winPtr->mainPtr == NULL) {
+ return;
+ }
bindInfoPtr = (BindInfo *) winPtr->mainPtr->bindInfo;
curPtr = bindInfoPtr->pendingList;
@@ -1931,58 +1890,59 @@ TkBindDeadWindow(winPtr)
*
* MatchPatterns --
*
- * Given a list of pattern sequences and a list of recent events,
- * return the pattern sequence that best matches the event list,
- * if there is one.
+ * Given a list of pattern sequences and a list of recent events, return
+ * the pattern sequence that best matches the event list, if there is
+ * one.
*
- * This procedure is used in two different ways. In the simplest
- * use, "object" is NULL and psPtr is a list of pattern sequences,
- * each of which corresponds to a binding. In this case, the
- * procedure finds the pattern sequences that match the event list
- * and returns the most specific of those, if there is more than one.
+ * This function is used in two different ways. In the simplest use,
+ * "object" is NULL and psPtr is a list of pattern sequences, each of
+ * which corresponds to a binding. In this case, the function finds the
+ * pattern sequences that match the event list and returns the most
+ * specific of those, if there is more than one.
*
- * In the second case, psPtr is a list of pattern sequences, each
- * of which corresponds to a definition for a virtual binding.
- * In order for one of these sequences to "match", it must match
- * the events (as above) but in addition there must be a binding
- * for its associated virtual event on the current object. The
- * "object" argument indicates which object the binding must be for.
+ * In the second case, psPtr is a list of pattern sequences, each of
+ * which corresponds to a definition for a virtual binding. In order for
+ * one of these sequences to "match", it must match the events (as above)
+ * but in addition there must be a binding for its associated virtual
+ * event on the current object. The "object" argument indicates which
+ * object the binding must be for.
*
* Results:
- * The return value is NULL if bestPtr is NULL and no pattern matches
- * the recent events from bindPtr. Otherwise the return value is
- * the most specific pattern sequence among bestPtr and all those
- * at psPtr that match the event list and object. If a pattern
- * sequence other than bestPtr is returned, then *bestCommandPtr
- * is filled in with a pointer to the command from the best sequence.
+
+ * The return value is NULL if bestPtr is NULL and no pattern matches the
+ * recent events from bindPtr. Otherwise the return value is the most
+ * specific pattern sequence among bestPtr and all those at psPtr that
+ * match the event list and object. If a pattern sequence other than
+ * bestPtr is returned, then *bestCommandPtr is filled in with a pointer
+ * to the command from the best sequence.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
static PatSeq *
-MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr)
- TkDisplay *dispPtr; /* Display from which the event came. */
- BindingTable *bindPtr; /* Information about binding table, such as
+MatchPatterns(
+ TkDisplay *dispPtr, /* Display from which the event came. */
+ BindingTable *bindPtr, /* Information about binding table, such as
* ring of recent events. */
- PatSeq *psPtr; /* List of pattern sequences. */
- PatSeq *bestPtr; /* The best match seen so far, from a
- * previous call to this procedure. NULL
- * means no prior best match. */
- ClientData *objectPtr; /* If NULL, the sequences at psPtr
- * correspond to "normal" bindings. If
- * non-NULL, the sequences at psPtr correspond
- * to virtual bindings; in order to match each
- * sequence must correspond to a virtual
- * binding for which a binding exists for
- * object in bindPtr. */
- PatSeq **sourcePtrPtr; /* Filled with the pattern sequence that
+ PatSeq *psPtr, /* List of pattern sequences. */
+ PatSeq *bestPtr, /* The best match seen so far, from a previous
+ * call to this function. NULL means no prior
+ * best match. */
+ ClientData *objectPtr, /* If NULL, the sequences at psPtr correspond
+ * to "normal" bindings. If non-NULL, the
+ * sequences at psPtr correspond to virtual
+ * bindings; in order to match each sequence
+ * must correspond to a virtual binding for
+ * which a binding exists for object in
+ * bindPtr. */
+ PatSeq **sourcePtrPtr) /* Filled with the pattern sequence that
* contains the eventProc and clientData
- * associated with the best match. If this
+ * associated with the best match. If this
* differs from the return value, it is the
* virtual event that most closely matched the
- * return value (a physical event). Not
+ * return value (a physical event). Not
* modified unless a result other than bestPtr
* is returned. */
{
@@ -1995,22 +1955,17 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr)
*/
for ( ; psPtr != NULL; psPtr = psPtr->nextSeqPtr) {
- XEvent *eventPtr;
- Pattern *patPtr;
- Window window;
- Detail *detailPtr;
- int patCount, ringCount, flags, state;
- int modMask;
+ XEvent *eventPtr = &bindPtr->eventRing[bindPtr->curEvent];
+ Detail *detailPtr = &bindPtr->detailRing[bindPtr->curEvent];
+ Pattern *patPtr = psPtr->pats;
+ Window window = eventPtr->xany.window;
+ int patCount, ringCount, flags, state, modMask, i;
/*
- * Iterate over all the patterns in a sequence to be
- * sure that they all match.
+ * Iterate over all the patterns in a sequence to be sure that they
+ * all match.
*/
- eventPtr = &bindPtr->eventRing[bindPtr->curEvent];
- detailPtr = &bindPtr->detailRing[bindPtr->curEvent];
- window = eventPtr->xany.window;
- patPtr = psPtr->pats;
patCount = psPtr->numPats;
ringCount = EVENT_BUFFER_SIZE;
while (patCount > 0) {
@@ -2019,21 +1974,21 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr)
}
if (eventPtr->xany.type != patPtr->eventType) {
/*
- * Most of the event types are considered superfluous
- * in that they are ignored if they occur in the middle
- * of a pattern sequence and have mismatching types. The
- * only ones that cannot be ignored are ButtonPress and
- * ButtonRelease events (if the next event in the pattern
- * is a KeyPress or KeyRelease) and KeyPress and KeyRelease
- * events (if the next pattern event is a ButtonPress or
- * ButtonRelease). Here are some tricky cases to consider:
+ * Most of the event types are considered superfluous in that
+ * they are ignored if they occur in the middle of a pattern
+ * sequence and have mismatching types. The only ones that
+ * cannot be ignored are ButtonPress and ButtonRelease events
+ * (if the next event in the pattern is a KeyPress or
+ * KeyRelease) and KeyPress and KeyRelease events (if the next
+ * pattern event is a ButtonPress or ButtonRelease). Here are
+ * some tricky cases to consider:
* 1. Double-Button or Double-Key events.
* 2. Double-ButtonRelease or Double-KeyRelease events.
- * 3. The arrival of various events like Enter and Leave
- * and FocusIn and GraphicsExpose between two button
- * presses or key presses.
- * 4. Modifier keys like Shift and Control shouldn't
- * generate conflicts with button events.
+ * 3. The arrival of various events like Enter and Leave and
+ * FocusIn and GraphicsExpose between two button presses or
+ * key presses.
+ * 4. Modifier keys like Shift and Control shouldn't generate
+ * conflicts with button events.
*/
if ((patPtr->eventType == KeyPress)
@@ -2046,8 +2001,6 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr)
|| (patPtr->eventType == ButtonRelease)) {
if ((eventPtr->xany.type == KeyPress)
|| (eventPtr->xany.type == KeyRelease)) {
- int i;
-
/*
* Ignore key events if they are modifier keys.
*/
@@ -2058,6 +2011,7 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr)
/*
* This key is a modifier key, so ignore it.
*/
+
goto nextEvent;
}
}
@@ -2067,32 +2021,28 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr)
goto nextEvent;
}
if (eventPtr->xany.type == CreateNotify
- && eventPtr->xcreatewindow.parent != window) {
+ && eventPtr->xcreatewindow.parent != window) {
goto nextSequence;
- } else
- if (eventPtr->xany.window != window) {
+ } else if (eventPtr->xany.window != window) {
goto nextSequence;
}
/*
- * Note: it's important for the keysym check to go before
- * the modifier check, so we can ignore unwanted modifier
- * keys before choking on the modifier check.
+ * Note: it's important for the keysym check to go before the
+ * modifier check, so we can ignore unwanted modifier keys before
+ * choking on the modifier check.
*/
if ((patPtr->detail.clientData != 0)
&& (patPtr->detail.clientData != detailPtr->clientData)) {
/*
- * The detail appears not to match. However, if the event
- * is a KeyPress for a modifier key then just ignore the
- * event. Otherwise event sequences like "aD" never match
- * because the shift key goes down between the "a" and the
- * "D".
+ * The detail appears not to match. However, if the event is a
+ * KeyPress for a modifier key then just ignore the event.
+ * Otherwise event sequences like "aD" never match because the
+ * shift key goes down between the "a" and the "D".
*/
if (eventPtr->xany.type == KeyPress) {
- int i;
-
for (i = 0; i < dispPtr->numModKeyCodes; i++) {
if (dispPtr->modKeyCodes[i] == eventPtr->xkey.keycode) {
goto nextEvent;
@@ -2102,7 +2052,7 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr)
goto nextSequence;
}
flags = flagArray[eventPtr->type];
- if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) {
+ if (flags & KEY_BUTTON_MOTION_VIRTUAL) {
state = eventPtr->xkey.state;
} else if (flags & CROSSING) {
state = eventPtr->xcrossing.state;
@@ -2130,10 +2080,9 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr)
}
}
if (psPtr->flags & PAT_NEARBY) {
- XEvent *firstPtr;
+ XEvent *firstPtr = &bindPtr->eventRing[bindPtr->curEvent];
int timeDiff;
- firstPtr = &bindPtr->eventRing[bindPtr->curEvent];
timeDiff = (Time) firstPtr->xkey.time - eventPtr->xkey.time;
if ((firstPtr->xkey.x_root
< (eventPtr->xkey.x_root - NEARBY_PIXELS))
@@ -2149,7 +2098,7 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr)
}
patPtr++;
patCount--;
- nextEvent:
+ nextEvent:
if (eventPtr == bindPtr->eventRing) {
eventPtr = &bindPtr->eventRing[EVENT_BUFFER_SIZE-1];
detailPtr = &bindPtr->detailRing[EVENT_BUFFER_SIZE-1];
@@ -2169,9 +2118,9 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr)
PatternTableKey key;
/*
- * The sequence matches the physical constraints.
- * Is this object interested in any of the virtual events
- * that correspond to this sequence?
+ * The sequence matches the physical constraints. Is this object
+ * interested in any of the virtual events that correspond to this
+ * sequence?
*/
voPtr = psPtr->voPtr;
@@ -2182,26 +2131,24 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr)
key.detail.clientData = 0;
for (iVirt = 0; iVirt < voPtr->numOwners; iVirt++) {
- Tcl_HashEntry *hPtr = voPtr->owners[iVirt];
+ Tcl_HashEntry *hPtr = voPtr->owners[iVirt];
- key.detail.name = (Tk_Uid) Tcl_GetHashKey(hPtr->tablePtr,
+ key.detail.name = (Tk_Uid) Tcl_GetHashKey(hPtr->tablePtr,
hPtr);
hPtr = Tcl_FindHashEntry(&bindPtr->patternTable,
(char *) &key);
if (hPtr != NULL) {
-
/*
* This tag is interested in this virtual event and its
* corresponding physical event is a good match with the
* virtual event's definition.
*/
- PatSeq *virtMatchPtr;
+ PatSeq *virtMatchPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
- virtMatchPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
if ((virtMatchPtr->numPats != 1)
|| (virtMatchPtr->nextSeqPtr != NULL)) {
- panic("MatchPattern: badly constructed virtual event");
+ Tcl_Panic("MatchPattern: badly constructed virtual event");
}
sourcePtr = virtMatchPtr;
goto match;
@@ -2212,19 +2159,19 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr)
* The physical event matches a virtual event's definition, but
* the tag isn't interested in it.
*/
+
goto nextSequence;
}
- match:
+ match:
/*
- * This sequence matches. If we've already got another match,
- * pick whichever is most specific. Detail is most important,
- * then needMods.
+ * This sequence matches. If we've already got another match, pick
+ * whichever is most specific. Detail is most important, then
+ * needMods.
*/
if (bestPtr != NULL) {
Pattern *patPtr2;
- int i;
if (matchPtr->numPats != bestPtr->numPats) {
if (bestPtr->numPats > matchPtr->numPats) {
@@ -2252,51 +2199,49 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr)
}
}
}
+
/*
* Tie goes to current best pattern.
*
- * (1) For virtual vs. virtual, the least recently defined
- * virtual wins, because virtuals are examined in order of
- * definition. This order is _not_ guaranteed in the
- * documentation.
+ * (1) For virtual vs. virtual, the least recently defined virtual
+ * wins, because virtuals are examined in order of definition.
+ * This order is _not_ guaranteed in the documentation.
*
- * (2) For virtual vs. physical, the physical wins because all
- * the physicals are examined before the virtuals. This order
- * is guaranteed in the documentation.
+ * (2) For virtual vs. physical, the physical wins because all the
+ * physicals are examined before the virtuals. This order is
+ * guaranteed in the documentation.
*
* (3) For physical vs. physical pattern, the most recently
* defined physical wins, because physicals are examined in
- * reverse order of definition. This order is guaranteed in
- * the documentation.
+ * reverse order of definition. This order is guaranteed in the
+ * documentation.
*/
- goto nextSequence;
+ goto nextSequence;
}
- newBest:
+ newBest:
bestPtr = matchPtr;
bestSourcePtr = sourcePtr;
- nextSequence:
+ nextSequence:
continue;
}
*sourcePtrPtr = bestSourcePtr;
return bestPtr;
}
-
/*
*--------------------------------------------------------------
*
* ExpandPercents --
*
- * Given a command and an event, produce a new command
- * by replacing % constructs in the original command
- * with information from the X event.
+ * Given a command and an event, produce a new command by replacing %
+ * constructs in the original command with information from the X event.
*
* Results:
- * The new expanded command is appended to the dynamic string
- * given by dsPtr.
+ * The new expanded command is appended to the dynamic string given by
+ * dsPtr.
*
* Side effects:
* None.
@@ -2305,23 +2250,23 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr)
*/
static void
-ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr)
- TkWindow *winPtr; /* Window where event occurred: needed to
- * get input context. */
- CONST char *before; /* Command containing percent expressions
- * to be replaced. */
- XEvent *eventPtr; /* X event containing information to be
- * used in % replacements. */
- KeySym keySym; /* KeySym: only relevant for KeyPress and
+ExpandPercents(
+ TkWindow *winPtr, /* Window where event occurred: needed to get
+ * input context. */
+ const char *before, /* Command containing percent expressions to
+ * be replaced. */
+ XEvent *eventPtr, /* X event containing information to be used
+ * in % replacements. */
+ KeySym keySym, /* KeySym: only relevant for KeyPress and
* KeyRelease events). */
- Tcl_DString *dsPtr; /* Dynamic string in which to append new
+ Tcl_DString *dsPtr) /* Dynamic string in which to append new
* command. */
{
int spaceNeeded, cvtFlags; /* Used to substitute string as proper Tcl
* list element. */
int number, flags, length;
#define NUM_SIZE 40
- CONST char *string;
+ const char *string;
Tcl_DString buf;
char numStorage[NUM_SIZE+1];
@@ -2332,10 +2277,11 @@ ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr)
} else {
flags = 0;
}
+
while (1) {
/*
- * Find everything up to the next % character and append it
- * to the result string.
+ * Find everything up to the next % character and append it to the
+ * result string.
*/
for (string = before; (*string != 0) && (*string != '%'); string++) {
@@ -2350,303 +2296,313 @@ ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr)
}
/*
- * There's a percent sequence here. Process it.
+ * There's a percent sequence here. Process it.
*/
number = 0;
string = "??";
switch (before[1]) {
- case '#':
- number = eventPtr->xany.serial;
- goto doNumber;
- case 'a':
- if (flags & CONFIG) {
- TkpPrintWindowId(numStorage, eventPtr->xconfigure.above);
- string = numStorage;
- }
- goto doString;
- case 'b':
- if (flags & BUTTON) {
- number = eventPtr->xbutton.button;
- goto doNumber;
- }
- goto doString;
- case 'c':
- if (flags & EXPOSE) {
- number = eventPtr->xexpose.count;
- goto doNumber;
- }
- goto doString;
- case 'd':
- if (flags & (CROSSING|FOCUS)) {
- if (flags & FOCUS) {
- number = eventPtr->xfocus.detail;
- } else {
- number = eventPtr->xcrossing.detail;
- }
- string = TkFindStateString(notifyDetail, number);
- } else if (flags & CONFIGREQ) {
- if (eventPtr->xconfigurerequest.value_mask & CWStackMode) {
- string = TkFindStateString(configureRequestDetail,
- eventPtr->xconfigurerequest.detail);
- } else {
- string = "";
- }
- }
- goto doString;
- case 'f':
- if (flags & CROSSING) {
- number = eventPtr->xcrossing.focus;
- goto doNumber;
- }
- goto doString;
- case 'h':
- if (flags & EXPOSE) {
- number = eventPtr->xexpose.height;
- } else if (flags & (CONFIG)) {
- number = eventPtr->xconfigure.height;
- } else if (flags & CREATE) {
- number = eventPtr->xcreatewindow.height;
- } else if (flags & CONFIGREQ) {
- number = eventPtr->xconfigurerequest.height;
- } else if (flags & RESIZEREQ) {
- number = eventPtr->xresizerequest.height;
- } else {
- goto doString;
- }
- goto doNumber;
- case 'i':
- if (flags & CREATE) {
- TkpPrintWindowId(numStorage, eventPtr->xcreatewindow.window);
- } else if (flags & CONFIGREQ) {
- TkpPrintWindowId(numStorage, eventPtr->xconfigurerequest.window);
- } else if (flags & MAPREQ) {
- TkpPrintWindowId(numStorage, eventPtr->xmaprequest.window);
- } else {
- TkpPrintWindowId(numStorage, eventPtr->xany.window);
- }
+ case '#':
+ number = eventPtr->xany.serial;
+ goto doNumber;
+ case 'a':
+ if (flags & CONFIG) {
+ TkpPrintWindowId(numStorage, eventPtr->xconfigure.above);
string = numStorage;
- goto doString;
- case 'k':
- if ((flags & KEY) && (eventPtr->type != MouseWheelEvent)) {
- number = eventPtr->xkey.keycode;
- goto doNumber;
- }
- goto doString;
- case 'm':
- if (flags & CROSSING) {
- number = eventPtr->xcrossing.mode;
- string = TkFindStateString(notifyMode, number);
- } else if (flags & FOCUS) {
- number = eventPtr->xfocus.mode;
- string = TkFindStateString(notifyMode, number);
- }
- goto doString;
- case 'o':
- if (flags & CREATE) {
- number = eventPtr->xcreatewindow.override_redirect;
- } else if (flags & MAP) {
- number = eventPtr->xmap.override_redirect;
- } else if (flags & REPARENT) {
- number = eventPtr->xreparent.override_redirect;
- } else if (flags & CONFIG) {
- number = eventPtr->xconfigure.override_redirect;
- } else {
- goto doString;
- }
- goto doNumber;
- case 'p':
- if (flags & CIRC) {
- string = TkFindStateString(circPlace, eventPtr->xcirculate.place);
- } else if (flags & CIRCREQ) {
- string = TkFindStateString(circPlace, eventPtr->xcirculaterequest.place);
- }
- goto doString;
- case 's':
- if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) {
- number = eventPtr->xkey.state;
- } else if (flags & CROSSING) {
- number = eventPtr->xcrossing.state;
- } else if (flags & PROP) {
- string = TkFindStateString(propNotify,
- eventPtr->xproperty.state);
- goto doString;
- } else if (flags & VISIBILITY) {
- string = TkFindStateString(visNotify,
- eventPtr->xvisibility.state);
- goto doString;
- } else {
- goto doString;
- }
- goto doNumber;
- case 't':
- if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) {
- number = (int) eventPtr->xkey.time;
- } else if (flags & CROSSING) {
- number = (int) eventPtr->xcrossing.time;
- } else if (flags & PROP) {
- number = (int) eventPtr->xproperty.time;
- } else {
- goto doString;
- }
+ }
+ goto doString;
+ case 'b':
+ if (flags & BUTTON) {
+ number = eventPtr->xbutton.button;
goto doNumber;
- case 'v':
- number = eventPtr->xconfigurerequest.value_mask;
+ }
+ goto doString;
+ case 'c':
+ if (flags & EXPOSE) {
+ number = eventPtr->xexpose.count;
goto doNumber;
- case 'w':
- if (flags & EXPOSE) {
- number = eventPtr->xexpose.width;
- } else if (flags & CONFIG) {
- number = eventPtr->xconfigure.width;
- } else if (flags & CREATE) {
- number = eventPtr->xcreatewindow.width;
- } else if (flags & CONFIGREQ) {
- number = eventPtr->xconfigurerequest.width;
- } else if (flags & RESIZEREQ) {
- number = eventPtr->xresizerequest.width;
+ }
+ goto doString;
+ case 'd':
+ if (flags & (CROSSING|FOCUS)) {
+ if (flags & FOCUS) {
+ number = eventPtr->xfocus.detail;
} else {
- goto doString;
+ number = eventPtr->xcrossing.detail;
}
- goto doNumber;
- case 'x':
- if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) {
- number = eventPtr->xkey.x;
- } else if (flags & CROSSING) {
- number = eventPtr->xcrossing.x;
- } else if (flags & EXPOSE) {
- number = eventPtr->xexpose.x;
- } else if (flags & (CREATE|CONFIG|GRAVITY)) {
- number = eventPtr->xcreatewindow.x;
- } else if (flags & REPARENT) {
- number = eventPtr->xreparent.x;
- } else if (flags & CREATE) {
- number = eventPtr->xcreatewindow.x;
- } else if (flags & CONFIGREQ) {
- number = eventPtr->xconfigurerequest.x;
+ string = TkFindStateString(notifyDetail, number);
+ } else if (flags & CONFIGREQ) {
+ if (eventPtr->xconfigurerequest.value_mask & CWStackMode) {
+ string = TkFindStateString(configureRequestDetail,
+ eventPtr->xconfigurerequest.detail);
} else {
- goto doString;
+ string = "";
}
- goto doNumber;
- case 'y':
- if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) {
- number = eventPtr->xkey.y;
- } else if (flags & EXPOSE) {
- number = eventPtr->xexpose.y;
- } else if (flags & (CREATE|CONFIG|GRAVITY)) {
- number = eventPtr->xcreatewindow.y;
- } else if (flags & REPARENT) {
- number = eventPtr->xreparent.y;
- } else if (flags & CROSSING) {
- number = eventPtr->xcrossing.y;
- } else if (flags & CREATE) {
- number = eventPtr->xcreatewindow.y;
- } else if (flags & CONFIGREQ) {
- number = eventPtr->xconfigurerequest.y;
+ } else if (flags & VIRTUAL) {
+ XVirtualEvent *vePtr = (XVirtualEvent *) eventPtr;
+
+ if (vePtr->user_data != NULL) {
+ string = Tcl_GetString(vePtr->user_data);
} else {
- goto doString;
+ string = "";
}
+ }
+ goto doString;
+ case 'f':
+ if (flags & CROSSING) {
+ number = eventPtr->xcrossing.focus;
goto doNumber;
- case 'A':
- if ((flags & KEY) && (eventPtr->type != MouseWheelEvent)) {
- Tcl_DStringFree(&buf);
- string = TkpGetString(winPtr, eventPtr, &buf);
- }
+ }
+ goto doString;
+ case 'h':
+ if (flags & EXPOSE) {
+ number = eventPtr->xexpose.height;
+ } else if (flags & CONFIG) {
+ number = eventPtr->xconfigure.height;
+ } else if (flags & CREATE) {
+ number = eventPtr->xcreatewindow.height;
+ } else if (flags & CONFIGREQ) {
+ number = eventPtr->xconfigurerequest.height;
+ } else if (flags & RESIZEREQ) {
+ number = eventPtr->xresizerequest.height;
+ } else {
goto doString;
- case 'B':
- if (flags & CREATE) {
- number = eventPtr->xcreatewindow.border_width;
- } else if (flags & CONFIGREQ) {
- number = eventPtr->xconfigurerequest.border_width;
- } else if (flags & CONFIG) {
- number = eventPtr->xconfigure.border_width;
- } else {
- goto doString;
- }
+ }
+ goto doNumber;
+ case 'i':
+ if (flags & CREATE) {
+ TkpPrintWindowId(numStorage, eventPtr->xcreatewindow.window);
+ } else if (flags & CONFIGREQ) {
+ TkpPrintWindowId(numStorage,
+ eventPtr->xconfigurerequest.window);
+ } else if (flags & MAPREQ) {
+ TkpPrintWindowId(numStorage, eventPtr->xmaprequest.window);
+ } else {
+ TkpPrintWindowId(numStorage, eventPtr->xany.window);
+ }
+ string = numStorage;
+ goto doString;
+ case 'k':
+ if ((flags & KEY) && (eventPtr->type != MouseWheelEvent)) {
+ number = eventPtr->xkey.keycode;
goto doNumber;
- case 'D':
- /*
- * This is used only by the MouseWheel event.
- */
- if ((flags & KEY) && (eventPtr->type == MouseWheelEvent)) {
- number = eventPtr->xkey.keycode;
- goto doNumber;
- }
+ }
+ goto doString;
+ case 'm':
+ if (flags & CROSSING) {
+ number = eventPtr->xcrossing.mode;
+ string = TkFindStateString(notifyMode, number);
+ } else if (flags & FOCUS) {
+ number = eventPtr->xfocus.mode;
+ string = TkFindStateString(notifyMode, number);
+ }
+ goto doString;
+ case 'o':
+ if (flags & CREATE) {
+ number = eventPtr->xcreatewindow.override_redirect;
+ } else if (flags & MAP) {
+ number = eventPtr->xmap.override_redirect;
+ } else if (flags & REPARENT) {
+ number = eventPtr->xreparent.override_redirect;
+ } else if (flags & CONFIG) {
+ number = eventPtr->xconfigure.override_redirect;
+ } else {
goto doString;
- case 'E':
- number = (int) eventPtr->xany.send_event;
+ }
+ goto doNumber;
+ case 'p':
+ if (flags & CIRC) {
+ string = TkFindStateString(circPlace,
+ eventPtr->xcirculate.place);
+ } else if (flags & CIRCREQ) {
+ string = TkFindStateString(circPlace,
+ eventPtr->xcirculaterequest.place);
+ }
+ goto doString;
+ case 's':
+ if (flags & KEY_BUTTON_MOTION_VIRTUAL) {
+ number = eventPtr->xkey.state;
goto doNumber;
- case 'K':
- if ((flags & KEY) && (eventPtr->type != MouseWheelEvent)) {
- char *name;
-
- name = TkKeysymToString(keySym);
- if (name != NULL) {
- string = name;
- }
- }
+ } else if (flags & CROSSING) {
+ number = eventPtr->xcrossing.state;
+ goto doNumber;
+ } else if (flags & PROP) {
+ string = TkFindStateString(propNotify,
+ eventPtr->xproperty.state);
+ } else if (flags & VISIBILITY) {
+ string = TkFindStateString(visNotify,
+ eventPtr->xvisibility.state);
+ }
+ goto doString;
+ case 't':
+ if (flags & KEY_BUTTON_MOTION_VIRTUAL) {
+ number = (int) eventPtr->xkey.time;
+ } else if (flags & CROSSING) {
+ number = (int) eventPtr->xcrossing.time;
+ } else if (flags & PROP) {
+ number = (int) eventPtr->xproperty.time;
+ } else {
goto doString;
- case 'N':
- if ((flags & KEY) && (eventPtr->type != MouseWheelEvent)) {
- number = (int) keySym;
- goto doNumber;
- }
+ }
+ goto doNumber;
+ case 'v':
+ number = eventPtr->xconfigurerequest.value_mask;
+ goto doNumber;
+ case 'w':
+ if (flags & EXPOSE) {
+ number = eventPtr->xexpose.width;
+ } else if (flags & CONFIG) {
+ number = eventPtr->xconfigure.width;
+ } else if (flags & CREATE) {
+ number = eventPtr->xcreatewindow.width;
+ } else if (flags & CONFIGREQ) {
+ number = eventPtr->xconfigurerequest.width;
+ } else if (flags & RESIZEREQ) {
+ number = eventPtr->xresizerequest.width;
+ } else {
goto doString;
- case 'P':
- if (flags & PROP) {
- string = Tk_GetAtomName((Tk_Window) winPtr, eventPtr->xproperty.atom);
- }
+ }
+ goto doNumber;
+ case 'x':
+ if (flags & KEY_BUTTON_MOTION_VIRTUAL) {
+ number = eventPtr->xkey.x;
+ } else if (flags & CROSSING) {
+ number = eventPtr->xcrossing.x;
+ } else if (flags & EXPOSE) {
+ number = eventPtr->xexpose.x;
+ } else if (flags & (CREATE|CONFIG|GRAVITY)) {
+ number = eventPtr->xcreatewindow.x;
+ } else if (flags & REPARENT) {
+ number = eventPtr->xreparent.x;
+ } else if (flags & CREATE) {
+ number = eventPtr->xcreatewindow.x;
+ } else if (flags & CONFIGREQ) {
+ number = eventPtr->xconfigurerequest.x;
+ } else {
goto doString;
- case 'R':
- if (flags & KEY_BUTTON_MOTION_CROSSING) {
- TkpPrintWindowId(numStorage, eventPtr->xkey.root);
- string = numStorage;
- }
+ }
+ goto doNumber;
+ case 'y':
+ if (flags & KEY_BUTTON_MOTION_VIRTUAL) {
+ number = eventPtr->xkey.y;
+ } else if (flags & EXPOSE) {
+ number = eventPtr->xexpose.y;
+ } else if (flags & (CREATE|CONFIG|GRAVITY)) {
+ number = eventPtr->xcreatewindow.y;
+ } else if (flags & REPARENT) {
+ number = eventPtr->xreparent.y;
+ } else if (flags & CROSSING) {
+ number = eventPtr->xcrossing.y;
+ } else if (flags & CREATE) {
+ number = eventPtr->xcreatewindow.y;
+ } else if (flags & CONFIGREQ) {
+ number = eventPtr->xconfigurerequest.y;
+ } else {
goto doString;
- case 'S':
- if (flags & KEY_BUTTON_MOTION_CROSSING) {
- TkpPrintWindowId(numStorage, eventPtr->xkey.subwindow);
- string = numStorage;
- }
+ }
+ goto doNumber;
+ case 'A':
+ if ((flags & KEY) && (eventPtr->type != MouseWheelEvent)) {
+ Tcl_DStringFree(&buf);
+ string = TkpGetString(winPtr, eventPtr, &buf);
+ }
+ goto doString;
+ case 'B':
+ if (flags & CREATE) {
+ number = eventPtr->xcreatewindow.border_width;
+ } else if (flags & CONFIGREQ) {
+ number = eventPtr->xconfigurerequest.border_width;
+ } else if (flags & CONFIG) {
+ number = eventPtr->xconfigure.border_width;
+ } else {
goto doString;
- case 'T':
- number = eventPtr->type;
- goto doNumber;
- case 'W': {
- Tk_Window tkwin;
+ }
+ goto doNumber;
+ case 'D':
+ /*
+ * This is used only by the MouseWheel event.
+ */
- tkwin = Tk_IdToWindow(eventPtr->xany.display,
- eventPtr->xany.window);
- if (tkwin != NULL) {
- string = Tk_PathName(tkwin);
- } else {
- string = "??";
- }
- goto doString;
+ if ((flags & KEY) && (eventPtr->type == MouseWheelEvent)) {
+ number = eventPtr->xkey.keycode;
+ goto doNumber;
}
- case 'X':
- if (flags & KEY_BUTTON_MOTION_CROSSING) {
- number = eventPtr->xkey.x_root;
- goto doNumber;
- }
- goto doString;
- case 'Y':
- if (flags & KEY_BUTTON_MOTION_CROSSING) {
- number = eventPtr->xkey.y_root;
- goto doNumber;
+ goto doString;
+ case 'E':
+ number = (int) eventPtr->xany.send_event;
+ goto doNumber;
+ case 'K':
+ if ((flags & KEY) && (eventPtr->type != MouseWheelEvent)) {
+ char *name = TkKeysymToString(keySym);
+
+ if (name != NULL) {
+ string = name;
}
- goto doString;
- default:
- numStorage[0] = before[1];
- numStorage[1] = '\0';
+ }
+ goto doString;
+ case 'N':
+ if ((flags & KEY) && (eventPtr->type != MouseWheelEvent)) {
+ number = (int) keySym;
+ goto doNumber;
+ }
+ goto doString;
+ case 'P':
+ if (flags & PROP) {
+ string = Tk_GetAtomName((Tk_Window) winPtr,
+ eventPtr->xproperty.atom);
+ }
+ goto doString;
+ case 'R':
+ if (flags & KEY_BUTTON_MOTION_CROSSING) {
+ TkpPrintWindowId(numStorage, eventPtr->xkey.root);
string = numStorage;
- goto doString;
+ }
+ goto doString;
+ case 'S':
+ if (flags & KEY_BUTTON_MOTION_CROSSING) {
+ TkpPrintWindowId(numStorage, eventPtr->xkey.subwindow);
+ string = numStorage;
+ }
+ goto doString;
+ case 'T':
+ number = eventPtr->type;
+ goto doNumber;
+ case 'W': {
+ Tk_Window tkwin;
+
+ tkwin = Tk_IdToWindow(eventPtr->xany.display,
+ eventPtr->xany.window);
+ if (tkwin != NULL) {
+ string = Tk_PathName(tkwin);
+ } else {
+ string = "??";
+ }
+ goto doString;
+ }
+ case 'X':
+ if (flags & KEY_BUTTON_MOTION_CROSSING) {
+ number = eventPtr->xkey.x_root;
+ goto doNumber;
+ }
+ goto doString;
+ case 'Y':
+ if (flags & KEY_BUTTON_MOTION_CROSSING) {
+ number = eventPtr->xkey.y_root;
+ goto doNumber;
+ }
+ goto doString;
+ default:
+ numStorage[0] = before[1];
+ numStorage[1] = '\0';
+ string = numStorage;
+ goto doString;
}
- doNumber:
+ doNumber:
sprintf(numStorage, "%d", number);
string = numStorage;
- doString:
+ doString:
spaceNeeded = Tcl_ScanElement(string, &cvtFlags);
length = Tcl_DStringLength(dsPtr);
Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
@@ -2664,28 +2620,27 @@ ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr)
*
* ChangeScreen --
*
- * This procedure is invoked whenever the current screen changes
- * in an application. It invokes a Tcl procedure named
- * "tk::ScreenChanged", passing it the screen name as argument.
- * tk::ScreenChanged does things like making the tk::Priv variable
- * point to an array for the current display.
+ * This function is invoked whenever the current screen changes in an
+ * application. It invokes a Tcl command named "tk::ScreenChanged",
+ * passing it the screen name as argument. tk::ScreenChanged does things
+ * like making the tk::Priv variable point to an array for the current
+ * display.
*
* Results:
* None.
*
* Side effects:
- * Depends on what tk::ScreenChanged does. If an error occurs
- * them bgerror will be invoked.
+ * Depends on what tk::ScreenChanged does. If an error occurs then
+ * bgerror will be invoked.
*
*----------------------------------------------------------------------
*/
static void
-ChangeScreen(interp, dispName, screenIndex)
- Tcl_Interp *interp; /* Interpreter in which to invoke
- * command. */
- char *dispName; /* Name of new display. */
- int screenIndex; /* Index of new screen. */
+ChangeScreen(
+ Tcl_Interp *interp, /* Interpreter in which to invoke command. */
+ char *dispName, /* Name of new display. */
+ int screenIndex) /* Index of new screen. */
{
Tcl_DString cmd;
int code;
@@ -2698,21 +2653,21 @@ ChangeScreen(interp, dispName, screenIndex)
Tcl_DStringAppend(&cmd, screen, -1);
code = Tcl_EvalEx(interp, Tcl_DStringValue(&cmd), Tcl_DStringLength(&cmd),
TCL_EVAL_GLOBAL);
+ Tcl_DStringFree(&cmd);
if (code != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (changing screen in event binding)");
Tcl_BackgroundError(interp);
}
}
-
/*
*----------------------------------------------------------------------
*
* Tk_EventCmd --
*
- * This procedure is invoked to process the "event" Tcl command.
- * It is used to define and generate events.
+ * This function is invoked to process the "event" Tcl command. It is
+ * used to define and generate events.
*
* Results:
* A standard Tcl result.
@@ -2724,17 +2679,17 @@ ChangeScreen(interp, dispName, screenIndex)
*/
int
-Tk_EventObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_EventObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
int index;
Tk_Window tkwin;
VirtualEventTable *vetPtr;
TkBindInfo bindInfo;
- static CONST char *optionStrings[] = {
+ static const char *optionStrings[] = {
"add", "delete", "generate", "info",
NULL
};
@@ -2756,64 +2711,61 @@ Tk_EventObjCmd(clientData, interp, objc, objv)
}
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;
+ case EVENT_ADD: {
+ int i;
+ char *name, *event;
+
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "virtual sequence ?sequence ...?");
+ return TCL_ERROR;
}
- case EVENT_DELETE: {
- int i;
- char *name, *event;
-
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "virtual ?sequence sequence ...?");
+ name = Tcl_GetString(objv[2]);
+ for (i = 3; i < objc; i++) {
+ event = Tcl_GetString(objv[i]);
+ if (CreateVirtualEvent(interp, vetPtr, name, event) != TCL_OK) {
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;
}
- 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);
+ break;
+ }
+ case EVENT_DELETE: {
+ int i;
+ char *name, *event;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "virtual ?sequence sequence ...?");
+ 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?");
+ name = Tcl_GetString(objv[2]);
+ if (objc == 3) {
+ return DeleteVirtualEvent(interp, vetPtr, name, NULL);
+ }
+ for (i = 3; i < objc; i++) {
+ event = Tcl_GetString(objv[i]);
+ if (DeleteVirtualEvent(interp, vetPtr, name, event) != TCL_OK) {
return TCL_ERROR;
}
}
+ break;
+ }
+ 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);
+ case EVENT_INFO:
+ if (objc == 2) {
+ GetAllVirtualEvents(interp, vetPtr);
+ return TCL_OK;
+ } else if (objc == 3) {
+ return GetVirtualEvent(interp, vetPtr, Tcl_GetString(objv[2]));
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, "?virtual?");
+ return TCL_ERROR;
+ }
}
return TCL_OK;
}
@@ -2823,8 +2775,8 @@ Tk_EventObjCmd(clientData, interp, objc, objv)
*
* InitVirtualEventTable --
*
- * Given storage for a virtual event table, set up the fields to
- * prepare a new domain in which virtual events may be defined.
+ * Given storage for a virtual event table, set up the fields to prepare
+ * a new domain in which virtual events may be defined.
*
* Results:
* None.
@@ -2836,9 +2788,9 @@ Tk_EventObjCmd(clientData, interp, objc, objv)
*/
static void
-InitVirtualEventTable(vetPtr)
- VirtualEventTable *vetPtr; /* Pointer to virtual event table. Memory
- * is supplied by the caller. */
+InitVirtualEventTable(
+ VirtualEventTable *vetPtr) /* Pointer to virtual event table. Memory is
+ * supplied by the caller. */
{
Tcl_InitHashTable(&vetPtr->patternTable,
sizeof(PatternTableKey) / sizeof(int));
@@ -2850,7 +2802,7 @@ InitVirtualEventTable(vetPtr)
*
* DeleteVirtualEventTable --
*
- * Delete the contents of a virtual event table. The caller is
+ * Delete the contents of a virtual event table. The caller is
* responsible for freeing any memory used by the table itself.
*
* Results:
@@ -2863,8 +2815,8 @@ InitVirtualEventTable(vetPtr)
*/
static void
-DeleteVirtualEventTable(vetPtr)
- VirtualEventTable *vetPtr; /* The virtual event table to delete. */
+DeleteVirtualEventTable(
+ VirtualEventTable *vetPtr) /* The virtual event table to delete. */
{
Tcl_HashEntry *hPtr;
Tcl_HashSearch search;
@@ -2883,7 +2835,7 @@ DeleteVirtualEventTable(vetPtr)
hPtr = Tcl_FirstHashEntry(&vetPtr->nameTable, &search);
for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- ckfree((char *) Tcl_GetHashValue(hPtr));
+ ckfree((char *) Tcl_GetHashValue(hPtr));
}
Tcl_DeleteHashTable(&vetPtr->nameTable);
}
@@ -2893,29 +2845,27 @@ DeleteVirtualEventTable(vetPtr)
*
* CreateVirtualEvent --
*
- * Add a new definition for a virtual event. If the virtual event
- * is already defined, the new definition augments those that
- * already exist.
+ * Add a new definition for a virtual event. If the virtual event is
+ * already defined, the new definition augments those that already exist.
*
* 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 the interp's result. If all went well then the
- * return value is TCL_OK.
+ * 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 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
- * behave differently than they did previously.
+ * The virtual event may cause future calls to Tk_BindEvent to behave
+ * differently than they did previously.
*
*----------------------------------------------------------------------
*/
static int
-CreateVirtualEvent(interp, vetPtr, virtString, eventString)
- Tcl_Interp *interp; /* Used for error reporting. */
- VirtualEventTable *vetPtr;/* Table in which to augment virtual event. */
- char *virtString; /* Name of new virtual event. */
- char *eventString; /* String describing physical event that
+CreateVirtualEvent(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ VirtualEventTable *vetPtr, /* Table in which to augment virtual event. */
+ char *virtString, /* Name of new virtual event. */
+ char *eventString) /* String describing physical event that
* triggers virtual event. */
{
PatSeq *psPtr;
@@ -2925,10 +2875,10 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString)
PhysicalsOwned *poPtr;
VirtualOwners *voPtr;
Tk_Uid virtUid;
-
+
virtUid = GetVirtualEventUid(interp, virtString);
if (virtUid == NULL) {
- return TCL_ERROR;
+ return TCL_ERROR;
}
/*
@@ -2938,7 +2888,7 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString)
psPtr = FindSequence(interp, &vetPtr->patternTable, NULL, eventString,
1, 0, &eventMask);
if (psPtr == NULL) {
- return TCL_ERROR;
+ return TCL_ERROR;
}
/*
@@ -2956,20 +2906,21 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString)
poPtr = (PhysicalsOwned *) ckalloc(sizeof(PhysicalsOwned));
poPtr->numOwned = 0;
} else {
- /*
+ /*
* See if this virtual event is already defined for this physical
* event and just return if it is.
*/
int i;
+
for (i = 0; i < poPtr->numOwned; i++) {
if (poPtr->patSeqs[i] == psPtr) {
- return TCL_OK;
+ return TCL_OK;
}
}
poPtr = (PhysicalsOwned *) ckrealloc((char *) poPtr,
sizeof(PhysicalsOwned) + poPtr->numOwned * sizeof(PatSeq *));
- }
+ }
Tcl_SetHashValue(vhPtr, (ClientData) poPtr);
poPtr->patSeqs[poPtr->numOwned] = psPtr;
poPtr->numOwned++;
@@ -2980,10 +2931,10 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString)
voPtr = psPtr->voPtr;
if (voPtr == NULL) {
- voPtr = (VirtualOwners *) ckalloc(sizeof(VirtualOwners));
+ voPtr = (VirtualOwners *) ckalloc(sizeof(VirtualOwners));
voPtr->numOwners = 0;
} else {
- voPtr = (VirtualOwners *) ckrealloc((char *) voPtr,
+ voPtr = (VirtualOwners *) ckrealloc((char *) voPtr,
sizeof(VirtualOwners)
+ voPtr->numOwners * sizeof(Tcl_HashEntry *));
}
@@ -2999,31 +2950,31 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString)
*
* DeleteVirtualEvent --
*
- * Remove the definition of a given virtual event. If the
- * event string is NULL, all definitions of the virtual event
- * will be removed. Otherwise, just the specified definition
- * of the virtual event will be removed.
+ * Remove the definition of a given virtual event. If the event string is
+ * NULL, all definitions of the virtual event will be removed.
+ * Otherwise, just the specified definition of the virtual event will be
+ * removed.
*
* Results:
- * The result is a standard Tcl return value. If an error
- * 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.
+ * The result is a standard Tcl return value. If an error 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.
*
* Side effects:
- * The virtual event given by virtString may be removed from the
- * virtual event table.
+ * The virtual event given by virtString may be removed from the virtual
+ * event table.
*
*--------------------------------------------------------------
*/
static int
-DeleteVirtualEvent(interp, vetPtr, virtString, eventString)
- Tcl_Interp *interp; /* Used for error reporting. */
- VirtualEventTable *vetPtr;/* Table in which to delete event. */
- char *virtString; /* String describing event sequence that
+DeleteVirtualEvent(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ VirtualEventTable *vetPtr, /* Table in which to delete event. */
+ char *virtString, /* String describing event sequence that
* triggers binding. */
- char *eventString; /* The event sequence that should be deleted,
+ char *eventString) /* The event sequence that should be deleted,
* or NULL to delete all event sequences for
* the entire virtual event. */
{
@@ -3035,12 +2986,12 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString)
virtUid = GetVirtualEventUid(interp, virtString);
if (virtUid == NULL) {
- return TCL_ERROR;
+ return TCL_ERROR;
}
-
+
vhPtr = Tcl_FindHashEntry(&vetPtr->nameTable, virtUid);
if (vhPtr == NULL) {
- return TCL_OK;
+ return TCL_OK;
}
poPtr = (PhysicalsOwned *) Tcl_GetHashValue(vhPtr);
@@ -3049,28 +3000,27 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString)
unsigned long eventMask;
/*
- * Delete only the specific physical event associated with the
- * virtual event. If the physical event doesn't already exist, or
- * the virtual event doesn't own that physical event, return w/o
- * doing anything.
+ * Delete only the specific physical event associated with the virtual
+ * event. If the physical event doesn't already exist, or the virtual
+ * event doesn't own that physical event, return w/o doing anything.
*/
eventPSPtr = FindSequence(interp, &vetPtr->patternTable, NULL,
eventString, 0, 0, &eventMask);
if (eventPSPtr == NULL) {
- CONST char *string;
+ const char *string = Tcl_GetStringResult(interp);
- string = Tcl_GetStringResult(interp);
return (string[0] != '\0') ? TCL_ERROR : TCL_OK;
}
}
for (iPhys = poPtr->numOwned; --iPhys >= 0; ) {
PatSeq *psPtr = poPtr->patSeqs[iPhys];
+
if ((eventPSPtr == NULL) || (psPtr == eventPSPtr)) {
int iVirt;
VirtualOwners *voPtr;
-
+
/*
* Remove association between this physical event and the given
* virtual event that it triggers.
@@ -3083,15 +3033,17 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString)
}
}
if (iVirt == voPtr->numOwners) {
- panic("DeleteVirtualEvent: couldn't find owner");
+ Tcl_Panic("DeleteVirtualEvent: couldn't find owner");
}
voPtr->numOwners--;
if (voPtr->numOwners == 0) {
/*
- * Removed last reference to this physical event, so
- * remove it from physical->virtual map.
+ * Removed last reference to this physical event, so remove it
+ * from physical->virtual map.
*/
+
PatSeq *prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr);
+
if (prevPtr == psPtr) {
if (psPtr->nextSeqPtr == NULL) {
Tcl_DeleteHashEntry(psPtr->hPtr);
@@ -3102,7 +3054,7 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString)
} else {
for ( ; ; prevPtr = prevPtr->nextSeqPtr) {
if (prevPtr == NULL) {
- panic("DeleteVirtualEvent couldn't find on hash chain");
+ Tcl_Panic("DeleteVirtualEvent couldn't find on hash chain");
}
if (prevPtr->nextSeqPtr == psPtr) {
prevPtr->nextSeqPtr = psPtr->nextSeqPtr;
@@ -3115,23 +3067,23 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString)
} else {
/*
* This physical event still triggers some other virtual
- * event(s). Consolidate the list of virtual owners for
- * this physical event so it no longer triggers the
- * given virtual event.
+ * event(s). Consolidate the list of virtual owners for this
+ * physical event so it no longer triggers the given virtual
+ * event.
*/
+
voPtr->owners[iVirt] = voPtr->owners[voPtr->numOwners];
}
/*
- * Now delete the virtual event's reference to the physical
- * event.
+ * Now delete the virtual event's reference to the physical event.
*/
poPtr->numOwned--;
if (eventPSPtr != NULL && poPtr->numOwned != 0) {
- /*
- * Just deleting this one physical event. Consolidate list
- * of owned physical events and return.
+ /*
+ * Just deleting this one physical event. Consolidate list of
+ * owned physical events and return.
*/
poPtr->patSeqs[iPhys] = poPtr->patSeqs[poPtr->numOwned];
@@ -3142,10 +3094,10 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString)
if (poPtr->numOwned == 0) {
/*
- * All the physical events for this virtual event were deleted,
- * either because there was only one associated physical event or
- * because the caller was deleting the entire virtual event. Now
- * the virtual event itself should be deleted.
+ * All the physical events for this virtual event were deleted, either
+ * because there was only one associated physical event or because the
+ * caller was deleting the entire virtual event. Now the virtual event
+ * itself should be deleted.
*/
ckfree((char *) poPtr);
@@ -3159,16 +3111,16 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString)
*
* GetVirtualEvent --
*
- * Return the list of physical events that can invoke the
- * given virtual event.
+ * Return the list of physical events that can invoke the given virtual
+ * event.
*
* Results:
* 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, 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 the interp's result.
+ * 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 the interp's result.
*
* Side effects:
* None.
@@ -3177,10 +3129,10 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString)
*/
static int
-GetVirtualEvent(interp, vetPtr, virtString)
- Tcl_Interp *interp; /* Interpreter for reporting. */
- VirtualEventTable *vetPtr;/* Table in which to look for event. */
- char *virtString; /* String describing virtual event. */
+GetVirtualEvent(
+ Tcl_Interp *interp, /* Interpreter for reporting. */
+ VirtualEventTable *vetPtr, /* Table in which to look for event. */
+ char *virtString) /* String describing virtual event. */
{
Tcl_HashEntry *vhPtr;
Tcl_DString ds;
@@ -3190,12 +3142,12 @@ GetVirtualEvent(interp, vetPtr, virtString)
virtUid = GetVirtualEventUid(interp, virtString);
if (virtUid == NULL) {
- return TCL_ERROR;
+ return TCL_ERROR;
}
vhPtr = Tcl_FindHashEntry(&vetPtr->nameTable, virtUid);
if (vhPtr == NULL) {
- return TCL_OK;
+ return TCL_OK;
}
Tcl_DStringInit(&ds);
@@ -3216,13 +3168,12 @@ GetVirtualEvent(interp, vetPtr, virtString)
*
* GetAllVirtualEvents --
*
- * Return a list that contains the names of all the virtual
- * event defined.
+ * Return a list that contains the names of all the virtual event
+ * defined.
*
* Results:
- * 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.
+ * 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.
*
* Side effects:
* None.
@@ -3231,9 +3182,9 @@ GetVirtualEvent(interp, vetPtr, virtString)
*/
static void
-GetAllVirtualEvents(interp, vetPtr)
- Tcl_Interp *interp; /* Interpreter returning result. */
- VirtualEventTable *vetPtr;/* Table containing events. */
+GetAllVirtualEvents(
+ Tcl_Interp *interp, /* Interpreter returning result. */
+ VirtualEventTable *vetPtr) /* Table containing events. */
{
Tcl_HashEntry *hPtr;
Tcl_HashSearch search;
@@ -3243,11 +3194,11 @@ GetAllVirtualEvents(interp, vetPtr)
hPtr = Tcl_FirstHashEntry(&vetPtr->nameTable, &search);
for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- Tcl_DStringSetLength(&ds, 0);
+ Tcl_DStringSetLength(&ds, 0);
Tcl_DStringAppend(&ds, "<<", 2);
Tcl_DStringAppend(&ds, Tcl_GetHashKey(hPtr->tablePtr, hPtr), -1);
Tcl_DStringAppend(&ds, ">>", 2);
- Tcl_AppendElement(interp, Tcl_DStringValue(&ds));
+ Tcl_AppendElement(interp, Tcl_DStringValue(&ds));
}
Tcl_DStringFree(&ds);
@@ -3258,45 +3209,45 @@ GetAllVirtualEvents(interp, vetPtr)
*
* HandleEventGenerate --
*
- * Helper function for the "event generate" command. Generate and
- * process an XEvent, constructed from information parsed from the
- * event description string and its optional arguments.
+ * Helper function for the "event generate" command. Generate and process
+ * an XEvent, constructed from information parsed from the event
+ * description string and its optional arguments.
*
* argv[0] contains name of the target window.
* argv[1] contains pattern string for one event (e.g, <Control-v>).
- * argv[2..argc-1] contains -field/option pairs for specifying
- * additional detail in the generated event.
+ * argv[2..argc-1] contains -field/option pairs for specifying additional
+ * detail in the generated event.
*
- * Either virtual or physical events can be generated this way.
- * The event description string must contain the specification
- * for only one event.
+ * Either virtual or physical events can be generated this way. The event
+ * description string must contain the specification for only one event.
*
* Results:
* None.
*
* Side effects:
- * When constructing the event,
- * event.xany.serial is filled with the current X serial number.
- * event.xany.window is filled with the target window.
- * event.xany.display is filled with the target window's display.
+ * When constructing the event,
+ * event.xany.serial is filled with the current X serial number.
+ * event.xany.window is filled with the target window.
+ * event.xany.display is filled with the target window's display.
* Any other fields in eventPtr which are not specified by the pattern
* string or the optional arguments, are set to 0.
*
- * The event may be handled sychronously or asynchronously, depending
- * on the value specified by the optional "-when" option. The
- * default setting is synchronous.
+ * The event may be handled sychronously or asynchronously, depending on
+ * the value specified by the optional "-when" option. The default
+ * setting is synchronous.
*
*---------------------------------------------------------------------------
*/
+
static int
-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. */
+HandleEventGenerate(
+ 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;
- CONST char *p;
+ union {XEvent general; XVirtualEvent virtual;} event;
+ const char *p;
char *name, *windowName;
int count, flags, synch, i, number, warp;
Tcl_QueuePosition pos;
@@ -3304,10 +3255,11 @@ HandleEventGenerate(interp, mainWin, objc, objv)
Tk_Window tkwin, tkwin2;
TkWindow *mainPtr;
unsigned long eventMask;
- static CONST char *fieldStrings[] = {
+ Tcl_Obj *userDataObj;
+ static const char *fieldStrings[] = {
"-when", "-above", "-borderwidth", "-button",
- "-count", "-delta", "-detail", "-focus",
- "-height",
+ "-count", "-data", "-delta", "-detail",
+ "-focus", "-height",
"-keycode", "-keysym", "-mode", "-override",
"-place", "-root", "-rootx", "-rooty",
"-sendevent", "-serial", "-state", "-subwindow",
@@ -3316,8 +3268,8 @@ HandleEventGenerate(interp, mainWin, objc, objv)
};
enum field {
EVENT_WHEN, EVENT_ABOVE, EVENT_BORDER, EVENT_BUTTON,
- EVENT_COUNT, EVENT_DELTA, EVENT_DETAIL, EVENT_FOCUS,
- EVENT_HEIGHT,
+ EVENT_COUNT, EVENT_DATA, 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,
@@ -3325,7 +3277,7 @@ HandleEventGenerate(interp, mainWin, objc, objv)
EVENT_X, EVENT_Y
};
- windowName = Tcl_GetStringFromObj(objv[0], NULL);
+ windowName = Tcl_GetString(objv[0]);
if (!windowName[0]) {
tkwin = mainWin;
} else if (NameToWindow(interp, mainWin, objv[0], &tkwin) != TCL_OK) {
@@ -3335,18 +3287,16 @@ HandleEventGenerate(interp, mainWin, objc, objv)
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);
+ Tcl_AppendResult(interp, "window id \"", Tcl_GetString(objv[0]),
+ "\" doesn't exist in this application", NULL);
return TCL_ERROR;
}
- name = Tcl_GetStringFromObj(objv[1], NULL);
+ name = Tcl_GetString(objv[1]);
p = name;
eventMask = 0;
+ userDataObj = NULL;
count = ParseEventDescription(interp, &p, &pat, &eventMask);
if (count == 0) {
return TCL_ERROR;
@@ -3362,48 +3312,49 @@ HandleEventGenerate(interp, mainWin, objc, objv)
return TCL_ERROR;
}
- memset((VOID *) &event, 0, sizeof(event));
- event.xany.type = pat.eventType;
- event.xany.serial = NextRequest(Tk_Display(tkwin));
- event.xany.send_event = False;
+ memset((void *) &event, 0, sizeof(event));
+ event.general.xany.type = pat.eventType;
+ event.general.xany.serial = NextRequest(Tk_Display(tkwin));
+ event.general.xany.send_event = False;
if (windowName[0]) {
- event.xany.window = Tk_WindowId(tkwin);
+ event.general.xany.window = Tk_WindowId(tkwin);
} else {
- event.xany.window = RootWindow(Tk_Display(tkwin), Tk_ScreenNumber(tkwin));
+ event.general.xany.window =
+ RootWindow(Tk_Display(tkwin), Tk_ScreenNumber(tkwin));
}
- event.xany.display = Tk_Display(tkwin);
+ event.general.xany.display = Tk_Display(tkwin);
- flags = flagArray[event.xany.type];
+ flags = flagArray[event.general.xany.type];
if (flags & DESTROY) {
/*
- * Event DesotryNotify should be generated by destroying
- * the window.
+ * Event DestroyNotify should be generated by destroying the window.
*/
+
Tk_DestroyWindow(tkwin);
return TCL_OK;
}
- if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) {
- event.xkey.state = pat.needMods;
- if ((flags & KEY) && (event.xany.type != MouseWheelEvent)) {
- TkpSetKeycodeAndState(tkwin, pat.detail.keySym, &event);
+ if (flags & KEY_BUTTON_MOTION_VIRTUAL) {
+ event.general.xkey.state = pat.needMods;
+ if ((flags & KEY) && (event.general.xany.type != MouseWheelEvent)) {
+ TkpSetKeycodeAndState(tkwin, pat.detail.keySym, &event.general);
} else if (flags & BUTTON) {
- event.xbutton.button = pat.detail.button;
+ event.general.xbutton.button = pat.detail.button;
} else if (flags & VIRTUAL) {
- ((XVirtualEvent *) &event)->name = pat.detail.name;
+ event.virtual.name = pat.detail.name;
}
}
if (flags & (CREATE|UNMAP|MAP|REPARENT|CONFIG|GRAVITY|CIRC)) {
- event.xcreatewindow.window = event.xany.window;
+ event.general.xcreatewindow.window = event.general.xany.window;
}
- if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) {
- event.xkey.x_root = -1;
- event.xkey.y_root = -1;
+ if (flags & KEY_BUTTON_MOTION_CROSSING) {
+ event.general.xkey.x_root = -1;
+ event.general.xkey.y_root = -1;
}
/*
- * Process the remaining arguments to fill in additional fields
- * of the event.
+ * Process the remaining arguments to fill in additional fields of the
+ * event.
*/
synch = 1;
@@ -3412,7 +3363,7 @@ HandleEventGenerate(interp, mainWin, objc, objv)
for (i = 2; i < objc; i += 2) {
Tcl_Obj *optionPtr, *valuePtr;
int index;
-
+
optionPtr = objv[i];
valuePtr = objv[i + 1];
@@ -3422,446 +3373,451 @@ HandleEventGenerate(interp, mainWin, objc, objv)
}
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.
+ * 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);
+ Tcl_AppendResult(interp, "value for \"", Tcl_GetString(optionPtr),
+ "\" missing", NULL);
return TCL_ERROR;
}
switch ((enum field) index) {
- case EVENT_WARP: {
- if (Tcl_GetBooleanFromObj(interp, valuePtr, &warp) != TCL_OK) {
- return TCL_ERROR;
- }
- if (!(flags & (KEY_BUTTON_MOTION_VIRTUAL))) {
- goto badopt;
- }
- break;
+ case EVENT_WARP:
+ if (Tcl_GetBooleanFromObj(interp, valuePtr, &warp) != TCL_OK) {
+ return TCL_ERROR;
}
- case EVENT_WHEN: {
- pos = (Tcl_QueuePosition) TkFindStateNumObj(interp, optionPtr,
- queuePosition, valuePtr);
- if ((int) pos < -1) {
- return TCL_ERROR;
- }
- synch = 0;
- if ((int) pos == -1) {
- synch = 1;
- }
- break;
+ if (!(flags & KEY_BUTTON_MOTION_VIRTUAL)) {
+ goto badopt;
}
- case EVENT_ABOVE: {
- if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) {
- return TCL_ERROR;
- }
- if (flags & CONFIG) {
- event.xconfigure.above = Tk_WindowId(tkwin2);
- } else {
- goto badopt;
- }
- break;
+ break;
+ case EVENT_WHEN:
+ pos = (Tcl_QueuePosition) TkFindStateNumObj(interp, optionPtr,
+ queuePosition, valuePtr);
+ if ((int) pos < -1) {
+ 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;
+ synch = 0;
+ if ((int) pos == -1) {
+ synch = 1;
}
- 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;
+ break;
+ case EVENT_ABOVE:
+ if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != 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 & CONFIG) {
+ event.general.xconfigure.above = Tk_WindowId(tkwin2);
+ } 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;
+ break;
+ case EVENT_BORDER:
+ if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&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 & (CREATE|CONFIG)) {
+ event.general.xcreatewindow.border_width = 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;
+ break;
+ case EVENT_BUTTON:
+ if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
+ 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 & BUTTON) {
+ event.general.xbutton.button = 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;
+ break;
+ case EVENT_COUNT:
+ if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
+ return TCL_ERROR;
}
- case EVENT_KEYSYM: {
- KeySym keysym;
- char *value;
+ if (flags & EXPOSE) {
+ event.general.xexpose.count = number;
+ } else {
+ goto badopt;
+ }
+ break;
+ case EVENT_DATA:
+ if (flags & VIRTUAL) {
+ /*
+ * Do not increment reference count until after parsing
+ * completes and we know that the event generation is really
+ * going to happen.
+ */
- value = Tcl_GetStringFromObj(valuePtr, NULL);
- keysym = TkStringToKeysym(value);
- if (keysym == NoSymbol) {
- Tcl_AppendResult(interp, "unknown keysym \"", value, "\"",
- (char *) NULL);
- return TCL_ERROR;
- }
+ userDataObj = valuePtr;
+ } else {
+ goto badopt;
+ }
+ break;
+ case EVENT_DELTA:
+ if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if ((flags & KEY) && (event.general.xkey.type == MouseWheelEvent)) {
+ event.general.xkey.keycode = number;
+ } else {
+ goto badopt;
+ }
+ break;
+ case EVENT_DETAIL:
+ number = TkFindStateNumObj(interp, optionPtr, notifyDetail,
+ valuePtr);
+ if (number < 0) {
+ return TCL_ERROR;
+ }
+ if (flags & FOCUS) {
+ event.general.xfocus.detail = number;
+ } else if (flags & CROSSING) {
+ event.general.xcrossing.detail = number;
+ } else {
+ goto badopt;
+ }
+ break;
+ case EVENT_FOCUS:
+ if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (flags & CROSSING) {
+ event.general.xcrossing.focus = number;
+ } else {
+ goto badopt;
+ }
+ break;
+ case EVENT_HEIGHT:
+ if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr,
+ &number) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (flags & EXPOSE) {
+ event.general.xexpose.height = number;
+ } else if (flags & CONFIG) {
+ event.general.xconfigure.height = number;
+ } else {
+ goto badopt;
+ }
+ break;
+ case EVENT_KEYCODE:
+ if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if ((flags & KEY) && (event.general.xkey.type != MouseWheelEvent)) {
+ event.general.xkey.keycode = number;
+ } else {
+ goto badopt;
+ }
+ break;
+ case EVENT_KEYSYM: {
+ KeySym keysym;
+ char *value;
+
+ value = Tcl_GetString(valuePtr);
+ keysym = TkStringToKeysym(value);
+ if (keysym == NoSymbol) {
+ Tcl_AppendResult(interp, "unknown keysym \"", value, "\"",
+ NULL);
+ return TCL_ERROR;
+ }
- TkpSetKeycodeAndState(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;
+ TkpSetKeycodeAndState(tkwin, keysym, &event.general);
+ if (event.general.xkey.keycode == 0) {
+ Tcl_AppendResult(interp, "no keycode for keysym \"", value,
+ "\"", NULL);
+ return TCL_ERROR;
}
- 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;
+ if (!(flags & KEY)
+ || (event.general.xkey.type == MouseWheelEvent)) {
+ goto badopt;
}
- 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;
+ break;
+ }
+ case EVENT_MODE:
+ number = TkFindStateNumObj(interp,optionPtr,notifyMode,valuePtr);
+ if (number < 0) {
+ return TCL_ERROR;
}
- 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;
+ if (flags & CROSSING) {
+ event.general.xcrossing.mode = number;
+ } else if (flags & FOCUS) {
+ event.general.xfocus.mode = number;
+ } else {
+ goto badopt;
}
- 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;
+ break;
+ case EVENT_OVERRIDE:
+ if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) {
+ return TCL_ERROR;
}
- 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;
+ if (flags & CREATE) {
+ event.general.xcreatewindow.override_redirect = number;
+ } else if (flags & MAP) {
+ event.general.xmap.override_redirect = number;
+ } else if (flags & REPARENT) {
+ event.general.xreparent.override_redirect = number;
+ } else if (flags & CONFIG) {
+ event.general.xconfigure.override_redirect = number;
+ } else {
+ goto badopt;
}
- 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;
+ break;
+ case EVENT_PLACE:
+ number = TkFindStateNumObj(interp, optionPtr, circPlace, valuePtr);
+ if (number < 0) {
+ return TCL_ERROR;
+ }
+ if (flags & CIRC) {
+ event.general.xcirculate.place = number;
+ } else {
+ goto badopt;
+ }
+ break;
+ case EVENT_ROOT:
+ if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (flags & KEY_BUTTON_MOTION_CROSSING) {
+ event.general.xkey.root = Tk_WindowId(tkwin2);
+ } else {
+ goto badopt;
}
- case EVENT_SEND: {
- CONST char *value;
+ break;
+ case EVENT_ROOTX:
+ if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (flags & KEY_BUTTON_MOTION_CROSSING) {
+ event.general.xkey.x_root = number;
+ } else {
+ goto badopt;
+ }
+ break;
+ case EVENT_ROOTY:
+ if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (flags & KEY_BUTTON_MOTION_CROSSING) {
+ event.general.xkey.y_root = number;
+ } else {
+ goto badopt;
+ }
+ break;
+ case EVENT_SEND: {
+ const char *value;
- 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.
- */
+ value = Tcl_GetString(valuePtr);
+ 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;
- }
- } else {
- if (Tcl_GetBooleanFromObj(interp, valuePtr, &number)
- != TCL_OK) {
- return TCL_ERROR;
- }
- }
- event.xany.send_event = number;
- break;
- }
- case EVENT_SERIAL: {
if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
return TCL_ERROR;
}
- event.xany.serial = number;
- break;
- }
- 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;
- }
- case EVENT_SUBWINDOW: {
- if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) {
+ } else {
+ if (Tcl_GetBooleanFromObj(interp,valuePtr,&number) != TCL_OK) {
return TCL_ERROR;
}
- if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) {
- event.xkey.subwindow = Tk_WindowId(tkwin2);
- } else {
- goto badopt;
- }
- break;
}
- case EVENT_TIME: {
+ event.general.xany.send_event = number;
+ break;
+ }
+ case EVENT_SERIAL:
+ if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ event.general.xany.serial = number;
+ break;
+ case EVENT_STATE:
+ if (flags & KEY_BUTTON_MOTION_CROSSING) {
if (Tcl_GetIntFromObj(interp, valuePtr, &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;
+ if (flags & KEY_BUTTON_MOTION_VIRTUAL) {
+ event.general.xkey.state = number;
} else {
- goto badopt;
+ event.general.xcrossing.state = number;
}
- break;
- }
- case EVENT_WIDTH: {
- if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number)
- != TCL_OK) {
+ } else if (flags & VISIBILITY) {
+ number = TkFindStateNumObj(interp, optionPtr, visNotify,
+ valuePtr);
+ if (number < 0) {
return TCL_ERROR;
}
- if (flags & EXPOSE) {
- event.xexpose.width = number;
- } else if (flags & (CREATE|CONFIG)) {
- event.xcreatewindow.width = number;
- } else {
- goto badopt;
- }
- break;
+ event.general.xvisibility.state = number;
+ } else {
+ goto badopt;
}
- case EVENT_WINDOW: {
- if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) {
- return TCL_ERROR;
- }
- if (flags & (CREATE|UNMAP|MAP|REPARENT|CONFIG
- |GRAVITY|CIRC)) {
- event.xcreatewindow.window = Tk_WindowId(tkwin2);
- } else {
- goto badopt;
- }
- break;
+ break;
+ case EVENT_SUBWINDOW:
+ if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) {
+ return TCL_ERROR;
}
- case EVENT_X: {
- if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number)
- != TCL_OK) {
- return TCL_ERROR;
- }
- if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) {
- event.xkey.x = number;
- /*
- * Only modify rootx as well if it hasn't been changed.
- */
- if (event.xkey.x_root == -1) {
- int rootX, rootY;
+ if (flags & KEY_BUTTON_MOTION_CROSSING) {
+ event.general.xkey.subwindow = Tk_WindowId(tkwin2);
+ } else {
+ goto badopt;
+ }
+ break;
+ case EVENT_TIME:
+ if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (flags & KEY_BUTTON_MOTION_CROSSING) {
+ event.general.xkey.time = (Time) number;
+ } else if (flags & PROP) {
+ event.general.xproperty.time = (Time) number;
+ } else {
+ goto badopt;
+ }
+ break;
+ case EVENT_WIDTH:
+ if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (flags & EXPOSE) {
+ event.general.xexpose.width = number;
+ } else if (flags & (CREATE|CONFIG)) {
+ event.general.xcreatewindow.width = number;
+ } else {
+ goto badopt;
+ }
+ break;
+ case EVENT_WINDOW:
+ if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (flags & (CREATE|UNMAP|MAP|REPARENT|CONFIG|GRAVITY|CIRC)) {
+ event.general.xcreatewindow.window = Tk_WindowId(tkwin2);
+ } else {
+ goto badopt;
+ }
+ break;
+ case EVENT_X:
+ if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) {
+ event.general.xkey.x = number;
- Tk_GetRootCoords(tkwin, &rootX, &rootY);
- event.xkey.x_root = rootX + number;
- }
- } 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;
+ /*
+ * Only modify rootx as well if it hasn't been changed.
+ */
+
+ if (event.general.xkey.x_root == -1) {
+ int rootX, rootY;
+
+ Tk_GetRootCoords(tkwin, &rootX, &rootY);
+ event.general.xkey.x_root = rootX + number;
}
- break;
+ } else if (flags & EXPOSE) {
+ event.general.xexpose.x = number;
+ } else if (flags & (CREATE|CONFIG|GRAVITY)) {
+ event.general.xcreatewindow.x = number;
+ } else if (flags & REPARENT) {
+ event.general.xreparent.x = number;
+ } else {
+ goto badopt;
}
- case EVENT_Y: {
- if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number)
- != TCL_OK) {
- return TCL_ERROR;
- }
- if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) {
- event.xkey.y = number;
- /*
- * Only modify rooty as well if it hasn't been changed.
- */
- if (event.xkey.y_root == -1) {
- int rootX, rootY;
+ break;
+ case EVENT_Y:
+ if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (flags & KEY_BUTTON_MOTION_CROSSING) {
+ event.general.xkey.y = number;
- Tk_GetRootCoords(tkwin, &rootX, &rootY);
- event.xkey.y_root = rootY + number;
- }
- } 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;
+ /*
+ * Only modify rooty as well if it hasn't been changed.
+ */
+
+ if (event.general.xkey.y_root == -1) {
+ int rootX, rootY;
+
+ Tk_GetRootCoords(tkwin, &rootX, &rootY);
+ event.general.xkey.y_root = rootY + number;
}
- break;
+ } else if (flags & EXPOSE) {
+ event.general.xexpose.y = number;
+ } else if (flags & (CREATE|CONFIG|GRAVITY)) {
+ event.general.xcreatewindow.y = number;
+ } else if (flags & REPARENT) {
+ event.general.xreparent.y = number;
+ } else {
+ goto badopt;
}
+ break;
}
continue;
-
- badopt:
+
+ badopt:
Tcl_AppendResult(interp, name, " event doesn't accept \"",
- Tcl_GetStringFromObj(optionPtr, NULL), "\" option", NULL);
+ Tcl_GetString(optionPtr), "\" option", NULL);
return TCL_ERROR;
}
+ if (userDataObj != NULL) {
+ XVirtualEvent *vePtr = (XVirtualEvent *) &event;
+
+ /*
+ * Must be virtual event to set that variable to non-NULL. Now we want
+ * to install the object into the event. Note that we must incr the
+ * refcount before firing it into the low-level event subsystem; the
+ * refcount will be decremented once the event has been processed.
+ */
+
+ vePtr->user_data = userDataObj;
+ Tcl_IncrRefCount(userDataObj);
+ }
+
+ /*
+ * Now we have constructed the event, inject it into the event handling
+ * code.
+ */
+
if (synch != 0) {
- Tk_HandleEvent(&event);
+ Tk_HandleEvent(&event.general);
} else {
- Tk_QueueWindowEvent(&event, pos);
+ Tk_QueueWindowEvent(&event.general, pos);
}
+
/*
- * We only allow warping if the window is mapped
+ * We only allow warping if the window is mapped.
*/
+
if ((warp != 0) && Tk_IsMapped(tkwin)) {
- TkDisplay *dispPtr;
- dispPtr = TkGetDisplay(event.xmotion.display);
+ TkDisplay *dispPtr = TkGetDisplay(event.general.xmotion.display);
+
if (!(dispPtr->flags & TK_DISPLAY_IN_WARP)) {
Tcl_DoWhenIdle(DoWarp, (ClientData) dispPtr);
dispPtr->flags |= TK_DISPLAY_IN_WARP;
}
- dispPtr->warpWindow = event.xany.window;
- dispPtr->warpX = event.xkey.x;
- dispPtr->warpY = event.xkey.y;
+ dispPtr->warpWindow = event.general.xany.window;
+ dispPtr->warpX = event.general.xkey.x;
+ dispPtr->warpY = event.general.xkey.y;
}
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. */
+NameToWindow(
+ 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;
Window id;
- name = Tcl_GetStringFromObj(objPtr, NULL);
+ name = Tcl_GetString(objPtr);
if (name[0] == '.') {
tkwin = Tk_NameToWindow(interp, name, mainWin);
if (tkwin == NULL) {
@@ -3871,14 +3827,14 @@ NameToWindow(interp, mainWin, objPtr, tkwinPtr)
} else {
/*
* Check for the winPtr being valid, even if it looks ok to
- * TkpScanWindowId. [Bug #411307]
+ * TkpScanWindowId. [Bug #411307]
*/
if ((TkpScanWindowId(NULL, name, &id) != TCL_OK) ||
((*tkwinPtr = Tk_IdToWindow(Tk_Display(mainWin), id))
== NULL)) {
Tcl_AppendResult(interp, "bad window name/identifier \"",
- name, "\"", (char *) NULL);
+ name, "\"", NULL);
return TCL_ERROR;
}
}
@@ -3901,13 +3857,13 @@ NameToWindow(interp, mainWin, objPtr, tkwinPtr)
*-------------------------------------------------------------------------
*/
static void
-DoWarp(clientData)
- ClientData clientData;
+DoWarp(
+ ClientData clientData)
{
TkDisplay *dispPtr = (TkDisplay *) clientData;
XWarpPointer(dispPtr->display, (Window) None, (Window) dispPtr->warpWindow,
- 0, 0, 0, 0, (int) dispPtr->warpX, (int) dispPtr->warpY);
+ 0, 0, 0, 0, (int) dispPtr->warpX, (int) dispPtr->warpY);
XForceScreenSaver(dispPtr->display, ScreenSaverReset);
dispPtr->flags &= ~TK_DISPLAY_IN_WARP;
}
@@ -3917,35 +3873,36 @@ DoWarp(clientData)
*
* GetVirtualEventUid --
*
- * Determine if the given string is in the proper format for a
- * virtual event.
+ * Determine if the given string is in the proper format for a virtual
+ * event.
*
* 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 the interp's result. Otherwise the return
- * value is a Tk_Uid that represents the virtual event.
+ * 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 the
+ * interp's result. Otherwise the return value is a Tk_Uid that
+ * represents the virtual event.
*
* Side effects:
* None.
*
*-------------------------------------------------------------------------
*/
+
static Tk_Uid
-GetVirtualEventUid(interp, virtString)
- Tcl_Interp *interp;
- char *virtString;
+GetVirtualEventUid(
+ Tcl_Interp *interp,
+ char *virtString)
{
Tk_Uid uid;
- int length;
+ size_t length;
length = strlen(virtString);
if (length < 5 || virtString[0] != '<' || virtString[1] != '<' ||
virtString[length - 2] != '>' || virtString[length - 1] != '>') {
- Tcl_AppendResult(interp, "virtual event \"", virtString,
- "\" is badly formed", (char *) NULL);
- return NULL;
+ Tcl_AppendResult(interp, "virtual event \"", virtString,
+ "\" is badly formed", NULL);
+ return NULL;
}
virtString[length - 2] = '\0';
uid = Tk_GetUid(virtString + 2);
@@ -3953,27 +3910,24 @@ GetVirtualEventUid(interp, virtString)
return uid;
}
-
/*
*----------------------------------------------------------------------
*
* FindSequence --
*
- * Find the entry in the pattern table that corresponds to a
- * particular pattern string, and return a pointer to that
- * entry.
+ * Find the entry in the pattern table that corresponds to a particular
+ * pattern string, and return a pointer to that entry.
*
* Results:
- * The return value is normally a pointer to the PatSeq
- * 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 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
- * on which the pattern sequence depends.
+ * The return value is normally a pointer to the PatSeq 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 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 on which the pattern sequence depends.
*
* Side effects:
* A new pattern sequence may be allocated.
@@ -3982,45 +3936,39 @@ GetVirtualEventUid(interp, virtString)
*/
static PatSeq *
-FindSequence(interp, patternTablePtr, object, eventString, create,
- allowVirtual, maskPtr)
- Tcl_Interp *interp; /* Interpreter to use for error
- * reporting. */
- Tcl_HashTable *patternTablePtr; /* Table to use for lookup. */
- ClientData object; /* For binding table, token for object with
- * which binding is associated.
- * For virtual event table, NULL. */
- CONST char *eventString; /* String description of pattern to
- * match on. See user documentation
- * for details. */
- int create; /* 0 means don't create the entry if
- * it doesn't already exist. Non-zero
- * means create. */
- int allowVirtual; /* 0 means that virtual events are not
- * allowed in the sequence. Non-zero
- * otherwise. */
- unsigned long *maskPtr; /* *maskPtr is filled in with the event
- * types on which this pattern sequence
- * depends. */
+FindSequence(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ Tcl_HashTable *patternTablePtr,
+ /* Table to use for lookup. */
+ ClientData object, /* For binding table, token for object with
+ * which binding is associated. For virtual
+ * event table, NULL. */
+ const char *eventString, /* String description of pattern to match on.
+ * See user documentation for details. */
+ int create, /* 0 means don't create the entry if it
+ * doesn't already exist. Non-zero means
+ * create. */
+ int allowVirtual, /* 0 means that virtual events are not allowed
+ * in the sequence. Non-zero otherwise. */
+ unsigned long *maskPtr) /* *maskPtr is filled in with the event types
+ * on which this pattern sequence depends. */
{
-
Pattern pats[EVENT_BUFFER_SIZE];
int numPats, virtualFound;
- CONST char *p;
+ const char *p;
Pattern *patPtr;
PatSeq *psPtr;
Tcl_HashEntry *hPtr;
- int flags, count, new;
+ int flags, count, isNew;
size_t sequenceSize;
unsigned long eventMask;
PatternTableKey key;
/*
*-------------------------------------------------------------
- * Step 1: parse the pattern string to produce an array
- * of Patterns. The array is generated backwards, so
- * that the lowest-indexed pattern corresponds to the last
- * event that must occur.
+ * Step 1: parse the pattern string to produce an array of Patterns. The
+ * array is generated backwards, so that the lowest-indexed pattern
+ * corresponds to the last event that must occur.
*-------------------------------------------------------------
*/
@@ -4045,7 +3993,7 @@ FindSequence(interp, patternTablePtr, object, eventString, create,
if (eventMask & VirtualEventMask) {
if (allowVirtual == 0) {
- Tcl_SetResult(interp,
+ Tcl_SetResult(interp,
"virtual event not allowed in definition of another virtual event",
TCL_STATIC);
return NULL;
@@ -4067,8 +4015,8 @@ FindSequence(interp, patternTablePtr, object, eventString, create,
/*
*-------------------------------------------------------------
- * Step 2: find the sequence in the binding table if it exists,
- * and add a new sequence to the table if it doesn't.
+ * Step 2: find the sequence in the binding table if it exists, and add a
+ * new sequence to the table if it doesn't.
*-------------------------------------------------------------
*/
@@ -4081,15 +4029,15 @@ FindSequence(interp, patternTablePtr, object, eventString, create,
TCL_STATIC);
return NULL;
}
-
+
patPtr = &pats[EVENT_BUFFER_SIZE-numPats];
memset(&key, 0, sizeof(key));
key.object = object;
key.type = patPtr->eventType;
key.detail = patPtr->detail;
- hPtr = Tcl_CreateHashEntry(patternTablePtr, (char *) &key, &new);
+ hPtr = Tcl_CreateHashEntry(patternTablePtr, (char *) &key, &isNew);
sequenceSize = numPats*sizeof(Pattern);
- if (!new) {
+ if (!isNew) {
for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); psPtr != NULL;
psPtr = psPtr->nextSeqPtr) {
if ((numPats == psPtr->numPats)
@@ -4101,17 +4049,18 @@ FindSequence(interp, patternTablePtr, object, eventString, create,
}
}
if (!create) {
- if (new) {
+ if (isNew) {
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.
+ * 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)
@@ -4128,9 +4077,9 @@ FindSequence(interp, patternTablePtr, object, eventString, create,
psPtr->nextObjPtr = NULL;
Tcl_SetHashValue(hPtr, psPtr);
- memcpy((VOID *) psPtr->pats, (VOID *) patPtr, sequenceSize);
+ memcpy((void *) psPtr->pats, (void *) patPtr, sequenceSize);
- done:
+ done:
*maskPtr = eventMask;
return psPtr;
}
@@ -4140,34 +4089,31 @@ FindSequence(interp, patternTablePtr, object, eventString, create,
*
* ParseEventDescription --
*
- * Fill Pattern buffer with information about event from
- * event string.
+ * Fill Pattern buffer with information about event from event string.
*
* Results:
- * Leaves error message in interp and returns 0 if there was an
- * error due to a badly formed event string. Returns 1 if proper
- * event was specified, 2 if Double modifier was used in event
- * string, or 3 if Triple was used.
+ * Leaves error message in interp and returns 0 if there was an error due
+ * to a badly formed event string. Returns 1 if proper event was
+ * specified, 2 if Double modifier was used in event string, or 3 if
+ * Triple was used.
*
* Side effects:
* On exit, eventStringPtr points to rest of event string (after the
- * closing '>', so that this procedure can be called repeatedly to
- * parse all the events in the entire sequence.
+ * closing '>', so that this function can be called repeatedly to parse
+ * all the events in the entire sequence.
*
*---------------------------------------------------------------------------
*/
static int
-ParseEventDescription(interp, eventStringPtr, patPtr,
- eventMaskPtr)
- Tcl_Interp *interp; /* For error messages. */
- CONST char **eventStringPtr;/* On input, holds a pointer to start of
- * event string. On exit, gets pointer to
- * rest of string after parsed event. */
- Pattern *patPtr; /* Filled with the pattern parsed from the
+ParseEventDescription(
+ Tcl_Interp *interp, /* For error messages. */
+ const char **eventStringPtr,/* On input, holds a pointer to start of event
+ * string. On exit, gets pointer to rest of
+ * string after parsed event. */
+ Pattern *patPtr, /* Filled with the pattern parsed from the
* event string. */
- unsigned long *eventMaskPtr;/* Filled with event mask of matched event. */
-
+ unsigned long *eventMaskPtr)/* Filled with event mask of matched event. */
{
char *p;
unsigned long eventMask;
@@ -4186,7 +4132,7 @@ ParseEventDescription(interp, eventStringPtr, patPtr,
eventMask = 0;
count = 1;
-
+
/*
* Handle simple ASCII characters.
*/
@@ -4204,7 +4150,7 @@ ParseEventDescription(interp, eventStringPtr, patPtr,
patPtr->detail.keySym = *p;
} else {
char buf[64];
-
+
sprintf(buf, "bad ASCII character 0x%x", (unsigned char) *p);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
count = 0;
@@ -4216,8 +4162,8 @@ ParseEventDescription(interp, eventStringPtr, patPtr,
}
/*
- * A fancier event description. This can be either a virtual event
- * or a physical event.
+ * A fancier event description. This can be either a virtual event or a
+ * physical event.
*
* A virtual event description consists of:
*
@@ -4228,30 +4174,30 @@ ParseEventDescription(interp, eventStringPtr, patPtr,
* A physical event description consists of:
*
* 1. open angle bracket.
- * 2. any number of modifiers, each followed by spaces
- * or dashes.
+ * 2. any number of modifiers, each followed by spaces or dashes.
* 3. an optional event name.
- * 4. an option button or keysym name. Either this or
- * item 3 *must* be present; if both are present
- * then they are separated by spaces or dashes.
+ * 4. an option button or keysym name. Either this or item 3 *must* be
+ * present; if both are present then they are separated by spaces or
+ * dashes.
* 5. a close angle bracket.
*/
p++;
if (*p == '<') {
/*
- * This is a virtual event: soak up all the characters up to
- * the next '>'.
+ * This is a virtual event: soak up all the characters up to the next
+ * '>'.
*/
- char *field = p + 1;
+ char *field = p + 1;
+
p = strchr(field, '>');
if (p == field) {
Tcl_SetResult(interp, "virtual event \"<<>>\" is badly formed",
TCL_STATIC);
count = 0;
goto done;
- }
+ }
if ((p == NULL) || (p[1] != '>')) {
Tcl_SetResult(interp, "missing \">\" in virtual binding",
TCL_STATIC);
@@ -4270,13 +4216,15 @@ ParseEventDescription(interp, eventStringPtr, patPtr,
while (1) {
ModInfo *modPtr;
+
p = GetField(p, field, FIELD_SIZE);
if (*p == '>') {
/*
* This solves the problem of, e.g., <Control-M> being
- * misinterpreted as Control + Meta + missing keysym
- * instead of Control + KeyPress + M.
+ * misinterpreted as Control + Meta + missing keysym instead of
+ * Control + KeyPress + M.
*/
+
break;
}
hPtr = Tcl_FindHashEntry(&modTable, field);
@@ -4285,10 +4233,13 @@ ParseEventDescription(interp, eventStringPtr, patPtr,
}
modPtr = (ModInfo *) Tcl_GetHashValue(hPtr);
patPtr->needMods |= modPtr->mask;
- if (modPtr->flags & (MULT_CLICKS)) {
+ if (modPtr->flags & MULT_CLICKS) {
int i = modPtr->flags & MULT_CLICKS;
+
count = 2;
- while (i >>= 1) count++;
+ while (i >>= 1) {
+ count++;
+ }
}
while ((*p == '-') || isspace(UCHAR(*p))) {
p++;
@@ -4298,8 +4249,7 @@ ParseEventDescription(interp, eventStringPtr, patPtr,
eventFlags = 0;
hPtr = Tcl_FindHashEntry(&eventTable, field);
if (hPtr != NULL) {
- EventInfo *eiPtr;
- eiPtr = (EventInfo *) Tcl_GetHashValue(hPtr);
+ EventInfo *eiPtr = (EventInfo *) Tcl_GetHashValue(hPtr);
patPtr->eventType = eiPtr->type;
eventFlags = flagArray[eiPtr->type];
@@ -4318,17 +4268,18 @@ ParseEventDescription(interp, eventStringPtr, patPtr,
goto getKeysym;
} else if ((eventFlags & BUTTON) == 0) {
Tcl_AppendResult(interp, "specified button \"", field,
- "\" for non-button event", (char *) NULL);
+ "\" for non-button event", NULL);
count = 0;
goto done;
}
patPtr->detail.button = (*field - '0');
} else {
- getKeysym:
+
+ getKeysym:
patPtr->detail.keySym = TkStringToKeysym(field);
if (patPtr->detail.keySym == NoSymbol) {
Tcl_AppendResult(interp, "bad event type or keysym \"",
- field, "\"", (char *) NULL);
+ field, "\"", NULL);
count = 0;
goto done;
}
@@ -4337,7 +4288,7 @@ ParseEventDescription(interp, eventStringPtr, patPtr,
eventMask = KeyPressMask;
} else if ((eventFlags & KEY) == 0) {
Tcl_AppendResult(interp, "specified keysym \"", field,
- "\" for non-key event", (char *) NULL);
+ "\" for non-key event", NULL);
count = 0;
goto done;
}
@@ -4369,10 +4320,10 @@ ParseEventDescription(interp, eventStringPtr, patPtr,
}
p++;
-end:
+ end:
*eventStringPtr += (p - Tcl_DStringValue(&copy));
*eventMaskPtr |= eventMask;
-done:
+ done:
Tcl_DStringFree(&copy);
return count;
}
@@ -4382,17 +4333,15 @@ done:
*
* GetField --
*
- * Used to parse pattern descriptions. Copies up to
- * size characters from p to copy, stopping at end of
- * string, space, "-", ">", or whenever size is
- * exceeded.
+ * Used to parse pattern descriptions. Copies up to size characters from
+ * p to copy, stopping at end of string, space, "-", ">", or whenever
+ * size is exceeded.
*
* Results:
- * The return value is a pointer to the character just
- * after the last one copied (usually "-" or space or
- * ">", but could be anything if size was exceeded).
- * Also places NULL-terminated string (up to size
- * character, including NULL), at copy.
+ * The return value is a pointer to the character just after the last one
+ * copied (usually "-" or space or ">", but could be anything if size was
+ * exceeded). Also places NULL-terminated string (up to size character,
+ * including NULL), at copy.
*
* Side effects:
* None.
@@ -4401,11 +4350,10 @@ done:
*/
static char *
-GetField(p, copy, size)
- char *p; /* Pointer to part of pattern. */
- char *copy; /* Place to copy field. */
- int size; /* Maximum number of characters to
- * copy. */
+GetField(
+ char *p, /* Pointer to part of pattern. */
+ char *copy, /* Place to copy field. */
+ int size) /* Maximum number of characters to copy. */
{
while ((*p != '\0') && !isspace(UCHAR(*p)) && (*p != '>')
&& (*p != '-') && (size > 1)) {
@@ -4423,22 +4371,23 @@ GetField(p, copy, size)
*
* GetPatternString --
*
- * Produce a string version of the given event, for displaying to
- * the user.
+ * Produce a string version of the given event, for displaying to the
+ * user.
*
* Results:
* The string is left in dsPtr.
*
* Side effects:
- * It is the caller's responsibility to initialize the DString before
- * and to free it after calling this procedure.
+ * It is the caller's responsibility to initialize the DString before and
+ * to free it after calling this function.
*
*---------------------------------------------------------------------------
*/
+
static void
-GetPatternString(psPtr, dsPtr)
- PatSeq *psPtr;
- Tcl_DString *dsPtr;
+GetPatternString(
+ PatSeq *psPtr,
+ Tcl_DString *dsPtr)
{
Pattern *patPtr;
char c, buffer[TCL_INTEGER_SPACE];
@@ -4453,19 +4402,17 @@ GetPatternString(psPtr, dsPtr)
for (patsLeft = psPtr->numPats, patPtr = &psPtr->pats[psPtr->numPats - 1];
patsLeft > 0; patsLeft--, patPtr--) {
-
/*
* Check for simple case of an ASCII character.
*/
if ((patPtr->eventType == KeyPress)
- && ((psPtr->flags & PAT_NEARBY) == 0)
+ && ((psPtr->flags & PAT_NEARBY) == 0)
&& (patPtr->needMods == 0)
&& (patPtr->detail.keySym < 128)
&& isprint(UCHAR(patPtr->detail.keySym))
&& (patPtr->detail.keySym != '<')
&& (patPtr->detail.keySym != ' ')) {
-
c = (char) patPtr->detail.keySym;
Tcl_DStringAppend(dsPtr, &c, 1);
continue;
@@ -4483,12 +4430,13 @@ GetPatternString(psPtr, dsPtr)
}
/*
- * It's a more general event specification. First check
- * for "Double", "Triple", "Quadruple", then modifiers,
- * then event type, then keysym or button detail.
+ * It's a more general event specification. First check for "Double",
+ * "Triple", "Quadruple", then modifiers, then event type, then keysym
+ * or button detail.
*/
Tcl_DStringAppend(dsPtr, "<", 1);
+
if ((psPtr->flags & PAT_NEARBY) && (patsLeft > 1)
&& (memcmp((char *) patPtr, (char *) (patPtr-1),
sizeof(Pattern)) == 0)) {
@@ -4510,6 +4458,7 @@ GetPatternString(psPtr, dsPtr)
Tcl_DStringAppend(dsPtr, "Double-", 7);
}
}
+
for (needMods = patPtr->needMods, modPtr = modArray;
needMods != 0; modPtr++) {
if (modPtr->mask & needMods) {
@@ -4518,6 +4467,7 @@ GetPatternString(psPtr, dsPtr)
Tcl_DStringAppend(dsPtr, "-", 1);
}
}
+
for (eiPtr = eventArray; eiPtr->name != NULL; eiPtr++) {
if (eiPtr->type == patPtr->eventType) {
Tcl_DStringAppend(dsPtr, eiPtr->name, -1);
@@ -4531,9 +4481,7 @@ GetPatternString(psPtr, dsPtr)
if (patPtr->detail.clientData != 0) {
if ((patPtr->eventType == KeyPress)
|| (patPtr->eventType == KeyRelease)) {
- char *string;
-
- string = TkKeysymToString(patPtr->detail.keySym);
+ char *string = TkKeysymToString(patPtr->detail.keySym);
if (string != NULL) {
Tcl_DStringAppend(dsPtr, string, -1);
}
@@ -4542,6 +4490,7 @@ GetPatternString(psPtr, dsPtr)
Tcl_DStringAppend(dsPtr, buffer, -1);
}
}
+
Tcl_DStringAppend(dsPtr, ">", 1);
}
}
@@ -4551,8 +4500,8 @@ GetPatternString(psPtr, dsPtr)
*
* EvalTclBinding --
*
- * The procedure that is invoked by Tk_BindEvent when a Tcl binding
- * is fired.
+ * The function that is invoked by Tk_BindEvent when a Tcl binding is
+ * fired.
*
* Results:
* A standard Tcl result code, the result of globally evaluating the
@@ -4565,8 +4514,8 @@ GetPatternString(psPtr, dsPtr)
*/
static void
-FreeTclBinding(clientData)
- ClientData clientData;
+FreeTclBinding(
+ ClientData clientData)
{
ckfree((char *) clientData);
}
@@ -4576,12 +4525,11 @@ FreeTclBinding(clientData)
*
* TkStringToKeysym --
*
- * This procedure finds the keysym associated with a given keysym
- * name.
+ * This function finds the keysym associated with a given keysym name.
*
* Results:
- * The return value is the keysym that corresponds to name, or
- * NoSymbol if there is no such keysym.
+ * The return value is the keysym that corresponds to name, or NoSymbol
+ * if there is no such keysym.
*
* Side effects:
* None.
@@ -4590,19 +4538,18 @@ FreeTclBinding(clientData)
*/
KeySym
-TkStringToKeysym(name)
- char *name; /* Name of a keysym. */
+TkStringToKeysym(
+ char *name) /* Name of a keysym. */
{
#ifdef REDO_KEYSYM_LOOKUP
- Tcl_HashEntry *hPtr;
- KeySym keysym;
+ Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&keySymTable, name);
- hPtr = Tcl_FindHashEntry(&keySymTable, name);
if (hPtr != NULL) {
return (KeySym) Tcl_GetHashValue(hPtr);
}
if (strlen(name) == 1) {
- keysym = (KeySym) (unsigned char) name[0];
+ KeySym keysym = (KeySym) (unsigned char) name[0];
+
if (TkKeysymToString(keysym) != NULL) {
return keysym;
}
@@ -4616,12 +4563,11 @@ TkStringToKeysym(name)
*
* TkKeysymToString --
*
- * This procedure finds the keysym name associated with a given
- * keysym.
+ * This function finds the keysym name associated with a given keysym.
*
* Results:
- * The return value is a pointer to a static string containing
- * the name of the given keysym, or NULL if there is no known name.
+ * The return value is a pointer to a static string containing the name
+ * of the given keysym, or NULL if there is no known name.
*
* Side effects:
* None.
@@ -4630,17 +4576,17 @@ TkStringToKeysym(name)
*/
char *
-TkKeysymToString(keysym)
- KeySym keysym;
+TkKeysymToString(
+ KeySym keysym)
{
#ifdef REDO_KEYSYM_LOOKUP
- Tcl_HashEntry *hPtr;
+ Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&nameTable, (char *)keysym);
- hPtr = Tcl_FindHashEntry(&nameTable, (char *)keysym);
if (hPtr != NULL) {
return (char *) Tcl_GetHashValue(hPtr);
}
#endif /* REDO_KEYSYM_LOOKUP */
+
return XKeysymToString(keysym);
}
@@ -4649,25 +4595,24 @@ TkKeysymToString(keysym)
*
* TkCopyAndGlobalEval --
*
- * This procedure makes a copy of a script then passes to Tcl
- * to evaluate it. It's used in situations where the execution of
- * a command may cause the original command string to be reallocated.
+ * This function makes a copy of a script then calls Tcl_EvalEx to
+ * evaluate it. It's used in situations where the execution of a command
+ * may cause the original command string to be reallocated.
*
* Results:
- * Returns the result of evaluating script, including both a standard
- * Tcl completion code and a string in the interp's result.
+ * Returns the result of evaluating script, including both a standard Tcl
+ * completion code and a string in the interp's result.
*
* Side effects:
- * None.
+ * Any; depends on script.
*
*----------------------------------------------------------------------
*/
int
-TkCopyAndGlobalEval(interp, script)
- Tcl_Interp *interp; /* Interpreter in which to evaluate
- * script. */
- char *script; /* Script to evaluate. */
+TkCopyAndGlobalEval(
+ Tcl_Interp *interp, /* Interpreter in which to evaluate script. */
+ char *script) /* Script to evaluate. */
{
Tcl_DString buffer;
int code;
@@ -4679,5 +4624,40 @@ TkCopyAndGlobalEval(interp, script)
Tcl_DStringFree(&buffer);
return code;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpGetBindingXEvent --
+ *
+ * This function returns the XEvent associated with the currently
+ * executing binding. This function can only be invoked while a binding
+ * is executing.
+ *
+ * Results:
+ * Returns a pointer to the XEvent that caused the current binding code
+ * to be run.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+XEvent *
+TkpGetBindingXEvent(
+ Tcl_Interp *interp) /* Interpreter. */
+{
+ TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp);
+ BindingTable *bindPtr = (BindingTable *) winPtr->mainPtr->bindingTable;
+ return &(bindPtr->eventRing[bindPtr->curEvent]);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkBitmap.c b/generic/tkBitmap.c
index 5c8a9fc..09545d6 100644
--- a/generic/tkBitmap.c
+++ b/generic/tkBitmap.c
@@ -1,43 +1,42 @@
-/*
+/*
* tkBitmap.c --
*
* This file maintains a database of read-only bitmaps for the Tk
- * toolkit. This allows bitmaps to be shared between widgets and
- * also avoids interactions with the X server.
+ * toolkit. This allows bitmaps to be shared between widgets and also
+ * avoids interactions with the X server.
*
* Copyright (c) 1990-1994 The Regents of the University of California.
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
/*
* The includes below are for pre-defined bitmaps.
*
- * Platform-specific issue: Windows complains when the bitmaps are
- * included, because an array of characters is being initialized with
- * integers as elements. For lint purposes, the following pragmas
- * temporarily turn off that warning message.
+ * Platform-specific issue: Windows complains when the bitmaps are included,
+ * because an array of characters is being initialized with integers as
+ * elements. For lint purposes, the following pragmas temporarily turn off
+ * that warning message.
*/
#if defined(_MSC_VER)
#pragma warning (disable : 4305)
#endif
-#include "error.bmp"
-#include "gray12.bmp"
-#include "gray25.bmp"
-#include "gray50.bmp"
-#include "gray75.bmp"
-#include "hourglass.bmp"
-#include "info.bmp"
-#include "questhead.bmp"
-#include "question.bmp"
-#include "warning.bmp"
+#include "error.xbm"
+#include "gray12.xbm"
+#include "gray25.xbm"
+#include "gray50.xbm"
+#include "gray75.xbm"
+#include "hourglass.xbm"
+#include "info.xbm"
+#include "questhead.xbm"
+#include "question.xbm"
+#include "warning.xbm"
#if defined(_MSC_VER)
#pragma warning (default : 4305)
@@ -45,82 +44,80 @@
/*
* One of the following data structures exists for each bitmap that is
- * currently in use. Each structure is indexed with both "idTable" and
+ * currently in use. Each structure is indexed with both "idTable" and
* "nameTable".
*/
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. */
+ 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 screenNum; /* Screen on which bitmap is valid */
+ int screenNum; /* Screen on which bitmap is valid. */
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
+ * 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. */
+ * 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). */
+ 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 or
- * screens) are chained together off a
- * single entry in nameTable. */
+ * the same name. All bitmaps with the same
+ * name (but different displays or screens)
+ * are chained together off a single entry in
+ * nameTable. */
} TkBitmap;
-/*
- * Used in bitmapDataTable, stored in the TkDisplay structure, to map
- * between in-core data about a bitmap to its TkBitmap structure.
+/*
+ * Used in bitmapDataTable, stored in the TkDisplay structure, to map between
+ * in-core data about a bitmap to its TkBitmap structure.
*/
typedef struct {
- CONST char *source; /* Bitmap bits. */
+ const char *source; /* Bitmap bits. */
int width, height; /* Dimensions of bitmap. */
} DataKey;
typedef struct ThreadSpecificData {
- int initialized; /* 0 means table below needs initializing. */
+ 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. */
+ /* 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;
/*
- * Forward declarations for procedures defined in this file:
+ * Forward declarations for functions defined in this file:
*/
-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));
+static void BitmapInit(TkDisplay *dispPtr);
+static void DupBitmapObjProc(Tcl_Obj *srcObjPtr,
+ Tcl_Obj *dupObjPtr);
+static void FreeBitmap(TkBitmap *bitmapPtr);
+static void FreeBitmapObjProc(Tcl_Obj *objPtr);
+static TkBitmap * GetBitmap(Tcl_Interp *interp, Tk_Window tkwin,
+ const char *name);
+static TkBitmap * GetBitmapFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
+static void InitBitmapObj(Tcl_Obj *objPtr);
/*
* 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.
+ * object, which maps a string bitmap name to a TkBitmap object. The ptr1
+ * field of the Tcl_Obj points to a TkBitmap object.
*/
Tcl_ObjType tkBitmapObjType = {
@@ -136,33 +133,33 @@ Tcl_ObjType tkBitmapObjType = {
*
* Tk_AllocBitmapFromObj --
*
- * Given a Tcl_Obj *, map the value to a corresponding
- * Pixmap structure based on the tkwin given.
+ * 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.
+ * 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.
+ * For each call to this function, there should eventually be a call to
+ * Tk_FreeBitmapFromObj, so that the database can be cleaned up when
+ * bitmaps aren't needed anymore.
*
*----------------------------------------------------------------------
*/
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. */
+Tk_AllocBitmapFromObj(
+ 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;
@@ -172,54 +169,54 @@ Tk_AllocBitmapFromObj(interp, tkwin, objPtr)
bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1;
/*
- * 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 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.
+ * 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)
- && (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum) ) {
+ } else if ((Tk_Display(tkwin) == bitmapPtr->display)
+ && (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) {
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.
+ * 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);
+ TkBitmap *firstBitmapPtr = (TkBitmap *)
+ Tcl_GetHashValue(bitmapPtr->nameHashPtr);
FreeBitmapObjProc(objPtr);
for (bitmapPtr = firstBitmapPtr; bitmapPtr != NULL;
bitmapPtr = bitmapPtr->nextPtr) {
- if ( (Tk_Display(tkwin) == bitmapPtr->display) &&
- (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum) ) {
+ if ((Tk_Display(tkwin) == bitmapPtr->display) &&
+ (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) {
bitmapPtr->resourceRefCount++;
bitmapPtr->objRefCount++;
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) bitmapPtr;
return bitmapPtr->bitmap;
}
}
}
/*
- * Still no luck. Call GetBitmap to allocate a new TkBitmap object.
+ * Still no luck. Call GetBitmap to allocate a new TkBitmap object.
*/
bitmapPtr = GetBitmap(interp, tkwin, Tcl_GetString(objPtr));
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) bitmapPtr;
if (bitmapPtr == NULL) {
return None;
}
@@ -232,35 +229,36 @@ Tk_AllocBitmapFromObj(interp, tkwin, objPtr)
*
* Tk_GetBitmap --
*
- * Given a string describing a bitmap, locate (or create if necessary)
- * a bitmap that fits the description.
+ * Given a string describing a bitmap, locate (or create if necessary) a
+ * bitmap that fits the description.
*
* 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.
+ * 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, so that the database can be cleaned up when bitmaps
+ * For each call to this function, there should eventually be a call to
+ * Tk_FreeBitmap, so that the database can be cleaned up when bitmaps
* aren't needed anymore.
*
*----------------------------------------------------------------------
*/
Pixmap
-Tk_GetBitmap(interp, tkwin, string)
- Tcl_Interp *interp; /* Interpreter to use for error reporting,
+Tk_GetBitmap(
+ 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. */
+ Tk_Window tkwin, /* Window in which bitmap will be used. */
+ const char *string) /* Description of bitmap. See manual entry for
+ * details on legal syntax. */
{
TkBitmap *bitmapPtr = GetBitmap(interp, tkwin, string);
+
if (bitmapPtr == NULL) {
return None;
}
@@ -272,53 +270,52 @@ Tk_GetBitmap(interp, tkwin, string)
*
* 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.
+ * 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.
+ * 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.
+ * For each call to this function, 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,
+GetBitmap(
+ 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. */
+ 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;
+ int isNew, width, height, dummy2;
TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (!dispPtr->bitmapInit) {
BitmapInit(dispPtr);
}
- nameHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapNameTable, string, &new);
- if (!new) {
+ nameHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapNameTable, string,
+ &isNew);
+ if (!isNew) {
existingBitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr);
for (bitmapPtr = existingBitmapPtr; bitmapPtr != NULL;
bitmapPtr = bitmapPtr->nextPtr) {
@@ -333,26 +330,25 @@ GetBitmap(interp, tkwin, string)
}
/*
- * No suitable bitmap exists. Create a new bitmap from the
- * information contained in the string. If the string starts
- * with "@" then the rest of the string is a file name containing
- * the bitmap. Otherwise the string must refer to a bitmap
- * defined by a call to Tk_DefineBitmap.
+ * No suitable bitmap exists. Create a new bitmap from the information
+ * contained in the string. If the string starts with "@" then the rest of
+ * the string is a file name containing the bitmap. Otherwise the string
+ * must refer to a bitmap defined by a call to Tk_DefineBitmap.
*/
if (*string == '@') { /* INTL: ISO char */
Tcl_DString buffer;
int result;
- if (Tcl_IsSafe(interp)) {
- Tcl_AppendResult(interp, "can't specify bitmap with '@' in a",
- " safe interpreter", (char *) NULL);
- goto error;
- }
+ if (Tcl_IsSafe(interp)) {
+ Tcl_AppendResult(interp, "can't specify bitmap with '@' in a",
+ " safe interpreter", NULL);
+ goto error;
+ }
/*
- * Note that we need to cast away the CONST from the string because
- * Tcl_TranslateFileName is non const, even though it doesn't modify
+ * 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.
*/
@@ -366,29 +362,29 @@ GetBitmap(interp, tkwin, string)
&bitmap, &dummy2, &dummy2);
if (result != BitmapSuccess) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "error reading bitmap file \"", string,
- "\"", (char *) NULL);
+ Tcl_AppendResult(interp, "error reading bitmap file \"",
+ string, "\"", NULL);
}
Tcl_DStringFree(&buffer);
goto error;
}
Tcl_DStringFree(&buffer);
} else {
- predefHashPtr = Tcl_FindHashEntry(&tsdPtr->predefBitmapTable,
- string);
+ predefHashPtr = Tcl_FindHashEntry(&tsdPtr->predefBitmapTable, string);
if (predefHashPtr == NULL) {
/*
- * The following platform specific call allows the user to
- * define bitmaps that may only exist during run time. If
- * it returns None nothing was found and we return the error.
+ * The following platform specific call allows the user to define
+ * bitmaps that may only exist during run time. If it returns None
+ * nothing was found and we return the error.
*/
+
bitmap = TkpGetNativeAppBitmap(Tk_Display(tkwin), string,
&width, &height);
-
+
if (bitmap == None) {
if (interp != NULL) {
Tcl_AppendResult(interp, "bitmap \"", string,
- "\" not defined", (char *) NULL);
+ "\" not defined", NULL);
}
goto error;
}
@@ -400,13 +396,12 @@ GetBitmap(interp, tkwin, string)
bitmap = TkpCreateNativeBitmap(Tk_Display(tkwin),
predefPtr->source);
if (bitmap == None) {
- panic("native bitmap creation failed");
+ Tcl_Panic("native bitmap creation failed");
}
} else {
bitmap = XCreateBitmapFromData(Tk_Display(tkwin),
- RootWindowOfScreen(Tk_Screen(tkwin)),
- predefPtr->source,
- (unsigned) width, (unsigned) height);
+ RootWindowOfScreen(Tk_Screen(tkwin)),
+ predefPtr->source, (unsigned)width, (unsigned)height);
}
}
}
@@ -424,18 +419,18 @@ GetBitmap(interp, tkwin, string)
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->idHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapIdTable,
+ (char *) bitmap, &isNew);
+ if (!isNew) {
+ Tcl_Panic("bitmap already registered in Tk_GetBitmap");
}
bitmapPtr->nextPtr = existingBitmapPtr;
Tcl_SetHashValue(nameHashPtr, bitmapPtr);
Tcl_SetHashValue(bitmapPtr->idHashPtr, bitmapPtr);
return bitmapPtr;
- error:
- if (new) {
+ error:
+ if (isNew) {
Tcl_DeleteHashEntry(nameHashPtr);
}
return NULL;
@@ -446,53 +441,53 @@ GetBitmap(interp, tkwin, string)
*
* Tk_DefineBitmap --
*
- * This procedure associates a textual name with a binary bitmap
- * description, so that the name may be used to refer to the
- * bitmap in future calls to Tk_GetBitmap.
+ * This function associates a textual name with a binary bitmap
+ * description, so that the name may be used to refer to the bitmap in
+ * future calls to Tk_GetBitmap.
*
* Results:
- * A standard Tcl result. If an error occurs then TCL_ERROR is
- * returned and a message is left in the interp's result.
+ * A standard Tcl result. If an error occurs then TCL_ERROR is 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
- * here on to refer to the given bitmap.
+ * "Name" is entered into the bitmap table and may be used from here on
+ * to refer to the given bitmap.
*
*----------------------------------------------------------------------
*/
int
-Tk_DefineBitmap(interp, name, source, width, height)
- Tcl_Interp *interp; /* Interpreter to use for error reporting. */
- CONST char *name; /* Name to use for bitmap. Must not already
- * be defined as a bitmap. */
- CONST char *source; /* Address of bits for bitmap. */
- int width; /* Width of bitmap. */
- int height; /* Height of bitmap. */
+Tk_DefineBitmap(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ const char *name, /* Name to use for bitmap. Must not already be
+ * defined as a bitmap. */
+ const char *source, /* Address of bits for bitmap. */
+ int width, /* Width of bitmap. */
+ int height) /* Height of bitmap. */
{
- int new;
+ int isNew;
Tcl_HashEntry *predefHashPtr;
TkPredefBitmap *predefPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ 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.
- */
+ * 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 (!tsdPtr->initialized) {
- BitmapInit((TkDisplay *) NULL);
+ BitmapInit(NULL);
}
- predefHashPtr = Tcl_CreateHashEntry(&tsdPtr->predefBitmapTable,
- name, &new);
- if (!new) {
- Tcl_AppendResult(interp, "bitmap \"", name,
- "\" is already defined", (char *) NULL);
+ predefHashPtr = Tcl_CreateHashEntry(&tsdPtr->predefBitmapTable,
+ name, &isNew);
+ if (!isNew) {
+ Tcl_AppendResult(interp, "bitmap \"", name, "\" is already defined",
+ NULL);
return TCL_ERROR;
}
predefPtr = (TkPredefBitmap *) ckalloc(sizeof(TkPredefBitmap));
@@ -509,8 +504,7 @@ Tk_DefineBitmap(interp, name, source, width, height)
*
* Tk_NameOfBitmap --
*
- * Given a bitmap, return a textual string identifying the
- * bitmap.
+ * Given a bitmap, return a textual string identifying the bitmap.
*
* Results:
* The return value is the string name associated with bitmap.
@@ -521,19 +515,18 @@ Tk_DefineBitmap(interp, name, source, width, height)
*--------------------------------------------------------------
*/
-CONST char *
-Tk_NameOfBitmap(display, bitmap)
- Display *display; /* Display for which bitmap was
- * allocated. */
- Pixmap bitmap; /* Bitmap whose name is wanted. */
+const char *
+Tk_NameOfBitmap(
+ Display *display, /* Display for which bitmap was allocated. */
+ Pixmap bitmap) /* Bitmap whose name is wanted. */
{
Tcl_HashEntry *idHashPtr;
TkBitmap *bitmapPtr;
TkDisplay *dispPtr = TkGetDisplay(display);
if (dispPtr == NULL || !dispPtr->bitmapInit) {
- unknown:
- panic("Tk_NameOfBitmap received unknown bitmap argument");
+ unknown:
+ Tcl_Panic("Tk_NameOfBitmap received unknown bitmap argument");
}
idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
@@ -549,35 +542,33 @@ Tk_NameOfBitmap(display, bitmap)
*
* Tk_SizeOfBitmap --
*
- * Given a bitmap managed by this module, returns the width
- * and height of the bitmap.
+ * Given a bitmap managed by this module, returns the width and height of
+ * the bitmap.
*
* Results:
- * The words at *widthPtr and *heightPtr are filled in with
- * the dimenstions of bitmap.
+ * The words at *widthPtr and *heightPtr are filled in with the
+ * dimenstions of bitmap.
*
* Side effects:
- * If bitmap isn't managed by this module then the procedure
- * panics..
+ * If bitmap isn't managed by this module then the function panics..
*
*--------------------------------------------------------------
*/
void
-Tk_SizeOfBitmap(display, bitmap, widthPtr, heightPtr)
- Display *display; /* Display for which bitmap was
- * allocated. */
- Pixmap bitmap; /* Bitmap whose size is wanted. */
- int *widthPtr; /* Store bitmap width here. */
- int *heightPtr; /* Store bitmap height here. */
+Tk_SizeOfBitmap(
+ Display *display, /* Display for which bitmap was allocated. */
+ Pixmap bitmap, /* Bitmap whose size is wanted. */
+ int *widthPtr, /* Store bitmap width here. */
+ int *heightPtr) /* Store bitmap height here. */
{
Tcl_HashEntry *idHashPtr;
TkBitmap *bitmapPtr;
TkDisplay *dispPtr = TkGetDisplay(display);
if (!dispPtr->bitmapInit) {
- unknownBitmap:
- panic("Tk_SizeOfBitmap received unknown bitmap argument");
+ unknownBitmap:
+ Tcl_Panic("Tk_SizeOfBitmap received unknown bitmap argument");
}
idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
@@ -594,23 +585,23 @@ 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
+ * This function 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.
+ * 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. */
+FreeBitmap(
+ TkBitmap *bitmapPtr) /* Bitmap to be released. */
{
TkBitmap *prevPtr;
@@ -644,35 +635,34 @@ FreeBitmap(bitmapPtr)
*
* Tk_FreeBitmap --
*
- * This procedure is called to release a bitmap allocated by
- * Tk_GetBitmap or TkGetBitmapFromData.
+ * This function is called to release a bitmap allocated by Tk_GetBitmap
+ * or TkGetBitmapFromData.
*
* Results:
* None.
*
* Side effects:
- * The reference count associated with bitmap is decremented, and
- * it is officially deallocated if no-one is using it anymore.
+ * The reference count associated with bitmap is decremented, and it is
+ * officially deallocated if no-one is using it anymore.
*
*----------------------------------------------------------------------
*/
void
-Tk_FreeBitmap(display, bitmap)
- Display *display; /* Display for which bitmap was
- * allocated. */
- Pixmap bitmap; /* Bitmap to be released. */
+Tk_FreeBitmap(
+ Display *display, /* Display for which bitmap was allocated. */
+ Pixmap bitmap) /* Bitmap to be released. */
{
Tcl_HashEntry *idHashPtr;
TkDisplay *dispPtr = TkGetDisplay(display);
if (!dispPtr->bitmapInit) {
- panic("Tk_FreeBitmap called before Tk_GetBitmap");
+ Tcl_Panic("Tk_FreeBitmap called before Tk_GetBitmap");
}
idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
if (idHashPtr == NULL) {
- panic("Tk_FreeBitmap received unknown bitmap argument");
+ Tcl_Panic("Tk_FreeBitmap received unknown bitmap argument");
}
FreeBitmap((TkBitmap *) Tcl_GetHashValue(idHashPtr));
}
@@ -682,27 +672,27 @@ Tk_FreeBitmap(display, bitmap)
*
* 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.
+ * This function 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.
+ * 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. */
+Tk_FreeBitmapFromObj(
+ 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));
}
@@ -710,26 +700,25 @@ Tk_FreeBitmapFromObj(tkwin, objPtr)
/*
*---------------------------------------------------------------------------
*
- * FreeBitmapObjProc --
+ * 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.
+ * 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.
+ * 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. */
+FreeBitmapObjProc(
+ Tcl_Obj *objPtr) /* The object we are releasing. */
{
TkBitmap *bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1;
@@ -739,37 +728,37 @@ FreeBitmapObjProc(objPtr)
&& (bitmapPtr->resourceRefCount == 0)) {
ckfree((char *) bitmapPtr);
}
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
+ objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}
}
/*
*---------------------------------------------------------------------------
*
- * DupBitmapObjProc --
+ * DupBitmapObjProc --
*
- * When a cached bitmap object is duplicated, this is called to
- * update the internal reps.
+ * 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.
+ * 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. */
+DupBitmapObjProc(
+ 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;
+ dupObjPtr->internalRep.twoPtrValue.ptr1 = (void *) bitmapPtr;
if (bitmapPtr != NULL) {
bitmapPtr->objRefCount++;
@@ -781,22 +770,22 @@ DupBitmapObjProc(srcObjPtr, dupObjPtr)
*
* Tk_GetBitmapFromData --
*
- * Given a description of the bits for a bitmap, make a bitmap that
- * has the given properties. *** NOTE: this procedure is obsolete
- * and really shouldn't be used anymore. ***
+ * Given a description of the bits for a bitmap, make a bitmap that has
+ * the given properties. *** NOTE: this function is obsolete and really
+ * shouldn't be used anymore. ***
*
* Results:
- * 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
- * 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.
+ * 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 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, so that the database can be cleaned up when bitmaps
+ * For each call to this function, there should eventually be a call to
+ * Tk_FreeBitmap, so that the database can be cleaned up when bitmaps
* aren't needed anymore.
*
*----------------------------------------------------------------------
@@ -804,15 +793,15 @@ DupBitmapObjProc(srcObjPtr, dupObjPtr)
/* ARGSUSED */
Pixmap
-Tk_GetBitmapFromData(interp, tkwin, source, width, height)
- Tcl_Interp *interp; /* Interpreter to use for error reporting. */
- Tk_Window tkwin; /* Window in which bitmap will be used. */
- CONST char *source; /* Bitmap data for bitmap shape. */
- int width, height; /* Dimensions of bitmap. */
+Tk_GetBitmapFromData(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ Tk_Window tkwin, /* Window in which bitmap will be used. */
+ const char *source, /* Bitmap data for bitmap shape. */
+ int width, int height) /* Dimensions of bitmap. */
{
DataKey nameKey;
Tcl_HashEntry *dataHashPtr;
- int new;
+ int isNew;
char string[16 + TCL_INTEGER_SPACE];
char *name;
TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
@@ -826,9 +815,9 @@ Tk_GetBitmapFromData(interp, tkwin, source, width, height)
nameKey.source = source;
nameKey.width = width;
nameKey.height = height;
- dataHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapDataTable,
- (char *) &nameKey, &new);
- if (!new) {
+ dataHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapDataTable,
+ (char *) &nameKey, &isNew);
+ if (!isNew) {
name = (char *) Tcl_GetHashValue(dataHashPtr);
} else {
dispPtr->bitmapAutoNumber++;
@@ -848,27 +837,28 @@ Tk_GetBitmapFromData(interp, tkwin, source, width, height)
*
* 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.
+ * 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.
+ * Returns the Pixmap 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.
+ * 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. */
+Tk_GetBitmapFromObj(
+ Tk_Window tkwin,
+ Tcl_Obj *objPtr) /* The object from which to get pixels. */
{
TkBitmap *bitmapPtr = GetBitmapFromObj(tkwin, objPtr);
+
return bitmapPtr->bitmap;
}
@@ -877,28 +867,28 @@ Tk_GetBitmapFromObj(tkwin, objPtr)
*
* 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.
+ * 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.
+ * 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.
+ * 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
+GetBitmapFromObj(
+ Tk_Window tkwin, /* Window in which the bitmap will be used. */
+ Tcl_Obj *objPtr) /* The object that describes the desired
* bitmap. */
{
- TkBitmap *bitmapPtr;
+ TkBitmap *bitmapPtr;
Tcl_HashEntry *hashPtr;
TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
@@ -907,7 +897,7 @@ GetBitmapFromObj(tkwin, objPtr)
}
bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1;
- if (bitmapPtr != NULL) {
+ if (bitmapPtr != NULL) {
if ((bitmapPtr->resourceRefCount > 0)
&& (Tk_Display(tkwin) == bitmapPtr->display)) {
return bitmapPtr;
@@ -915,29 +905,29 @@ GetBitmapFromObj(tkwin, objPtr)
hashPtr = bitmapPtr->nameHashPtr;
FreeBitmapObjProc(objPtr);
} else {
- hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable,
- Tcl_GetString(objPtr));
+ 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.
+ * 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;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) bitmapPtr;
bitmapPtr->objRefCount++;
return bitmapPtr;
}
}
- error:
- panic("GetBitmapFromObj called with non-existent bitmap!");
+ error:
+ Tcl_Panic("GetBitmapFromObj called with non-existent bitmap!");
/*
* The following code isn't reached; it's just there to please compilers.
*/
@@ -949,27 +939,27 @@ GetBitmapFromObj(tkwin, objPtr)
*
* InitBitmapObj --
*
- * Bookeeping procedure to change an objPtr to a bitmap type.
+ * Bookeeping function 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.
+ * 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. */
+InitBitmapObj(
+ Tcl_Obj *objPtr) /* The object to convert. */
{
- Tcl_ObjType *typePtr;
+ const Tcl_ObjType *typePtr;
/*
- * Free the old internalRep before setting the new one.
+ * Free the old internalRep before setting the new one.
*/
Tcl_GetString(objPtr);
@@ -978,21 +968,22 @@ InitBitmapObj(objPtr)
(*typePtr->freeIntRepProc)(objPtr);
}
objPtr->typePtr = &tkBitmapObjType;
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
+ objPtr->internalRep.twoPtrValue.ptr1 = 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.
+ *
+ * Initializes hash tables used by this module. Initializes tables stored
+ * in TkDisplay structure if a TkDisplay pointer is passed in. Also
+ * initializes the thread-local data in the current thread's
+ * ThreadSpecificData structure.
*
* Results:
- * None.
- *
+ * None.
+ *
* Side effects:
* Read the code.
*
@@ -1000,70 +991,70 @@ InitBitmapObj(objPtr)
*/
static void
-BitmapInit(dispPtr)
- TkDisplay *dispPtr; /* TkDisplay structure encapsulating
- * thread-specific data used by this
- * module, or NULL if unavailable. */
+BitmapInit(
+ 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));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- /*
- * First initialize the data in the ThreadSpecificData strucuture,
- * if needed.
+ /*
+ * First initialize the data in the ThreadSpecificData strucuture, if
+ * needed.
*/
if (!tsdPtr->initialized) {
tsdPtr->initialized = 1;
- dummy = Tcl_CreateInterp();
+ dummy = Tcl_CreateInterp();
Tcl_InitHashTable(&tsdPtr->predefBitmapTable, TCL_STRING_KEYS);
- Tk_DefineBitmap(dummy, "error", (char *) error_bits,
+ 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);
+ 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);
}
/*
- * Was a valid TkDisplay pointer passed? If so, initialize the
- * Bitmap module tables in that structure.
+ * Was a valid TkDisplay pointer passed? If so, initialize the Bitmap
+ * module tables in that structure.
*/
if (dispPtr != NULL) {
- dispPtr->bitmapInit = 1;
+ dispPtr->bitmapInit = 1;
Tcl_InitHashTable(&dispPtr->bitmapNameTable, TCL_STRING_KEYS);
- Tcl_InitHashTable(&dispPtr->bitmapDataTable, sizeof(DataKey)
- /sizeof(int));
+ 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 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);
}
}
@@ -1073,8 +1064,8 @@ BitmapInit(dispPtr)
*
* TkReadBitmapFile --
*
- * Loads a bitmap image in X bitmap format into the specified
- * drawable. This is equivelent to the XReadBitmapFile in X.
+ * Loads a bitmap image in X bitmap format into the specified drawable.
+ * This is equivelent to the XReadBitmapFile in X.
*
* Results:
* Sets the size, hotspot, and bitmap on success.
@@ -1086,16 +1077,15 @@ BitmapInit(dispPtr)
*/
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;
+TkReadBitmapFile(
+ 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)
{
char *data;
@@ -1108,23 +1098,22 @@ TkReadBitmapFile(display, d, filename, width_return, height_return,
*bitmap_return = XCreateBitmapFromData(display, d, data, *width_return,
*height_return);
-
ckfree(data);
return BitmapSuccess;
- }
+}
/*
*----------------------------------------------------------------------
*
* TkDebugBitmap --
*
- * This procedure returns debugging information about a bitmap.
+ * This function 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.
+ * corresponding to "name". Each sublist has two elements that contain
+ * the resourceRefCount and objRefCount fields from the TkBitmap
+ * structure.
*
* Side effects:
* None.
@@ -1133,10 +1122,10 @@ TkReadBitmapFile(display, d, filename, width_return, height_return,
*/
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. */
+TkDebugBitmap(
+ 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;
@@ -1148,45 +1137,54 @@ TkDebugBitmap(tkwin, name)
if (hashPtr != NULL) {
bitmapPtr = (TkBitmap *) Tcl_GetHashValue(hashPtr);
if (bitmapPtr == NULL) {
- panic("TkDebugBitmap found empty hash table entry");
+ Tcl_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_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.
+ *
+ * This function 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.
+ * Returns a pointer to the predefined bitmap hash table for the current
+ * thread.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
+
Tcl_HashTable *
-TkGetBitmapPredefTable()
+TkGetBitmapPredefTable(void)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
return &tsdPtr->predefBitmapTable;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkButton.c b/generic/tkButton.c
index 9a261e9..70bba83 100644
--- a/generic/tkButton.c
+++ b/generic/tkButton.c
@@ -1,39 +1,40 @@
-/*
+/*
* tkButton.c --
*
- * This module implements a collection of button-like
- * widgets for the Tk toolkit. The widgets implemented
- * include labels, buttons, checkbuttons, and radiobuttons.
+ * This module implements a collection of button-like widgets for the Tk
+ * toolkit. The widgets implemented include buttons, checkbuttons,
+ * radiobuttons, and labels.
*
* Copyright (c) 1990-1994 The Regents of the University of California.
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
+#include "tkInt.h"
#include "tkButton.h"
#include "default.h"
-typedef struct ThreadSpecificData {
+typedef struct ThreadSpecificData {
int defaultsInitialized;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
/*
- * Class names for buttons, indexed by one of the type values defined
- * in tkButton.h.
+ * Class names for buttons, indexed by one of the type values defined in
+ * tkButton.h.
*/
-static CONST char *CONST classNames[] = {"Label", "Button", "Checkbutton", "Radiobutton"};
+static const char *const classNames[] = {"Label", "Button", "Checkbutton", "Radiobutton"};
/*
- * The following table defines the legal values for the -default option.
- * It is used together with the "enum defaultValue" declaration in tkButton.h.
+ * The following table defines the legal values for the -default option. It is
+ * used together with the "enum defaultValue" declaration in tkButton.h.
*/
-static CONST char *CONST defaultStrings[] = {
- "active", "disabled", "normal", (char *) NULL
+static const char *const defaultStrings[] = {
+ "active", "disabled", "normal", NULL
};
/*
@@ -41,8 +42,8 @@ static CONST char *CONST defaultStrings[] = {
* It is used together with the "enum state" declaration in tkButton.h.
*/
-static CONST char *CONST stateStrings[] = {
- "active", "disabled", "normal", (char *) NULL
+static const char *const stateStrings[] = {
+ "active", "disabled", "normal", NULL
};
/*
@@ -50,18 +51,24 @@ static CONST char *CONST stateStrings[] = {
* It is used with the "enum compound" declaration in tkButton.h
*/
-static CONST char *CONST compoundStrings[] = {
- "bottom", "center", "left", "none", "right", "top", (char *) NULL
+static const char *const compoundStrings[] = {
+ "bottom", "center", "left", "none", "right", "top", NULL
};
+char tkDefButtonHighlightWidth[TCL_INTEGER_SPACE] = DEF_BUTTON_HIGHLIGHT_WIDTH;
+char tkDefButtonPadx[TCL_INTEGER_SPACE] = DEF_BUTTON_PADX;
+char tkDefButtonPady[TCL_INTEGER_SPACE] = DEF_BUTTON_PADY;
char tkDefButtonBorderWidth[TCL_INTEGER_SPACE] = DEF_BUTTON_BORDER_WIDTH;
+char tkDefLabelHighlightWidth[TCL_INTEGER_SPACE] = DEF_LABEL_HIGHLIGHT_WIDTH;
+char tkDefLabelPadx[TCL_INTEGER_SPACE] = DEF_LABCHKRAD_PADX;
+char tkDefLabelPady[TCL_INTEGER_SPACE] = DEF_LABCHKRAD_PADY;
/*
* Information used for parsing configuration options. There is a
* separate table for each of the four widget classes.
*/
-static CONST Tk_OptionSpec labelOptionSpecs[] = {
+static const Tk_OptionSpec labelOptionSpecs[] = {
{TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(TkButton, activeBorder),
0, (ClientData) DEF_BUTTON_ACTIVE_BG_MONO, 0},
@@ -73,10 +80,10 @@ static CONST Tk_OptionSpec labelOptionSpecs[] = {
{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_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ 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},
@@ -93,8 +100,8 @@ static CONST Tk_OptionSpec labelOptionSpecs[] = {
"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_SYNONYM, "-fg", "foreground", NULL,
+ 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",
@@ -109,7 +116,7 @@ static CONST Tk_OptionSpec labelOptionSpecs[] = {
DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
0, 0, 0},
{TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
- "HighlightThickness", DEF_LABEL_HIGHLIGHT_WIDTH,
+ "HighlightThickness", tkDefLabelHighlightWidth,
Tk_Offset(TkButton, highlightWidthPtr),
Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
{TK_OPTION_STRING, "-image", "image", "Image",
@@ -118,10 +125,10 @@ static CONST Tk_OptionSpec labelOptionSpecs[] = {
{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),
+ tkDefLabelPadx, Tk_Offset(TkButton, padXPtr),
Tk_Offset(TkButton, padX), 0, 0, 0},
{TK_OPTION_PIXELS, "-pady", "padY", "Pad",
- DEF_LABCHKRAD_PADY, Tk_Offset(TkButton, padYPtr),
+ tkDefLabelPady, 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},
@@ -143,11 +150,10 @@ static CONST Tk_OptionSpec labelOptionSpecs[] = {
{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}
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0}
};
-static CONST Tk_OptionSpec buttonOptionSpecs[] = {
+static const 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},
@@ -159,10 +165,10 @@ static CONST Tk_OptionSpec buttonOptionSpecs[] = {
{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_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ 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},
@@ -185,8 +191,8 @@ static CONST Tk_OptionSpec buttonOptionSpecs[] = {
"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_SYNONYM, "-fg", "foreground", NULL,
+ 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",
@@ -201,7 +207,7 @@ static CONST Tk_OptionSpec buttonOptionSpecs[] = {
DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
0, 0, 0},
{TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
- "HighlightThickness", DEF_BUTTON_HIGHLIGHT_WIDTH,
+ "HighlightThickness", tkDefButtonHighlightWidth,
Tk_Offset(TkButton, highlightWidthPtr),
Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
{TK_OPTION_STRING, "-image", "image", "Image",
@@ -213,10 +219,10 @@ static CONST Tk_OptionSpec buttonOptionSpecs[] = {
DEF_BUTTON_OVER_RELIEF, -1, Tk_Offset(TkButton, overRelief),
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-padx", "padX", "Pad",
- DEF_BUTTON_PADX, Tk_Offset(TkButton, padXPtr),
+ tkDefButtonPadx, Tk_Offset(TkButton, padXPtr),
Tk_Offset(TkButton, padX), 0, 0, 0},
{TK_OPTION_PIXELS, "-pady", "padY", "Pad",
- DEF_BUTTON_PADY, Tk_Offset(TkButton, padYPtr),
+ tkDefButtonPady, 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),
@@ -245,11 +251,10 @@ static CONST Tk_OptionSpec buttonOptionSpecs[] = {
{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}
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};
-static CONST Tk_OptionSpec checkbuttonOptionSpecs[] = {
+static const 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},
@@ -261,10 +266,10 @@ static CONST Tk_OptionSpec checkbuttonOptionSpecs[] = {
{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_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ 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},
@@ -284,8 +289,8 @@ static CONST Tk_OptionSpec checkbuttonOptionSpecs[] = {
"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_SYNONYM, "-fg", "foreground", NULL,
+ 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",
@@ -300,7 +305,7 @@ static CONST Tk_OptionSpec checkbuttonOptionSpecs[] = {
DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
0, 0, 0},
{TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
- "HighlightThickness", DEF_BUTTON_HIGHLIGHT_WIDTH,
+ "HighlightThickness", tkDefButtonHighlightWidth,
Tk_Offset(TkButton, highlightWidthPtr),
Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
{TK_OPTION_STRING, "-image", "image", "Image",
@@ -320,10 +325,10 @@ static CONST Tk_OptionSpec checkbuttonOptionSpecs[] = {
DEF_BUTTON_OVER_RELIEF, -1, Tk_Offset(TkButton, overRelief),
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-padx", "padX", "Pad",
- DEF_LABCHKRAD_PADX, Tk_Offset(TkButton, padXPtr),
+ tkDefLabelPadx, Tk_Offset(TkButton, padXPtr),
Tk_Offset(TkButton, padX), 0, 0, 0},
{TK_OPTION_PIXELS, "-pady", "padY", "Pad",
- DEF_LABCHKRAD_PADY, Tk_Offset(TkButton, padYPtr),
+ tkDefLabelPady, 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},
@@ -344,6 +349,11 @@ static CONST Tk_OptionSpec checkbuttonOptionSpecs[] = {
{TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
+ DEF_BUTTON_IMAGE, Tk_Offset(TkButton, tristateImagePtr), -1,
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-tristatevalue", "tristateValue", "TristateValue",
+ DEF_BUTTON_TRISTATE_VALUE, Tk_Offset(TkButton, tristateValuePtr), -1, 0, 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",
@@ -354,11 +364,10 @@ static CONST Tk_OptionSpec checkbuttonOptionSpecs[] = {
{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}
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};
-static CONST Tk_OptionSpec radiobuttonOptionSpecs[] = {
+static const 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},
@@ -370,10 +379,10 @@ static CONST Tk_OptionSpec radiobuttonOptionSpecs[] = {
{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_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ 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},
@@ -393,8 +402,8 @@ static CONST Tk_OptionSpec radiobuttonOptionSpecs[] = {
"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_SYNONYM, "-fg", "foreground", NULL,
+ 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",
@@ -409,7 +418,7 @@ static CONST Tk_OptionSpec radiobuttonOptionSpecs[] = {
DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
0, 0, 0},
{TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
- "HighlightThickness", DEF_BUTTON_HIGHLIGHT_WIDTH,
+ "HighlightThickness", tkDefButtonHighlightWidth,
Tk_Offset(TkButton, highlightWidthPtr),
Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
{TK_OPTION_STRING, "-image", "image", "Image",
@@ -426,10 +435,10 @@ static CONST Tk_OptionSpec radiobuttonOptionSpecs[] = {
DEF_BUTTON_OVER_RELIEF, -1, Tk_Offset(TkButton, overRelief),
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-padx", "padX", "Pad",
- DEF_LABCHKRAD_PADX, Tk_Offset(TkButton, padXPtr),
+ tkDefLabelPadx, Tk_Offset(TkButton, padXPtr),
Tk_Offset(TkButton, padX), 0, 0, 0},
{TK_OPTION_PIXELS, "-pady", "padY", "Pad",
- DEF_LABCHKRAD_PADY, Tk_Offset(TkButton, padYPtr),
+ tkDefLabelPady, 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},
@@ -450,6 +459,11 @@ static CONST Tk_OptionSpec radiobuttonOptionSpecs[] = {
{TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
+ DEF_BUTTON_IMAGE, Tk_Offset(TkButton, tristateImagePtr), -1,
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-tristatevalue", "tristateValue", "TristateValue",
+ DEF_BUTTON_TRISTATE_VALUE, Tk_Offset(TkButton, tristateValuePtr), -1, 0, 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",
@@ -462,17 +476,15 @@ static CONST Tk_OptionSpec radiobuttonOptionSpecs[] = {
{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}
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};
/*
- * 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.
+ * 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 CONST Tk_OptionSpec *CONST optionSpecs[] = {
+static const Tk_OptionSpec *const optionSpecs[] = {
labelOptionSpecs,
buttonOptionSpecs,
checkbuttonOptionSpecs,
@@ -480,18 +492,17 @@ static CONST Tk_OptionSpec *CONST optionSpecs[] = {
};
/*
- * 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.
+ * 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 CONST char *commandNames[][8] = {
- {"cget", "configure", (char *) NULL},
- {"cget", "configure", "flash", "invoke", (char *) NULL},
- {"cget", "configure", "deselect", "flash", "invoke", "select",
- "toggle", (char *) NULL},
+static const char *commandNames[][8] = {
+ {"cget", "configure", NULL},
+ {"cget", "configure", "flash", "invoke", NULL},
{"cget", "configure", "deselect", "flash", "invoke", "select",
- (char *) NULL}
+ "toggle", NULL},
+ {"cget", "configure", "deselect", "flash", "invoke", "select", NULL}
};
enum command {
COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DESELECT, COMMAND_FLASH,
@@ -507,91 +518,92 @@ static enum command map[][8] = {
};
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static void ButtonCmdDeletedProc _ANSI_ARGS_((
- ClientData clientData));
-static int ButtonCreate _ANSI_ARGS_((ClientData clientData,
+static void ButtonCmdDeletedProc(ClientData clientData);
+static int ButtonCreate(ClientData clientData,
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,
+ Tcl_Obj *const objv[], int type);
+static void ButtonEventProc(ClientData clientData,
+ XEvent *eventPtr);
+static void ButtonImageProc(ClientData clientData,
int x, int y, int width, int height,
- int imgWidth, int imgHeight));
-static void ButtonSelectImageProc _ANSI_ARGS_((
- ClientData clientData, int x, int y, int width,
- int height, int imgWidth, int imgHeight));
-static char * ButtonTextVarProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, CONST char *name1,
- CONST char *name2, int flags));
-static char * ButtonVarProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, CONST char *name1,
- CONST char *name2, int flags));
-static int ButtonWidgetObjCmd _ANSI_ARGS_((ClientData clientData,
+ int imgWidth, int imgHeight);
+static void ButtonSelectImageProc(ClientData clientData,
+ int x, int y, int width, int height,
+ int imgWidth, int imgHeight);
+static void ButtonTristateImageProc(ClientData clientData,
+ int x, int y, int width, int height,
+ int imgWidth, int imgHeight);
+static char * ButtonTextVarProc(ClientData clientData,
+ Tcl_Interp *interp, const char *name1,
+ const char *name2, int flags);
+static char * ButtonVarProc(ClientData clientData,
+ Tcl_Interp *interp, const char *name1,
+ const char *name2, int flags);
+static int ButtonWidgetObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int ConfigureButton _ANSI_ARGS_((Tcl_Interp *interp,
- TkButton *butPtr, int objc,
- Tcl_Obj *CONST objv[]));
-static void DestroyButton _ANSI_ARGS_((TkButton *butPtr));
+ Tcl_Obj *const objv[]);
+static int ConfigureButton(Tcl_Interp *interp, TkButton *butPtr,
+ int objc, Tcl_Obj *const objv[]);
+static void DestroyButton(TkButton *butPtr);
/*
*--------------------------------------------------------------
*
* Tk_ButtonCmd, Tk_CheckbuttonCmd, Tk_LabelCmd, Tk_RadiobuttonCmd --
*
- * These procedures are invoked to process the "button", "label",
- * "radiobutton", and "checkbutton" Tcl commands. See the
- * user documentation for details on what they do.
+ * These functions are invoked to process the "button", "label",
+ * "radiobutton", and "checkbutton" Tcl commands. See the user
+ * documentation for details on what they do.
*
* Results:
* A standard Tcl result.
*
* Side effects:
- * See the user documentation. These procedures are just wrappers;
- * they call ButtonCreate to do all of the real work.
+ * See the user documentation. These functions are just wrappers; they
+ * call ButtonCreate to do all of the real work.
*
*--------------------------------------------------------------
*/
int
-Tk_ButtonObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Either NULL or pointer to option table. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+Tk_ButtonObjCmd(
+ ClientData clientData, /* Either NULL or pointer to option table. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument values. */
{
return ButtonCreate(clientData, interp, objc, objv, TYPE_BUTTON);
}
int
-Tk_CheckbuttonObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Either NULL or pointer to option table. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+Tk_CheckbuttonObjCmd(
+ ClientData clientData, /* Either NULL or pointer to option table. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument values. */
{
return ButtonCreate(clientData, interp, objc, objv, TYPE_CHECK_BUTTON);
}
int
-Tk_LabelObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Either NULL or pointer to option table. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+Tk_LabelObjCmd(
+ ClientData clientData, /* Either NULL or pointer to option table. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument values. */
{
return ButtonCreate(clientData, interp, objc, objv, TYPE_LABEL);
}
int
-Tk_RadiobuttonObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Either NULL or pointer to option table. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+Tk_RadiobuttonObjCmd(
+ ClientData clientData, /* Either NULL or pointer to option table. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument values. */
{
return ButtonCreate(clientData, interp, objc, objv, TYPE_RADIO_BUTTON);
}
@@ -601,9 +613,9 @@ Tk_RadiobuttonObjCmd(clientData, interp, objc, objv)
*
* ButtonCreate --
*
- * This procedure does all the real work of implementing the
- * "button", "label", "radiobutton", and "checkbutton" Tcl
- * commands. See the user documentation for details on what it does.
+ * This function does all the real work of implementing the "button",
+ * "label", "radiobutton", and "checkbutton" Tcl commands. See the user
+ * documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -615,23 +627,23 @@ Tk_RadiobuttonObjCmd(clientData, interp, objc, objv)
*/
static int
-ButtonCreate(clientData, interp, objc, objv, type)
- ClientData clientData; /* NULL. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
- int type; /* Type of button to create: TYPE_LABEL,
+ButtonCreate(
+ ClientData clientData, /* NULL. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ 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. */
{
TkButton *butPtr;
Tk_OptionTable optionTable;
Tk_Window tkwin;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (!tsdPtr->defaultsInitialized) {
- TkpButtonSetDefaults(NULL);
+ TkpButtonSetDefaults();
tsdPtr->defaultsInitialized = 1;
}
@@ -645,14 +657,14 @@ ButtonCreate(clientData, interp, objc, objv, type)
*/
tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
- Tcl_GetString(objv[1]), (char *) NULL);
+ Tcl_GetString(objv[1]), NULL);
if (tkwin == NULL) {
return TCL_ERROR;
}
/*
- * Create the option table for this widget class. If it has already
- * been created, the cached pointer will be returned.
+ * Create the option table for this widget class. If it has already been
+ * created, the cached pointer will be returned.
*/
optionTable = Tk_CreateOptionTable(interp, optionSpecs[type]);
@@ -681,6 +693,8 @@ ButtonCreate(clientData, interp, objc, objv, type)
butPtr->image = NULL;
butPtr->selectImagePtr = NULL;
butPtr->selectImage = NULL;
+ butPtr->tristateImagePtr = NULL;
+ butPtr->tristateImage = NULL;
butPtr->state = STATE_NORMAL;
butPtr->normalBorder = NULL;
butPtr->activeBorder = NULL;
@@ -725,6 +739,7 @@ ButtonCreate(clientData, interp, objc, objv, type)
butPtr->selVarNamePtr = NULL;
butPtr->onValuePtr = NULL;
butPtr->offValuePtr = NULL;
+ butPtr->tristateValuePtr = NULL;
butPtr->cursor = None;
butPtr->takeFocusPtr = NULL;
butPtr->commandPtr = NULL;
@@ -754,9 +769,9 @@ ButtonCreate(clientData, interp, objc, objv, type)
*
* ButtonWidgetCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to a widget managed by this module.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the Tcl command that corresponds
+ * to a widget managed by this module. See the user documentation for
+ * details on what it does.
*
* Results:
* A standard Tcl result.
@@ -768,11 +783,11 @@ ButtonCreate(clientData, interp, objc, objv, type)
*/
static int
-ButtonWidgetObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Information about button widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+ButtonWidgetObjCmd(
+ ClientData clientData, /* Information about button widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument values. */
{
TkButton *butPtr = (TkButton *) clientData;
int index;
@@ -791,137 +806,126 @@ ButtonWidgetObjCmd(clientData, interp, objc, objv)
Tcl_Preserve((ClientData) butPtr);
switch (map[butPtr->type][index]) {
- case COMMAND_CGET: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "cget option");
- goto error;
- }
- objPtr = Tk_GetOptionValue(interp, (char *) butPtr,
- butPtr->optionTable, objv[2], butPtr->tkwin);
+ case COMMAND_CGET:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "cget option");
+ goto error;
+ }
+ objPtr = Tk_GetOptionValue(interp, (char *) butPtr,
+ butPtr->optionTable, objv[2], butPtr->tkwin);
+ if (objPtr == NULL) {
+ goto error;
+ } else {
+ Tcl_SetObjResult(interp, objPtr);
+ }
+ break;
+
+ case COMMAND_CONFIGURE:
+ if (objc <= 3) {
+ objPtr = Tk_GetOptionInfo(interp, (char *) butPtr,
+ butPtr->optionTable, (objc == 3) ? objv[2] : NULL,
+ butPtr->tkwin);
if (objPtr == NULL) {
- goto error;
+ goto error;
} else {
Tcl_SetObjResult(interp, objPtr);
}
- break;
+ } else {
+ result = ConfigureButton(interp, butPtr, objc-2, objv+2);
}
+ break;
- 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;
+ case COMMAND_DESELECT:
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "deselect");
+ goto error;
}
-
- case COMMAND_DESELECT: {
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "deselect");
+ 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;
}
- 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;
- }
+ } 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;
}
+ break;
- case COMMAND_FLASH: {
+ case COMMAND_FLASH:
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "flash");
+ goto error;
+ }
+ if (butPtr->state != STATE_DISABLED) {
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);
+ 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;
}
+ break;
- case COMMAND_INVOKE: {
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "invoke");
- goto error;
- }
- if (butPtr->state != STATE_DISABLED) {
- result = TkInvokeButton(butPtr);
- }
- break;
+ case COMMAND_INVOKE:
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "invoke");
+ goto error;
+ }
+ if (butPtr->state != STATE_DISABLED) {
+ result = TkInvokeButton(butPtr);
}
+ break;
- 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;
+ 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;
- case COMMAND_TOGGLE: {
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "toggle");
- goto 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;
+ case COMMAND_TOGGLE:
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "toggle");
+ goto 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;
}
Tcl_Release((ClientData) butPtr);
return result;
- error:
+ error:
Tcl_Release((ClientData) butPtr);
return TCL_ERROR;
}
@@ -931,8 +935,8 @@ ButtonWidgetObjCmd(clientData, interp, objc, objv)
*
* DestroyButton --
*
- * This procedure is invoked by ButtonEventProc to free all the
- * resources of a button and clean up its state.
+ * This function is invoked by ButtonEventProc to free all the resources
+ * of a button and clean up its state.
*
* Results:
* None.
@@ -944,8 +948,8 @@ ButtonWidgetObjCmd(clientData, interp, objc, objv)
*/
static void
-DestroyButton(butPtr)
- TkButton *butPtr; /* Info about button widget. */
+DestroyButton(
+ TkButton *butPtr) /* Info about button widget. */
{
butPtr->flags |= BUTTON_DELETED;
TkpDestroyButton(butPtr);
@@ -955,9 +959,8 @@ DestroyButton(butPtr)
}
/*
- * Free up all the stuff that requires special handling, then
- * let Tk_FreeOptions handle all the standard option-related
- * stuff.
+ * Free up all the stuff that requires special handling, then let
+ * Tk_FreeOptions handle all the standard option-related stuff.
*/
Tcl_DeleteCommandFromToken(butPtr->interp, butPtr->widgetCmd);
@@ -972,6 +975,9 @@ DestroyButton(butPtr)
if (butPtr->selectImage != NULL) {
Tk_FreeImage(butPtr->selectImage);
}
+ if (butPtr->tristateImage != NULL) {
+ Tk_FreeImage(butPtr->tristateImage);
+ }
if (butPtr->normalTextGC != None) {
Tk_FreeGC(butPtr->display, butPtr->normalTextGC);
}
@@ -1009,28 +1015,28 @@ DestroyButton(butPtr)
*
* ConfigureButton --
*
- * This procedure is called to process an objc/objv list to set
+ * This function 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 an error message is left in interp's result.
+ * The return value is a standard Tcl result. If TCL_ERROR is returned,
+ * then an error message is left in interp's result.
*
* Side effects:
- * Configuration information, such as text string, colors, font,
- * etc. get set for butPtr; old resources get freed, if there
- * were any. The button is redisplayed.
+ * Configuration information, such as text string, colors, font, etc. get
+ * set for butPtr; old resources get freed, if there were any. The button
+ * is redisplayed.
*
*----------------------------------------------------------------------
*/
static int
-ConfigureButton(interp, butPtr, objc, objv)
- Tcl_Interp *interp; /* Used for error reporting. */
- register TkButton *butPtr; /* Information about widget; may or may
+ConfigureButton(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ register TkButton *butPtr, /* Information about widget; may or may
* not already have values for some fields. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument values. */
{
Tk_SavedOptions savedOptions;
Tcl_Obj *errorResult = NULL;
@@ -1042,21 +1048,21 @@ ConfigureButton(interp, butPtr, objc, objv)
*/
if (butPtr->textVarNamePtr != NULL) {
- Tcl_UntraceVar(interp, Tcl_GetString(butPtr->textVarNamePtr),
+ Tcl_UntraceVar(interp, Tcl_GetString(butPtr->textVarNamePtr),
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonTextVarProc, (ClientData) butPtr);
}
if (butPtr->selVarNamePtr != NULL) {
- Tcl_UntraceVar(interp, Tcl_GetString(butPtr->selVarNamePtr),
+ Tcl_UntraceVar(interp, Tcl_GetString(butPtr->selVarNamePtr),
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonVarProc, (ClientData) butPtr);
}
/*
- * 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.
+ * 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.
*/
for (error = 0; error <= 1; error++) {
@@ -1067,7 +1073,7 @@ ConfigureButton(interp, butPtr, objc, objv)
if (Tk_SetOptions(interp, (char *) butPtr,
butPtr->optionTable, objc, objv,
- butPtr->tkwin, &savedOptions, (int *) NULL) != TCL_OK) {
+ butPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
continue;
}
} else {
@@ -1089,8 +1095,8 @@ ConfigureButton(interp, butPtr, objc, objv)
/*
* 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.
+ * background from a 3-D border, or filling in complicated defaults
+ * that couldn't be specified to Tk_SetOptions.
*/
if ((butPtr->state == STATE_ACTIVE)
@@ -1114,28 +1120,43 @@ ConfigureButton(interp, butPtr, objc, objv)
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.
+ * 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;
+ butPtr->flags &= ~TRISTATED;
if (valuePtr != NULL) {
- if (strcmp(Tcl_GetString(valuePtr),
- Tcl_GetString(butPtr->onValuePtr)) == 0) {
+ const char *value = Tcl_GetString(valuePtr);
+ if (strcmp(value, Tcl_GetString(butPtr->onValuePtr)) == 0) {
butPtr->flags |= SELECTED;
- }
+ } else if (strcmp(value,
+ Tcl_GetString(butPtr->tristateValuePtr)) == 0) {
+ butPtr->flags |= TRISTATED;
+
+ /*
+ * For checkbuttons if the tristate value is the
+ * same as the offvalue then prefer off to tristate
+ */
+
+ if (butPtr->offValuePtr
+ && strcmp(value,
+ Tcl_GetString(butPtr->offValuePtr)) == 0) {
+ butPtr->flags &= ~TRISTATED;
+ }
+ }
} else {
if (Tcl_ObjSetVar2(interp, namePtr, NULL,
(butPtr->type == TYPE_CHECK_BUTTON)
@@ -1146,8 +1167,8 @@ ConfigureButton(interp, butPtr, objc, objv)
}
/*
- * If a radiobutton has the empty string as value
- * it should be selected.
+ * If a radiobutton has the empty string as value it should be
+ * selected.
*/
if ((butPtr->type == TYPE_RADIO_BUTTON) &&
@@ -1158,11 +1179,11 @@ ConfigureButton(interp, butPtr, objc, objv)
}
/*
- * 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.
+ * 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->imagePtr != NULL) {
image = Tk_GetImage(butPtr->interp, butPtr->tkwin,
Tcl_GetString(butPtr->imagePtr), ButtonImageProc,
@@ -1191,6 +1212,20 @@ ConfigureButton(interp, butPtr, objc, objv)
Tk_FreeImage(butPtr->selectImage);
}
butPtr->selectImage = image;
+ if (butPtr->tristateImagePtr != NULL) {
+ image = Tk_GetImage(butPtr->interp, butPtr->tkwin,
+ Tcl_GetString(butPtr->tristateImagePtr),
+ ButtonTristateImageProc, (ClientData) butPtr);
+ if (image == NULL) {
+ continue;
+ }
+ } else {
+ image = NULL;
+ }
+ if (butPtr->tristateImage != NULL) {
+ Tk_FreeImage(butPtr->tristateImage);
+ }
+ butPtr->tristateImage = image;
haveImage = 0;
if (butPtr->imagePtr != NULL || butPtr->bitmap != None) {
@@ -1203,7 +1238,7 @@ ConfigureButton(interp, butPtr, objc, objv)
* 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;
@@ -1222,22 +1257,21 @@ ConfigureButton(interp, butPtr, objc, objv)
Tcl_IncrRefCount(butPtr->textPtr);
}
}
-
+
if ((butPtr->bitmap != None) || (butPtr->imagePtr != NULL)) {
/*
- * The button must display the contents of an image or
- * bitmap.
+ * The button must display the contents of an image or bitmap.
*/
if (Tk_GetPixelsFromObj(interp, butPtr->tkwin, butPtr->widthPtr,
&butPtr->width) != TCL_OK) {
- widthError:
+ widthError:
Tcl_AddErrorInfo(interp, "\n (processing -width option)");
continue;
}
if (Tk_GetPixelsFromObj(interp, butPtr->tkwin, butPtr->heightPtr,
&butPtr->height) != TCL_OK) {
- heightError:
+ heightError:
Tcl_AddErrorInfo(interp, "\n (processing -height option)");
continue;
}
@@ -1275,7 +1309,7 @@ ConfigureButton(interp, butPtr, objc, objv)
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonVarProc, (ClientData) butPtr);
}
-
+
TkButtonWorldChanged((ClientData) butPtr);
if (error) {
Tcl_SetObjResult(interp, errorResult);
@@ -1291,9 +1325,9 @@ ConfigureButton(interp, butPtr, objc, objv)
*
* TkButtonWorldChanged --
*
- * This procedure is called when the world has changed in some
- * way and the widget needs to recompute all its graphics contexts
- * and determine its new geometry.
+ * This function is called when the world has changed in some way and the
+ * widget needs to recompute all its graphics contexts and determine its
+ * new geometry.
*
* Results:
* None.
@@ -1303,10 +1337,10 @@ ConfigureButton(interp, butPtr, objc, objv)
*
*---------------------------------------------------------------------------
*/
-
+
void
-TkButtonWorldChanged(instanceData)
- ClientData instanceData; /* Information about widget. */
+TkButtonWorldChanged(
+ ClientData instanceData) /* Information about widget. */
{
XGCValues gcValues;
GC newGC;
@@ -1322,7 +1356,7 @@ TkButtonWorldChanged(instanceData)
gcValues.font = Tk_FontId(butPtr->tkfont);
gcValues.foreground = butPtr->normalFg->pixel;
gcValues.background = Tk_3DBorderColor(butPtr->normalBorder)->pixel;
-
+
/*
* Note: GraphicsExpose events are disabled in normalTextGC because it's
* used to copy stuff from an off-screen pixmap onto the screen (we know
@@ -1369,8 +1403,8 @@ TkButtonWorldChanged(instanceData)
}
/*
- * Allocate the disabled graphics context, for drawing text in
- * its disabled state.
+ * Allocate the disabled graphics context, for drawing text in its
+ * disabled state.
*/
mask = GCForeground | GCBackground | GCFont;
@@ -1406,31 +1440,31 @@ TkButtonWorldChanged(instanceData)
*
* ButtonEventProc --
*
- * This procedure is invoked by the Tk dispatcher for various
- * events on buttons.
+ * This function is invoked by the Tk dispatcher for various events on
+ * buttons.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up. When
+ * it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-ButtonEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- XEvent *eventPtr; /* Information about event. */
+ButtonEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
TkButton *butPtr = (TkButton *) clientData;
if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
goto redraw;
} else if (eventPtr->type == ConfigureNotify) {
/*
- * Must redraw after size changes, since layout could have changed
- * and borders will need to be redrawn.
+ * Must redraw after size changes, since layout could have changed and
+ * borders will need to be redrawn.
*/
goto redraw;
@@ -1453,7 +1487,7 @@ ButtonEventProc(clientData, eventPtr)
}
return;
- redraw:
+ redraw:
if ((butPtr->tkwin != NULL) && !(butPtr->flags & REDRAW_PENDING)) {
Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr);
butPtr->flags |= REDRAW_PENDING;
@@ -1465,9 +1499,9 @@ ButtonEventProc(clientData, eventPtr)
*
* ButtonCmdDeletedProc --
*
- * 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.
+ * This function 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.
@@ -1479,16 +1513,16 @@ ButtonEventProc(clientData, eventPtr)
*/
static void
-ButtonCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+ButtonCmdDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
TkButton *butPtr = (TkButton *) clientData;
/*
- * This procedure could be invoked either because the window was
- * 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.
+ * This function could be invoked either because the window was destroyed
+ * and the command was then deleted or because the command was deleted,
+ * and then this function destroys the widget. The BUTTON_DELETED flag
+ * distinguishes these cases.
*/
if (!(butPtr->flags & BUTTON_DELETED)) {
@@ -1501,14 +1535,14 @@ ButtonCmdDeletedProc(clientData)
*
* TkInvokeButton --
*
- * This procedure is called to carry out the actions associated
- * with a button, such as invoking a Tcl command or setting a
- * variable. This procedure is invoked, for example, when the
- * button is invoked via the mouse.
+ * This function is called to carry out the actions associated with a
+ * button, such as invoking a Tcl command or setting a variable. This
+ * function is invoked, for example, when the button is invoked via the
+ * mouse.
*
* Results:
- * A standard Tcl return value. Information is also left in
- * the interp's result.
+ * A standard Tcl return value. Information is also left in the interp's
+ * result.
*
* Side effects:
* Depends on the button and its associated command.
@@ -1517,8 +1551,8 @@ ButtonCmdDeletedProc(clientData)
*/
int
-TkInvokeButton(butPtr)
- TkButton *butPtr; /* Information about button. */
+TkInvokeButton(
+ TkButton *butPtr) /* Information about button. */
{
Tcl_Obj *namePtr = butPtr->selVarNamePtr;
@@ -1555,10 +1589,9 @@ TkInvokeButton(butPtr)
*
* ButtonVarProc --
*
- * This procedure is invoked when someone changes the
- * state variable associated with a radio button. Depending
- * on the new value of the button's variable, the button
- * may be selected or deselected.
+ * This function is invoked when someone changes the state variable
+ * associated with a radio button. Depending on the new value of the
+ * button's variable, the button may be selected or deselected.
*
* Results:
* NULL is always returned.
@@ -1571,12 +1604,12 @@ TkInvokeButton(butPtr)
/* ARGSUSED */
static char *
-ButtonVarProc(clientData, interp, name1, name2, flags)
- ClientData clientData; /* Information about button. */
- Tcl_Interp *interp; /* Interpreter containing variable. */
- CONST char *name1; /* Name of variable. */
- CONST char *name2; /* Second part of variable name. */
- int flags; /* Information about what happened. */
+ButtonVarProc(
+ ClientData clientData, /* Information about button. */
+ Tcl_Interp *interp, /* Interpreter containing variable. */
+ const char *name1, /* Name of variable. */
+ const char *name2, /* Second part of variable name. */
+ int flags) /* Information about what happened. */
{
register TkButton *butPtr = (TkButton *) clientData;
char *name, *value;
@@ -1585,12 +1618,13 @@ ButtonVarProc(clientData, interp, name1, name2, flags)
name = Tcl_GetString(butPtr->selVarNamePtr);
/*
- * If the variable is being unset, then just re-establish the
- * trace unless the whole interpreter is going away.
+ * If the variable is being unset, then just re-establish the trace unless
+ * the whole interpreter is going away.
*/
if (flags & TCL_TRACE_UNSETS) {
butPtr->flags &= ~SELECTED;
+ butPtr->flags &= ~TRISTATED;
if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {
Tcl_TraceVar(interp, name,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
@@ -1600,34 +1634,47 @@ ButtonVarProc(clientData, interp, name1, name2, flags)
}
/*
- * Use the value of the variable to update the selected status of
- * the button.
+ * Use the value of the variable to update the selected status of the
+ * button.
*/
valuePtr = Tcl_GetVar2Ex(interp, name, NULL, TCL_GLOBAL_ONLY);
if (valuePtr == NULL) {
- value = "";
+ value = Tcl_GetString(butPtr->tristateValuePtr);
} else {
value = Tcl_GetString(valuePtr);
}
if (strcmp(value, Tcl_GetString(butPtr->onValuePtr)) == 0) {
if (butPtr->flags & SELECTED) {
- return (char *) NULL;
+ return NULL;
}
butPtr->flags |= SELECTED;
- } else if (butPtr->flags & SELECTED) {
- butPtr->flags &= ~SELECTED;
+ butPtr->flags &= ~TRISTATED;
+ } else if (butPtr->offValuePtr
+ && strcmp(value, Tcl_GetString(butPtr->offValuePtr)) == 0) {
+ if (!(butPtr->flags & (SELECTED | TRISTATED))) {
+ return NULL;
+ }
+ butPtr->flags &= ~(SELECTED | TRISTATED);
+ } else if (strcmp(value, Tcl_GetString(butPtr->tristateValuePtr)) == 0) {
+ if (butPtr->flags & TRISTATED) {
+ return NULL;
+ }
+ butPtr->flags |= TRISTATED;
+ butPtr->flags &= ~SELECTED;
+ } else if (butPtr->flags & (SELECTED | TRISTATED)) {
+ butPtr->flags &= ~(SELECTED | TRISTATED);
} else {
- return (char *) NULL;
+ return NULL;
}
- redisplay:
+ redisplay:
if ((butPtr->tkwin != NULL) && Tk_IsMapped(butPtr->tkwin)
&& !(butPtr->flags & REDRAW_PENDING)) {
Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr);
butPtr->flags |= REDRAW_PENDING;
}
- return (char *) NULL;
+ return NULL;
}
/*
@@ -1635,52 +1682,51 @@ ButtonVarProc(clientData, interp, name1, name2, flags)
*
* ButtonTextVarProc --
*
- * This procedure is invoked when someone changes the variable
- * whose contents are to be displayed in a button.
+ * This function is invoked when someone changes the variable whose
+ * contents are to be displayed in a button.
*
* Results:
* NULL is always returned.
*
* Side effects:
- * The text displayed in the button will change to match the
- * variable.
+ * The text displayed in the button will change to match the variable.
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static char *
-ButtonTextVarProc(clientData, interp, name1, name2, flags)
- ClientData clientData; /* Information about button. */
- Tcl_Interp *interp; /* Interpreter containing variable. */
- CONST char *name1; /* Not used. */
- CONST char *name2; /* Not used. */
- int flags; /* Information about what happened. */
+ButtonTextVarProc(
+ ClientData clientData, /* Information about button. */
+ Tcl_Interp *interp, /* Interpreter containing variable. */
+ const char *name1, /* Not used. */
+ const char *name2, /* Not used. */
+ int flags) /* Information about what happened. */
{
TkButton *butPtr = (TkButton *) clientData;
char *name;
Tcl_Obj *valuePtr;
if (butPtr->flags & BUTTON_DELETED) {
- return (char *) NULL;
+ return NULL;
}
name = Tcl_GetString(butPtr->textVarNamePtr);
/*
- * If the variable is unset, then immediately recreate it unless
- * the whole interpreter is going away.
+ * If the variable is unset, then immediately recreate it unless the whole
+ * interpreter is going away.
*/
if (flags & TCL_TRACE_UNSETS) {
if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {
- Tcl_SetVar2Ex(interp, name, NULL, butPtr->textPtr,
+ Tcl_SetVar2Ex(interp, name, NULL, butPtr->textPtr,
TCL_GLOBAL_ONLY);
Tcl_TraceVar(interp, name,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonTextVarProc, clientData);
}
- return (char *) NULL;
+ return NULL;
}
valuePtr = Tcl_GetVar2Ex(interp, name, NULL, TCL_GLOBAL_ONLY);
@@ -1697,7 +1743,7 @@ ButtonTextVarProc(clientData, interp, name1, name2, flags)
Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr);
butPtr->flags |= REDRAW_PENDING;
}
- return (char *) NULL;
+ return NULL;
}
/*
@@ -1705,9 +1751,9 @@ 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 or contents
- * of an image displayed in a button.
+ * This function is invoked by the image code whenever the manager for an
+ * image does something that affects the size or contents of an image
+ * displayed in a button.
*
* Results:
* None.
@@ -1719,13 +1765,13 @@ ButtonTextVarProc(clientData, interp, name1, name2, flags)
*/
static void
-ButtonImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
- ClientData clientData; /* Pointer to widget record. */
- int x, y; /* Upper left pixel (within image)
- * that must be redisplayed. */
- int width, height; /* Dimensions of area to redisplay
- * (may be <= 0). */
- int imgWidth, imgHeight; /* New dimensions of image. */
+ButtonImageProc(
+ ClientData clientData, /* Pointer to widget record. */
+ int x, int y, /* Upper left pixel (within image) that must
+ * be redisplayed. */
+ int width, int height, /* Dimensions of area to redisplay (might be
+ * <= 0). */
+ int imgWidth, int imgHeight)/* New dimensions of image. */
{
register TkButton *butPtr = (TkButton *) clientData;
@@ -1743,9 +1789,9 @@ 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 or contents
- * of the image displayed in a button when it is selected.
+ * This function is invoked by the image code whenever the manager for an
+ * image does something that affects the size or contents of the image
+ * displayed in a button when it is selected.
*
* Results:
* None.
@@ -1757,18 +1803,18 @@ ButtonImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
*/
static void
-ButtonSelectImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
- ClientData clientData; /* Pointer to widget record. */
- int x, y; /* Upper left pixel (within image)
- * that must be redisplayed. */
- int width, height; /* Dimensions of area to redisplay
- * (may be <= 0). */
- int imgWidth, imgHeight; /* New dimensions of image. */
+ButtonSelectImageProc(
+ ClientData clientData, /* Pointer to widget record. */
+ int x, int y, /* Upper left pixel (within image) that must
+ * be redisplayed. */
+ int width, int height, /* Dimensions of area to redisplay (might be
+ * <= 0). */
+ int imgWidth, int imgHeight)/* New dimensions of image. */
{
register TkButton *butPtr = (TkButton *) clientData;
/*
- * Don't recompute geometry: it's controlled by the primary image.
+ * Don't recompute geometry: it's controlled by the primary image.
*/
if ((butPtr->flags & SELECTED) && (butPtr->tkwin != NULL)
@@ -1778,3 +1824,52 @@ ButtonSelectImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
butPtr->flags |= REDRAW_PENDING;
}
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ButtonTristateImageProc --
+ *
+ * This function is invoked by the image code whenever the manager for an
+ * image does something that affects the size or contents of the image
+ * displayed in a button when it is selected.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May arrange for the button to get redisplayed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ButtonTristateImageProc(
+ ClientData clientData, /* Pointer to widget record. */
+ int x, int y, /* Upper left pixel (within image) that must
+ * be redisplayed. */
+ int width, int height, /* Dimensions of area to redisplay (might be
+ * <= 0). */
+ int imgWidth, int imgHeight)/* New dimensions of image. */
+{
+ register TkButton *butPtr = (TkButton *) clientData;
+
+ /*
+ * Don't recompute geometry: it's controlled by the primary image.
+ */
+
+ if ((butPtr->flags & TRISTATED) && (butPtr->tkwin != NULL)
+ && Tk_IsMapped(butPtr->tkwin)
+ && !(butPtr->flags & REDRAW_PENDING)) {
+ Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr);
+ butPtr->flags |= REDRAW_PENDING;
+ }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkButton.h b/generic/tkButton.h
index 9547c9a..09aaee2 100644
--- a/generic/tkButton.h
+++ b/generic/tkButton.h
@@ -1,13 +1,13 @@
/*
* tkButton.h --
*
- * Declarations of types and functions used to implement
- * button-like widgets.
+ * Declarations of types and functions used to implement button-like
+ * widgets.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKBUTTON
@@ -17,11 +17,6 @@
#include "tkInt.h"
#endif
-#ifdef BUILD_tk
-# undef TCL_STORAGE_CLASS
-# define TCL_STORAGE_CLASS DLLEXPORT
-#endif
-
/*
* Legal values for the "compound" field of TkButton records.
*/
@@ -48,20 +43,20 @@ enum defaultState {
};
/*
- * A data structure of the following type is kept for each
- * widget managed by this file:
+ * A data structure of the following type is kept for each widget managed by
+ * this file:
*/
typedef struct {
- Tk_Window tkwin; /* Window that embodies the button. NULL
- * means that the window has been destroyed. */
- Display *display; /* Display containing widget. Needed to
- * free up resources after tkwin is gone. */
+ Tk_Window tkwin; /* Window that embodies the button. NULL means
+ * that the window has been destroyed. */
+ Display *display; /* Display containing widget. Needed to 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, such as TYPE_LABEL:
* restricts operations that may be performed
- * on widget. See below for legal values. */
+ * on widget. See below for legal values. */
Tk_OptionTable optionTable; /* Table that defines configuration options
* available for this widget. */
@@ -71,96 +66,102 @@ typedef struct {
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. */
+ int underline; /* Value of -underline option: specifies index
+ * of character to underline. < 0 means don't
+ * underline anything. */
Tcl_Obj *textVarNamePtr; /* Value of -textvariable option: specifies
- * name of variable or NULL. If non-NULL,
+ * name of variable or NULL. If non-NULL,
* button displays the contents of this
* variable. */
- Pixmap bitmap; /* Value of -bitmap option. If not None,
+ 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.*/
+ 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. */
+ * 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
+ * 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. */
+ * Tk_GetImage, or NULL if selectImagePtr is
+ * NULL. */
+ Tcl_Obj *tristateImagePtr; /* Value of -tristateimage option: specifies
+ * image to display in window when selected,
+ * or NULL if none. Ignored if imagePtr is
+ * NULL. */
+ Tk_Image tristateImage; /* Derived from tristateImagePtr by calling
+ * Tk_GetImage, or NULL if tristateImagePtr is
+ * NULL. */
/*
* Information used when displaying widget:
*/
- enum state state; /* Value of -state option: specifies
- * state of button for display purposes.*/
+ 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. */
+ 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. */
+ * borderWidthPtr. Always >= 0. */
int relief; /* Value of -relief option: specifies 3-d
* effect for border, such as
* TK_RELIEF_RAISED. */
- int overRelief; /* Value of -overrelief option: specifies a 3-d
- * effect for the border, such as
+ int overRelief; /* Value of -overrelief option: specifies a
+ * 3-d effect for the border, such as
* TK_RELIEF_RAISED, to be used when the mouse
* is over the button. */
int offRelief; /* Value of -offrelief option: specifies a 3-d
* effect for the border, such as
* TK_RELIEF_RAISED, to be used when a
- * checkbutton or radiobutton without
- * indicator is off */
+ * checkbutton or radiobutton without
+ * indicator is off. */
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. */
int highlightWidth; /* Integer value corresponding to
- * highlightWidthPtr. Always >= 0. */
+ * 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. */
+ 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; /* Value of -font option: specifies font
- * to use for display text. */
+ * Indicates how much interior stuff must be
+ * offset from outside edges to leave room for
+ * borders. */
+ 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. */
+ * 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
+ * foreground color when disabled. NULL means
+ * use normalFg with a 50% stipple instead. */
+ GC normalTextGC; /* GC for drawing text in normal mode. Also
* used to copy from off-screen pixmap onto
* screen. */
GC activeTextGC; /* GC for drawing text in active mode (NULL
* means use normalTextGC). */
GC disabledGC; /* Used to produce disabled effect for text
* and check/radio marks. */
- GC stippleGC; /* Used to produce disabled stipple effect
- * for images when disabled. */
+ GC stippleGC; /* Used to produce disabled stipple effect for
+ * images when disabled. */
Pixmap gray; /* Pixmap for displaying disabled text if
* disabledFg is NULL. */
GC copyGC; /* Used for copying information from an
@@ -169,33 +170,34 @@ typedef struct {
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. */
+ 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 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
+ * right of text. Ignored for bitmaps and
* images. */
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
+ * 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_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. */
+ * 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,
@@ -206,26 +208,28 @@ typedef struct {
int indicatorDiameter; /* Diameter of indicator, in pixels. */
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. */
+ * 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.
+ * For check and radio buttons, the fields below are used to manage the
+ * variable indicating the button's state.
*/
Tcl_Obj *selVarNamePtr; /* Value of -variable option: specifies name
- * of variable used to control selected
- * state of button. */
+ * 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. */
+ * to store in variable when this button isn't
+ * selected. Used only by checkbuttons. */
+ Tcl_Obj *tristateValuePtr; /* Value of -tristatevalue option: specifies
+ * value to display Tristate or Multivalue
+ * mode when variable matches this value.
+ * Used by check- buttons. */
/*
* Miscellaneous information:
@@ -233,31 +237,30 @@ typedef struct {
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
+ Tcl_Obj *takeFocusPtr; /* Value of -takefocus option; not used in the
+ * C code, but used by keyboard traversal
* 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 compound; /* Value of -compound option; specifies whether
- * the button should show both an image and
- * text, and, if so, how. */
- int repeatDelay; /* Value of -repeatdelay option; specifies
- * the number of ms after which the button will
+ 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 compound; /* Value of -compound option; specifies
+ * whether the button should show both an
+ * image and text, and, if so, how. */
+ int repeatDelay; /* Value of -repeatdelay option; specifies the
+ * number of ms after which the button will
* start to auto-repeat its command. */
int repeatInterval; /* Value of -repeatinterval option; specifies
* the number of ms between auto-repeat
* invocataions of the button command. */
- int flags; /* Various flags; see below for
+ int flags; /* Various flags; see below for
* definitions. */
} TkButton;
/*
- * Possible "type" values for buttons. These are the kinds of
- * widgets supported by this file. The ordering of the type
- * numbers is significant: greater means more features and is
- * used in the code.
+ * Possible "type" values for buttons. These are the kinds of widgets
+ * supported by this file. The ordering of the type numbers is significant:
+ * greater means more features and is used in the code.
*/
#define TYPE_LABEL 0
@@ -268,53 +271,52 @@ typedef struct {
/*
* Flag bits for buttons:
*
- * REDRAW_PENDING: Non-zero means a DoWhenIdle handler
- * has already been queued to redraw
- * this window.
- * SELECTED: Non-zero means this button is selected,
- * so special highlight should be drawn.
- * GOT_FOCUS: Non-zero means this button currently
- * has the input focus.
+ * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has
+ * already been queued to redraw this window.
+ * SELECTED: Non-zero means this button is selected, 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.
+ * deleted, or is in the process of being deleted
*/
#define REDRAW_PENDING (1 << 0)
#define SELECTED (1 << 1)
#define GOT_FOCUS (1 << 2)
#define BUTTON_DELETED (1 << 3)
+#define TRISTATED (1 << 4)
+
/*
* Declaration of button class functions structure
* and button/label defaults, for use in optionSpecs.
*/
-extern Tk_ClassProcs tkpButtonProcs;
-extern char tkDefButtonBorderWidth[TCL_INTEGER_SPACE];
+MODULE_SCOPE Tk_ClassProcs tkpButtonProcs;
+MODULE_SCOPE char tkDefButtonHighlightWidth[TCL_INTEGER_SPACE];
+MODULE_SCOPE char tkDefButtonPadx[TCL_INTEGER_SPACE];
+MODULE_SCOPE char tkDefButtonPady[TCL_INTEGER_SPACE];
+MODULE_SCOPE char tkDefButtonBorderWidth[TCL_INTEGER_SPACE];
+MODULE_SCOPE char tkDefLabelHighlightWidth[TCL_INTEGER_SPACE];
+MODULE_SCOPE char tkDefLabelPadx[TCL_INTEGER_SPACE];
+MODULE_SCOPE char tkDefLabelPady[TCL_INTEGER_SPACE];
/*
- * Declaration of procedures used in the implementation of the button
- * widget.
+ * Declaration of functions used in the implementation of the button widget.
*/
#ifndef TkpButtonSetDefaults
-EXTERN void TkpButtonSetDefaults _ANSI_ARGS_((
- Tk_OptionSpec *specPtr));
+MODULE_SCOPE void TkpButtonSetDefaults();
#endif
-EXTERN void TkButtonWorldChanged _ANSI_ARGS_((
- ClientData instanceData));
-EXTERN void TkpComputeButtonGeometry _ANSI_ARGS_((
- TkButton *butPtr));
-EXTERN TkButton * TkpCreateButton _ANSI_ARGS_((Tk_Window tkwin));
+MODULE_SCOPE void TkButtonWorldChanged(ClientData instanceData);
+MODULE_SCOPE void TkpComputeButtonGeometry(TkButton *butPtr);
+MODULE_SCOPE TkButton *TkpCreateButton(Tk_Window tkwin);
#ifndef TkpDestroyButton
-EXTERN void TkpDestroyButton _ANSI_ARGS_((TkButton *butPtr));
+MODULE_SCOPE void TkpDestroyButton(TkButton *butPtr);
#endif
#ifndef TkpDisplayButton
-EXTERN void TkpDisplayButton _ANSI_ARGS_((ClientData clientData));
+MODULE_SCOPE void TkpDisplayButton(ClientData clientData);
#endif
-EXTERN int TkInvokeButton _ANSI_ARGS_((TkButton *butPtr));
-
-# undef TCL_STORAGE_CLASS
-# define TCL_STORAGE_CLASS DLLIMPORT
+MODULE_SCOPE int TkInvokeButton(TkButton *butPtr);
#endif /* _TKBUTTON */
diff --git a/generic/tkCanvArc.c b/generic/tkCanvArc.c
index 9bee1ef..ecd57b8 100644
--- a/generic/tkCanvArc.c
+++ b/generic/tkCanvArc.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkCanvArc.c --
*
* This file implements arc items for canvas widgets.
@@ -6,14 +6,14 @@
* Copyright (c) 1992-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <stdio.h>
-#include "tkPort.h"
#include "tkInt.h"
#include "tkCanvas.h"
+
/*
* The structure below defines the record for each arc item.
*/
@@ -22,41 +22,42 @@ typedef enum {
PIESLICE_STYLE, CHORD_STYLE, ARC_STYLE
} Style;
-typedef struct ArcItem {
+typedef struct ArcItem {
Tk_Item header; /* Generic stuff that's the same for all
- * types. MUST BE FIRST IN STRUCTURE. */
+ * types. MUST BE FIRST IN STRUCTURE. */
Tk_Outline outline; /* Outline structure */
double bbox[4]; /* Coordinates (x1, y1, x2, y2) of bounding
* box for oval of which arc is a piece. */
double start; /* Angle at which arc begins, in degrees
* between 0 and 360. */
- double extent; /* Extent of arc (angular distance from
- * start to end of arc) in degrees between
- * -360 and 360. */
- double *outlinePtr; /* Points to (x,y) coordinates for points
- * that define one or two closed polygons
+ double extent; /* Extent of arc (angular distance from start
+ * to end of arc) in degrees between -360 and
+ * 360. */
+ double *outlinePtr; /* Points to (x,y) coordinates for points that
+ * define one or two closed polygons
* representing the portion of the outline
- * that isn't part of the arc (the V-shape
- * for a pie slice or a line-like segment
- * for a chord). Malloc'ed. */
- int numOutlinePoints; /* Number of points at outlinePtr. Zero
- * means no space allocated. */
+ * that isn't part of the arc (the V-shape for
+ * a pie slice or a line-like segment for a
+ * chord). Malloc'ed. */
+ int numOutlinePoints; /* Number of points at outlinePtr. Zero means
+ * no space allocated. */
Tk_TSOffset tsoffset;
XColor *fillColor; /* Color for filling arc (used for drawing
- * outline too when style is "arc"). NULL
+ * outline too when style is "arc"). NULL
* means don't fill arc. */
XColor *activeFillColor; /* Color for filling arc (used for drawing
* outline too when style is "arc" and state
- * is "active"). NULL means use fillColor. */
+ * is "active"). NULL means use fillColor. */
XColor *disabledFillColor; /* Color for filling arc (used for drawing
* outline too when style is "arc" and state
* is "disabled". NULL means use fillColor */
Pixmap fillStipple; /* Stipple bitmap for filling item. */
- Pixmap activeFillStipple; /* Stipple bitmap for filling item if state
- * is active. */
- Pixmap disabledFillStipple; /* Stipple bitmap for filling item if state
- * is disabled. */
- Style style; /* How to draw arc: arc, chord, or pieslice. */
+ Pixmap activeFillStipple; /* Stipple bitmap for filling item if state is
+ * active. */
+ Pixmap disabledFillStipple; /* Stipple bitmap for filling item if state is
+ * disabled. */
+ Style style; /* How to draw arc: arc, chord, or
+ * pieslice. */
GC fillGC; /* Graphics context for filling item. */
double center1[2]; /* Coordinates of center of arc outline at
* start (see ComputeArcOutline). */
@@ -65,8 +66,8 @@ typedef struct ArcItem {
} ArcItem;
/*
- * The definitions below define the sizes of the polygons used to
- * display outline information for various styles of arcs:
+ * The definitions below define the sizes of the polygons used to display
+ * outline information for various styles of arcs:
*/
#define CHORD_OUTLINE_PTS 7
@@ -77,14 +78,11 @@ typedef struct ArcItem {
* Information used for parsing configuration specs:
*/
-static int StyleParseProc _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp,
+static int StyleParseProc(ClientData clientData, Tcl_Interp *interp,
Tk_Window tkwin, CONST char *value,
- char *widgRec, int offset));
-static char * StylePrintProc _ANSI_ARGS_((
- ClientData clientData, Tk_Window tkwin,
- char *widgRec, int offset,
- Tcl_FreeProc **freeProcPtr));
+ char *widgRec, int offset);
+static char * StylePrintProc(ClientData clientData, Tk_Window tkwin,
+ char *widgRec, int offset, Tcl_FreeProc **freeProcPtr);
static Tk_CustomOption stateOption = {
(Tk_OptionParseProc *) TkStateParseProc,
@@ -112,169 +110,152 @@ static Tk_CustomOption pixelOption = {
};
static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_CUSTOM, "-activedash", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, outline.activeDash),
+ {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, outline.activeDash),
TK_CONFIG_NULL_OK, &dashOption},
- {TK_CONFIG_COLOR, "-activefill", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, activeFillColor),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_COLOR, "-activeoutline", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, outline.activeColor),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-activeoutlinestipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, outline.activeStipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-activestipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, activeFillStipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-activewidth", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, activeFillColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, outline.activeColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, outline.activeStipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, activeFillStipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
"0.0", Tk_Offset(ArcItem, outline.activeWidth),
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
- {TK_CONFIG_CUSTOM, "-dash", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, outline.dash),
+ {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, outline.dash),
TK_CONFIG_NULL_OK, &dashOption},
- {TK_CONFIG_PIXELS, "-dashoffset", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
"0", Tk_Offset(ArcItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_CUSTOM, "-disableddash", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, outline.disabledDash),
+ {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, outline.disabledDash),
TK_CONFIG_NULL_OK, &dashOption},
- {TK_CONFIG_COLOR, "-disabledfill", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, disabledFillColor),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_COLOR, "-disabledoutline", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, outline.disabledColor),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-disabledoutlinestipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, outline.disabledStipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-disabledstipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, disabledFillStipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-disabledwidth", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, disabledFillColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, outline.disabledColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, outline.disabledStipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, disabledFillStipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
"0.0", Tk_Offset(ArcItem, outline.disabledWidth),
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
- {TK_CONFIG_DOUBLE, "-extent", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_DOUBLE, "-extent", NULL, NULL,
"90", Tk_Offset(ArcItem, extent), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, fillColor), TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-offset", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_COLOR, "-fill", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, fillColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
"0,0", Tk_Offset(ArcItem, tsoffset),
TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
- {TK_CONFIG_COLOR, "-outline", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_COLOR, "-outline", NULL, NULL,
"black", Tk_Offset(ArcItem, outline.color), TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-outlineoffset", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
"0,0", Tk_Offset(ArcItem, outline.tsoffset),
TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
- {TK_CONFIG_BITMAP, "-outlinestipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, outline.stipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_DOUBLE, "-start", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, outline.stipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_DOUBLE, "-start", NULL, NULL,
"0", Tk_Offset(ArcItem, start), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
- &stateOption},
- {TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, fillStipple), TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-style", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ArcItem, style), TK_CONFIG_DONT_SET_DEFAULT,
+ {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
+ NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
+ {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, fillStipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-style", NULL, NULL,
+ NULL, Tk_Offset(ArcItem, style), TK_CONFIG_DONT_SET_DEFAULT,
&styleOption},
- {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
- {TK_CONFIG_CUSTOM, "-width", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
+ NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
+ {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
"1.0", Tk_Offset(ArcItem, outline.width), TK_CONFIG_DONT_SET_DEFAULT,
&pixelOption},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+ {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};
/*
- * Prototypes for procedures defined in this file:
+ * Prototypes for functions defined in this file:
*/
-static void ComputeArcBbox _ANSI_ARGS_((Tk_Canvas canvas,
- ArcItem *arcPtr));
-static int ConfigureArc _ANSI_ARGS_((Tcl_Interp *interp,
+static void ComputeArcBbox(Tk_Canvas canvas, ArcItem *arcPtr);
+static int ConfigureArc(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
- Tcl_Obj *CONST objv[], int flags));
-static int CreateArc _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *CONST objv[], int flags);
+static int CreateArc(Tcl_Interp *interp,
Tk_Canvas canvas, struct Tk_Item *itemPtr,
- int objc, Tcl_Obj *CONST objv[]));
-static void DeleteArc _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, Display *display));
-static void DisplayArc _ANSI_ARGS_((Tk_Canvas canvas,
+ int objc, Tcl_Obj *CONST objv[]);
+static void DeleteArc(Tk_Canvas canvas,
+ Tk_Item *itemPtr, Display *display);
+static void DisplayArc(Tk_Canvas canvas,
Tk_Item *itemPtr, Display *display, Drawable dst,
- int x, int y, int width, int height));
-static int ArcCoords _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
- Tcl_Obj *CONST objv[]));
-static int ArcToArea _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *rectPtr));
-static double ArcToPoint _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *coordPtr));
-static int ArcToPostscript _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));
-static void ScaleArc _ANSI_ARGS_((Tk_Canvas canvas,
+ int x, int y, int width, int height);
+static int ArcCoords(Tcl_Interp *interp, Tk_Canvas canvas,
+ Tk_Item *itemPtr, int objc, Tcl_Obj *CONST objv[]);
+static int ArcToArea(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double *rectPtr);
+static double ArcToPoint(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double *coordPtr);
+static int ArcToPostscript(Tcl_Interp *interp,
+ Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
+static void ScaleArc(Tk_Canvas canvas,
Tk_Item *itemPtr, double originX, double originY,
- double scaleX, double scaleY));
-static void TranslateArc _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double deltaX, double deltaY));
-static int AngleInRange _ANSI_ARGS_((double x, double y,
- double start, double extent));
-static void ComputeArcOutline _ANSI_ARGS_((Tk_Canvas canvas,
- ArcItem *arcPtr));
-static int HorizLineToArc _ANSI_ARGS_((double x1, double x2,
+ double scaleX, double scaleY);
+static void TranslateArc(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double deltaX, double deltaY);
+static int AngleInRange(double x, double y,
+ double start, double extent);
+static void ComputeArcOutline(Tk_Canvas canvas, ArcItem *arcPtr);
+static int HorizLineToArc(double x1, double x2,
double y, double rx, double ry,
- double start, double extent));
-static int VertLineToArc _ANSI_ARGS_((double x, double y1,
+ double start, double extent);
+static int VertLineToArc(double x, double y1,
double y2, double rx, double ry,
- double start, double extent));
+ double start, double extent);
/*
- * The structures below defines the arc item types by means of procedures
- * that can be invoked by generic item code.
+ * The structures below defines the arc item types by means of functions that
+ * can be invoked by generic item code.
*/
Tk_ItemType tkArcType = {
- "arc", /* name */
- sizeof(ArcItem), /* itemSize */
- CreateArc, /* createProc */
- configSpecs, /* configSpecs */
- ConfigureArc, /* configureProc */
- ArcCoords, /* coordProc */
- DeleteArc, /* deleteProc */
- DisplayArc, /* displayProc */
- TK_CONFIG_OBJS, /* flags */
- ArcToPoint, /* pointProc */
- ArcToArea, /* areaProc */
- ArcToPostscript, /* postscriptProc */
- ScaleArc, /* scaleProc */
- TranslateArc, /* translateProc */
- (Tk_ItemIndexProc *) NULL, /* indexProc */
- (Tk_ItemCursorProc *) NULL, /* icursorProc */
- (Tk_ItemSelectionProc *) NULL, /* selectionProc */
- (Tk_ItemInsertProc *) NULL, /* insertProc */
- (Tk_ItemDCharsProc *) NULL, /* dTextProc */
- (Tk_ItemType *) NULL, /* nextPtr */
+ "arc", /* name */
+ sizeof(ArcItem), /* itemSize */
+ CreateArc, /* createProc */
+ configSpecs, /* configSpecs */
+ ConfigureArc, /* configureProc */
+ ArcCoords, /* coordProc */
+ DeleteArc, /* deleteProc */
+ DisplayArc, /* displayProc */
+ TK_CONFIG_OBJS, /* flags */
+ ArcToPoint, /* pointProc */
+ ArcToArea, /* areaProc */
+ ArcToPostscript, /* postscriptProc */
+ ScaleArc, /* scaleProc */
+ TranslateArc, /* translateProc */
+ NULL, /* indexProc */
+ NULL, /* icursorProc */
+ NULL, /* selectionProc */
+ NULL, /* insertProc */
+ NULL, /* dTextProc */
+ NULL, /* nextPtr */
};
#ifndef PI
-# define PI 3.14159265358979323846
+#define PI 3.14159265358979323846
#endif
-
/*
*--------------------------------------------------------------
*
* CreateArc --
*
- * This procedure is invoked to create a new arc item in
- * a canvas.
+ * This function is invoked to create a new arc item in a canvas.
*
* Results:
- * A standard Tcl return value. If an error occurred in
- * creating the item, then an error message is left in
- * the interp's result; in this case itemPtr is
- * left uninitialized, so it can be safely freed by the
+ * A standard Tcl return value. If an error occurred in creating the
+ * item, then an error message is left in the interp's result; in this
+ * case itemPtr is left uninitialized, so it can be safely freed by the
* caller.
*
* Side effects:
@@ -284,24 +265,24 @@ Tk_ItemType tkArcType = {
*/
static int
-CreateArc(interp, canvas, itemPtr, objc, objv)
- 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 objc; /* Number of arguments in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing arc. */
+CreateArc(
+ 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 objc, /* Number of arguments in objv. */
+ Tcl_Obj *CONST objv[]) /* Arguments describing arc. */
{
ArcItem *arcPtr = (ArcItem *) itemPtr;
int i;
if (objc == 0) {
- panic("canvas did not pass any coords\n");
+ Tcl_Panic("canvas did not pass any coords\n");
}
/*
- * 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 function.
*/
Tk_CreateOutline(&(arcPtr->outline));
@@ -327,6 +308,7 @@ CreateArc(interp, canvas, itemPtr, objc, objv)
for (i = 1; i < objc; i++) {
char *arg = Tcl_GetString(objv[i]);
+
if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
break;
}
@@ -337,7 +319,8 @@ CreateArc(interp, canvas, itemPtr, objc, objv)
if (ConfigureArc(interp, canvas, itemPtr, objc-i, objv+i, 0) == TCL_OK) {
return TCL_OK;
}
- error:
+
+ error:
DeleteArc(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
return TCL_ERROR;
}
@@ -347,9 +330,8 @@ CreateArc(interp, canvas, itemPtr, objc, objv)
*
* ArcCoords --
*
- * This procedure is invoked to process the "coords" widget
- * command on arcs. See the user documentation for details
- * on what it does.
+ * This function is invoked to process the "coords" widget command on
+ * arcs. See the user documentation for details on what it does.
*
* Results:
* Returns TCL_OK or TCL_ERROR, and sets the interp's result.
@@ -361,21 +343,20 @@ CreateArc(interp, canvas, itemPtr, objc, objv)
*/
static int
-ArcCoords(interp, canvas, itemPtr, objc, objv)
- 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 objc; /* Number of coordinates supplied in
- * objv. */
- Tcl_Obj *CONST objv[]; /* Array of coordinates: x1, y1,
- * x2, y2, ... */
+ArcCoords(
+ 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 objc, /* Number of coordinates supplied in objv. */
+ Tcl_Obj *CONST objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */
{
ArcItem *arcPtr = (ArcItem *) itemPtr;
if (objc == 0) {
Tcl_Obj *obj = Tcl_NewObj();
Tcl_Obj *subobj = Tcl_NewDoubleObj(arcPtr->bbox[0]);
+
Tcl_ListObjAppendElement(interp, obj, subobj);
subobj = Tcl_NewDoubleObj(arcPtr->bbox[1]);
Tcl_ListObjAppendElement(interp, obj, subobj);
@@ -391,7 +372,7 @@ ArcCoords(interp, canvas, itemPtr, objc, objv)
return TCL_ERROR;
} else if (objc != 4) {
char buf[64 + TCL_INTEGER_SPACE];
-
+
sprintf(buf, "wrong # coordinates: expected 4, got %d", objc);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_ERROR;
@@ -410,7 +391,7 @@ ArcCoords(interp, canvas, itemPtr, objc, objv)
ComputeArcBbox(canvas, arcPtr);
} else {
char buf[64 + TCL_INTEGER_SPACE];
-
+
sprintf(buf, "wrong # coordinates: expected 0 or 4, got %d", objc);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_ERROR;
@@ -423,28 +404,28 @@ ArcCoords(interp, canvas, itemPtr, objc, objv)
*
* ConfigureArc --
*
- * This procedure is invoked to configure various aspects
- * of a arc item, such as its outline and fill colors.
+ * This function is invoked to configure various aspects of a arc item,
+ * such as its outline and fill colors.
*
* Results:
- * A standard Tcl result code. If an error occurs, then
- * an error message is left in the interp's result.
+ * A standard Tcl result code. If an error occurs, then an error message
+ * is left in the interp's result.
*
* Side effects:
- * Configuration information, such as colors and stipple
- * patterns, may be set for itemPtr.
+ * Configuration information, such as colors and stipple patterns, may be
+ * set for itemPtr.
*
*--------------------------------------------------------------
*/
static int
-ConfigureArc(interp, canvas, itemPtr, objc, objv, flags)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Canvas canvas; /* Canvas containing itemPtr. */
- Tk_Item *itemPtr; /* Arc item to reconfigure. */
- int objc; /* Number of elements in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing things to configure. */
- int flags; /* Flags to pass to Tk_ConfigureWidget. */
+ConfigureArc(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_Canvas canvas, /* Canvas containing itemPtr. */
+ Tk_Item *itemPtr, /* Arc item to reconfigure. */
+ int objc, /* Number of elements in objv. */
+ Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */
+ int flags) /* Flags to pass to Tk_ConfigureWidget. */
{
ArcItem *arcPtr = (ArcItem *) itemPtr;
XGCValues gcValues;
@@ -466,8 +447,8 @@ ConfigureArc(interp, canvas, itemPtr, objc, objv, flags)
state = itemPtr->state;
/*
- * A few of the options require additional processing, such as
- * style and graphics contexts.
+ * A few of the options require additional processing, such as style and
+ * graphics contexts.
*/
if (arcPtr->outline.activeWidth > arcPtr->outline.width ||
@@ -506,8 +487,7 @@ ConfigureArc(interp, canvas, itemPtr, objc, objv, flags)
i = (int) (arcPtr->extent/360.0);
arcPtr->extent -= i*360.0;
- mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr,
- &(arcPtr->outline));
+ mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &(arcPtr->outline));
if (mask) {
gcValues.cap_style = CapButt;
mask |= GCCapStyle;
@@ -596,8 +576,8 @@ ConfigureArc(interp, canvas, itemPtr, objc, objv, flags)
*
* DeleteArc --
*
- * This procedure is called to clean up the data structure
- * associated with a arc item.
+ * This function is called to clean up the data structure associated with
+ * an arc item.
*
* Results:
* None.
@@ -609,11 +589,10 @@ ConfigureArc(interp, canvas, itemPtr, objc, objv, flags)
*/
static void
-DeleteArc(canvas, itemPtr, display)
- Tk_Canvas canvas; /* Info about overall canvas. */
- Tk_Item *itemPtr; /* Item that is being deleted. */
- Display *display; /* Display containing window for
- * canvas. */
+DeleteArc(
+ Tk_Canvas canvas, /* Info about overall canvas. */
+ Tk_Item *itemPtr, /* Item that is being deleted. */
+ Display *display) /* Display containing window for canvas. */
{
ArcItem *arcPtr = (ArcItem *) itemPtr;
@@ -649,31 +628,29 @@ DeleteArc(canvas, itemPtr, display)
*
* ComputeArcBbox --
*
- * This procedure is invoked to compute the bounding box of
- * all the pixels that may be drawn as part of an arc.
+ * This function is invoked to compute the bounding box of all the pixels
+ * that may be drawn as part of an arc.
*
* Results:
* None.
*
* Side effects:
- * The fields x1, y1, x2, and y2 are updated in the header
- * for itemPtr.
+ * The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static void
-ComputeArcBbox(canvas, arcPtr)
- Tk_Canvas canvas; /* Canvas that contains item. */
- ArcItem *arcPtr; /* Item whose bbox is to be
- * recomputed. */
+ComputeArcBbox(
+ Tk_Canvas canvas, /* Canvas that contains item. */
+ ArcItem *arcPtr) /* Item whose bbox is to be recomputed. */
{
double tmp, center[2], point[2];
double width;
Tk_State state = arcPtr->header.state;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
@@ -700,14 +677,14 @@ ComputeArcBbox(canvas, arcPtr)
*/
if (arcPtr->bbox[1] > arcPtr->bbox[3]) {
- double tmp;
- tmp = arcPtr->bbox[3];
+ double tmp = arcPtr->bbox[3];
+
arcPtr->bbox[3] = arcPtr->bbox[1];
arcPtr->bbox[1] = tmp;
}
if (arcPtr->bbox[0] > arcPtr->bbox[2]) {
- double tmp;
- tmp = arcPtr->bbox[2];
+ double tmp = arcPtr->bbox[2];
+
arcPtr->bbox[2] = arcPtr->bbox[0];
arcPtr->bbox[0] = tmp;
}
@@ -715,10 +692,10 @@ ComputeArcBbox(canvas, arcPtr)
ComputeArcOutline(canvas,arcPtr);
/*
- * To compute the bounding box, start with the the bbox formed
- * by the two endpoints of the arc. Then add in the center of
- * the arc's oval (if relevant) and the 3-o'clock, 6-o'clock,
- * 9-o'clock, and 12-o'clock positions, if they are relevant.
+ * To compute the bounding box, start with the the bbox formed by the two
+ * endpoints of the arc. Then add in the center of the arc's oval (if
+ * relevant) and the 3-o'clock, 6-o'clock, 9-o'clock, and 12-o'clock
+ * positions, if they are relevant.
*/
arcPtr->header.x1 = arcPtr->header.x2 = (int) arcPtr->center1[0];
@@ -768,8 +745,8 @@ ComputeArcBbox(canvas, arcPtr)
}
/*
- * Lastly, expand by the width of the arc (if the arc's outline is
- * being drawn) and add one extra pixel just for safety.
+ * Lastly, expand by the width of the arc (if the arc's outline is being
+ * drawn) and add one extra pixel just for safety.
*/
if (arcPtr->outline.gc == None) {
@@ -788,28 +765,26 @@ ComputeArcBbox(canvas, arcPtr)
*
* DisplayArc --
*
- * This procedure is invoked to draw an arc item in a given
- * drawable.
+ * This function is invoked to draw an arc item in a given drawable.
*
* Results:
* None.
*
* Side effects:
- * ItemPtr is drawn in drawable using the transformation
- * information in canvas.
+ * ItemPtr is drawn in drawable using the transformation information in
+ * canvas.
*
*--------------------------------------------------------------
*/
static void
-DisplayArc(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). */
+DisplayArc(
+ 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, int y, /* Describes region of canvas that must be */
+ int width, int height) /* redisplayed (not used). */
{
ArcItem *arcPtr = (ArcItem *) itemPtr;
short x1, y1, x2, y2;
@@ -818,7 +793,7 @@ DisplayArc(canvas, itemPtr, display, drawable, x, y, width, height)
Tk_State state = itemPtr->state;
Pixmap stipple;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
lineWidth = arcPtr->outline.width;
@@ -837,7 +812,7 @@ DisplayArc(canvas, itemPtr, display, drawable, x, y, width, height)
if (arcPtr->activeFillStipple != None) {
stipple = arcPtr->activeFillStipple;
}
- } else if (state==TK_STATE_DISABLED) {
+ } else if (state == TK_STATE_DISABLED) {
if (arcPtr->outline.disabledWidth > 0) {
lineWidth = arcPtr->outline.disabledWidth;
}
@@ -850,8 +825,8 @@ DisplayArc(canvas, itemPtr, display, drawable, x, y, width, height)
}
/*
- * Compute the screen coordinates of the bounding box for the item,
- * plus integer values for the angles.
+ * Compute the screen coordinates of the bounding box for the item, plus
+ * integer values for the angles.
*/
Tk_CanvasDrawableCoords(canvas, arcPtr->bbox[0], arcPtr->bbox[1],
@@ -868,16 +843,18 @@ DisplayArc(canvas, itemPtr, display, drawable, x, y, width, height)
extent = (int) ((64*arcPtr->extent) + 0.5);
/*
- * Display filled arc first (if wanted), then outline. If the extent
- * is zero then don't invoke XFillArc or XDrawArc, since this causes
- * some window servers to crash and should be a no-op anyway.
+ * Display filled arc first (if wanted), then outline. If the extent is
+ * zero then don't invoke XFillArc or XDrawArc, since this causes some
+ * window servers to crash and should be a no-op anyway.
*/
if ((arcPtr->fillGC != None) && (extent != 0)) {
if (stipple != None) {
- int w=0; int h=0;
+ int w = 0;
+ int h = 0;
Tk_TSOffset *tsoffset = &arcPtr->tsoffset;
int flags = tsoffset->flags;
+
if (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE)) {
Tk_SizeOfBitmap(display, stipple, &w, &h);
if (flags & TK_OFFSET_CENTER) {
@@ -914,10 +891,10 @@ DisplayArc(canvas, itemPtr, display, drawable, x, y, width, height)
}
/*
- * If the outline width is very thin, don't use polygons to draw
- * the linear parts of the outline (this often results in nothing
- * being displayed); just draw lines instead. The same is done if
- * the outline is dashed, because then polygons don't work.
+ * If the outline width is very thin, don't use polygons to draw the
+ * linear parts of the outline (this often results in nothing being
+ * displayed); just draw lines instead. The same is done if the
+ * outline is dashed, because then polygons don't work.
*/
if (lineWidth < 1.5 || dashnumber != 0) {
@@ -948,8 +925,8 @@ DisplayArc(canvas, itemPtr, display, drawable, x, y, width, height)
TkFillPolygon(canvas, arcPtr->outlinePtr, PIE_OUTLINE1_PTS,
display, drawable, arcPtr->outline.gc, None);
TkFillPolygon(canvas, arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
- PIE_OUTLINE2_PTS, display, drawable, arcPtr->outline.gc,
- None);
+ PIE_OUTLINE2_PTS, display, drawable,
+ arcPtr->outline.gc, None);
}
}
@@ -962,17 +939,16 @@ DisplayArc(canvas, itemPtr, display, drawable, x, y, width, height)
*
* ArcToPoint --
*
- * Computes the distance from a given point to a given
- * arc, in canvas units.
+ * Computes the distance from a given point to a given arc, in canvas
+ * units.
*
* Results:
- * The return value is 0 if the point whose x and y coordinates
- * are coordPtr[0] and coordPtr[1] is inside the arc. If the
- * point isn't inside the arc then the return value is the
- * distance from the point to the arc. If itemPtr is filled,
- * then anywhere in the interior is considered "inside"; if
- * itemPtr isn't filled, then "inside" means only the area
- * occupied by the outline.
+ * The return value is 0 if the point whose x and y coordinates are
+ * coordPtr[0] and coordPtr[1] is inside the arc. If the point isn't
+ * inside the arc then the return value is the distance from the point to
+ * the arc. If itemPtr is filled, then anywhere in the interior is
+ * considered "inside"; if itemPtr isn't filled, then "inside" means only
+ * the area occupied by the outline.
*
* Side effects:
* None.
@@ -982,10 +958,10 @@ DisplayArc(canvas, itemPtr, display, drawable, x, y, width, height)
/* ARGSUSED */
static double
-ArcToPoint(canvas, itemPtr, pointPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against point. */
- double *pointPtr; /* Pointer to x and y coordinates. */
+ArcToPoint(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against point. */
+ double *pointPtr) /* Pointer to x and y coordinates. */
{
ArcItem *arcPtr = (ArcItem *) itemPtr;
double vertex[2], pointAngle, diff, dist, newDist;
@@ -993,7 +969,7 @@ ArcToPoint(canvas, itemPtr, pointPtr)
int filled, angleInRange;
Tk_State state = itemPtr->state;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
@@ -1009,10 +985,9 @@ ArcToPoint(canvas, itemPtr, pointPtr)
}
/*
- * See if the point is within the angular range of the arc.
- * Remember, X angles are backwards from the way we'd normally
- * think of them. Also, compensate for any eccentricity of
- * the oval.
+ * See if the point is within the angular range of the arc. Remember, X
+ * angles are backwards from the way we'd normally think of them. Also,
+ * compensate for any eccentricity of the oval.
*/
vertex[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2.0;
@@ -1039,14 +1014,13 @@ ArcToPoint(canvas, itemPtr, pointPtr)
((arcPtr->extent < 0) && ((diff - 360.0) >= arcPtr->extent));
/*
- * Now perform different tests depending on what kind of arc
- * we're dealing with.
+ * Now perform different tests depending on what kind of arc we're dealing
+ * with.
*/
if (arcPtr->style == ARC_STYLE) {
if (angleInRange) {
- return TkOvalToPoint(arcPtr->bbox, width,
- 0, pointPtr);
+ return TkOvalToPoint(arcPtr->bbox, width, 0, pointPtr);
}
dist = hypot(pointPtr[0] - arcPtr->center1[0],
pointPtr[1] - arcPtr->center1[1]);
@@ -1072,7 +1046,7 @@ ArcToPoint(canvas, itemPtr, pointPtr)
dist = TkPolygonToPoint(arcPtr->outlinePtr, PIE_OUTLINE1_PTS,
pointPtr);
newDist = TkPolygonToPoint(arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
- PIE_OUTLINE2_PTS, pointPtr);
+ PIE_OUTLINE2_PTS, pointPtr);
} else {
dist = TkLineToPoint(vertex, arcPtr->center1, pointPtr);
newDist = TkLineToPoint(vertex, arcPtr->center2, pointPtr);
@@ -1090,17 +1064,16 @@ ArcToPoint(canvas, itemPtr, pointPtr)
}
/*
- * This is a chord-style arc. We have to deal specially with the
- * triangular piece that represents the difference between a
- * chord-style arc and a pie-slice arc (for small angles this piece
- * is excluded here where it would be included for pie slices;
- * for large angles the piece is included here but would be
- * excluded for pie slices).
+ * This is a chord-style arc. We have to deal specially with the
+ * triangular piece that represents the difference between a chord-style
+ * arc and a pie-slice arc (for small angles this piece is excluded here
+ * where it would be included for pie slices; for large angles the piece
+ * is included here but would be excluded for pie slices).
*/
if (width > 1.0) {
dist = TkPolygonToPoint(arcPtr->outlinePtr, CHORD_OUTLINE_PTS,
- pointPtr);
+ pointPtr);
} else {
dist = TkLineToPoint(arcPtr->center1, arcPtr->center2, pointPtr);
}
@@ -1134,14 +1107,13 @@ ArcToPoint(canvas, itemPtr, pointPtr)
*
* ArcToArea --
*
- * This procedure is called to determine whether an item
- * lies entirely inside, entirely outside, or overlapping
- * a given area.
+ * This function is called to determine whether an item lies entirely
+ * inside, entirely outside, or overlapping a given area.
*
* Results:
- * -1 is returned if the item is entirely outside the area
- * given by rectPtr, 0 if it overlaps, and 1 if it is entirely
- * inside the given area.
+ * -1 is returned if the item is entirely outside the area given by
+ * rectPtr, 0 if it overlaps, and 1 if it is entirely inside the given
+ * area.
*
* Side effects:
* None.
@@ -1151,26 +1123,25 @@ ArcToPoint(canvas, itemPtr, pointPtr)
/* ARGSUSED */
static int
-ArcToArea(canvas, itemPtr, rectPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against arc. */
- double *rectPtr; /* Pointer to array of four coordinates
- * (x1, y1, x2, y2) describing rectangular
- * area. */
+ArcToArea(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against arc. */
+ double *rectPtr) /* Pointer to array of four coordinates (x1,
+ * y1, x2, y2) describing rectangular area. */
{
ArcItem *arcPtr = (ArcItem *) itemPtr;
- double rx, ry; /* Radii for transformed oval: these define
- * an oval centered at the origin. */
- double tRect[4]; /* Transformed version of x1, y1, x2, y2,
- * for coord. system where arc is centered
- * on the origin. */
+ double rx, ry; /* Radii for transformed oval: these define an
+ * oval centered at the origin. */
+ double tRect[4]; /* Transformed version of x1, y1, x2, y2, for
+ * coord. system where arc is centered on the
+ * origin. */
double center[2], width, angle, tmp;
double points[20], *pointPtr;
int numPoints, filled;
int inside; /* Non-zero means every test so far suggests
- * that arc is inside rectangle. 0 means
- * every test so far shows arc to be outside
- * of rectangle. */
+ * that arc is inside rectangle. 0 means every
+ * test so far shows arc to be outside of
+ * rectangle. */
int newInside;
Tk_State state = itemPtr->state;
@@ -1182,7 +1153,7 @@ ArcToArea(canvas, itemPtr, rectPtr)
if (arcPtr->outline.activeWidth>width) {
width = (double) arcPtr->outline.activeWidth;
}
- } else if (state==TK_STATE_DISABLED) {
+ } else if (state == TK_STATE_DISABLED) {
if (arcPtr->outline.disabledWidth>0) {
width = (double) arcPtr->outline.disabledWidth;
}
@@ -1198,8 +1169,8 @@ ArcToArea(canvas, itemPtr, rectPtr)
}
/*
- * Transform both the arc and the rectangle so that the arc's oval
- * is centered on the origin.
+ * Transform both the arc and the rectangle so that the arc's oval is
+ * centered on the origin.
*/
center[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2.0;
@@ -1212,17 +1183,16 @@ ArcToArea(canvas, itemPtr, rectPtr)
ry = arcPtr->bbox[3] - center[1] + width/2.0;
/*
- * Find the extreme points of the arc and see whether these are all
- * inside the rectangle (in which case we're done), partly in and
- * partly out (in which case we're done), or all outside (in which
- * case we have more work to do). The extreme points include the
- * following, which are checked in order:
+ * Find the extreme points of the arc and see whether these are all inside
+ * the rectangle (in which case we're done), partly in and partly out (in
+ * which case we're done), or all outside (in which case we have more work
+ * to do). The extreme points include the following, which are checked in
+ * order:
*
- * 1. The outside points of the arc, corresponding to start and
- * extent.
+ * 1. The outside points of the arc, corresponding to start and extent.
* 2. The center of the arc (but only in pie-slice mode).
- * 3. The 12, 3, 6, and 9-o'clock positions (but only if the arc
- * includes those angles).
+ * 3. The 12, 3, 6, and 9-o'clock positions (but only if the arc includes
+ * those angles).
*/
pointPtr = points;
@@ -1283,8 +1253,8 @@ ArcToArea(canvas, itemPtr, rectPtr)
}
/*
- * Now that we've located the extreme points, loop through them all
- * to see which are inside the rectangle.
+ * Now that we've located the extreme points, loop through them all to see
+ * which are inside the rectangle.
*/
inside = (points[0] > tRect[0]) && (points[0] < tRect[2])
@@ -1302,17 +1272,17 @@ ArcToArea(canvas, itemPtr, rectPtr)
}
/*
- * So far, oval appears to be outside rectangle, but can't yet tell
- * for sure. Next, test each of the four sides of the rectangle
- * against the bounding region for the arc. If any intersections
- * are found, then return "overlapping". First, test against the
- * polygon(s) forming the sides of a chord or pie-slice.
+ * So far, oval appears to be outside rectangle, but can't yet tell for
+ * sure. Next, test each of the four sides of the rectangle against the
+ * bounding region for the arc. If any intersections are found, then
+ * return "overlapping". First, test against the polygon(s) forming the
+ * sides of a chord or pie-slice.
*/
if (arcPtr->style == PIESLICE_STYLE) {
if (width >= 1.0) {
if (TkPolygonToArea(arcPtr->outlinePtr, PIE_OUTLINE1_PTS,
- rectPtr) != -1) {
+ rectPtr) != -1) {
return 0;
}
if (TkPolygonToArea(arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
@@ -1340,9 +1310,9 @@ ArcToArea(canvas, itemPtr, rectPtr)
}
/*
- * Next check for overlap between each of the four sides and the
- * outer perimiter of the arc. If the arc isn't filled, then also
- * check the inner perimeter of the arc.
+ * Next check for overlap between each of the four sides and the outer
+ * perimiter of the arc. If the arc isn't filled, then also check the
+ * inner perimeter of the arc.
*/
if (HorizLineToArc(tRect[0], tRect[2], tRect[1], rx, ry, arcPtr->start,
@@ -1371,11 +1341,11 @@ ArcToArea(canvas, itemPtr, rectPtr)
}
/*
- * The arc still appears to be totally disjoint from the rectangle,
- * but it's also possible that the rectangle is totally inside the arc.
- * Do one last check, which is to check one point of the rectangle
- * to see if it's inside the arc. If it is, we've got overlap. If
- * it isn't, the arc's really outside the rectangle.
+ * The arc still appears to be totally disjoint from the rectangle, but
+ * it's also possible that the rectangle is totally inside the arc. Do one
+ * last check, which is to check one point of the rectangle to see if it's
+ * inside the arc. If it is, we've got overlap. If it isn't, the arc's
+ * really outside the rectangle.
*/
if (ArcToPoint(canvas, itemPtr, rectPtr) == 0.0) {
@@ -1389,15 +1359,14 @@ ArcToArea(canvas, itemPtr, rectPtr)
*
* ScaleArc --
*
- * This procedure is invoked to rescale an arc item.
+ * This function is invoked to rescale an arc item.
*
* Results:
* None.
*
* Side effects:
- * The arc referred to by itemPtr is rescaled so that the
- * following transformation is applied to all point
- * coordinates:
+ * The arc referred to by itemPtr is rescaled so that the following
+ * transformation is applied to all point coordinates:
* x' = originX + scaleX*(x-originX)
* y' = originY + scaleY*(y-originY)
*
@@ -1405,12 +1374,13 @@ ArcToArea(canvas, itemPtr, rectPtr)
*/
static void
-ScaleArc(canvas, itemPtr, originX, originY, scaleX, scaleY)
- Tk_Canvas canvas; /* Canvas containing arc. */
- Tk_Item *itemPtr; /* Arc 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. */
+ScaleArc(
+ Tk_Canvas canvas, /* Canvas containing arc. */
+ Tk_Item *itemPtr, /* Arc to be scaled. */
+ double originX, /* Origin about which to scale rect. */
+ double originY,
+ double scaleX, /* Amount to scale in X direction. */
+ double scaleY) /* Amount to scale in Y direction. */
{
ArcItem *arcPtr = (ArcItem *) itemPtr;
@@ -1426,25 +1396,24 @@ ScaleArc(canvas, itemPtr, originX, originY, scaleX, scaleY)
*
* TranslateArc --
*
- * This procedure is called to move an arc by a given amount.
+ * This function is called to move an arc by a given amount.
*
* Results:
* None.
*
* Side effects:
- * The position of the arc is offset by (xDelta, yDelta), and
- * the bounding box is updated in the generic part of the item
- * structure.
+ * The position of the arc is offset by (xDelta, yDelta), and the
+ * bounding box is updated in the generic part of the item structure.
*
*--------------------------------------------------------------
*/
static void
-TranslateArc(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. */
+TranslateArc(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item that is being moved. */
+ double deltaX, /* Amount by which item is to be moved. */
+ double deltaY)
{
ArcItem *arcPtr = (ArcItem *) itemPtr;
@@ -1460,26 +1429,25 @@ TranslateArc(canvas, itemPtr, deltaX, deltaY)
*
* ComputeArcOutline --
*
- * This procedure creates a polygon describing everything in
- * the outline for an arc except what's in the curved part.
- * For a "pie slice" arc this is a V-shaped chunk, and for
- * a "chord" arc this is a linear chunk (with cutaway corners).
- * For "arc" arcs, this stuff isn't relevant.
+ * This function creates a polygon describing everything in the outline
+ * for an arc except what's in the curved part. For a "pie slice" arc
+ * this is a V-shaped chunk, and for a "chord" arc this is a linear chunk
+ * (with cutaway corners). For "arc" arcs, this stuff isn't relevant.
*
* Results:
* None.
*
* Side effects:
- * The information at arcPtr->outlinePtr gets modified, and
- * storage for arcPtr->outlinePtr may be allocated or freed.
+ * The information at arcPtr->outlinePtr gets modified, and storage for
+ * arcPtr->outlinePtr may be allocated or freed.
*
*--------------------------------------------------------------
*/
static void
-ComputeArcOutline(canvas,arcPtr)
- Tk_Canvas canvas; /* Information about overall canvas. */
- ArcItem *arcPtr; /* Information about arc. */
+ComputeArcOutline(
+ Tk_Canvas canvas, /* Information about overall canvas. */
+ ArcItem *arcPtr) /* Information about arc. */
{
double sin1, cos1, sin2, cos2, angle, width, halfWidth;
double boxWidth, boxHeight;
@@ -1487,10 +1455,9 @@ ComputeArcOutline(canvas,arcPtr)
double *outlinePtr;
Tk_State state = arcPtr->header.state;
-
/*
- * Make sure that the outlinePtr array is large enough to hold
- * either a chord or pie-slice outline.
+ * Make sure that the outlinePtr array is large enough to hold either a
+ * chord or pie-slice outline.
*/
if (arcPtr->numOutlinePoints == 0) {
@@ -1500,14 +1467,13 @@ ComputeArcOutline(canvas,arcPtr)
}
outlinePtr = arcPtr->outlinePtr;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
/*
- * First compute the two points that lie at the centers of
- * the ends of the curved arc segment, which are marked with
- * X's in the figure below:
+ * First compute the two points that lie at the centers of the ends of the
+ * curved arc segment, which are marked with X's in the figure below:
*
*
* * * *
@@ -1517,13 +1483,13 @@ ComputeArcOutline(canvas,arcPtr)
* * * * *
* X * * X
*
- * The code is tricky because the arc can be ovular in shape.
- * It computes the position for a unit circle, and then
- * scales to fit the shape of the arc's bounding box.
+ * The code is tricky because the arc can be ovular in shape. It computes
+ * the position for a unit circle, and then scales to fit the shape of the
+ * arc's bounding box.
*
- * Also, watch out because angles go counter-clockwise like you
- * might expect, but the y-coordinate system is inverted. To
- * handle this, just negate the angles in all the computations.
+ * Also, watch out because angles go counter-clockwise like you might
+ * expect, but the y-coordinate system is inverted. To handle this, just
+ * negate the angles in all the computations.
*/
boxWidth = arcPtr->bbox[2] - arcPtr->bbox[0];
@@ -1542,8 +1508,8 @@ ComputeArcOutline(canvas,arcPtr)
arcPtr->center2[1] = vertex[1] + sin2*boxHeight/2.0;
/*
- * Next compute the "outermost corners" of the arc, which are
- * marked with X's in the figure below:
+ * Next compute the "outermost corners" of the arc, which are marked with
+ * X's in the figure below:
*
* * * *
* * *
@@ -1552,12 +1518,11 @@ ComputeArcOutline(canvas,arcPtr)
* X * * X
* * *
*
- * The code below is tricky because it has to handle eccentricity
- * in the shape of the oval. The key in the code below is to
- * realize that the slope of the line from arcPtr->center1 to corner1
- * is (boxWidth*sin1)/(boxHeight*cos1), and similarly for arcPtr->center2
- * and corner2. These formulas can be computed from the formula for
- * the oval.
+ * The code below is tricky because it has to handle eccentricity in the
+ * shape of the oval. The key in the code below is to realize that the
+ * slope of the line from arcPtr->center1 to corner1 is (boxWidth*sin1)
+ * divided by (boxHeight*cos1), and similarly for arcPtr->center2 and
+ * corner2. These formulas can be computed from the formula for the oval.
*/
width = arcPtr->outline.width;
@@ -1565,7 +1530,7 @@ ComputeArcOutline(canvas,arcPtr)
if (arcPtr->outline.activeWidth>arcPtr->outline.width) {
width = arcPtr->outline.activeWidth;
}
- } else if (state==TK_STATE_DISABLED) {
+ } else if (state == TK_STATE_DISABLED) {
if (arcPtr->outline.disabledWidth>arcPtr->outline.width) {
width = arcPtr->outline.disabledWidth;
}
@@ -1588,10 +1553,10 @@ ComputeArcOutline(canvas,arcPtr)
corner2[1] = arcPtr->center2[1] + sin(angle)*halfWidth;
/*
- * For a chord outline, generate a six-sided polygon with three
- * points for each end of the chord. The first and third points
- * for each end are butt points generated on either side of the
- * center point. The second point is the corner point.
+ * For a chord outline, generate a six-sided polygon with three points for
+ * each end of the chord. The first and third points for each end are butt
+ * points generated on either side of the center point. The second point
+ * is the corner point.
*/
if (arcPtr->style == CHORD_STYLE) {
@@ -1611,10 +1576,9 @@ ComputeArcOutline(canvas,arcPtr)
- arcPtr->center1[1];
} else if (arcPtr->style == PIESLICE_STYLE) {
/*
- * For pie slices, generate two polygons, one for each side
- * of the pie slice. The first arm has a shape like this,
- * where the center of the oval is X, arcPtr->center1 is at Y, and
- * corner1 is at Z:
+ * For pie slices, generate two polygons, one for each side of the pie
+ * slice. The first arm has a shape like this, where the center of the
+ * oval is X, arcPtr->center1 is at Y, and corner1 is at Z:
*
* _____________________
* | \
@@ -1622,7 +1586,6 @@ ComputeArcOutline(canvas,arcPtr)
* X Y Z
* | /
* |_____________________/
- *
*/
TkGetButtPoints(arcPtr->center1, vertex, width, 0,
@@ -1639,7 +1602,6 @@ ComputeArcOutline(canvas,arcPtr)
/*
* The second arm has a shape like this:
*
- *
* ______________________
* / \
* / \
@@ -1648,10 +1610,10 @@ ComputeArcOutline(canvas,arcPtr)
* \______________________/
*
* Similar to above X is the center of the oval/circle, Y is
- * arcPtr->center2, and Z is corner2. The extra jog out to the left
- * of X is needed in or to produce a butted joint with the
- * first arm; the corner to the right of X is one of the
- * first two points of the first arm, depending on extent.
+ * arcPtr->center2, and Z is corner2. The extra jog out to the left of
+ * X is needed in or to produce a butted joint with the first arm; the
+ * corner to the right of X is one of the first two points of the
+ * first arm, depending on extent.
*/
TkGetButtPoints(arcPtr->center2, vertex, width, 0,
@@ -1680,15 +1642,13 @@ ComputeArcOutline(canvas,arcPtr)
*
* HorizLineToArc --
*
- * Determines whether a horizontal line segment intersects
- * a given arc.
+ * Determines whether a horizontal line segment intersects a given arc.
*
* Results:
- * The return value is 1 if the given line intersects the
- * infinitely-thin arc section defined by rx, ry, start,
- * and extent, and 0 otherwise. Only the perimeter of the
- * arc is checked: interior areas (e.g. pie-slice or chord)
- * are not checked.
+ * The return value is 1 if the given line intersects the infinitely-thin
+ * arc section defined by rx, ry, start, and extent, and 0 otherwise.
+ * Only the perimeter of the arc is checked: interior areas (e.g. chord
+ * or pie-slice) are not checked.
*
* Side effects:
* None.
@@ -1697,25 +1657,24 @@ ComputeArcOutline(canvas,arcPtr)
*/
static int
-HorizLineToArc(x1, x2, y, rx, ry, start, extent)
- double x1, x2; /* X-coords of endpoints of line segment.
- * X1 must be <= x2. */
- double y; /* Y-coordinate of line segment. */
- double rx, ry; /* These x- and y-radii define an oval
+HorizLineToArc(
+ double x1, double x2, /* X-coords of endpoints of line segment. X1
+ * must be <= x2. */
+ double y, /* Y-coordinate of line segment. */
+ double rx, double ry, /* These x- and y-radii define an oval
* centered at the origin. */
- double start, extent; /* Angles that define extent of arc, in
- * the standard fashion for this module. */
+ double start, double extent)/* Angles that define extent of arc, in the
+ * standard fashion for this module. */
{
- double tmp;
+ double tmp, x;
double tx, ty; /* Coordinates of intersection point in
* transformed coordinate system. */
- double x;
/*
- * Compute the x-coordinate of one possible intersection point
- * between the arc and the line. Use a transformed coordinate
- * system where the oval is a unit circle centered at the origin.
- * Then scale back to get actual x-coordinate.
+ * Compute the x-coordinate of one possible intersection point between the
+ * arc and the line. Use a transformed coordinate system where the oval is
+ * a unit circle centered at the origin. Then scale back to get actual
+ * x-coordinate.
*/
ty = y/ry;
@@ -1744,15 +1703,13 @@ HorizLineToArc(x1, x2, y, rx, ry, start, extent)
*
* VertLineToArc --
*
- * Determines whether a vertical line segment intersects
- * a given arc.
+ * Determines whether a vertical line segment intersects a given arc.
*
* Results:
- * The return value is 1 if the given line intersects the
- * infinitely-thin arc section defined by rx, ry, start,
- * and extent, and 0 otherwise. Only the perimeter of the
- * arc is checked: interior areas (e.g. pie-slice or chord)
- * are not checked.
+ * The return value is 1 if the given line intersects the infinitely-thin
+ * arc section defined by rx, ry, start, and extent, and 0 otherwise.
+ * Only the perimeter of the arc is checked: interior areas (e.g. chord
+ * or pie-slice) are not checked.
*
* Side effects:
* None.
@@ -1761,25 +1718,24 @@ HorizLineToArc(x1, x2, y, rx, ry, start, extent)
*/
static int
-VertLineToArc(x, y1, y2, rx, ry, start, extent)
- double x; /* X-coordinate of line segment. */
- double y1, y2; /* Y-coords of endpoints of line segment.
- * Y1 must be <= y2. */
- double rx, ry; /* These x- and y-radii define an oval
+VertLineToArc(
+ double x, /* X-coordinate of line segment. */
+ double y1, double y2, /* Y-coords of endpoints of line segment. Y1
+ * must be <= y2. */
+ double rx, double ry, /* These x- and y-radii define an oval
* centered at the origin. */
- double start, extent; /* Angles that define extent of arc, in
- * the standard fashion for this module. */
+ double start, double extent)/* Angles that define extent of arc, in the
+ * standard fashion for this module. */
{
- double tmp;
+ double tmp, y;
double tx, ty; /* Coordinates of intersection point in
* transformed coordinate system. */
- double y;
/*
- * Compute the y-coordinate of one possible intersection point
- * between the arc and the line. Use a transformed coordinate
- * system where the oval is a unit circle centered at the origin.
- * Then scale back to get actual y-coordinate.
+ * Compute the y-coordinate of one possible intersection point between the
+ * arc and the line. Use a transformed coordinate system where the oval is
+ * a unit circle centered at the origin. Then scale back to get actual
+ * y-coordinate.
*/
tx = x/rx;
@@ -1808,15 +1764,14 @@ VertLineToArc(x, y1, y2, rx, ry, start, extent)
*
* AngleInRange --
*
- * Determine whether the angle from the origin to a given
- * point is within a given range.
+ * Determine whether the angle from the origin to a given point is within
+ * a given range.
*
* Results:
- * The return value is 1 if the angle from (0,0) to (x,y)
- * is in the range given by start and extent, where angles
- * are interpreted in the standard way for ovals (meaning
- * backwards from normal interpretation). Otherwise the
- * return value is 0.
+ * The return value is 1 if the angle from (0,0) to (x,y) is in the range
+ * given by start and extent, where angles are interpreted in the
+ * standard way for ovals (meaning backwards from normal interpretation).
+ * Otherwise the return value is 0.
*
* Side effects:
* None.
@@ -1825,11 +1780,11 @@ VertLineToArc(x, y1, y2, rx, ry, start, extent)
*/
static int
-AngleInRange(x, y, start, extent)
- double x, y; /* Coordinate of point; angle measured
- * from origin to here, relative to x-axis. */
- double start; /* First angle, degrees, >=0, <=360. */
- double extent; /* Size of arc in degrees >=-360, <=360. */
+AngleInRange(
+ double x, double y, /* Coordinate of point; angle measured from
+ * origin to here, relative to x-axis. */
+ double start, /* First angle, degrees, >=0, <=360. */
+ double extent) /* Size of arc in degrees >=-360, <=360. */
{
double diff;
@@ -1855,15 +1810,13 @@ AngleInRange(x, y, start, extent)
*
* ArcToPostscript --
*
- * This procedure is called to generate Postscript for
- * arc items.
+ * This function is called to generate Postscript for arc items.
*
* Results:
- * The return value is a standard Tcl result. If an error
- * occurs in generating Postscript then an error message is
- * 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.
+ * The return value is a standard Tcl result. If an error occurs in
+ * generating Postscript then an error message is 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.
*
* Side effects:
* None.
@@ -1872,15 +1825,13 @@ AngleInRange(x, y, start, extent)
*/
static int
-ArcToPostscript(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. */
+ArcToPostscript(
+ 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. */
{
ArcItem *arcPtr = (ArcItem *) itemPtr;
char buffer[400];
@@ -1900,7 +1851,7 @@ ArcToPostscript(interp, canvas, itemPtr, prepass)
ang2 = arcPtr->start;
}
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
color = arcPtr->outline.color;
@@ -1920,7 +1871,7 @@ ArcToPostscript(interp, canvas, itemPtr, prepass)
if (arcPtr->activeFillStipple!=None) {
fillStipple = arcPtr->activeFillStipple;
}
- } else if (state==TK_STATE_DISABLED) {
+ } else if (state == TK_STATE_DISABLED) {
if (arcPtr->outline.disabledColor!=NULL) {
color = arcPtr->outline.disabledColor;
}
@@ -1936,15 +1887,15 @@ ArcToPostscript(interp, canvas, itemPtr, prepass)
}
/*
- * If the arc is filled, output Postscript for the interior region
- * of the arc.
+ * If the arc is filled, output Postscript for the interior region of the
+ * arc.
*/
if (arcPtr->fillGC != None) {
sprintf(buffer, "matrix currentmatrix\n%.15g %.15g translate %.15g %.15g scale\n",
(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);
+ Tcl_AppendResult(interp, buffer, NULL);
if (arcPtr->style == CHORD_STYLE) {
sprintf(buffer, "0 0 1 %.15g %.15g arc closepath\nsetmatrix\n",
ang1, ang2);
@@ -1953,21 +1904,20 @@ ArcToPostscript(interp, canvas, itemPtr, prepass)
"0 0 moveto 0 0 1 %.15g %.15g arc closepath\nsetmatrix\n",
ang1, ang2);
}
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) {
return TCL_ERROR;
- };
+ }
if (fillStipple != None) {
- Tcl_AppendResult(interp, "clip ", (char *) NULL);
- if (Tk_CanvasPsStipple(interp, canvas, fillStipple)
- != TCL_OK) {
+ Tcl_AppendResult(interp, "clip ", NULL);
+ if (Tk_CanvasPsStipple(interp, canvas, fillStipple) != TCL_OK) {
return TCL_ERROR;
}
if (arcPtr->outline.gc != None) {
- Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);
+ Tcl_AppendResult(interp, "grestore gsave\n", NULL);
}
} else {
- Tcl_AppendResult(interp, "fill\n", (char *) NULL);
+ Tcl_AppendResult(interp, "fill\n", NULL);
}
}
@@ -1979,16 +1929,15 @@ ArcToPostscript(interp, canvas, itemPtr, prepass)
sprintf(buffer, "matrix currentmatrix\n%.15g %.15g translate %.15g %.15g scale\n",
(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);
+ Tcl_AppendResult(interp, buffer, NULL);
sprintf(buffer, "0 0 1 %.15g %.15g", ang1, ang2);
Tcl_AppendResult(interp, buffer,
- " arc\nsetmatrix\n0 setlinecap\n", (char *) NULL);
- if (Tk_CanvasPsOutline(canvas, itemPtr,
- &(arcPtr->outline)) != TCL_OK) {
+ " arc\nsetmatrix\n0 setlinecap\n", NULL);
+ if (Tk_CanvasPsOutline(canvas, itemPtr, &(arcPtr->outline)) != TCL_OK){
return TCL_ERROR;
}
if (arcPtr->style != ARC_STYLE) {
- Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);
+ Tcl_AppendResult(interp, "grestore gsave\n", NULL);
if (arcPtr->style == CHORD_STYLE) {
Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
CHORD_OUTLINE_PTS);
@@ -2000,15 +1949,14 @@ ArcToPostscript(interp, canvas, itemPtr, prepass)
return TCL_ERROR;
}
if (stipple != None) {
- Tcl_AppendResult(interp, "clip ", (char *) NULL);
- if (Tk_CanvasPsStipple(interp, canvas,
- stipple) != TCL_OK) {
+ Tcl_AppendResult(interp, "clip ", NULL);
+ if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK){
return TCL_ERROR;
}
} else {
- Tcl_AppendResult(interp, "fill\n", (char *) NULL);
+ Tcl_AppendResult(interp, "fill\n", NULL);
}
- Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);
+ Tcl_AppendResult(interp, "grestore gsave\n", NULL);
Tk_CanvasPsPath(interp, canvas,
arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
PIE_OUTLINE2_PTS);
@@ -2018,13 +1966,12 @@ ArcToPostscript(interp, canvas, itemPtr, prepass)
return TCL_ERROR;
}
if (stipple != None) {
- Tcl_AppendResult(interp, "clip ", (char *) NULL);
- if (Tk_CanvasPsStipple(interp, canvas,
- stipple) != TCL_OK) {
+ Tcl_AppendResult(interp, "clip ", NULL);
+ if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
return TCL_ERROR;
}
} else {
- Tcl_AppendResult(interp, "fill\n", (char *) NULL);
+ Tcl_AppendResult(interp, "fill\n", NULL);
}
}
}
@@ -2037,34 +1984,34 @@ ArcToPostscript(interp, canvas, itemPtr, prepass)
*
* StyleParseProc --
*
- * This procedure is invoked during option processing to handle
- * the "-style" option.
+ * This function is invoked during option processing to handle the
+ * "-style" option.
*
* Results:
* A standard Tcl return value.
*
* Side effects:
- * The state for a given item gets replaced by the state
- * indicated in the value argument.
+ * The state for a given item gets replaced by the state indicated in the
+ * value argument.
*
*--------------------------------------------------------------
*/
static int
-StyleParseProc(clientData, interp, tkwin, value, widgRec, offset)
- ClientData clientData; /* some flags.*/
- Tcl_Interp *interp; /* Used for reporting errors. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- CONST char *value; /* Value of option. */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Offset into item. */
+StyleParseProc(
+ ClientData clientData, /* some flags.*/
+ Tcl_Interp *interp, /* Used for reporting errors. */
+ Tk_Window tkwin, /* Window containing canvas widget. */
+ CONST char *value, /* Value of option. */
+ char *widgRec, /* Pointer to record for item. */
+ int offset) /* Offset into item. */
{
int c;
size_t length;
register Style *stylePtr = (Style *) (widgRec + offset);
- if(value == NULL || *value == 0) {
+ if (value == NULL || *value == 0) {
*stylePtr = PIESLICE_STYLE;
return TCL_OK;
}
@@ -2085,9 +2032,8 @@ StyleParseProc(clientData, interp, tkwin, value, widgRec, offset)
return TCL_OK;
}
- Tcl_AppendResult(interp, "bad -style option \"",
- value, "\": must be arc, chord, or pieslice",
- (char *) NULL);
+ Tcl_AppendResult(interp, "bad -style option \"", value,
+ "\": must be arc, chord, or pieslice", NULL);
*stylePtr = PIESLICE_STYLE;
return TCL_ERROR;
}
@@ -2097,16 +2043,15 @@ StyleParseProc(clientData, interp, tkwin, value, widgRec, offset)
*
* StylePrintProc --
*
- * This procedure is invoked by the Tk configuration code
- * to produce a printable string for the "-style"
- * configuration option.
+ * This function is invoked by the Tk configuration code to produce a
+ * printable string for the "-style" configuration option.
*
* Results:
- * The return value is a string describing the state for
- * the item referred to by "widgRec". In addition, *freeProcPtr
- * is filled in with the address of a procedure to call to free
- * the result string when it's no longer needed (or NULL to
- * indicate that the string doesn't need to be freed).
+ * The return value is a string describing the state for the item
+ * referred to by "widgRec". In addition, *freeProcPtr is filled in with
+ * the address of a function to call to free the result string when it's
+ * no longer needed (or NULL to indicate that the string doesn't need to
+ * be freed).
*
* Side effects:
* None.
@@ -2115,22 +2060,30 @@ StyleParseProc(clientData, interp, tkwin, value, widgRec, offset)
*/
static char *
-StylePrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
- ClientData clientData; /* Ignored. */
- Tk_Window tkwin; /* Ignored. */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Offset into item. */
- Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
- * information about how to reclaim
- * storage for return string. */
+StylePrintProc(
+ ClientData clientData, /* Ignored. */
+ Tk_Window tkwin, /* Ignored. */
+ char *widgRec, /* Pointer to record for item. */
+ int offset, /* Offset into item. */
+ Tcl_FreeProc **freeProcPtr) /* Pointer to variable to fill in with
+ * information about how to reclaim storage
+ * for return string. */
{
register Style *stylePtr = (Style *) (widgRec + offset);
- if (*stylePtr==ARC_STYLE) {
+ if (*stylePtr == ARC_STYLE) {
return "arc";
- } else if (*stylePtr==CHORD_STYLE) {
+ } else if (*stylePtr == CHORD_STYLE) {
return "chord";
} else {
return "pieslice";
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkCanvBmap.c b/generic/tkCanvBmap.c
index f308c52..30aa429 100644
--- a/generic/tkCanvBmap.c
+++ b/generic/tkCanvBmap.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkCanvBmap.c --
*
* This file implements bitmap items for canvas widgets.
@@ -6,13 +6,12 @@
* Copyright (c) 1992-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <stdio.h>
#include "tkInt.h"
-#include "tkPort.h"
#include "tkCanvas.h"
/*
@@ -21,11 +20,10 @@
typedef struct BitmapItem {
Tk_Item header; /* Generic stuff that's the same for all
- * types. MUST BE FIRST IN STRUCTURE. */
+ * types. MUST BE FIRST IN STRUCTURE. */
double x, y; /* Coordinates of positioning point for
* bitmap. */
- Tk_Anchor anchor; /* Where to anchor bitmap relative to
- * (x,y). */
+ Tk_Anchor anchor; /* Where to anchor bitmap relative to (x,y) */
Pixmap bitmap; /* Bitmap to display in window. */
Pixmap activeBitmap; /* Bitmap to display in window. */
Pixmap disabledBitmap; /* Bitmap to display in window. */
@@ -35,8 +33,8 @@ typedef struct BitmapItem {
XColor *bgColor; /* Background color to use for bitmap. */
XColor *activeBgColor; /* Background color to use for bitmap. */
XColor *disabledBgColor; /* Background color to use for bitmap. */
- GC gc; /* Graphics context to use for drawing
- * bitmap on screen. */
+ GC gc; /* Graphics context to use for drawing bitmap
+ * on screen. */
} BitmapItem;
/*
@@ -53,96 +51,95 @@ static Tk_CustomOption tagsOption = {
};
static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_COLOR, "-activebackground", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(BitmapItem, activeBgColor), TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-activebitmap", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(BitmapItem, activeBitmap), TK_CONFIG_NULL_OK},
- {TK_CONFIG_COLOR, "-activeforeground", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(BitmapItem, activeFgColor), TK_CONFIG_NULL_OK},
- {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_COLOR, "-activebackground", NULL, NULL,
+ NULL, Tk_Offset(BitmapItem, activeBgColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_BITMAP, "-activebitmap", NULL, NULL,
+ NULL, Tk_Offset(BitmapItem, activeBitmap), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_COLOR, "-activeforeground", NULL, NULL,
+ NULL, Tk_Offset(BitmapItem, activeFgColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
"center", Tk_Offset(BitmapItem, anchor), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_COLOR, "-background", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(BitmapItem, bgColor), TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-bitmap", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(BitmapItem, bitmap), TK_CONFIG_NULL_OK},
- {TK_CONFIG_COLOR, "-disabledbackground", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(BitmapItem, disabledBgColor),
+ {TK_CONFIG_COLOR, "-background", NULL, NULL,
+ NULL, Tk_Offset(BitmapItem, bgColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_BITMAP, "-bitmap", NULL, NULL,
+ NULL, Tk_Offset(BitmapItem, bitmap), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_COLOR, "-disabledbackground", NULL, NULL,
+ NULL, Tk_Offset(BitmapItem, disabledBgColor),
TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-disabledbitmap", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(BitmapItem, disabledBitmap),
+ {TK_CONFIG_BITMAP, "-disabledbitmap", NULL, NULL,
+ NULL, Tk_Offset(BitmapItem, disabledBitmap),
TK_CONFIG_NULL_OK},
- {TK_CONFIG_COLOR, "-disabledforeground", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(BitmapItem, disabledFgColor),
+ {TK_CONFIG_COLOR, "-disabledforeground", NULL, NULL,
+ NULL, Tk_Offset(BitmapItem, disabledFgColor),
TK_CONFIG_NULL_OK},
- {TK_CONFIG_COLOR, "-foreground", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_COLOR, "-foreground", NULL, NULL,
"black", Tk_Offset(BitmapItem, fgColor), 0},
- {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
+ {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
+ NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
&stateOption},
- {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+ {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
+ NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
+ {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};
/*
- * Prototypes for procedures defined in this file:
+ * Prototypes for functions defined in this file:
*/
-static int BitmapCoords _ANSI_ARGS_((Tcl_Interp *interp,
+static int BitmapCoords(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
- Tcl_Obj *CONST objv[]));
-static int BitmapToArea _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *rectPtr));
-static double BitmapToPoint _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *coordPtr));
-static int BitmapToPostscript _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));
-static void ComputeBitmapBbox _ANSI_ARGS_((Tk_Canvas canvas,
- BitmapItem *bmapPtr));
-static int ConfigureBitmap _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *CONST objv[]);
+static int BitmapToArea(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double *rectPtr);
+static double BitmapToPoint(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double *coordPtr);
+static int BitmapToPostscript(Tcl_Interp *interp,
+ Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
+static void ComputeBitmapBbox(Tk_Canvas canvas,
+ BitmapItem *bmapPtr);
+static int ConfigureBitmap(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
- Tcl_Obj *CONST objv[], int flags));
-static int TkcCreateBitmap _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *CONST objv[], int flags);
+static int TkcCreateBitmap(Tcl_Interp *interp,
Tk_Canvas canvas, struct Tk_Item *itemPtr,
- int objc, Tcl_Obj *CONST objv[]));
-static void DeleteBitmap _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, Display *display));
-static void DisplayBitmap _ANSI_ARGS_((Tk_Canvas canvas,
+ int objc, Tcl_Obj *CONST objv[]);
+static void DeleteBitmap(Tk_Canvas canvas,
+ Tk_Item *itemPtr, Display *display);
+static void DisplayBitmap(Tk_Canvas canvas,
Tk_Item *itemPtr, Display *display, Drawable dst,
- int x, int y, int width, int height));
-static void ScaleBitmap _ANSI_ARGS_((Tk_Canvas canvas,
+ int x, int y, int width, int height);
+static void ScaleBitmap(Tk_Canvas canvas,
Tk_Item *itemPtr, double originX, double originY,
- double scaleX, double scaleY));
-static void TranslateBitmap _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double deltaX, double deltaY));
+ double scaleX, double scaleY);
+static void TranslateBitmap(Tk_Canvas canvas, Tk_Item *itemPtr,
+ double deltaX, double deltaY);
/*
- * The structures below defines the bitmap item type in terms of
- * procedures that can be invoked by generic item code.
+ * The structures below defines the bitmap item type in terms of functions
+ * that can be invoked by generic item code.
*/
Tk_ItemType tkBitmapType = {
- "bitmap", /* name */
- sizeof(BitmapItem), /* itemSize */
- TkcCreateBitmap, /* createProc */
- configSpecs, /* configSpecs */
- ConfigureBitmap, /* configureProc */
- BitmapCoords, /* coordProc */
- DeleteBitmap, /* deleteProc */
- DisplayBitmap, /* displayProc */
- TK_CONFIG_OBJS, /* flags */
- BitmapToPoint, /* pointProc */
- BitmapToArea, /* areaProc */
- BitmapToPostscript, /* postscriptProc */
- ScaleBitmap, /* scaleProc */
- TranslateBitmap, /* translateProc */
- (Tk_ItemIndexProc *) NULL, /* indexProc */
- (Tk_ItemCursorProc *) NULL, /* icursorProc */
- (Tk_ItemSelectionProc *) NULL, /* selectionProc */
- (Tk_ItemInsertProc *) NULL, /* insertProc */
- (Tk_ItemDCharsProc *) NULL, /* dTextProc */
- (Tk_ItemType *) NULL, /* nextPtr */
+ "bitmap", /* name */
+ sizeof(BitmapItem), /* itemSize */
+ TkcCreateBitmap, /* createProc */
+ configSpecs, /* configSpecs */
+ ConfigureBitmap, /* configureProc */
+ BitmapCoords, /* coordProc */
+ DeleteBitmap, /* deleteProc */
+ DisplayBitmap, /* displayProc */
+ TK_CONFIG_OBJS, /* flags */
+ BitmapToPoint, /* pointProc */
+ BitmapToArea, /* areaProc */
+ BitmapToPostscript, /* postscriptProc */
+ ScaleBitmap, /* scaleProc */
+ TranslateBitmap, /* translateProc */
+ NULL, /* indexProc */
+ NULL, /* icursorProc */
+ NULL, /* selectionProc */
+ NULL, /* insertProc */
+ NULL, /* dTextProc */
+ NULL, /* nextPtr */
};
/*
@@ -150,14 +147,13 @@ Tk_ItemType tkBitmapType = {
*
* TkcCreateBitmap --
*
- * This procedure is invoked to create a new bitmap
- * item in a canvas.
+ * This function is invoked to create a new bitmap item in a canvas.
*
* Results:
- * A standard Tcl return value. If an error occurred in
- * creating the item, then an error message is left in
- * the interp's result; in this case itemPtr is left uninitialized,
- * so it can be safely freed by the caller.
+ * A standard Tcl return value. If an error occurred in creating the
+ * item, then an error message is left in the interp's result; in this
+ * case itemPtr is left uninitialized, so it can be safely freed by the
+ * caller.
*
* Side effects:
* A new bitmap item is created.
@@ -166,13 +162,13 @@ Tk_ItemType tkBitmapType = {
*/
static int
-TkcCreateBitmap(interp, canvas, itemPtr, objc, objv)
- 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 objc; /* Number of arguments in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing rectangle. */
+TkcCreateBitmap(
+ 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 objc, /* Number of arguments in objv. */
+ Tcl_Obj *CONST objv[]) /* Arguments describing rectangle. */
{
BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
int i;
@@ -198,8 +194,8 @@ TkcCreateBitmap(interp, canvas, itemPtr, objc, objv)
bmapPtr->gc = None;
/*
- * Process the arguments to fill in the item record.
- * Only 1 (list) or 2 (x y) coords are allowed.
+ * Process the arguments to fill in the item record. Only 1 (list) or 2 (x
+ * y) coords are allowed.
*/
if (objc == 1) {
@@ -219,7 +215,7 @@ TkcCreateBitmap(interp, canvas, itemPtr, objc, objv)
return TCL_OK;
}
- error:
+ error:
DeleteBitmap(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
return TCL_ERROR;
}
@@ -229,9 +225,8 @@ TkcCreateBitmap(interp, canvas, itemPtr, objc, objv)
*
* BitmapCoords --
*
- * This procedure is invoked to process the "coords" widget
- * command on bitmap items. See the user documentation for
- * details on what it does.
+ * This function is invoked to process the "coords" widget command on
+ * bitmap items. See the user documentation for details on what it does.
*
* Results:
* Returns TCL_OK or TCL_ERROR, and sets the interp's result.
@@ -243,20 +238,19 @@ TkcCreateBitmap(interp, canvas, itemPtr, objc, objv)
*/
static int
-BitmapCoords(interp, canvas, itemPtr, objc, objv)
- 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 objc; /* Number of coordinates supplied in
- * objv. */
- Tcl_Obj *CONST objv[]; /* Array of coordinates: x1, y1,
- * x2, y2, ... */
+BitmapCoords(
+ 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 objc, /* Number of coordinates supplied in objv. */
+ Tcl_Obj *CONST objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */
{
BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
if (objc == 0) {
Tcl_Obj *obj = Tcl_NewObj();
+
Tcl_Obj *subobj = Tcl_NewDoubleObj(bmapPtr->x);
Tcl_ListObjAppendElement(interp, obj, subobj);
subobj = Tcl_NewDoubleObj(bmapPtr->y);
@@ -297,12 +291,12 @@ BitmapCoords(interp, canvas, itemPtr, objc, objv)
*
* ConfigureBitmap --
*
- * This procedure is invoked to configure various aspects
- * of a bitmap item, such as its anchor position.
+ * This function is invoked to configure various aspects of a bitmap
+ * item, such as its anchor position.
*
* Results:
- * A standard Tcl result code. If an error occurs, then
- * an error message is left in the interp's result.
+ * A standard Tcl result code. If an error occurs, then an error message
+ * is left in the interp's result.
*
* Side effects:
* Configuration information may be set for itemPtr.
@@ -311,13 +305,13 @@ BitmapCoords(interp, canvas, itemPtr, objc, objv)
*/
static int
-ConfigureBitmap(interp, canvas, itemPtr, objc, objv, flags)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Canvas canvas; /* Canvas containing itemPtr. */
- Tk_Item *itemPtr; /* Bitmap item to reconfigure. */
- int objc; /* Number of elements in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing things to configure. */
- int flags; /* Flags to pass to Tk_ConfigureWidget. */
+ConfigureBitmap(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_Canvas canvas, /* Canvas containing itemPtr. */
+ Tk_Item *itemPtr, /* Bitmap item to reconfigure. */
+ int objc, /* Number of elements in objv. */
+ Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */
+ int flags) /* Flags to pass to Tk_ConfigureWidget. */
{
BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
XGCValues gcValues;
@@ -336,8 +330,8 @@ ConfigureBitmap(interp, canvas, itemPtr, objc, objv, flags)
}
/*
- * A few of the options require additional processing, such as those
- * that determine the graphics context.
+ * A few of the options require additional processing, such as those that
+ * determine the graphics context.
*/
state = itemPtr->state;
@@ -410,8 +404,8 @@ ConfigureBitmap(interp, canvas, itemPtr, objc, objv, flags)
*
* DeleteBitmap --
*
- * This procedure is called to clean up the data structure
- * associated with a bitmap item.
+ * This function is called to clean up the data structure associated with
+ * a bitmap item.
*
* Results:
* None.
@@ -423,11 +417,10 @@ ConfigureBitmap(interp, canvas, itemPtr, objc, objv, flags)
*/
static void
-DeleteBitmap(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. */
+DeleteBitmap(
+ Tk_Canvas canvas, /* Info about overall canvas widget. */
+ Tk_Item *itemPtr, /* Item that is being deleted. */
+ Display *display) /* Display containing window for canvas. */
{
BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
@@ -468,27 +461,24 @@ DeleteBitmap(canvas, itemPtr, display)
*
* ComputeBitmapBbox --
*
- * This procedure is invoked to compute the bounding box of
- * all the pixels that may be drawn as part of a bitmap item.
- * This procedure is where the child bitmap's placement is
- * computed.
+ * This function is invoked to compute the bounding box of all the pixels
+ * that may be drawn as part of a bitmap item. This function is where the
+ * child bitmap's placement is computed.
*
* Results:
* None.
*
* Side effects:
- * The fields x1, y1, x2, and y2 are updated in the header
- * for itemPtr.
+ * The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static void
-ComputeBitmapBbox(canvas, bmapPtr)
- Tk_Canvas canvas; /* Canvas that contains item. */
- BitmapItem *bmapPtr; /* Item whose bbox is to be
- * recomputed. */
+ComputeBitmapBbox(
+ Tk_Canvas canvas, /* Canvas that contains item. */
+ BitmapItem *bmapPtr) /* Item whose bbox is to be recomputed. */
{
int width, height;
int x, y;
@@ -525,36 +515,36 @@ ComputeBitmapBbox(canvas, bmapPtr)
Tk_SizeOfBitmap(Tk_Display(Tk_CanvasTkwin(canvas)), bitmap,
&width, &height);
switch (bmapPtr->anchor) {
- case TK_ANCHOR_N:
- x -= width/2;
- break;
- case TK_ANCHOR_NE:
- x -= width;
- break;
- case TK_ANCHOR_E:
- x -= width;
- y -= height/2;
- break;
- case TK_ANCHOR_SE:
- x -= width;
- y -= height;
- break;
- case TK_ANCHOR_S:
- x -= width/2;
- y -= height;
- break;
- case TK_ANCHOR_SW:
- y -= height;
- break;
- case TK_ANCHOR_W:
- y -= height/2;
- break;
- case TK_ANCHOR_NW:
- break;
- case TK_ANCHOR_CENTER:
- x -= width/2;
- y -= height/2;
- break;
+ case TK_ANCHOR_N:
+ x -= width/2;
+ break;
+ case TK_ANCHOR_NE:
+ x -= width;
+ break;
+ case TK_ANCHOR_E:
+ x -= width;
+ y -= height/2;
+ break;
+ case TK_ANCHOR_SE:
+ x -= width;
+ y -= height;
+ break;
+ case TK_ANCHOR_S:
+ x -= width/2;
+ y -= height;
+ break;
+ case TK_ANCHOR_SW:
+ y -= height;
+ break;
+ case TK_ANCHOR_W:
+ y -= height/2;
+ break;
+ case TK_ANCHOR_NW:
+ break;
+ case TK_ANCHOR_CENTER:
+ x -= width/2;
+ y -= height/2;
+ break;
}
/*
@@ -572,28 +562,27 @@ ComputeBitmapBbox(canvas, bmapPtr)
*
* DisplayBitmap --
*
- * This procedure is invoked to draw a bitmap item in a given
- * drawable.
+ * This function is invoked to draw a bitmap item in a given drawable.
*
* Results:
* None.
*
* Side effects:
- * ItemPtr is drawn in drawable using the transformation
- * information in canvas.
+ * ItemPtr is drawn in drawable using the transformation information in
+ * canvas.
*
*--------------------------------------------------------------
*/
static void
-DisplayBitmap(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). */
+DisplayBitmap(
+ 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, int y, int width, int height)
+ /* Describes region of canvas that must be
+ * redisplayed (not used). */
{
BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
int bmapX, bmapY, bmapWidth, bmapHeight;
@@ -602,9 +591,8 @@ DisplayBitmap(canvas, itemPtr, display, drawable, x, y, width, height)
Tk_State state = itemPtr->state;
/*
- * If the area being displayed doesn't cover the whole bitmap,
- * then only redisplay the part of the bitmap that needs
- * redisplay.
+ * If the area being displayed doesn't cover the whole bitmap, then only
+ * redisplay the part of the bitmap that needs redisplay.
*/
if (state == TK_STATE_NULL) {
@@ -650,9 +638,9 @@ DisplayBitmap(canvas, itemPtr, display, drawable, x, y, width, height)
&drawableX, &drawableY);
/*
- * Must modify the mask origin within the graphics context
- * to line up with the bitmap's origin (in order to make
- * bitmaps with "-background {}" work right).
+ * Must modify the mask origin within the graphics context to line up
+ * with the bitmap's origin (in order to make bitmaps with
+ * "-background {}" work right).
*/
XSetClipOrigin(display, bmapPtr->gc, drawableX - bmapX,
@@ -669,14 +657,14 @@ DisplayBitmap(canvas, itemPtr, display, drawable, x, y, width, height)
*
* BitmapToPoint --
*
- * Computes the distance from a given point to a given
- * rectangle, in canvas units.
+ * Computes the distance from a given point to a given rectangle, in
+ * canvas units.
*
* Results:
- * The return value is 0 if the point whose x and y coordinates
- * are coordPtr[0] and coordPtr[1] is inside the bitmap. If the
- * point isn't inside the bitmap then the return value is the
- * distance from the point to the bitmap.
+ * The return value is 0 if the point whose x and y coordinates are
+ * coordPtr[0] and coordPtr[1] is inside the bitmap. If the point isn't
+ * inside the bitmap then the return value is the distance from the point
+ * to the bitmap.
*
* Side effects:
* None.
@@ -686,10 +674,10 @@ DisplayBitmap(canvas, itemPtr, display, drawable, x, y, width, height)
/* ARGSUSED */
static double
-BitmapToPoint(canvas, itemPtr, coordPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against point. */
- double *coordPtr; /* Pointer to x and y coordinates. */
+BitmapToPoint(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against point. */
+ double *coordPtr) /* Pointer to x and y coordinates. */
{
BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
double x1, x2, y1, y2, xDiff, yDiff;
@@ -727,14 +715,13 @@ BitmapToPoint(canvas, itemPtr, coordPtr)
*
* BitmapToArea --
*
- * This procedure is called to determine whether an item
- * lies entirely inside, entirely outside, or overlapping
- * a given rectangle.
+ * This function is called to determine whether an item lies entirely
+ * inside, entirely outside, or overlapping a given rectangle.
*
* Results:
- * -1 is returned if the item is entirely outside the area
- * given by rectPtr, 0 if it overlaps, and 1 if it is entirely
- * inside the given area.
+ * -1 is returned if the item is entirely outside the area given by
+ * rectPtr, 0 if it overlaps, and 1 if it is entirely inside the given
+ * area.
*
* Side effects:
* None.
@@ -744,12 +731,12 @@ BitmapToPoint(canvas, itemPtr, coordPtr)
/* ARGSUSED */
static int
-BitmapToArea(canvas, itemPtr, rectPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against rectangle. */
- double *rectPtr; /* Pointer to array of four coordinates
- * (x1, y1, x2, y2) describing rectangular
- * area. */
+BitmapToArea(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against rectangle. */
+ double *rectPtr) /* Pointer to array of four coordinates
+ * (x1,y1,x2,y2) describing rectangular
+ * area. */
{
BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
@@ -773,16 +760,16 @@ BitmapToArea(canvas, itemPtr, rectPtr)
*
* ScaleBitmap --
*
- * This procedure is invoked to rescale a bitmap item in a
- * canvas. It is one of the standard item procedures for
- * bitmap items, and is invoked by the generic canvas code.
+ * This function is invoked to rescale a bitmap item in a canvas. It is
+ * one of the standard item functions for bitmap items, and is invoked by
+ * the generic canvas code.
*
* Results:
* None.
*
* Side effects:
- * The item referred to by itemPtr is rescaled so that the
- * following transformation is applied to all point coordinates:
+ * The item referred to by itemPtr is rescaled so that the following
+ * transformation is applied to all point coordinates:
* x' = originX + scaleX*(x-originX)
* y' = originY + scaleY*(y-originY)
*
@@ -790,12 +777,13 @@ BitmapToArea(canvas, itemPtr, rectPtr)
*/
static void
-ScaleBitmap(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 item. */
- double scaleX; /* Amount to scale in X direction. */
- double scaleY; /* Amount to scale in Y direction. */
+ScaleBitmap(
+ Tk_Canvas canvas, /* Canvas containing rectangle. */
+ Tk_Item *itemPtr, /* Rectangle to be scaled. */
+ double originX, double originY,
+ /* Origin about which to scale item. */
+ double scaleX, /* Amount to scale in X direction. */
+ double scaleY) /* Amount to scale in Y direction. */
{
BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
@@ -809,25 +797,24 @@ ScaleBitmap(canvas, itemPtr, originX, originY, scaleX, scaleY)
*
* TranslateBitmap --
*
- * This procedure is called to move an item by a given amount.
+ * This function is called to move an item by a given amount.
*
* Results:
* None.
*
* Side effects:
- * The position of the item is offset by (xDelta, yDelta), and
- * the bounding box is updated in the generic part of the item
- * structure.
+ * The position of the item is offset by (xDelta, yDelta), and the
+ * bounding box is updated in the generic part of the item structure.
*
*--------------------------------------------------------------
*/
static void
-TranslateBitmap(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. */
+TranslateBitmap(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item that is being moved. */
+ double deltaX, double deltaY)
+ /* Amount by which item is to be moved. */
{
BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
@@ -841,15 +828,13 @@ TranslateBitmap(canvas, itemPtr, deltaX, deltaY)
*
* BitmapToPostscript --
*
- * This procedure is called to generate Postscript for
- * bitmap items.
+ * This function is called to generate Postscript for bitmap items.
*
* Results:
- * The return value is a standard Tcl result. If an error
- * occurs in generating Postscript then an error message is
- * 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.
+ * The return value is a standard Tcl result. If an error occurs in
+ * generating Postscript then an error message is 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.
*
* Side effects:
* None.
@@ -858,15 +843,13 @@ TranslateBitmap(canvas, itemPtr, deltaX, deltaY)
*/
static int
-BitmapToPostscript(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. */
+BitmapToPostscript(
+ 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. */
{
BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
double x, y;
@@ -911,8 +894,8 @@ BitmapToPostscript(interp, canvas, itemPtr, prepass)
}
/*
- * Compute the coordinates of the lower-left corner of the bitmap,
- * taking into account the anchor position for the bitmp.
+ * Compute the coordinates of the lower-left corner of the bitmap, taking
+ * into account the anchor position for the bitmp.
*/
x = bmapPtr->x;
@@ -920,15 +903,15 @@ BitmapToPostscript(interp, canvas, itemPtr, prepass)
Tk_SizeOfBitmap(Tk_Display(Tk_CanvasTkwin(canvas)), bitmap,
&width, &height);
switch (bmapPtr->anchor) {
- case TK_ANCHOR_NW: y -= height; break;
- case TK_ANCHOR_N: x -= width/2.0; y -= height; break;
- case TK_ANCHOR_NE: x -= width; y -= height; break;
- case TK_ANCHOR_E: x -= width; y -= height/2.0; break;
- case TK_ANCHOR_SE: x -= width; break;
- case TK_ANCHOR_S: x -= width/2.0; break;
- case TK_ANCHOR_SW: break;
- case TK_ANCHOR_W: y -= height/2.0; break;
- case TK_ANCHOR_CENTER: x -= width/2.0; y -= height/2.0; break;
+ case TK_ANCHOR_NW: y -= height; break;
+ case TK_ANCHOR_N: x -= width/2.0; y -= height; break;
+ case TK_ANCHOR_NE: x -= width; y -= height; break;
+ case TK_ANCHOR_E: x -= width; y -= height/2.0; break;
+ case TK_ANCHOR_SE: x -= width; break;
+ case TK_ANCHOR_S: x -= width/2.0; break;
+ case TK_ANCHOR_SW: break;
+ case TK_ANCHOR_W: y -= height/2.0; break;
+ case TK_ANCHOR_CENTER: x -= width/2.0; y -= height/2.0; break;
}
/*
@@ -939,18 +922,18 @@ BitmapToPostscript(interp, canvas, itemPtr, prepass)
sprintf(buffer,
"%.15g %.15g moveto %d 0 rlineto 0 %d rlineto %d %s\n",
x, y, width, height, -width, "0 rlineto closepath");
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
if (Tk_CanvasPsColor(interp, canvas, bgColor) != TCL_OK) {
return TCL_ERROR;
}
- Tcl_AppendResult(interp, "fill\n", (char *) NULL);
+ Tcl_AppendResult(interp, "fill\n", NULL);
}
/*
- * Draw the bitmap, if there is a foreground color. If the bitmap
- * is very large, then chop it up into multiple bitmaps, each
- * consisting of one or more rows. This is needed because Postscript
- * can't handle single strings longer than 64 KBytes long.
+ * Draw the bitmap, if there is a foreground color. If the bitmap is very
+ * large, then chop it up into multiple bitmaps, each consisting of one or
+ * more rows. This is needed because Postscript can't handle single
+ * strings longer than 64 KBytes long.
*/
if (fgColor != NULL) {
@@ -960,8 +943,7 @@ BitmapToPostscript(interp, canvas, itemPtr, prepass)
if (width > 60000) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "can't generate Postscript",
- " for bitmaps more than 60000 pixels wide",
- (char *) NULL);
+ " for bitmaps more than 60000 pixels wide", NULL);
return TCL_ERROR;
}
rowsAtOnce = 60000/width;
@@ -969,7 +951,7 @@ BitmapToPostscript(interp, canvas, itemPtr, prepass)
rowsAtOnce = 1;
}
sprintf(buffer, "%.15g %.15g translate\n", x, y+height);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
for (curRow = 0; curRow < height; curRow += rowsAtOnce) {
rowsThisTime = rowsAtOnce;
if (rowsThisTime > (height - curRow)) {
@@ -977,13 +959,21 @@ BitmapToPostscript(interp, canvas, itemPtr, prepass)
}
sprintf(buffer, "0 -%.15g translate\n%d %d true matrix {\n",
(double) rowsThisTime, width, rowsThisTime);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
if (Tk_CanvasPsBitmap(interp, canvas, bitmap,
0, curRow, width, rowsThisTime) != TCL_OK) {
return TCL_ERROR;
}
- Tcl_AppendResult(interp, "\n} imagemask\n", (char *) NULL);
+ Tcl_AppendResult(interp, "\n} imagemask\n", NULL);
}
}
return TCL_OK;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkCanvImg.c b/generic/tkCanvImg.c
index ba85b4f..9e928c7 100644
--- a/generic/tkCanvImg.c
+++ b/generic/tkCanvImg.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkCanvImg.c --
*
* This file implements image items for canvas widgets.
@@ -6,13 +6,12 @@
* Copyright (c) 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <stdio.h>
#include "tkInt.h"
-#include "tkPort.h"
#include "tkCanvas.h"
/*
@@ -21,24 +20,24 @@
typedef struct ImageItem {
Tk_Item header; /* Generic stuff that's the same for all
- * types. MUST BE FIRST IN STRUCTURE. */
+ * types. MUST BE FIRST IN STRUCTURE. */
Tk_Canvas canvas; /* Canvas containing the image. */
double x, y; /* Coordinates of positioning point for
* image. */
- Tk_Anchor anchor; /* Where to anchor image relative to
- * (x,y). */
- char *imageString; /* String describing -image option (malloc-ed).
- * NULL means no image right now. */
+ Tk_Anchor anchor; /* Where to anchor image relative to (x,y). */
+ char *imageString; /* String describing -image option
+ * (malloc-ed). NULL means no image right
+ * now. */
char *activeImageString; /* String describing -activeimage option.
* NULL means no image right now. */
char *disabledImageString; /* String describing -disabledimage option.
* NULL means no image right now. */
- Tk_Image image; /* Image to display in window, or NULL if
- * no image at present. */
- Tk_Image activeImage; /* Image to display in window, or NULL if
- * no image at present. */
- Tk_Image disabledImage; /* Image to display in window, or NULL if
- * no image at present. */
+ Tk_Image image; /* Image to display in window, or NULL if no
+ * image at present. */
+ Tk_Image activeImage; /* Image to display in window, or NULL if no
+ * image at present. */
+ Tk_Image disabledImage; /* Image to display in window, or NULL if no
+ * image at present. */
} ImageItem;
/*
@@ -55,86 +54,81 @@ static Tk_CustomOption tagsOption = {
};
static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_STRING, "-activeimage", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ImageItem, activeImageString),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_STRING, "-activeimage", NULL, NULL,
+ NULL, Tk_Offset(ImageItem, activeImageString), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
"center", Tk_Offset(ImageItem, anchor), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_STRING, "-disabledimage", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ImageItem, disabledImageString),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-image", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(ImageItem, imageString), TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
- &stateOption},
- {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+ {TK_CONFIG_STRING, "-disabledimage", NULL, NULL,
+ NULL, Tk_Offset(ImageItem, disabledImageString), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_STRING, "-image", NULL, NULL,
+ NULL, Tk_Offset(ImageItem, imageString), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
+ NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
+ {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
+ NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
+ {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};
/*
- * Prototypes for procedures defined in this file:
+ * Prototypes for functions defined in this file:
*/
-static void ImageChangedProc _ANSI_ARGS_((ClientData clientData,
+static void ImageChangedProc(ClientData clientData,
int x, int y, int width, int height, int imgWidth,
- int imgHeight));
-static int ImageCoords _ANSI_ARGS_((Tcl_Interp *interp,
+ int imgHeight);
+static int ImageCoords(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
- Tcl_Obj *CONST argv[]));
-static int ImageToArea _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *rectPtr));
-static double ImageToPoint _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *coordPtr));
-static int ImageToPostscript _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));
-static void ComputeImageBbox _ANSI_ARGS_((Tk_Canvas canvas,
- ImageItem *imgPtr));
-static int ConfigureImage _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *CONST argv[]);
+static int ImageToArea(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double *rectPtr);
+static double ImageToPoint(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double *coordPtr);
+static int ImageToPostscript(Tcl_Interp *interp,
+ Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
+static void ComputeImageBbox(Tk_Canvas canvas, ImageItem *imgPtr);
+static int ConfigureImage(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
- Tcl_Obj *CONST argv[], int flags));
-static int CreateImage _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *CONST argv[], int flags);
+static int CreateImage(Tcl_Interp *interp,
Tk_Canvas canvas, struct Tk_Item *itemPtr,
- int argc, Tcl_Obj *CONST argv[]));
-static void DeleteImage _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, Display *display));
-static void DisplayImage _ANSI_ARGS_((Tk_Canvas canvas,
+ int argc, Tcl_Obj *CONST argv[]);
+static void DeleteImage(Tk_Canvas canvas,
+ Tk_Item *itemPtr, Display *display);
+static void DisplayImage(Tk_Canvas canvas,
Tk_Item *itemPtr, Display *display, Drawable dst,
- int x, int y, int width, int height));
-static void ScaleImage _ANSI_ARGS_((Tk_Canvas canvas,
+ int x, int y, int width, int height);
+static void ScaleImage(Tk_Canvas canvas,
Tk_Item *itemPtr, double originX, double originY,
- double scaleX, double scaleY));
-static void TranslateImage _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double deltaX, double deltaY));
+ double scaleX, double scaleY);
+static void TranslateImage(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double deltaX, double deltaY);
/*
- * The structures below defines the image item type in terms of
- * procedures that can be invoked by generic item code.
+ * The structures below defines the image item type in terms of functions that
+ * can be invoked by generic item code.
*/
Tk_ItemType tkImageType = {
- "image", /* name */
- sizeof(ImageItem), /* itemSize */
- CreateImage, /* createProc */
- configSpecs, /* configSpecs */
- ConfigureImage, /* configureProc */
- ImageCoords, /* coordProc */
- DeleteImage, /* deleteProc */
- DisplayImage, /* displayProc */
- TK_CONFIG_OBJS, /* flags */
- ImageToPoint, /* pointProc */
- ImageToArea, /* areaProc */
- ImageToPostscript, /* postscriptProc */
- ScaleImage, /* scaleProc */
- TranslateImage, /* translateProc */
- (Tk_ItemIndexProc *) NULL, /* indexProc */
- (Tk_ItemCursorProc *) NULL, /* icursorProc */
- (Tk_ItemSelectionProc *) NULL, /* selectionProc */
- (Tk_ItemInsertProc *) NULL, /* insertProc */
- (Tk_ItemDCharsProc *) NULL, /* dTextProc */
- (Tk_ItemType *) NULL, /* nextPtr */
+ "image", /* name */
+ sizeof(ImageItem), /* itemSize */
+ CreateImage, /* createProc */
+ configSpecs, /* configSpecs */
+ ConfigureImage, /* configureProc */
+ ImageCoords, /* coordProc */
+ DeleteImage, /* deleteProc */
+ DisplayImage, /* displayProc */
+ TK_CONFIG_OBJS, /* flags */
+ ImageToPoint, /* pointProc */
+ ImageToArea, /* areaProc */
+ ImageToPostscript, /* postscriptProc */
+ ScaleImage, /* scaleProc */
+ TranslateImage, /* translateProc */
+ NULL, /* indexProc */
+ NULL, /* icursorProc */
+ NULL, /* selectionProc */
+ NULL, /* insertProc */
+ NULL, /* dTextProc */
+ NULL, /* nextPtr */
};
/*
@@ -142,14 +136,13 @@ Tk_ItemType tkImageType = {
*
* CreateImage --
*
- * This procedure is invoked to create a new image
- * item in a canvas.
+ * This function is invoked to create a new image item in a canvas.
*
* Results:
- * A standard Tcl return value. If an error occurred in
- * creating the item, then an error message is left in
- * the interp's result; in this case itemPtr is left uninitialized,
- * so it can be safely freed by the caller.
+ * A standard Tcl return value. If an error occurred in creating the
+ * item, then an error message is left in the interp's result; in this
+ * case itemPtr is left uninitialized, so it can be safely freed by the
+ * caller.
*
* Side effects:
* A new image item is created.
@@ -158,19 +151,19 @@ Tk_ItemType tkImageType = {
*/
static int
-CreateImage(interp, canvas, itemPtr, objc, objv)
- 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 objc; /* Number of arguments in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing rectangle. */
+CreateImage(
+ 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 objc, /* Number of arguments in objv. */
+ Tcl_Obj *CONST objv[]) /* Arguments describing rectangle. */
{
ImageItem *imgPtr = (ImageItem *) itemPtr;
int i;
if (objc == 0) {
- panic("canvas did not pass any coords\n");
+ Tcl_Panic("canvas did not pass any coords\n");
}
/*
@@ -187,8 +180,8 @@ CreateImage(interp, canvas, itemPtr, objc, objv)
imgPtr->disabledImage = NULL;
/*
- * Process the arguments to fill in the item record.
- * Only 1 (list) or 2 (x y) coords are allowed.
+ * Process the arguments to fill in the item record. Only 1 (list) or 2 (x
+ * y) coords are allowed.
*/
if (objc == 1) {
@@ -207,7 +200,7 @@ CreateImage(interp, canvas, itemPtr, objc, objv)
return TCL_OK;
}
- error:
+ error:
DeleteImage(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
return TCL_ERROR;
}
@@ -217,9 +210,8 @@ CreateImage(interp, canvas, itemPtr, objc, objv)
*
* ImageCoords --
*
- * This procedure is invoked to process the "coords" widget
- * command on image items. See the user documentation for
- * details on what it does.
+ * This function is invoked to process the "coords" widget command on
+ * image items. See the user documentation for details on what it does.
*
* Results:
* Returns TCL_OK or TCL_ERROR, and sets the interp's result.
@@ -231,20 +223,19 @@ CreateImage(interp, canvas, itemPtr, objc, objv)
*/
static int
-ImageCoords(interp, canvas, itemPtr, objc, objv)
- 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 objc; /* Number of coordinates supplied in
- * objv. */
- Tcl_Obj *CONST objv[]; /* Array of coordinates: x1, y1,
- * x2, y2, ... */
+ImageCoords(
+ 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 objc, /* Number of coordinates supplied in objv. */
+ Tcl_Obj *CONST objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */
{
ImageItem *imgPtr = (ImageItem *) itemPtr;
if (objc == 0) {
Tcl_Obj *obj = Tcl_NewObj();
+
Tcl_Obj *subobj = Tcl_NewDoubleObj(imgPtr->x);
Tcl_ListObjAppendElement(interp, obj, subobj);
subobj = Tcl_NewDoubleObj(imgPtr->y);
@@ -271,7 +262,7 @@ ImageCoords(interp, canvas, itemPtr, objc, objv)
ComputeImageBbox(canvas, imgPtr);
} else {
char buf[64];
-
+
sprintf(buf, "wrong # coordinates: expected 0 or 2, got %d", objc);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_ERROR;
@@ -284,12 +275,12 @@ ImageCoords(interp, canvas, itemPtr, objc, objv)
*
* ConfigureImage --
*
- * This procedure is invoked to configure various aspects
- * of an image item, such as its anchor position.
+ * This function is invoked to configure various aspects of an image
+ * item, such as its anchor position.
*
* Results:
- * A standard Tcl result code. If an error occurs, then
- * an error message is left in the interp's result.
+ * A standard Tcl result code. If an error occurs, then an error message
+ * is left in the interp's result.
*
* Side effects:
* Configuration information may be set for itemPtr.
@@ -298,13 +289,13 @@ ImageCoords(interp, canvas, itemPtr, objc, objv)
*/
static int
-ConfigureImage(interp, canvas, itemPtr, objc, objv, flags)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Canvas canvas; /* Canvas containing itemPtr. */
- Tk_Item *itemPtr; /* Image item to reconfigure. */
- int objc; /* Number of elements in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing things to configure. */
- int flags; /* Flags to pass to Tk_ConfigureWidget. */
+ConfigureImage(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_Canvas canvas, /* Canvas containing itemPtr. */
+ Tk_Item *itemPtr, /* Image item to reconfigure. */
+ int objc, /* Number of elements in objv. */
+ Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */
+ int flags) /* Flags to pass to Tk_ConfigureWidget. */
{
ImageItem *imgPtr = (ImageItem *) itemPtr;
Tk_Window tkwin;
@@ -317,10 +308,10 @@ ConfigureImage(interp, canvas, itemPtr, objc, objv, flags)
}
/*
- * Create the image. Save the old image around and don't free it
- * until after the new one is allocated. This keeps the reference
- * count from going to zero so the image doesn't have to be recreated
- * if it hasn't changed.
+ * Create the image. Save the old image around and don't free it until
+ * after the new one is allocated. This keeps the reference count from
+ * going to zero so the image doesn't have to be recreated if it hasn't
+ * changed.
*/
if (imgPtr->activeImageString != NULL) {
@@ -376,8 +367,8 @@ ConfigureImage(interp, canvas, itemPtr, objc, objv, flags)
*
* DeleteImage --
*
- * This procedure is called to clean up the data structure
- * associated with a image item.
+ * This function is called to clean up the data structure associated with
+ * a image item.
*
* Results:
* None.
@@ -389,11 +380,10 @@ ConfigureImage(interp, canvas, itemPtr, objc, objv, flags)
*/
static void
-DeleteImage(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. */
+DeleteImage(
+ Tk_Canvas canvas, /* Info about overall canvas widget. */
+ Tk_Item *itemPtr, /* Item that is being deleted. */
+ Display *display) /* Display containing window for canvas. */
{
ImageItem *imgPtr = (ImageItem *) itemPtr;
@@ -422,27 +412,24 @@ DeleteImage(canvas, itemPtr, display)
*
* ComputeImageBbox --
*
- * This procedure is invoked to compute the bounding box of
- * all the pixels that may be drawn as part of a image item.
- * This procedure is where the child image's placement is
- * computed.
+ * This function is invoked to compute the bounding box of all the pixels
+ * that may be drawn as part of a image item. This function is where the
+ * child image's placement is computed.
*
* Results:
* None.
*
* Side effects:
- * The fields x1, y1, x2, and y2 are updated in the header
- * for itemPtr.
+ * The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static void
-ComputeImageBbox(canvas, imgPtr)
- Tk_Canvas canvas; /* Canvas that contains item. */
- ImageItem *imgPtr; /* Item whose bbox is to be
- * recomputed. */
+ComputeImageBbox(
+ Tk_Canvas canvas, /* Canvas that contains item. */
+ ImageItem *imgPtr) /* Item whose bbox is to be recomputed. */
{
int width, height;
int x, y;
@@ -478,36 +465,36 @@ ComputeImageBbox(canvas, imgPtr)
Tk_SizeOfImage(image, &width, &height);
switch (imgPtr->anchor) {
- case TK_ANCHOR_N:
- x -= width/2;
- break;
- case TK_ANCHOR_NE:
- x -= width;
- break;
- case TK_ANCHOR_E:
- x -= width;
- y -= height/2;
- break;
- case TK_ANCHOR_SE:
- x -= width;
- y -= height;
- break;
- case TK_ANCHOR_S:
- x -= width/2;
- y -= height;
- break;
- case TK_ANCHOR_SW:
- y -= height;
- break;
- case TK_ANCHOR_W:
- y -= height/2;
- break;
- case TK_ANCHOR_NW:
- break;
- case TK_ANCHOR_CENTER:
- x -= width/2;
- y -= height/2;
- break;
+ case TK_ANCHOR_N:
+ x -= width/2;
+ break;
+ case TK_ANCHOR_NE:
+ x -= width;
+ break;
+ case TK_ANCHOR_E:
+ x -= width;
+ y -= height/2;
+ break;
+ case TK_ANCHOR_SE:
+ x -= width;
+ y -= height;
+ break;
+ case TK_ANCHOR_S:
+ x -= width/2;
+ y -= height;
+ break;
+ case TK_ANCHOR_SW:
+ y -= height;
+ break;
+ case TK_ANCHOR_W:
+ y -= height/2;
+ break;
+ case TK_ANCHOR_NW:
+ break;
+ case TK_ANCHOR_CENTER:
+ x -= width/2;
+ y -= height/2;
+ break;
}
/*
@@ -525,35 +512,34 @@ ComputeImageBbox(canvas, imgPtr)
*
* DisplayImage --
*
- * This procedure is invoked to draw a image item in a given
- * drawable.
+ * This function is invoked to draw a image item in a given drawable.
*
* Results:
* None.
*
* Side effects:
- * ItemPtr is drawn in drawable using the transformation
- * information in canvas.
+ * ItemPtr is drawn in drawable using the transformation information in
+ * canvas.
*
*--------------------------------------------------------------
*/
static void
-DisplayImage(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). */
+DisplayImage(
+ 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, int y, int width, int height)
+ /* Describes region of canvas that must be
+ * redisplayed (not used). */
{
ImageItem *imgPtr = (ImageItem *) itemPtr;
short drawableX, drawableY;
Tk_Image image;
Tk_State state = itemPtr->state;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
@@ -587,14 +573,14 @@ DisplayImage(canvas, itemPtr, display, drawable, x, y, width, height)
*
* ImageToPoint --
*
- * Computes the distance from a given point to a given
- * rectangle, in canvas units.
+ * Computes the distance from a given point to a given rectangle, in
+ * canvas units.
*
* Results:
- * The return value is 0 if the point whose x and y coordinates
- * are coordPtr[0] and coordPtr[1] is inside the image. If the
- * point isn't inside the image then the return value is the
- * distance from the point to the image.
+ * The return value is 0 if the point whose x and y coordinates are
+ * coordPtr[0] and coordPtr[1] is inside the image. If the point isn't
+ * inside the image then the return value is the distance from the point
+ * to the image.
*
* Side effects:
* None.
@@ -603,10 +589,10 @@ DisplayImage(canvas, itemPtr, display, drawable, x, y, width, height)
*/
static double
-ImageToPoint(canvas, itemPtr, coordPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against point. */
- double *coordPtr; /* Pointer to x and y coordinates. */
+ImageToPoint(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against point. */
+ double *coordPtr) /* Pointer to x and y coordinates. */
{
ImageItem *imgPtr = (ImageItem *) itemPtr;
double x1, x2, y1, y2, xDiff, yDiff;
@@ -644,14 +630,13 @@ ImageToPoint(canvas, itemPtr, coordPtr)
*
* ImageToArea --
*
- * This procedure is called to determine whether an item
- * lies entirely inside, entirely outside, or overlapping
- * a given rectangle.
+ * This function is called to determine whether an item lies entirely
+ * inside, entirely outside, or overlapping a given rectangle.
*
* Results:
- * -1 is returned if the item is entirely outside the area
- * given by rectPtr, 0 if it overlaps, and 1 if it is entirely
- * inside the given area.
+ * -1 is returned if the item is entirely outside the area given by
+ * rectPtr, 0 if it overlaps, and 1 if it is entirely inside the given
+ * area.
*
* Side effects:
* None.
@@ -660,12 +645,12 @@ ImageToPoint(canvas, itemPtr, coordPtr)
*/
static int
-ImageToArea(canvas, itemPtr, rectPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against rectangle. */
- double *rectPtr; /* Pointer to array of four coordinates
- * (x1, y1, x2, y2) describing rectangular
- * area. */
+ImageToArea(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against rectangle. */
+ double *rectPtr) /* Pointer to array of four coordinates
+ * (x1,y1,x2,y2) describing rectangular
+ * area. */
{
ImageItem *imgPtr = (ImageItem *) itemPtr;
@@ -689,15 +674,13 @@ ImageToArea(canvas, itemPtr, rectPtr)
*
* ImageToPostscript --
*
- * This procedure is called to generate Postscript for
- * image items.
+ * This function is called to generate Postscript for image items.
*
* 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.
- * If no error occurs, then Postscript for the item is appended
- * to the result.
+ * 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. If no error occurs, then
+ * Postscript for the item is appended to the result.
*
* Side effects:
* None.
@@ -706,15 +689,13 @@ ImageToArea(canvas, itemPtr, rectPtr)
*/
static int
-ImageToPostscript(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.*/
+ImageToPostscript(
+ 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.*/
{
ImageItem *imgPtr = (ImageItem *)itemPtr;
Tk_Window canvasWin = Tk_CanvasTkwin(canvas);
@@ -725,7 +706,7 @@ ImageToPostscript(interp, canvas, itemPtr, prepass)
Tk_Image image;
Tk_State state = itemPtr->state;
- if (state == TK_STATE_NULL) {
+ if(state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
@@ -743,33 +724,34 @@ ImageToPostscript(interp, canvas, itemPtr, prepass)
/*
* Image item without actual image specified.
*/
- return TCL_OK;
+
+ return TCL_OK;
}
Tk_SizeOfImage(image, &width, &height);
/*
- * Compute the coordinates of the lower-left corner of the image,
- * taking into account the anchor position for the image.
+ * Compute the coordinates of the lower-left corner of the image, taking
+ * into account the anchor position for the image.
*/
x = imgPtr->x;
y = Tk_CanvasPsY(canvas, imgPtr->y);
switch (imgPtr->anchor) {
- case TK_ANCHOR_NW: y -= height; break;
- case TK_ANCHOR_N: x -= width/2.0; y -= height; break;
- case TK_ANCHOR_NE: x -= width; y -= height; break;
- case TK_ANCHOR_E: x -= width; y -= height/2.0; break;
- case TK_ANCHOR_SE: x -= width; break;
- case TK_ANCHOR_S: x -= width/2.0; break;
- case TK_ANCHOR_SW: break;
- case TK_ANCHOR_W: y -= height/2.0; break;
- case TK_ANCHOR_CENTER: x -= width/2.0; y -= height/2.0; break;
+ case TK_ANCHOR_NW: y -= height; break;
+ case TK_ANCHOR_N: x -= width/2.0; y -= height; break;
+ case TK_ANCHOR_NE: x -= width; y -= height; break;
+ case TK_ANCHOR_E: x -= width; y -= height/2.0; break;
+ case TK_ANCHOR_SE: x -= width; break;
+ case TK_ANCHOR_S: x -= width/2.0; break;
+ case TK_ANCHOR_SW: break;
+ case TK_ANCHOR_W: y -= height/2.0; break;
+ case TK_ANCHOR_CENTER: x -= width/2.0; y -= height/2.0; break;
}
if (!prepass) {
sprintf(buffer, "%.15g %.15g", x, y);
- Tcl_AppendResult(interp, buffer, " translate\n", (char *) NULL);
+ Tcl_AppendResult(interp, buffer, " translate\n", NULL);
}
return Tk_PostscriptImage(image, interp, canvasWin,
@@ -781,14 +763,14 @@ ImageToPostscript(interp, canvas, itemPtr, prepass)
*
* ScaleImage --
*
- * This procedure is invoked to rescale an item.
+ * This function is invoked to rescale an item.
*
* Results:
* None.
*
* Side effects:
- * The item referred to by itemPtr is rescaled so that the
- * following transformation is applied to all point coordinates:
+ * The item referred to by itemPtr is rescaled so that the following
+ * transformation is applied to all point coordinates:
* x' = originX + scaleX*(x-originX)
* y' = originY + scaleY*(y-originY)
*
@@ -796,12 +778,13 @@ ImageToPostscript(interp, canvas, itemPtr, prepass)
*/
static void
-ScaleImage(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. */
+ScaleImage(
+ Tk_Canvas canvas, /* Canvas containing rectangle. */
+ Tk_Item *itemPtr, /* Rectangle to be scaled. */
+ double originX, double originY,
+ /* Origin about which to scale rect. */
+ double scaleX, /* Amount to scale in X direction. */
+ double scaleY) /* Amount to scale in Y direction. */
{
ImageItem *imgPtr = (ImageItem *) itemPtr;
@@ -815,25 +798,24 @@ ScaleImage(canvas, itemPtr, originX, originY, scaleX, scaleY)
*
* TranslateImage --
*
- * This procedure is called to move an item by a given amount.
+ * This function is called to move an item by a given amount.
*
* Results:
* None.
*
* Side effects:
- * The position of the item is offset by (xDelta, yDelta), and
- * the bounding box is updated in the generic part of the item
- * structure.
+ * The position of the item is offset by (xDelta, yDelta), and the
+ * bounding box is updated in the generic part of the item structure.
*
*--------------------------------------------------------------
*/
static void
-TranslateImage(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. */
+TranslateImage(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item that is being moved. */
+ double deltaX, double deltaY)
+ /* Amount by which item is to be moved. */
{
ImageItem *imgPtr = (ImageItem *) itemPtr;
@@ -847,9 +829,9 @@ TranslateImage(canvas, itemPtr, deltaX, deltaY)
*
* ImageChangedProc --
*
- * This procedure is invoked by the image code whenever the manager
- * for an image does something that affects the image's size or
- * how it is displayed.
+ * This function is invoked by the image code whenever the manager for an
+ * image does something that affects the image's size or how it is
+ * displayed.
*
* Results:
* None.
@@ -861,21 +843,21 @@ TranslateImage(canvas, itemPtr, deltaX, deltaY)
*/
static void
-ImageChangedProc(clientData, x, y, width, height, imgWidth, imgHeight)
- ClientData clientData; /* Pointer to canvas item for image. */
- int x, y; /* Upper left pixel (within image)
- * that must be redisplayed. */
- int width, height; /* Dimensions of area to redisplay
- * (may be <= 0). */
- int imgWidth, imgHeight; /* New dimensions of image. */
+ImageChangedProc(
+ ClientData clientData, /* Pointer to canvas item for image. */
+ int x, int y, /* Upper left pixel (within image) that must
+ * be redisplayed. */
+ int width, int height, /* Dimensions of area to redisplay (may be <=
+ * 0). */
+ int imgWidth, int imgHeight)/* New dimensions of image. */
{
ImageItem *imgPtr = (ImageItem *) clientData;
/*
- * If the image's size changed and it's not anchored at its
- * northwest corner then just redisplay the entire area of the
- * image. This is a bit over-conservative, but we need to do
- * something because a size change also means a position change.
+ * If the image's size changed and it's not anchored at its northwest
+ * corner then just redisplay the entire area of the image. This is a bit
+ * over-conservative, but we need to do something because a size change
+ * also means a position change.
*/
if (((imgPtr->header.x2 - imgPtr->header.x1) != imgWidth)
@@ -885,9 +867,17 @@ ImageChangedProc(clientData, x, y, width, height, imgWidth, imgHeight)
height = imgHeight;
Tk_CanvasEventuallyRedraw(imgPtr->canvas, imgPtr->header.x1,
imgPtr->header.y1, imgPtr->header.x2, imgPtr->header.y2);
- }
+ }
ComputeImageBbox(imgPtr->canvas, imgPtr);
Tk_CanvasEventuallyRedraw(imgPtr->canvas, imgPtr->header.x1 + x,
imgPtr->header.y1 + y, (int) (imgPtr->header.x1 + x + width),
(int) (imgPtr->header.y1 + y + height));
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkCanvLine.c b/generic/tkCanvLine.c
index 4c7b9be..cce3460 100644
--- a/generic/tkCanvLine.c
+++ b/generic/tkCanvLine.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkCanvLine.c --
*
* This file implements line items for canvas widgets.
@@ -7,13 +7,12 @@
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <stdio.h>
#include "tkInt.h"
-#include "tkPort.h"
#include "tkCanvas.h"
/*
@@ -26,21 +25,21 @@ typedef enum {
typedef struct LineItem {
Tk_Item header; /* Generic stuff that's the same for all
- * types. MUST BE FIRST IN STRUCTURE. */
+ * types. MUST BE FIRST IN STRUCTURE. */
Tk_Outline outline; /* Outline structure */
- Tk_Canvas canvas; /* Canvas containing item. Needed for
- * parsing arrow shapes. */
+ Tk_Canvas canvas; /* Canvas containing item. Needed for parsing
+ * arrow shapes. */
int numPoints; /* Number of points in line (always >= 0). */
- double *coordPtr; /* Pointer to malloc-ed array containing
- * x- and y-coords of all points in line.
+ double *coordPtr; /* Pointer to malloc-ed array containing x-
+ * and y-coords of all points in line.
* X-coords are even-valued indices, y-coords
* are corresponding odd-valued indices. If
- * the line has arrowheads then the first
- * and last points have been adjusted to refer
- * to the necks of the arrowheads rather than
- * their tips. The actual endpoints are
- * stored in the *firstArrowPtr and
- * *lastArrowPtr, if they exist. */
+ * the line has arrowheads then the first and
+ * last points have been adjusted to refer to
+ * the necks of the arrowheads rather than
+ * their tips. The actual endpoints are stored
+ * in the *firstArrowPtr and *lastArrowPtr, if
+ * they exist. */
int capStyle; /* Cap style for line. */
int joinStyle; /* Join style for line. */
GC arrowGC; /* Graphics context for drawing arrowheads. */
@@ -53,13 +52,13 @@ typedef struct LineItem {
* edge of shaft. */
double *firstArrowPtr; /* Points to array of PTS_IN_ARROW points
* describing polygon for arrowhead at first
- * point in line. First point of arrowhead
- * is tip. Malloc'ed. NULL means no arrowhead
- * at first point. */
+ * point in line. First point of arrowhead is
+ * tip. Malloc'ed. NULL means no arrowhead at
+ * first point. */
double *lastArrowPtr; /* Points to polygon for arrowhead at last
* point in line (PTS_IN_ARROW points, first
- * of which is tip). Malloc'ed. NULL means
- * no arrowhead at last point. */
+ * of which is tip). Malloc'ed. NULL means no
+ * arrowhead at last point. */
Tk_SmoothMethod *smooth; /* Non-zero means draw line smoothed (i.e.
* with Bezier splines). */
int splineSteps; /* Number of steps in each spline segment. */
@@ -72,65 +71,63 @@ typedef struct LineItem {
#define PTS_IN_ARROW 6
/*
- * Prototypes for procedures defined in this file:
+ * Prototypes for functions defined in this file:
*/
-static int ArrowheadPostscript _ANSI_ARGS_((Tcl_Interp *interp,
+static int ArrowheadPostscript(Tcl_Interp *interp,
Tk_Canvas canvas, LineItem *linePtr,
- double *arrowPtr));
-static void ComputeLineBbox _ANSI_ARGS_((Tk_Canvas canvas,
- LineItem *linePtr));
-static int ConfigureLine _ANSI_ARGS_((Tcl_Interp *interp,
+ double *arrowPtr);
+static void ComputeLineBbox(Tk_Canvas canvas, LineItem *linePtr);
+static int ConfigureLine(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
- Tcl_Obj *CONST objv[], int flags));
-static int ConfigureArrows _ANSI_ARGS_((Tk_Canvas canvas,
- LineItem *linePtr));
-static int CreateLine _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *CONST objv[], int flags);
+static int ConfigureArrows(Tk_Canvas canvas, LineItem *linePtr);
+static int CreateLine(Tcl_Interp *interp,
Tk_Canvas canvas, struct Tk_Item *itemPtr,
- int objc, Tcl_Obj *CONST objv[]));
-static void DeleteLine _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, Display *display));
-static void DisplayLine _ANSI_ARGS_((Tk_Canvas canvas,
+ int objc, Tcl_Obj *CONST objv[]);
+static void DeleteLine(Tk_Canvas canvas,
+ Tk_Item *itemPtr, Display *display);
+static void DisplayLine(Tk_Canvas canvas,
Tk_Item *itemPtr, Display *display, Drawable dst,
- int x, int y, int width, int height));
-static int GetLineIndex _ANSI_ARGS_((Tcl_Interp *interp,
+ int x, int y, int width, int height);
+static int GetLineIndex(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr,
- Tcl_Obj *obj, int *indexPtr));
-static int LineCoords _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *obj, int *indexPtr);
+static int LineCoords(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr,
- int objc, Tcl_Obj *CONST objv[]));
-static void LineDeleteCoords _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, int first, int last));
-static void LineInsert _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, int beforeThis, Tcl_Obj *obj));
-static int LineToArea _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *rectPtr));
-static double LineToPoint _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *coordPtr));
-static int LineToPostscript _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));
-static int ArrowParseProc _ANSI_ARGS_((ClientData clientData,
+ int objc, Tcl_Obj *CONST objv[]);
+static void LineDeleteCoords(Tk_Canvas canvas,
+ Tk_Item *itemPtr, int first, int last);
+static void LineInsert(Tk_Canvas canvas,
+ Tk_Item *itemPtr, int beforeThis, Tcl_Obj *obj);
+static int LineToArea(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double *rectPtr);
+static double LineToPoint(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double *coordPtr);
+static int LineToPostscript(Tcl_Interp *interp,
+ Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
+static int ArrowParseProc(ClientData clientData,
Tcl_Interp *interp, Tk_Window tkwin,
- CONST char *value, char *recordPtr, int offset));
-static char * ArrowPrintProc _ANSI_ARGS_((ClientData clientData,
+ CONST char *value, char *recordPtr, int offset);
+static char * ArrowPrintProc(ClientData clientData,
Tk_Window tkwin, char *recordPtr, int offset,
- Tcl_FreeProc **freeProcPtr));
-static int ParseArrowShape _ANSI_ARGS_((ClientData clientData,
+ Tcl_FreeProc **freeProcPtr);
+static int ParseArrowShape(ClientData clientData,
Tcl_Interp *interp, Tk_Window tkwin,
- CONST char *value, char *recordPtr, int offset));
-static char * PrintArrowShape _ANSI_ARGS_((ClientData clientData,
+ CONST char *value, char *recordPtr, int offset);
+static char * PrintArrowShape(ClientData clientData,
Tk_Window tkwin, char *recordPtr, int offset,
- Tcl_FreeProc **freeProcPtr));
-static void ScaleLine _ANSI_ARGS_((Tk_Canvas canvas,
+ Tcl_FreeProc **freeProcPtr);
+static void ScaleLine(Tk_Canvas canvas,
Tk_Item *itemPtr, double originX, double originY,
- double scaleX, double scaleY));
-static void TranslateLine _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double deltaX, double deltaY));
+ double scaleX, double scaleY);
+static void TranslateLine(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double deltaX, double deltaY);
/*
- * Information used for parsing configuration specs. If you change any
- * of the default strings, be sure to change the corresponding default
- * values in CreateLine.
+ * Information used for parsing configuration specs. If you change any of the
+ * default strings, be sure to change the corresponding default values in
+ * CreateLine.
*/
static Tk_CustomOption arrowShapeOption = {
@@ -168,73 +165,65 @@ static Tk_CustomOption pixelOption = {
};
static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_CUSTOM, "-activedash", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(LineItem, outline.activeDash),
+ {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
+ NULL, Tk_Offset(LineItem, outline.activeDash),
TK_CONFIG_NULL_OK, &dashOption},
- {TK_CONFIG_COLOR, "-activefill", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(LineItem, outline.activeColor),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-activestipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(LineItem, outline.activeStipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-activewidth", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
+ NULL, Tk_Offset(LineItem, outline.activeColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
+ NULL, Tk_Offset(LineItem, outline.activeStipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
"0.0", Tk_Offset(LineItem, outline.activeWidth),
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
- {TK_CONFIG_CUSTOM, "-arrow", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_CUSTOM, "-arrow", NULL, NULL,
"none", Tk_Offset(LineItem, arrow), TK_CONFIG_DONT_SET_DEFAULT, &arrowOption},
- {TK_CONFIG_CUSTOM, "-arrowshape", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_CUSTOM, "-arrowshape", NULL, NULL,
"8 10 3", Tk_Offset(LineItem, arrowShapeA),
TK_CONFIG_DONT_SET_DEFAULT, &arrowShapeOption},
- {TK_CONFIG_CAP_STYLE, "-capstyle", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_CAP_STYLE, "-capstyle", NULL, NULL,
"butt", Tk_Offset(LineItem, capStyle), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_COLOR, "-fill", NULL, NULL,
"black", Tk_Offset(LineItem, outline.color), TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-dash", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(LineItem, outline.dash),
+ {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
+ NULL, Tk_Offset(LineItem, outline.dash),
TK_CONFIG_NULL_OK, &dashOption},
- {TK_CONFIG_PIXELS, "-dashoffset", (char *) NULL, (char *) NULL,
- "0", Tk_Offset(LineItem, outline.offset),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_CUSTOM, "-disableddash", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(LineItem, outline.disabledDash),
+ {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
+ "0", Tk_Offset(LineItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT},
+ {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
+ NULL, Tk_Offset(LineItem, outline.disabledDash),
TK_CONFIG_NULL_OK, &dashOption},
- {TK_CONFIG_COLOR, "-disabledfill", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(LineItem, outline.disabledColor),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-disabledstipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(LineItem, outline.disabledStipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-disabledwidth", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
+ NULL, Tk_Offset(LineItem, outline.disabledColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
+ NULL, Tk_Offset(LineItem, outline.disabledStipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
"0.0", Tk_Offset(LineItem, outline.disabledWidth),
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
- {TK_CONFIG_JOIN_STYLE, "-joinstyle", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_JOIN_STYLE, "-joinstyle", NULL, NULL,
"round", Tk_Offset(LineItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_CUSTOM, "-offset", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
"0,0", Tk_Offset(LineItem, outline.tsoffset),
TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
- {TK_CONFIG_CUSTOM, "-smooth", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_CUSTOM, "-smooth", NULL, NULL,
"0", Tk_Offset(LineItem, smooth),
TK_CONFIG_DONT_SET_DEFAULT, &smoothOption},
- {TK_CONFIG_INT, "-splinesteps", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_INT, "-splinesteps", NULL, NULL,
"12", Tk_Offset(LineItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
- &stateOption},
- {TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(LineItem, outline.stipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
- {TK_CONFIG_CUSTOM, "-width", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
+ NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
+ {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
+ NULL, Tk_Offset(LineItem, outline.stipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
+ NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
+ {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
"1.0", Tk_Offset(LineItem, outline.width),
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+ {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};
/*
- * The structures below defines the line item type by means
- * of procedures that can be invoked by generic item code.
+ * The structures below defines the line item type by means of functions that
+ * can be invoked by generic item code.
*/
Tk_ItemType tkLineType = {
@@ -253,17 +242,17 @@ Tk_ItemType tkLineType = {
ScaleLine, /* scaleProc */
TranslateLine, /* translateProc */
(Tk_ItemIndexProc *) GetLineIndex, /* indexProc */
- (Tk_ItemCursorProc *) NULL, /* icursorProc */
- (Tk_ItemSelectionProc *) NULL, /* selectionProc */
+ NULL, /* icursorProc */
+ NULL, /* selectionProc */
(Tk_ItemInsertProc *) LineInsert, /* insertProc */
LineDeleteCoords, /* dTextProc */
- (Tk_ItemType *) NULL, /* nextPtr */
+ NULL, /* nextPtr */
};
/*
- * 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).
+ * 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).
*/
#define MAX_STATIC_POINTS 200
@@ -273,14 +262,13 @@ Tk_ItemType tkLineType = {
*
* CreateLine --
*
- * This procedure is invoked to create a new line item in
- * a canvas.
+ * This function is invoked to create a new line item in a canvas.
*
* Results:
- * A standard Tcl return value. If an error occurred in
- * creating the item, then an error message is left in
- * the interp's result; in this case itemPtr is left uninitialized,
- * so it can be safely freed by the caller.
+ * A standard Tcl return value. If an error occurred in creating the
+ * item, then an error message is left in the interp's result; in this
+ * case itemPtr is left uninitialized, so it can be safely freed by the
+ * caller.
*
* Side effects:
* A new line item is created.
@@ -289,25 +277,24 @@ Tk_ItemType tkLineType = {
*/
static int
-CreateLine(interp, canvas, itemPtr, objc, objv)
- 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 objc; /* Number of arguments in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing line. */
+CreateLine(
+ 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 objc, /* Number of arguments in objv. */
+ Tcl_Obj *CONST objv[]) /* Arguments describing line. */
{
LineItem *linePtr = (LineItem *) itemPtr;
int i;
if (objc == 0) {
- panic("canvas did not pass any coords\n");
+ Tcl_Panic("canvas did not pass any coords\n");
}
/*
- * Carry out initialization that is needed to set defaults and to
- * allow proper cleanup after errors during the the remainder of
- * this procedure.
+ * Carry out initialization that is needed to set defaults and to allow
+ * proper cleanup after errors during the the remainder of this function.
*/
Tk_CreateOutline(&(linePtr->outline));
@@ -323,17 +310,18 @@ CreateLine(interp, canvas, itemPtr, objc, objv)
linePtr->arrowShapeC = (float)3.0;
linePtr->firstArrowPtr = NULL;
linePtr->lastArrowPtr = NULL;
- linePtr->smooth = (Tk_SmoothMethod *) NULL;
+ linePtr->smooth = NULL;
linePtr->splineSteps = 12;
/*
- * Count the number of points and then parse them into a point
- * array. Leading arguments are assumed to be points if they
- * start with a digit or a minus sign followed by a digit.
+ * Count the number of points and then parse them into a point array.
+ * Leading arguments are assumed to be points if they start with a digit
+ * or a minus sign followed by a digit.
*/
for (i = 1; i < objc; i++) {
char *arg = Tcl_GetString(objv[i]);
+
if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
break;
}
@@ -345,7 +333,7 @@ CreateLine(interp, canvas, itemPtr, objc, objv)
return TCL_OK;
}
- error:
+ error:
DeleteLine(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
return TCL_ERROR;
}
@@ -355,9 +343,8 @@ CreateLine(interp, canvas, itemPtr, objc, objv)
*
* LineCoords --
*
- * This procedure is invoked to process the "coords" widget
- * command on lines. See the user documentation for details
- * on what it does.
+ * This function is invoked to process the "coords" widget command on
+ * lines. See the user documentation for details on what it does.
*
* Results:
* Returns TCL_OK or TCL_ERROR, and sets the interp's result.
@@ -369,15 +356,13 @@ CreateLine(interp, canvas, itemPtr, objc, objv)
*/
static int
-LineCoords(interp, canvas, itemPtr, objc, objv)
- 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 objc; /* Number of coordinates supplied in
- * objv. */
- Tcl_Obj *CONST objv[]; /* Array of coordinates: x1, y1,
- * x2, y2, ... */
+LineCoords(
+ 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 objc, /* Number of coordinates supplied in objv. */
+ Tcl_Obj *CONST objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */
{
LineItem *linePtr = (LineItem *) itemPtr;
int i, numPoints;
@@ -414,20 +399,22 @@ LineCoords(interp, canvas, itemPtr, objc, objv)
}
if (objc & 1) {
char buf[64 + TCL_INTEGER_SPACE];
+
sprintf(buf, "wrong # coordinates: expected an even number, got %d",
objc);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_ERROR;
} else if (objc < 4) {
char buf[64 + TCL_INTEGER_SPACE];
+
sprintf(buf, "wrong # coordinates: expected at least 4, got %d", objc);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_ERROR;
} else {
numPoints = objc/2;
if (linePtr->numPoints != numPoints) {
- coordPtr = (double *) ckalloc((unsigned)
- (sizeof(double) * objc));
+ coordPtr = (double *)
+ ckalloc((unsigned) (sizeof(double) * objc));
if (linePtr->coordPtr != NULL) {
ckfree((char *) linePtr->coordPtr);
}
@@ -468,28 +455,28 @@ LineCoords(interp, canvas, itemPtr, objc, objv)
*
* ConfigureLine --
*
- * This procedure is invoked to configure various aspects
- * of a line item such as its background color.
+ * This function is invoked to configure various aspects of a line item
+ * such as its background color.
*
* Results:
- * A standard Tcl result code. If an error occurs, then
- * an error message is left in the interp's result.
+ * A standard Tcl result code. If an error occurs, then an error message
+ * is left in the interp's result.
*
* Side effects:
- * Configuration information, such as colors and stipple
- * patterns, may be set for itemPtr.
+ * Configuration information, such as colors and stipple patterns, may be
+ * set for itemPtr.
*
*--------------------------------------------------------------
*/
static int
-ConfigureLine(interp, canvas, itemPtr, objc, objv, flags)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Canvas canvas; /* Canvas containing itemPtr. */
- Tk_Item *itemPtr; /* Line item to reconfigure. */
- int objc; /* Number of elements in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing things to configure. */
- int flags; /* Flags to pass to Tk_ConfigureWidget. */
+ConfigureLine(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_Canvas canvas, /* Canvas containing itemPtr. */
+ Tk_Item *itemPtr, /* Line item to reconfigure. */
+ int objc, /* Number of elements in objv. */
+ Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */
+ int flags) /* Flags to pass to Tk_ConfigureWidget. */
{
LineItem *linePtr = (LineItem *) itemPtr;
XGCValues gcValues;
@@ -505,8 +492,8 @@ ConfigureLine(interp, canvas, itemPtr, objc, objv, flags)
}
/*
- * A few of the options require additional processing, such as
- * graphics contexts.
+ * A few of the options require additional processing, such as graphics
+ * contexts.
*/
state = itemPtr->state;
@@ -571,9 +558,8 @@ ConfigureLine(interp, canvas, itemPtr, objc, objv, flags)
}
/*
- * Setup arrowheads, if needed. If arrowheads are turned off,
- * restore the line's endpoints (they were shortened when the
- * arrowheads were added).
+ * Setup arrowheads, if needed. If arrowheads are turned off, restore the
+ * line's endpoints (they were shortened when the arrowheads were added).
*/
if ((linePtr->firstArrowPtr != NULL) && (linePtr->arrow != ARROWS_FIRST)
@@ -611,8 +597,8 @@ ConfigureLine(interp, canvas, itemPtr, objc, objv, flags)
*
* DeleteLine --
*
- * This procedure is called to clean up the data structure
- * associated with a line item.
+ * This function is called to clean up the data structure associated with
+ * a line item.
*
* Results:
* None.
@@ -624,11 +610,10 @@ ConfigureLine(interp, canvas, itemPtr, objc, objv, flags)
*/
static void
-DeleteLine(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. */
+DeleteLine(
+ Tk_Canvas canvas, /* Info about overall canvas widget. */
+ Tk_Item *itemPtr, /* Item that is being deleted. */
+ Display *display) /* Display containing window for canvas. */
{
LineItem *linePtr = (LineItem *) itemPtr;
@@ -652,24 +637,22 @@ DeleteLine(canvas, itemPtr, display)
*
* ComputeLineBbox --
*
- * This procedure is invoked to compute the bounding box of
- * all the pixels that may be drawn as part of a line.
+ * This function is invoked to compute the bounding box of all the pixels
+ * that may be drawn as part of a line.
*
* Results:
* None.
*
* Side effects:
- * The fields x1, y1, x2, and y2 are updated in the header
- * for itemPtr.
+ * The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
*
*--------------------------------------------------------------
*/
static void
-ComputeLineBbox(canvas, linePtr)
- Tk_Canvas canvas; /* Canvas that contains item. */
- LineItem *linePtr; /* Item whose bbos is to be
- * recomputed. */
+ComputeLineBbox(
+ Tk_Canvas canvas, /* Canvas that contains item. */
+ LineItem *linePtr) /* Item whose bbos is to be recomputed. */
{
double *coordPtr;
int i, intWidth;
@@ -705,13 +688,12 @@ ComputeLineBbox(canvas, linePtr)
linePtr->header.y1 = linePtr->header.y2 = (int) coordPtr[1];
/*
- * Compute the bounding box of all the points in the line,
- * then expand in all directions by the line's width to take
- * care of butting or rounded corners and projecting or
- * rounded caps. This expansion is an overestimate (worst-case
- * is square root of two over two) but it's simple. Don't do
- * anything special for curves. This causes an additional
- * overestimate in the bounding box, but is faster.
+ * Compute the bounding box of all the points in the line, then expand in
+ * all directions by the line's width to take care of butting or rounded
+ * corners and projecting or rounded caps. This expansion is an
+ * overestimate (worst-case is square root of two over two) but it's
+ * simple. eDon't do anything special for curves. This causes an
+ * additional overestimate in the bounding box, but is faster.
*/
for (i = 1, coordPtr = linePtr->coordPtr+2; i < linePtr->numPoints;
@@ -780,9 +762,9 @@ ComputeLineBbox(canvas, linePtr)
}
/*
- * For mitered lines, make a second pass through all the points.
- * Compute the locations of the two miter vertex points and add
- * those into the bounding box.
+ * For mitered lines, make a second pass through all the points. Compute
+ * the locations of the two miter vertex points and add those into the
+ * bounding box.
*/
if (linePtr->joinStyle == JoinMiter) {
@@ -790,7 +772,7 @@ ComputeLineBbox(canvas, linePtr)
i--, coordPtr += 2) {
double miter[4];
int j;
-
+
if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4,
width, miter, miter+2)) {
for (j = 0; j < 4; j += 2) {
@@ -820,8 +802,8 @@ ComputeLineBbox(canvas, linePtr)
}
/*
- * Add one more pixel of fudge factor just to be safe (e.g.
- * X may round differently than we do).
+ * Add one more pixel of fudge factor just to be safe (e.g. X may round
+ * differently than we do).
*/
linePtr->header.x1 -= 1;
@@ -835,28 +817,27 @@ ComputeLineBbox(canvas, linePtr)
*
* DisplayLine --
*
- * This procedure is invoked to draw a line item in a given
- * drawable.
+ * This function is invoked to draw a line item in a given drawable.
*
* Results:
* None.
*
* Side effects:
- * ItemPtr is drawn in drawable using the transformation
- * information in canvas.
+ * ItemPtr is drawn in drawable using the transformation information in
+ * canvas.
*
*--------------------------------------------------------------
*/
static void
-DisplayLine(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). */
+DisplayLine(
+ 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, int y, int width, int height)
+ /* Describes region of canvas that must be
+ * redisplayed (not used). */
{
LineItem *linePtr = (LineItem *) itemPtr;
XPoint staticPoints[MAX_STATIC_POINTS*3];
@@ -883,16 +864,15 @@ DisplayLine(canvas, itemPtr, display, drawable, x, y, width, height)
}
}
/*
- * Build up an array of points in screen coordinates. Use a
- * static array unless the line has an enormous number of points;
- * in this case, dynamically allocate an array. For smoothed lines,
- * generate the curve points on each redisplay.
+ * Build up an array of points in screen coordinates. Use a static array
+ * unless the line has an enormous number of points; in this case,
+ * dynamically allocate an array. For smoothed lines, generate the curve
+ * points on each redisplay.
*/
if ((linePtr->smooth) && (linePtr->numPoints > 2)) {
- numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL,
- linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,
- (double *) NULL);
+ numPoints = linePtr->smooth->coordProc(canvas, NULL,
+ linePtr->numPoints, linePtr->splineSteps, NULL, NULL);
} else {
numPoints = linePtr->numPoints;
}
@@ -905,18 +885,17 @@ DisplayLine(canvas, itemPtr, display, drawable, x, y, width, height)
if ((linePtr->smooth) && (linePtr->numPoints > 2)) {
numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
- linePtr->numPoints, linePtr->splineSteps, pointPtr,
- (double *) NULL);
+ linePtr->numPoints, linePtr->splineSteps, pointPtr, NULL);
} else {
numPoints = TkCanvTranslatePath((TkCanvas*)canvas, numPoints,
linePtr->coordPtr, 0, pointPtr);
}
/*
- * Display line, the free up line storage if it was dynamically
- * allocated. If we're stippling, then modify the stipple offset
- * in the GC. Be sure to reset the offset when done, since the
- * GC is supposed to be read-only.
+ * Display line, the free up line storage if it was dynamically allocated.
+ * If we're stippling, then modify the stipple offset in the GC. Be sure
+ * to reset the offset when done, since the GC is supposed to be
+ * read-only.
*/
if (Tk_ChangeOutlineGC(canvas, itemPtr, &(linePtr->outline))) {
@@ -972,24 +951,24 @@ DisplayLine(canvas, itemPtr, display, drawable, x, y, width, height)
*/
static void
-LineInsert(canvas, itemPtr, beforeThis, obj)
- Tk_Canvas canvas; /* Canvas containing text item. */
- Tk_Item *itemPtr; /* Line item to be modified. */
- int beforeThis; /* Index before which new coordinates
- * are to be inserted. */
- Tcl_Obj *obj; /* New coordinates to be inserted. */
+LineInsert(
+ Tk_Canvas canvas, /* Canvas containing text item. */
+ Tk_Item *itemPtr, /* Line item to be modified. */
+ int beforeThis, /* Index before which new coordinates are to
+ * be inserted. */
+ Tcl_Obj *obj) /* New coordinates to be inserted. */
{
LineItem *linePtr = (LineItem *) itemPtr;
int length, objc, i;
- double *new, *coordPtr;
+ double *newCoordPtr, *coordPtr;
Tk_State state = itemPtr->state;
Tcl_Obj **objv;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
- if (!obj || (Tcl_ListObjGetElements((Tcl_Interp *) NULL, obj, &objc, &objv) != TCL_OK)
+ if (!obj || (Tcl_ListObjGetElements(NULL, obj, &objc, &objv) != TCL_OK)
|| !objc || objc&1) {
return;
}
@@ -1008,38 +987,40 @@ LineInsert(canvas, itemPtr, beforeThis, obj)
linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0];
linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1];
}
- new = (double *) ckalloc((unsigned)(sizeof(double) * (length + objc)));
- for(i=0; i<beforeThis; i++) {
- new[i] = linePtr->coordPtr[i];
+ newCoordPtr = (double *)
+ ckalloc(sizeof(double) * (unsigned)(length + objc));
+ for (i=0; i<beforeThis; i++) {
+ newCoordPtr[i] = linePtr->coordPtr[i];
}
- for(i=0; i<objc; i++) {
- if (Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,objv[i],
- new+(i+beforeThis))!=TCL_OK) {
+ for (i=0; i<objc; i++) {
+ if (Tcl_GetDoubleFromObj(NULL, objv[i],
+ &newCoordPtr[i + beforeThis]) != TCL_OK) {
Tcl_ResetResult(((TkCanvas *)canvas)->interp);
- ckfree((char *) new);
+ ckfree((char *) newCoordPtr);
return;
}
}
- for(i=beforeThis; i<length; i++) {
- new[i+objc] = linePtr->coordPtr[i];
+ for (i=beforeThis; i<length; i++) {
+ newCoordPtr[i+objc] = linePtr->coordPtr[i];
}
if (linePtr->coordPtr) {
ckfree((char *) linePtr->coordPtr);
}
- linePtr->coordPtr = new;
+ linePtr->coordPtr = newCoordPtr;
length += objc;
linePtr->numPoints = length / 2;
if ((length>3) && (state != TK_STATE_HIDDEN)) {
/*
- * This is some optimizing code that will result that only the part
- * of the polygon that changed (and the objects that are overlapping
- * with that part) need to be redrawn. A special flag is set that
- * instructs the general canvas code not to redraw the whole
- * object. If this flag is not set, the canvas will do the redrawing,
- * otherwise I have to do it here.
+ * This is some optimizing code that will result that only the part of
+ * the polygon that changed (and the objects that are overlapping with
+ * that part) need to be redrawn. A special flag is set that instructs
+ * the general canvas code not to redraw the whole object. If this
+ * flag is not set, the canvas will do the redrawing, otherwise I have
+ * to do it here.
*/
+
itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;
if (beforeThis>0) {beforeThis -= 2; objc+=2; }
@@ -1055,23 +1036,29 @@ LineInsert(canvas, itemPtr, beforeThis, obj)
itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[beforeThis];
itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[beforeThis+1];
if ((linePtr->firstArrowPtr != NULL) && (beforeThis<1)) {
- /* include old first arrow */
+ /*
+ * Include old first arrow.
+ */
+
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
i++, coordPtr += 2) {
TkIncludePoint(itemPtr, coordPtr);
}
}
if ((linePtr->lastArrowPtr != NULL) && ((beforeThis+objc)>=length)) {
- /* include old last arrow */
+ /*
+ * Include old last arrow.
+ */
+
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
i++, coordPtr += 2) {
TkIncludePoint(itemPtr, coordPtr);
}
}
coordPtr = linePtr->coordPtr+beforeThis+2;
- for(i=2; i<objc; i+=2) {
+ for (i=2; i<objc; i+=2) {
TkIncludePoint(itemPtr, coordPtr);
- coordPtr+=2;
+ coordPtr+=2;
}
}
if (linePtr->firstArrowPtr != NULL) {
@@ -1083,21 +1070,28 @@ LineInsert(canvas, itemPtr, beforeThis, obj)
linePtr->lastArrowPtr = NULL;
}
if (linePtr->arrow != ARROWS_NONE) {
- ConfigureArrows(canvas, linePtr);
+ ConfigureArrows(canvas, linePtr);
}
- if(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
+ if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
double width;
int intWidth;
+
if ((linePtr->firstArrowPtr != NULL) && (beforeThis>2)) {
- /* include new first arrow */
+ /*
+ * Include new first arrow.
+ */
+
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
i++, coordPtr += 2) {
TkIncludePoint(itemPtr, coordPtr);
}
}
- if ((linePtr->lastArrowPtr != NULL) && ((beforeThis+objc)<(length-2))) {
- /* include new right arrow */
+ if ((linePtr->lastArrowPtr != NULL) && (beforeThis+objc < length-2)) {
+ /*
+ * Include new right arrow.
+ */
+
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
i++, coordPtr += 2) {
TkIncludePoint(itemPtr, coordPtr);
@@ -1105,13 +1099,13 @@ LineInsert(canvas, itemPtr, beforeThis, obj)
}
width = linePtr->outline.width;
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
- if (linePtr->outline.activeWidth>width) {
- width = linePtr->outline.activeWidth;
- }
+ if (linePtr->outline.activeWidth>width) {
+ width = linePtr->outline.activeWidth;
+ }
} else if (state==TK_STATE_DISABLED) {
- if (linePtr->outline.disabledWidth>0) {
- width = linePtr->outline.disabledWidth;
- }
+ if (linePtr->outline.disabledWidth>0) {
+ width = linePtr->outline.disabledWidth;
+ }
}
intWidth = (int) (width + 0.5);
if (intWidth < 1) {
@@ -1137,18 +1131,18 @@ LineInsert(canvas, itemPtr, beforeThis, obj)
* None.
*
* Side effects:
- * Characters between "first" and "last", inclusive, get
- * deleted from itemPtr.
+ * Characters between "first" and "last", inclusive, get deleted from
+ * itemPtr.
*
*--------------------------------------------------------------
*/
static void
-LineDeleteCoords(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. */
+LineDeleteCoords(
+ 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. */
{
LineItem *linePtr = (LineItem *) itemPtr;
int count, i, first1, last1;
@@ -1156,7 +1150,7 @@ LineDeleteCoords(canvas, itemPtr, first, last)
double *coordPtr;
Tk_State state = itemPtr->state;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
@@ -1180,36 +1174,51 @@ LineDeleteCoords(canvas, itemPtr, first, last)
linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0];
linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1];
}
- first1 = first; last1 = last;
- if(first1>0) first1 -= 2;
- if(last1<length-2) last1 += 2;
+ first1 = first;
+ last1 = last;
+ if (first1 > 0) {
+ first1 -= 2;
+ }
+ if (last1 < length-2) {
+ last1 += 2;
+ }
if (linePtr->smooth) {
- if(first1>0) first1 -= 2;
- if(last1<length-2) last1 += 2;
+ if (first1 > 0) {
+ first1 -= 2;
+ }
+ if (last1 < length-2) {
+ last1 += 2;
+ }
}
- if((first1<2) && (last1 >= length-2)) {
+ if (!(first1 < 2) && (last1 >= length-2)) {
/*
- * This is some optimizing code that will result that only the part
- * of the line that changed (and the objects that are overlapping
- * with that part) need to be redrawn. A special flag is set that
- * instructs the general canvas code not to redraw the whole
- * object. If this flag is set, the redrawing has to be done here,
- * otherwise the general Canvas code will take care of it.
+ * This is some optimizing code that will result that only the part of
+ * the line that changed (and the objects that are overlapping with
+ * that part) need to be redrawn. A special flag is set that instructs
+ * the general canvas code not to redraw the whole object. If this
+ * flag is set, the redrawing has to be done here, otherwise the
+ * general Canvas code will take care of it.
*/
itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;
itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[first1];
itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[first1+1];
- if ((linePtr->firstArrowPtr != NULL) && (first1<2)) {
- /* include old first arrow */
+ if ((linePtr->firstArrowPtr != NULL) && (first1 < 2)) {
+ /*
+ * Include old first arrow.
+ */
+
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
i++, coordPtr += 2) {
TkIncludePoint(itemPtr, coordPtr);
}
}
- if ((linePtr->lastArrowPtr != NULL) && (last1>=length-2)) {
- /* include old last arrow */
+ if ((linePtr->lastArrowPtr != NULL) && (last1 >= length-2)) {
+ /*
+ * Include old last arrow.
+ */
+
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
i++, coordPtr += 2) {
TkIncludePoint(itemPtr, coordPtr);
@@ -1218,7 +1227,7 @@ LineDeleteCoords(canvas, itemPtr, first, last)
coordPtr = linePtr->coordPtr+first1+2;
for (i=first1+2; i<=last1; i+=2) {
TkIncludePoint(itemPtr, coordPtr);
- coordPtr+=2;
+ coordPtr += 2;
}
}
@@ -1236,20 +1245,27 @@ LineDeleteCoords(canvas, itemPtr, first, last)
linePtr->lastArrowPtr = NULL;
}
if (linePtr->arrow != ARROWS_NONE) {
- ConfigureArrows(canvas, linePtr);
+ ConfigureArrows(canvas, linePtr);
}
- if(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
+ if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
double width;
int intWidth;
- if ((linePtr->firstArrowPtr != NULL) && (first1<4)) {
- /* include new first arrow */
+
+ if ((linePtr->firstArrowPtr != NULL) && (first1 < 4)) {
+ /*
+ * Include new first arrow.
+ */
+
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
i++, coordPtr += 2) {
TkIncludePoint(itemPtr, coordPtr);
}
}
- if ((linePtr->lastArrowPtr != NULL) && (last1>(length-4))) {
- /* include new right arrow */
+ if ((linePtr->lastArrowPtr != NULL) && (last1 > length-4)) {
+ /*
+ * Include new right arrow.
+ */
+
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
i++, coordPtr += 2) {
TkIncludePoint(itemPtr, coordPtr);
@@ -1257,20 +1273,22 @@ LineDeleteCoords(canvas, itemPtr, first, last)
}
width = linePtr->outline.width;
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
- if (linePtr->outline.activeWidth>width) {
- width = linePtr->outline.activeWidth;
- }
+ if (linePtr->outline.activeWidth > width) {
+ width = linePtr->outline.activeWidth;
+ }
} else if (state==TK_STATE_DISABLED) {
- if (linePtr->outline.disabledWidth>0) {
- width = linePtr->outline.disabledWidth;
- }
+ if (linePtr->outline.disabledWidth > 0) {
+ width = linePtr->outline.disabledWidth;
+ }
}
intWidth = (int) (width + 0.5);
if (intWidth < 1) {
intWidth = 1;
}
- itemPtr->x1 -= intWidth; itemPtr->y1 -= intWidth;
- itemPtr->x2 += intWidth; itemPtr->y2 += intWidth;
+ itemPtr->x1 -= intWidth;
+ itemPtr->y1 -= intWidth;
+ itemPtr->x2 += intWidth;
+ itemPtr->y2 += intWidth;
Tk_CanvasEventuallyRedraw(canvas, itemPtr->x1, itemPtr->y1,
itemPtr->x2, itemPtr->y2);
}
@@ -1282,14 +1300,14 @@ LineDeleteCoords(canvas, itemPtr, first, last)
*
* LineToPoint --
*
- * Computes the distance from a given point to a given
- * line, in canvas units.
+ * Computes the distance from a given point to a given line, in canvas
+ * units.
*
* Results:
- * The return value is 0 if the point whose x and y coordinates
- * are pointPtr[0] and pointPtr[1] is inside the line. If the
- * point isn't inside the line then the return value is the
- * distance from the point to the line.
+ * The return value is 0 if the point whose x and y coordinates are
+ * pointPtr[0] and pointPtr[1] is inside the line. If the point isn't
+ * inside the line then the return value is the distance from the point
+ * to the line.
*
* Side effects:
* None.
@@ -1299,10 +1317,10 @@ LineDeleteCoords(canvas, itemPtr, first, last)
/* ARGSUSED */
static double
-LineToPoint(canvas, itemPtr, pointPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against point. */
- double *pointPtr; /* Pointer to x and y coordinates. */
+LineToPoint(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against point. */
+ double *pointPtr) /* Pointer to x and y coordinates. */
{
Tk_State state = itemPtr->state;
LineItem *linePtr = (LineItem *) itemPtr;
@@ -1311,15 +1329,15 @@ LineToPoint(canvas, itemPtr, pointPtr)
double poly[10];
double bestDist, dist, width;
int numPoints, count;
- int changedMiterToBevel; /* Non-zero means that a mitered corner
- * had to be treated as beveled after all
- * because the angle was < 11 degrees. */
+ int changedMiterToBevel; /* Non-zero means that a mitered corner had to
+ * be treated as beveled after all because the
+ * angle was < 11 degrees. */
bestDist = 1.0e36;
/*
- * Handle smoothed lines by generating an expanded set of points
- * against which to do the check.
+ * Handle smoothed lines by generating an expanded set of points against
+ * which to do the check.
*/
if(state == TK_STATE_NULL) {
@@ -1338,9 +1356,8 @@ LineToPoint(canvas, itemPtr, pointPtr)
}
if ((linePtr->smooth) && (linePtr->numPoints > 2)) {
- numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL,
- linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,
- (double *) NULL);
+ numPoints = linePtr->smooth->coordProc(canvas, NULL,
+ linePtr->numPoints, linePtr->splineSteps, NULL, NULL);
if (numPoints <= MAX_STATIC_POINTS) {
linePoints = staticSpace;
} else {
@@ -1348,8 +1365,7 @@ LineToPoint(canvas, itemPtr, pointPtr)
(2*numPoints*sizeof(double)));
}
numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
- linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,
- linePoints);
+ linePtr->numPoints, linePtr->splineSteps, NULL, linePoints);
} else {
numPoints = linePtr->numPoints;
linePoints = linePtr->coordPtr;
@@ -1362,26 +1378,25 @@ LineToPoint(canvas, itemPtr, pointPtr)
if (!numPoints || itemPtr->state==TK_STATE_HIDDEN) {
return bestDist;
} else if (numPoints == 1) {
- bestDist = hypot(linePoints[0] - pointPtr[0], linePoints[1] - pointPtr[1])
- - width/2.0;
+ bestDist = hypot(linePoints[0]-pointPtr[0], linePoints[1]-pointPtr[1])
+ - width/2.0;
if (bestDist < 0) bestDist = 0;
return bestDist;
}
/*
- * The overall idea is to iterate through all of the edges of
- * the line, computing a polygon for each edge and testing the
- * point against that polygon. In addition, there are additional
- * tests to deal with rounded joints and caps.
+ * The overall idea is to iterate through all of the edges of the line,
+ * computing a polygon for each edge and testing the point against that
+ * polygon. In addition, there are additional tests to deal with rounded
+ * joints and caps.
*/
changedMiterToBevel = 0;
for (count = numPoints, coordPtr = linePoints; count >= 2;
count--, coordPtr += 2) {
-
/*
- * If rounding is done around the first point then compute
- * the distance between the point and the point.
+ * If rounding is done around the first point then compute the
+ * distance between the point and the point.
*/
if (((linePtr->capStyle == CapRound) && (count == numPoints))
@@ -1398,9 +1413,9 @@ LineToPoint(canvas, itemPtr, pointPtr)
}
/*
- * Compute the polygonal shape corresponding to this edge,
- * consisting of two points for the first point of the edge
- * and two points for the last point of the edge.
+ * Compute the polygonal shape corresponding to this edge, consisting
+ * of two points for the first point of the edge and two points for
+ * the last point of the edge.
*/
if (count == numPoints) {
@@ -1412,14 +1427,13 @@ LineToPoint(canvas, itemPtr, pointPtr)
poly[2] = poly[4];
poly[3] = poly[5];
} else {
- TkGetButtPoints(coordPtr+2, coordPtr, width, 0,
- poly, poly+2);
+ TkGetButtPoints(coordPtr+2, coordPtr, width, 0, poly, poly+2);
/*
- * If this line uses beveled joints, then check the distance
- * to a polygon comprising the last two points of the previous
- * polygon and the first two from this polygon; this checks
- * the wedges that fill the mitered joint.
+ * If this line uses beveled joints, then check the distance to a
+ * polygon comprising the last two points of the previous polygon
+ * and the first two from this polygon; this checks the wedges
+ * that fill the mitered joint.
*/
if ((linePtr->joinStyle == JoinBevel) || changedMiterToBevel) {
@@ -1442,8 +1456,8 @@ LineToPoint(canvas, itemPtr, pointPtr)
if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4,
width, poly+4, poly+6) == 0) {
changedMiterToBevel = 1;
- TkGetButtPoints(coordPtr, coordPtr+2, width,
- 0, poly+4, poly+6);
+ TkGetButtPoints(coordPtr, coordPtr+2, width, 0,
+ poly+4, poly+6);
}
} else {
TkGetButtPoints(coordPtr, coordPtr+2, width, 0,
@@ -1461,8 +1475,8 @@ LineToPoint(canvas, itemPtr, pointPtr)
}
/*
- * If caps are rounded, check the distance to the cap around the
- * final end point of the line.
+ * If caps are rounded, check the distance to the cap around the final end
+ * point of the line.
*/
if (linePtr->capStyle == CapRound) {
@@ -1503,7 +1517,7 @@ LineToPoint(canvas, itemPtr, pointPtr)
}
}
- done:
+ done:
if ((linePoints != staticSpace) && (linePoints != linePtr->coordPtr)) {
ckfree((char *) linePoints);
}
@@ -1515,14 +1529,12 @@ LineToPoint(canvas, itemPtr, pointPtr)
*
* LineToArea --
*
- * This procedure is called to determine whether an item
- * lies entirely inside, entirely outside, or overlapping
- * a given rectangular area.
+ * This function is called to determine whether an item lies entirely
+ * inside, entirely outside, or overlapping a given rectangular area.
*
* Results:
- * -1 is returned if the item is entirely outside the
- * area, 0 if it overlaps, and 1 if it is entirely
- * inside the given area.
+ * -1 is returned if the item is entirely outside the area, 0 if it
+ * overlaps, and 1 if it is entirely inside the given area.
*
* Side effects:
* None.
@@ -1532,10 +1544,10 @@ LineToPoint(canvas, itemPtr, pointPtr)
/* ARGSUSED */
static int
-LineToArea(canvas, itemPtr, rectPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against line. */
- double *rectPtr;
+LineToArea(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against line. */
+ double *rectPtr)
{
LineItem *linePtr = (LineItem *) itemPtr;
double staticSpace[2*MAX_STATIC_POINTS];
@@ -1564,6 +1576,7 @@ LineToArea(canvas, itemPtr, rectPtr)
return -1;
} else if (linePtr->numPoints == 1) {
double oval[4];
+
oval[0] = linePtr->coordPtr[0]-radius;
oval[1] = linePtr->coordPtr[1]-radius;
oval[2] = linePtr->coordPtr[0]+radius;
@@ -1572,14 +1585,13 @@ LineToArea(canvas, itemPtr, rectPtr)
}
/*
- * Handle smoothed lines by generating an expanded set of points
- * against which to do the check.
+ * Handle smoothed lines by generating an expanded set of points against
+ * which to do the check.
*/
if ((linePtr->smooth) && (linePtr->numPoints > 2)) {
- numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL,
- linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,
- (double *) NULL);
+ numPoints = linePtr->smooth->coordProc(canvas, NULL,
+ linePtr->numPoints, linePtr->splineSteps, NULL, NULL);
if (numPoints <= MAX_STATIC_POINTS) {
linePoints = staticSpace;
} else {
@@ -1587,8 +1599,7 @@ LineToArea(canvas, itemPtr, rectPtr)
(2*numPoints*sizeof(double)));
}
numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
- linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,
- linePoints);
+ linePtr->numPoints, linePtr->splineSteps, NULL, linePoints);
} else {
numPoints = linePtr->numPoints;
linePoints = linePtr->coordPtr;
@@ -1602,7 +1613,7 @@ LineToArea(canvas, itemPtr, rectPtr)
width = 1.0;
}
- result = TkThickPolyLineToArea(linePoints, numPoints,
+ result = TkThickPolyLineToArea(linePoints, numPoints,
width, linePtr->capStyle, linePtr->joinStyle,
rectPtr);
if (result == 0) {
@@ -1630,7 +1641,7 @@ LineToArea(canvas, itemPtr, rectPtr)
}
}
- done:
+ done:
if ((linePoints != staticSpace) && (linePoints != linePtr->coordPtr)) {
ckfree((char *) linePoints);
}
@@ -1642,15 +1653,14 @@ LineToArea(canvas, itemPtr, rectPtr)
*
* ScaleLine --
*
- * This procedure is invoked to rescale a line item.
+ * This function is invoked to rescale a line item.
*
* Results:
* None.
*
* Side effects:
- * The line referred to by itemPtr is rescaled so that the
- * following transformation is applied to all point
- * coordinates:
+ * The line referred to by itemPtr is rescaled so that the following
+ * transformation is applied to all point coordinates:
* x' = originX + scaleX*(x-originX)
* y' = originY + scaleY*(y-originY)
*
@@ -1658,20 +1668,21 @@ LineToArea(canvas, itemPtr, rectPtr)
*/
static void
-ScaleLine(canvas, itemPtr, originX, originY, scaleX, scaleY)
- Tk_Canvas canvas; /* Canvas containing line. */
- Tk_Item *itemPtr; /* Line 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. */
+ScaleLine(
+ Tk_Canvas canvas, /* Canvas containing line. */
+ Tk_Item *itemPtr, /* Line to be scaled. */
+ double originX, double originY,
+ /* Origin about which to scale rect. */
+ double scaleX, /* Amount to scale in X direction. */
+ double scaleY) /* Amount to scale in Y direction. */
{
LineItem *linePtr = (LineItem *) itemPtr;
double *coordPtr;
int i;
/*
- * Delete any arrowheads before scaling all the points (so that
- * the end-points of the line get restored).
+ * Delete any arrowheads before scaling all the points (so that the
+ * end-points of the line get restored).
*/
if (linePtr->firstArrowPtr != NULL) {
@@ -1705,14 +1716,13 @@ ScaleLine(canvas, itemPtr, originX, originY, scaleX, scaleY)
*
* GetLineIndex --
*
- * Parse an index into a line item and return either its value
- * or an error.
+ * Parse an index into a line item and return either its value or an
+ * error.
*
* Results:
- * 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.
+ * 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.
*
* Side effects:
* None.
@@ -1721,14 +1731,14 @@ ScaleLine(canvas, itemPtr, originX, originY, scaleX, scaleY)
*/
static int
-GetLineIndex(interp, canvas, itemPtr, obj, indexPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item for which the index is being
+GetLineIndex(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item for which the index is being
* specified. */
- Tcl_Obj *obj; /* Specification of a particular coord
- * in itemPtr's line. */
- int *indexPtr; /* Where to store converted index. */
+ Tcl_Obj *obj, /* Specification of a particular coord in
+ * itemPtr's line. */
+ int *indexPtr) /* Where to store converted index. */
{
LineItem *linePtr = (LineItem *) itemPtr;
int length;
@@ -1738,16 +1748,14 @@ GetLineIndex(interp, canvas, itemPtr, obj, indexPtr)
if (strncmp(string, "end", (unsigned) length) == 0) {
*indexPtr = 2*linePtr->numPoints;
} else {
- badIndex:
-
/*
- * Some of the paths here leave messages in interp->result,
- * so we have to clear it out before storing our own message.
+ * Some of the paths here leave messages in interp->result, so we
+ * have to clear it out before storing our own message.
*/
- Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);
- Tcl_AppendResult(interp, "bad index \"", string, "\"",
- (char *) NULL);
+ badIndex:
+ Tcl_SetResult(interp, NULL, TCL_STATIC);
+ Tcl_AppendResult(interp, "bad index \"", string, "\"", NULL);
return TCL_ERROR;
}
} else if (string[0] == '@') {
@@ -1780,7 +1788,7 @@ GetLineIndex(interp, canvas, itemPtr, obj, indexPtr)
if (Tcl_GetIntFromObj(interp, obj, indexPtr) != TCL_OK) {
goto badIndex;
}
- *indexPtr &= -2; /* if index is odd, make it even */
+ *indexPtr &= -2; /* if index is odd, make it even */
if (*indexPtr < 0){
*indexPtr = 0;
} else if (*indexPtr > (2*linePtr->numPoints)) {
@@ -1795,25 +1803,24 @@ GetLineIndex(interp, canvas, itemPtr, obj, indexPtr)
*
* TranslateLine --
*
- * This procedure is called to move a line by a given amount.
+ * This function is called to move a line by a given amount.
*
* Results:
* None.
*
* Side effects:
- * The position of the line is offset by (xDelta, yDelta), and
- * the bounding box is updated in the generic part of the item
- * structure.
+ * The position of the line is offset by (xDelta, yDelta), and the
+ * bounding box is updated in the generic part of the item structure.
*
*--------------------------------------------------------------
*/
static void
-TranslateLine(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. */
+TranslateLine(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item that is being moved. */
+ double deltaX, double deltaY)
+ /* Amount by which item is to be moved. */
{
LineItem *linePtr = (LineItem *) itemPtr;
double *coordPtr;
@@ -1846,13 +1853,13 @@ TranslateLine(canvas, itemPtr, deltaX, deltaY)
*
* ParseArrowShape --
*
- * This procedure is called back during option parsing to
- * parse arrow shape information.
+ * This function is called back during option parsing to parse arrow
+ * shape information.
*
* Results:
- * The return value is a standard Tcl result: TCL_OK means
- * that the arrow shape information was parsed ok, and
- * TCL_ERROR means it couldn't be parsed.
+ * The return value is a standard Tcl result: TCL_OK means that the arrow
+ * shape information was parsed ok, and TCL_ERROR means it couldn't be
+ * parsed.
*
* Side effects:
* Arrow information in recordPtr is updated.
@@ -1862,14 +1869,14 @@ TranslateLine(canvas, itemPtr, deltaX, deltaY)
/* ARGSUSED */
static int
-ParseArrowShape(clientData, interp, tkwin, value, recordPtr, offset)
- ClientData clientData; /* Not used. */
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Window tkwin; /* Not used. */
- CONST char *value; /* Textual specification of arrow shape. */
- char *recordPtr; /* Pointer to item record in which to
- * store arrow information. */
- int offset; /* Offset of shape information in widget
+ParseArrowShape(
+ ClientData clientData, /* Not used. */
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_Window tkwin, /* Not used. */
+ CONST char *value, /* Textual specification of arrow shape. */
+ char *recordPtr, /* Pointer to item record in which to store
+ * arrow information. */
+ int offset) /* Offset of shape information in widget
* record. */
{
LineItem *linePtr = (LineItem *) recordPtr;
@@ -1878,14 +1885,14 @@ ParseArrowShape(clientData, interp, tkwin, value, recordPtr, offset)
CONST char **argv = NULL;
if (offset != Tk_Offset(LineItem, arrowShapeA)) {
- panic("ParseArrowShape received bogus offset");
+ Tcl_Panic("ParseArrowShape received bogus offset");
}
if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {
syntaxError:
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "bad arrow shape \"", value,
- "\": must be list with three numbers", (char *) NULL);
+ "\": must be list with three numbers", NULL);
if (argv != NULL) {
ckfree((char *) argv);
}
@@ -1913,8 +1920,8 @@ ParseArrowShape(clientData, interp, tkwin, value, recordPtr, offset)
*
* PrintArrowShape --
*
- * This procedure is a callback invoked by the configuration
- * code to return a printable value describing an arrow shape.
+ * This function is a callback invoked by the configuration code to
+ * return a printable value describing an arrow shape.
*
* Results:
* None.
@@ -1927,14 +1934,14 @@ ParseArrowShape(clientData, interp, tkwin, value, recordPtr, offset)
/* ARGSUSED */
static char *
-PrintArrowShape(clientData, tkwin, recordPtr, offset, freeProcPtr)
- ClientData clientData; /* Not used. */
- Tk_Window tkwin; /* Window associated with linePtr's widget. */
- char *recordPtr; /* Pointer to item record containing current
+PrintArrowShape(
+ ClientData clientData, /* Not used. */
+ Tk_Window tkwin, /* Window associated with linePtr's widget. */
+ char *recordPtr, /* Pointer to item record containing current
* shape information. */
- int offset; /* Offset of arrow information in record. */
- Tcl_FreeProc **freeProcPtr; /* Store address of procedure to call to
- * free string here. */
+ int offset, /* Offset of arrow information in record. */
+ Tcl_FreeProc **freeProcPtr) /* Store address of function to call to free
+ * string here. */
{
LineItem *linePtr = (LineItem *) recordPtr;
char *buffer;
@@ -1952,27 +1959,27 @@ PrintArrowShape(clientData, tkwin, recordPtr, offset, freeProcPtr)
*
* ArrowParseProc --
*
- * This procedure is invoked during option processing to handle
- * the "-arrow" option.
+ * This function is invoked during option processing to handle the
+ * "-arrow" option.
*
* Results:
* A standard Tcl return value.
*
* Side effects:
- * The arrow for a given item gets replaced by the arrow
- * indicated in the value argument.
+ * The arrow for a given item gets replaced by the arrow indicated in the
+ * value argument.
*
*--------------------------------------------------------------
*/
static int
-ArrowParseProc(clientData, interp, tkwin, value, widgRec, offset)
- ClientData clientData; /* some flags.*/
- Tcl_Interp *interp; /* Used for reporting errors. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- CONST char *value; /* Value of option. */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Offset into item. */
+ArrowParseProc(
+ ClientData clientData, /* some flags.*/
+ Tcl_Interp *interp, /* Used for reporting errors. */
+ Tk_Window tkwin, /* Window containing canvas widget. */
+ CONST char *value, /* Value of option. */
+ char *widgRec, /* Pointer to record for item. */
+ int offset) /* Offset into item. */
{
int c;
size_t length;
@@ -2004,9 +2011,8 @@ ArrowParseProc(clientData, interp, tkwin, value, widgRec, offset)
return TCL_OK;
}
- Tcl_AppendResult(interp, "bad arrow spec \"", value,
- "\": must be none, first, last, or both",
- (char *) NULL);
+ Tcl_AppendResult(interp, "bad arrow spec \"", value,
+ "\": must be none, first, last, or both", NULL);
*arrowPtr = ARROWS_NONE;
return TCL_ERROR;
}
@@ -2016,16 +2022,15 @@ ArrowParseProc(clientData, interp, tkwin, value, widgRec, offset)
*
* ArrowPrintProc --
*
- * This procedure is invoked by the Tk configuration code
- * to produce a printable string for the "-arrow"
- * configuration option.
+ * This function is invoked by the Tk configuration code to produce a
+ * printable string for the "-arrow" configuration option.
*
* Results:
- * The return value is a string describing the arrows for
- * the item referred to by "widgRec". In addition, *freeProcPtr
- * is filled in with the address of a procedure to call to free
- * the result string when it's no longer needed (or NULL to
- * indicate that the string doesn't need to be freed).
+ * The return value is a string describing the arrows for the item
+ * referred to by "widgRec". In addition, *freeProcPtr is filled in with
+ * the address of a function to call to free the result string when it's
+ * no longer needed (or NULL to indicate that the string doesn't need to
+ * be freed).
*
* Side effects:
* None.
@@ -2034,25 +2039,25 @@ ArrowParseProc(clientData, interp, tkwin, value, widgRec, offset)
*/
static char *
-ArrowPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
- ClientData clientData; /* Ignored. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Offset into item. */
- Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
- * information about how to reclaim
- * storage for return string. */
+ArrowPrintProc(
+ ClientData clientData, /* Ignored. */
+ Tk_Window tkwin, /* Window containing canvas widget. */
+ char *widgRec, /* Pointer to record for item. */
+ int offset, /* Offset into item. */
+ Tcl_FreeProc **freeProcPtr) /* Pointer to variable to fill in with
+ * information about how to reclaim storage
+ * for return string. */
{
register Arrows *arrowPtr = (Arrows *) (widgRec + offset);
switch (*arrowPtr) {
- case ARROWS_FIRST:
+ case ARROWS_FIRST:
return "first";
- case ARROWS_LAST:
+ case ARROWS_LAST:
return "last";
- case ARROWS_BOTH:
+ case ARROWS_BOTH:
return "both";
- default:
+ default:
return "none";
}
}
@@ -2062,40 +2067,38 @@ ArrowPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
*
* ConfigureArrows --
*
- * If arrowheads have been requested for a line, this
- * procedure makes arrangements for the arrowheads.
+ * If arrowheads have been requested for a line, this function makes
+ * arrangements for the arrowheads.
*
* Results:
* Always returns TCL_OK.
*
* Side effects:
- * Information in linePtr is set up for one or two arrowheads.
- * the firstArrowPtr and lastArrowPtr polygons are allocated
- * and initialized, if need be, and the end points of the line
- * are adjusted so that a thick line doesn't stick out past
- * the arrowheads.
+ * Information in linePtr is set up for one or two arrowheads. The
+ * firstArrowPtr and lastArrowPtr polygons are allocated and initialized,
+ * if need be, and the end points of the line are adjusted so that a
+ * thick line doesn't stick out past the arrowheads.
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static int
-ConfigureArrows(canvas, linePtr)
- Tk_Canvas canvas; /* Canvas in which arrows will be
- * displayed (interp and tkwin
- * fields are needed). */
- LineItem *linePtr; /* Item to configure for arrows. */
+ConfigureArrows(
+ Tk_Canvas canvas, /* Canvas in which arrows will be displayed
+ * (interp and tkwin fields are needed). */
+ LineItem *linePtr) /* Item to configure for arrows. */
{
double *poly, *coordPtr;
double dx, dy, length, sinTheta, cosTheta, temp;
- double fracHeight; /* Line width as fraction of
- * arrowhead width. */
- double backup; /* Distance to backup end points
- * so the line ends in the middle
- * of the arrowhead. */
- double vertX, vertY; /* Position of arrowhead vertex. */
- double shapeA, shapeB, shapeC; /* Adjusted coordinates (see
- * explanation below). */
+ double fracHeight; /* Line width as fraction of arrowhead
+ * width. */
+ double backup; /* Distance to backup end points so the line
+ * ends in the middle of the arrowhead. */
+ double vertX, vertY; /* Position of arrowhead vertex. */
+ double shapeA, shapeB, shapeC;
+ /* Adjusted coordinates (see explanation
+ * below). */
double width;
Tk_State state = linePtr->header.state;
@@ -2119,10 +2122,10 @@ ConfigureArrows(canvas, linePtr)
}
/*
- * The code below makes a tiny increase in the shape parameters
- * for the line. This is a bit of a hack, but it seems to result
- * in displays that more closely approximate the specified parameters.
- * Without the adjustment, the arrows come out smaller than expected.
+ * The code below makes a tiny increase in the shape parameters for the
+ * line. This is a bit of a hack, but it seems to result in displays that
+ * more closely approximate the specified parameters. Without the
+ * adjustment, the arrows come out smaller than expected.
*/
shapeA = linePtr->arrowShapeA + 0.001;
@@ -2130,9 +2133,9 @@ ConfigureArrows(canvas, linePtr)
shapeC = linePtr->arrowShapeC + width/2.0 + 0.001;
/*
- * If there's an arrowhead on the first point of the line, compute
- * its polygon and adjust the first point of the line so that the
- * line doesn't stick out past the leading edge of the arrowhead.
+ * If there's an arrowhead on the first point of the line, compute its
+ * polygon and adjust the first point of the line so that the line doesn't
+ * stick out past the leading edge of the arrowhead.
*/
fracHeight = (width/2.0)/shapeC;
@@ -2169,9 +2172,8 @@ ConfigureArrows(canvas, linePtr)
poly[7] = poly[9]*fracHeight + vertY*(1.0-fracHeight);
/*
- * Polygon done. Now move the first point towards the second so
- * that the corners at the end of the line are inside the
- * arrowhead.
+ * Polygon done. Now move the first point towards the second so that
+ * the corners at the end of the line are inside the arrowhead.
*/
linePtr->coordPtr[0] = poly[0] - backup*cosTheta;
@@ -2186,8 +2188,8 @@ ConfigureArrows(canvas, linePtr)
coordPtr = linePtr->coordPtr + 2*(linePtr->numPoints-2);
poly = linePtr->lastArrowPtr;
if (poly == NULL) {
- poly = (double *) ckalloc((unsigned)
- (2*PTS_IN_ARROW*sizeof(double)));
+ poly = (double *)
+ ckalloc((unsigned) (2*PTS_IN_ARROW*sizeof(double)));
poly[0] = poly[10] = coordPtr[2];
poly[1] = poly[11] = coordPtr[3];
linePtr->lastArrowPtr = poly;
@@ -2203,10 +2205,10 @@ ConfigureArrows(canvas, linePtr)
}
vertX = poly[0] - shapeA*cosTheta;
vertY = poly[1] - shapeA*sinTheta;
- temp = shapeC*sinTheta;
+ temp = shapeC * sinTheta;
poly[2] = poly[0] - shapeB*cosTheta + temp;
poly[8] = poly[2] - 2*temp;
- temp = shapeC*cosTheta;
+ temp = shapeC * cosTheta;
poly[3] = poly[1] - shapeB*sinTheta - temp;
poly[9] = poly[3] + 2*temp;
poly[4] = poly[2]*fracHeight + vertX*(1.0-fracHeight);
@@ -2225,15 +2227,13 @@ ConfigureArrows(canvas, linePtr)
*
* LineToPostscript --
*
- * This procedure is called to generate Postscript for
- * line items.
+ * This function is called to generate Postscript for line items.
*
* Results:
- * The return value is a standard Tcl result. If an error
- * occurs in generating Postscript then an error message is
- * 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.
+ * The return value is a standard Tcl result. If an error occurs in
+ * generating Postscript then an error message is 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.
*
* Side effects:
* None.
@@ -2242,15 +2242,13 @@ ConfigureArrows(canvas, linePtr)
*/
static int
-LineToPostscript(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. */
+LineToPostscript(
+ 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. */
{
LineItem *linePtr = (LineItem *) itemPtr;
char buffer[64 + TCL_INTEGER_SPACE];
@@ -2299,24 +2297,23 @@ LineToPostscript(interp, canvas, itemPtr, prepass)
linePtr->coordPtr[0], Tk_CanvasPsY(canvas, linePtr->coordPtr[1]),
width/2.0, width/2.0);
Tcl_AppendResult(interp, "matrix currentmatrix\n",buffer,
- " scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", (char *) NULL);
- if (Tk_CanvasPsColor(interp, canvas, color)
- != TCL_OK) {
+ " scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", NULL);
+ if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
return TCL_ERROR;
}
if (stipple != None) {
- Tcl_AppendResult(interp, "clip ", (char *) NULL);
+ Tcl_AppendResult(interp, "clip ", NULL);
if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
return TCL_ERROR;
}
} else {
- Tcl_AppendResult(interp, "fill\n", (char *) NULL);
+ Tcl_AppendResult(interp, "fill\n", NULL);
}
return TCL_OK;
}
/*
- * Generate a path for the line's center-line (do this differently
- * for straight lines and smoothed lines).
+ * Generate a path for the line's center-line (do this differently for
+ * straight lines and smoothed lines).
*/
if ((!linePtr->smooth) || (linePtr->numPoints < 3)) {
@@ -2327,29 +2324,27 @@ LineToPostscript(interp, canvas, itemPtr, prepass)
linePtr->coordPtr, linePtr->numPoints, linePtr->splineSteps);
} else {
/*
- * Special hack: Postscript printers don't appear to be able
- * to turn a path drawn with "curveto"s into a clipping path
- * without exceeding resource limits, so TkMakeBezierPostscript
- * won't work for stippled curves. Instead, generate all of
- * the intermediate points here and output them into the
- * Postscript file with "lineto"s instead.
+ * Special hack: Postscript printers don't appear to be able to
+ * turn a path drawn with "curveto"s into a clipping path without
+ * exceeding resource limits, so TkMakeBezierPostscript won't work
+ * for stippled curves. Instead, generate all of the intermediate
+ * points here and output them into the Postscript file with
+ * "lineto"s instead.
*/
double staticPoints[2*MAX_STATIC_POINTS];
double *pointPtr;
int numPoints;
- numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL,
- linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,
- (double *) NULL);
+ numPoints = linePtr->smooth->coordProc(canvas, NULL,
+ linePtr->numPoints, linePtr->splineSteps, NULL, NULL);
pointPtr = staticPoints;
if (numPoints > MAX_STATIC_POINTS) {
pointPtr = (double *) ckalloc((unsigned)
(numPoints * 2 * sizeof(double)));
}
numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
- linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,
- pointPtr);
+ linePtr->numPoints, linePtr->splineSteps, NULL, pointPtr);
Tk_CanvasPsPath(interp, canvas, pointPtr, numPoints);
if (pointPtr != staticPoints) {
ckfree((char *) pointPtr);
@@ -2367,17 +2362,16 @@ LineToPostscript(interp, canvas, itemPtr, prepass)
} else if (linePtr->capStyle == CapProjecting) {
style = "2 setlinecap\n";
}
- Tcl_AppendResult(interp, style, (char *) NULL);
+ Tcl_AppendResult(interp, style, NULL);
style = "0 setlinejoin\n";
if (linePtr->joinStyle == JoinRound) {
style = "1 setlinejoin\n";
} else if (linePtr->joinStyle == JoinBevel) {
style = "2 setlinejoin\n";
}
- Tcl_AppendResult(interp, style, (char *) NULL);
+ Tcl_AppendResult(interp, style, NULL);
- if (Tk_CanvasPsOutline(canvas, itemPtr,
- &(linePtr->outline)) != TCL_OK) {
+ if (Tk_CanvasPsOutline(canvas, itemPtr, &(linePtr->outline)) != TCL_OK) {
return TCL_ERROR;
}
@@ -2387,8 +2381,7 @@ LineToPostscript(interp, canvas, itemPtr, prepass)
if (linePtr->firstArrowPtr != NULL) {
if (stipple != None) {
- Tcl_AppendResult(interp, "grestore gsave\n",
- (char *) NULL);
+ Tcl_AppendResult(interp, "grestore gsave\n", NULL);
}
if (ArrowheadPostscript(interp, canvas, linePtr,
linePtr->firstArrowPtr) != TCL_OK) {
@@ -2397,7 +2390,7 @@ LineToPostscript(interp, canvas, itemPtr, prepass)
}
if (linePtr->lastArrowPtr != NULL) {
if (stipple != None) {
- Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);
+ Tcl_AppendResult(interp, "grestore gsave\n", NULL);
}
if (ArrowheadPostscript(interp, canvas, linePtr,
linePtr->lastArrowPtr) != TCL_OK) {
@@ -2412,15 +2405,14 @@ LineToPostscript(interp, canvas, itemPtr, prepass)
*
* ArrowheadPostscript --
*
- * This procedure is called to generate Postscript for
- * an arrowhead for a line item.
+ * This function is called to generate Postscript for an arrowhead for a
+ * line item.
*
* Results:
- * The return value is a standard Tcl result. If an error
- * occurs in generating Postscript then an error message is
- * 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.
+ * The return value is a standard Tcl result. If an error occurs in
+ * generating Postscript then an error message is 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.
*
* Side effects:
* None.
@@ -2429,14 +2421,13 @@ LineToPostscript(interp, canvas, itemPtr, prepass)
*/
static int
-ArrowheadPostscript(interp, canvas, linePtr, arrowPtr)
- Tcl_Interp *interp; /* Leave Postscript or error message
- * here. */
- Tk_Canvas canvas; /* Information about overall canvas. */
- LineItem *linePtr; /* Line item for which Postscript is
- * being generated. */
- double *arrowPtr; /* Pointer to first of five points
- * describing arrowhead polygon. */
+ArrowheadPostscript(
+ Tcl_Interp *interp, /* Leave Postscript or error message here. */
+ Tk_Canvas canvas, /* Information about overall canvas. */
+ LineItem *linePtr, /* Line item for which Postscript is being
+ * generated. */
+ double *arrowPtr) /* Pointer to first of five points describing
+ * arrowhead polygon. */
{
Pixmap stipple;
Tk_State state = linePtr->header.state;
@@ -2458,13 +2449,20 @@ ArrowheadPostscript(interp, canvas, linePtr, arrowPtr)
Tk_CanvasPsPath(interp, canvas, arrowPtr, PTS_IN_ARROW);
if (stipple != None) {
- Tcl_AppendResult(interp, "clip ", (char *) NULL);
- if (Tk_CanvasPsStipple(interp, canvas, stipple)
- != TCL_OK) {
+ Tcl_AppendResult(interp, "clip ", NULL);
+ if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
return TCL_ERROR;
}
} else {
- Tcl_AppendResult(interp, "fill\n", (char *) NULL);
+ Tcl_AppendResult(interp, "fill\n", NULL);
}
return TCL_OK;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkCanvPoly.c b/generic/tkCanvPoly.c
index 3027c88..b86bc63 100644
--- a/generic/tkCanvPoly.c
+++ b/generic/tkCanvPoly.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkCanvPoly.c --
*
* This file implements polygon items for canvas widgets.
@@ -7,13 +7,12 @@
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
* Copyright (c) 1998-2000 Ajuba Solutions.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <stdio.h>
#include "tkInt.h"
-#include "tkPort.h"
#include "tkCanvas.h"
/*
@@ -22,24 +21,28 @@
typedef struct PolygonItem {
Tk_Item header; /* Generic stuff that's the same for all
- * types. MUST BE FIRST IN STRUCTURE. */
+ * types. MUST BE FIRST IN STRUCTURE. */
Tk_Outline outline; /* Outline structure */
- int numPoints; /* Number of points in polygon.
- * Polygon is always closed. */
+ int numPoints; /* Number of points in polygon. Polygon is
+ * always closed. */
int pointsAllocated; /* Number of points for which space is
* allocated at *coordPtr. */
- double *coordPtr; /* Pointer to malloc-ed array containing
- * x- and y-coords of all points in polygon.
+ double *coordPtr; /* Pointer to malloc-ed array containing x-
+ * and y-coords of all points in polygon.
* X-coords are even-valued indices, y-coords
* are corresponding odd-valued indices. */
int joinStyle; /* Join style for outline */
Tk_TSOffset tsoffset;
XColor *fillColor; /* Foreground color for polygon. */
- XColor *activeFillColor; /* Foreground color for polygon if state is active. */
- XColor *disabledFillColor; /* Foreground color for polygon if state is disabled. */
+ XColor *activeFillColor; /* Foreground color for polygon if state is
+ * active. */
+ XColor *disabledFillColor; /* Foreground color for polygon if state is
+ * disabled. */
Pixmap fillStipple; /* Stipple bitmap for filling polygon. */
- Pixmap activeFillStipple; /* Stipple bitmap for filling polygon if state is active. */
- Pixmap disabledFillStipple; /* Stipple bitmap for filling polygon if state is disabled. */
+ Pixmap activeFillStipple; /* Stipple bitmap for filling polygon if state
+ * is active. */
+ Pixmap disabledFillStipple; /* Stipple bitmap for filling polygon if state
+ * is disabled. */
GC fillGC; /* Graphics context for filling polygon. */
Tk_SmoothMethod *smooth; /* Non-zero means draw shape smoothed (i.e.
* with Bezier splines). */
@@ -79,125 +82,116 @@ static Tk_CustomOption pixelOption = {
};
static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_CUSTOM, "-activedash", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PolygonItem, outline.activeDash),
+ {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
+ NULL, Tk_Offset(PolygonItem, outline.activeDash),
TK_CONFIG_NULL_OK, &dashOption},
- {TK_CONFIG_COLOR, "-activefill", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PolygonItem, activeFillColor),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_COLOR, "-activeoutline", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PolygonItem, outline.activeColor),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-activeoutlinestipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PolygonItem, outline.activeStipple),
+ {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
+ NULL, Tk_Offset(PolygonItem, activeFillColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
+ NULL, Tk_Offset(PolygonItem, outline.activeColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
+ NULL, Tk_Offset(PolygonItem, outline.activeStipple),
TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-activestipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PolygonItem, activeFillStipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-activewidth", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
+ NULL, Tk_Offset(PolygonItem, activeFillStipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
"0.0", Tk_Offset(PolygonItem, outline.activeWidth),
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
- {TK_CONFIG_CUSTOM, "-dash", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PolygonItem, outline.dash),
+ {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
+ NULL, Tk_Offset(PolygonItem, outline.dash),
TK_CONFIG_NULL_OK, &dashOption},
- {TK_CONFIG_PIXELS, "-dashoffset", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
"0", Tk_Offset(PolygonItem, outline.offset),
TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_CUSTOM, "-disableddash", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PolygonItem, outline.disabledDash),
+ {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
+ NULL, Tk_Offset(PolygonItem, outline.disabledDash),
TK_CONFIG_NULL_OK, &dashOption},
- {TK_CONFIG_COLOR, "-disabledfill", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PolygonItem, disabledFillColor),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_COLOR, "-disabledoutline", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PolygonItem, outline.disabledColor),
+ {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
+ NULL, Tk_Offset(PolygonItem, disabledFillColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
+ NULL, Tk_Offset(PolygonItem, outline.disabledColor),
TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-disabledoutlinestipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PolygonItem, outline.disabledStipple),
+ {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
+ NULL, Tk_Offset(PolygonItem, outline.disabledStipple),
TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-disabledstipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PolygonItem, disabledFillStipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-disabledwidth", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
+ NULL, Tk_Offset(PolygonItem, disabledFillStipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
"0.0", Tk_Offset(PolygonItem, outline.disabledWidth),
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
- {TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_COLOR, "-fill", NULL, NULL,
"black", Tk_Offset(PolygonItem, fillColor), TK_CONFIG_NULL_OK},
- {TK_CONFIG_JOIN_STYLE, "-joinstyle", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_JOIN_STYLE, "-joinstyle", NULL, NULL,
"round", Tk_Offset(PolygonItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_CUSTOM, "-offset", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
"0,0", Tk_Offset(PolygonItem, tsoffset),
TK_CONFIG_NULL_OK, &offsetOption},
- {TK_CONFIG_COLOR, "-outline", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PolygonItem, outline.color),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-outlineoffset", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_COLOR, "-outline", NULL, NULL,
+ NULL, Tk_Offset(PolygonItem, outline.color), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
"0,0", Tk_Offset(PolygonItem, outline.tsoffset),
TK_CONFIG_NULL_OK, &offsetOption},
- {TK_CONFIG_BITMAP, "-outlinestipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PolygonItem, outline.stipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-smooth", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL,
+ NULL, Tk_Offset(PolygonItem, outline.stipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-smooth", NULL, NULL,
"0", Tk_Offset(PolygonItem, smooth),
TK_CONFIG_DONT_SET_DEFAULT, &smoothOption},
- {TK_CONFIG_INT, "-splinesteps", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_INT, "-splinesteps", NULL, NULL,
"12", Tk_Offset(PolygonItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
- &stateOption},
- {TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PolygonItem, fillStipple), TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
- {TK_CONFIG_CUSTOM, "-width", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
+ NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
+ {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
+ NULL, Tk_Offset(PolygonItem, fillStipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
+ NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
+ {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
"1.0", Tk_Offset(PolygonItem, outline.width),
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+ {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};
/*
- * Prototypes for procedures defined in this file:
+ * Prototypes for functions defined in this file:
*/
-static void ComputePolygonBbox _ANSI_ARGS_((Tk_Canvas canvas,
- PolygonItem *polyPtr));
-static int ConfigurePolygon _ANSI_ARGS_((Tcl_Interp *interp,
+static void ComputePolygonBbox(Tk_Canvas canvas,
+ PolygonItem *polyPtr);
+static int ConfigurePolygon(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
- Tcl_Obj *CONST objv[], int flags));
-static int CreatePolygon _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *CONST objv[], int flags);
+static int CreatePolygon(Tcl_Interp *interp,
Tk_Canvas canvas, struct Tk_Item *itemPtr,
- int objc, Tcl_Obj *CONST objv[]));
-static void DeletePolygon _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, Display *display));
-static void DisplayPolygon _ANSI_ARGS_((Tk_Canvas canvas,
+ int objc, Tcl_Obj *CONST objv[]);
+static void DeletePolygon(Tk_Canvas canvas,
+ Tk_Item *itemPtr, Display *display);
+static void DisplayPolygon(Tk_Canvas canvas,
Tk_Item *itemPtr, Display *display, Drawable dst,
- int x, int y, int width, int height));
-static int GetPolygonIndex _ANSI_ARGS_((Tcl_Interp *interp,
+ int x, int y, int width, int height);
+static int GetPolygonIndex(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr,
- Tcl_Obj *obj, int *indexPtr));
-static int PolygonCoords _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *obj, int *indexPtr);
+static int PolygonCoords(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr,
- int objc, Tcl_Obj *CONST objv[]));
-static void PolygonDeleteCoords _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, int first, int last));
-static void PolygonInsert _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, int beforeThis, Tcl_Obj *obj));
-static int PolygonToArea _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *rectPtr));
-static double PolygonToPoint _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *pointPtr));
-static int PolygonToPostscript _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));
-static void ScalePolygon _ANSI_ARGS_((Tk_Canvas canvas,
+ int objc, Tcl_Obj *CONST objv[]);
+static void PolygonDeleteCoords(Tk_Canvas canvas,
+ Tk_Item *itemPtr, int first, int last);
+static void PolygonInsert(Tk_Canvas canvas,
+ Tk_Item *itemPtr, int beforeThis, Tcl_Obj *obj);
+static int PolygonToArea(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double *rectPtr);
+static double PolygonToPoint(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double *pointPtr);
+static int PolygonToPostscript(Tcl_Interp *interp,
+ Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
+static void ScalePolygon(Tk_Canvas canvas,
Tk_Item *itemPtr, double originX, double originY,
- double scaleX, double scaleY));
-static void TranslatePolygon _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double deltaX, double deltaY));
+ double scaleX, double scaleY);
+static void TranslatePolygon(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double deltaX, double deltaY);
/*
- * The structures below defines the polygon item type by means
- * of procedures that can be invoked by generic item code.
+ * The structures below defines the polygon item type by means of functions
+ * that can be invoked by generic item code.
*/
Tk_ItemType tkPolygonType = {
@@ -216,17 +210,17 @@ Tk_ItemType tkPolygonType = {
ScalePolygon, /* scaleProc */
TranslatePolygon, /* translateProc */
(Tk_ItemIndexProc *) GetPolygonIndex,/* indexProc */
- (Tk_ItemCursorProc *) NULL, /* icursorProc */
- (Tk_ItemSelectionProc *) NULL, /* selectionProc */
+ NULL, /* icursorProc */
+ NULL, /* selectionProc */
(Tk_ItemInsertProc *) PolygonInsert,/* insertProc */
PolygonDeleteCoords, /* dTextProc */
- (Tk_ItemType *) NULL, /* nextPtr */
+ NULL, /* nextPtr */
};
/*
- * 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).
+ * 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).
*/
#define MAX_STATIC_POINTS 200
@@ -236,14 +230,12 @@ Tk_ItemType tkPolygonType = {
*
* CreatePolygon --
*
- * This procedure is invoked to create a new polygon item in
- * a canvas.
+ * This function is invoked to create a new polygon item in a canvas.
*
* Results:
- * A standard Tcl return value. If an error occurred in
- * creating the item, then an error message is left in
- * the interp's result; in this case itemPtr is
- * left uninitialized, so it can be safely freed by the
+ * A standard Tcl return value. If an error occurred in creating the
+ * item, then an error message is left in the interp's result; in this
+ * case itemPtr is left uninitialized, so it can be safely freed by the
* caller.
*
* Side effects:
@@ -253,24 +245,24 @@ Tk_ItemType tkPolygonType = {
*/
static int
-CreatePolygon(interp, canvas, itemPtr, objc, objv)
- 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 objc; /* Number of arguments in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing polygon. */
+CreatePolygon(
+ 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 objc, /* Number of arguments in objv. */
+ Tcl_Obj *CONST objv[]) /* Arguments describing polygon. */
{
PolygonItem *polyPtr = (PolygonItem *) itemPtr;
int i;
if (objc == 0) {
- panic("canvas did not pass any coords\n");
+ Tcl_Panic("canvas did not pass any coords\n");
}
/*
- * 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 function.
*/
Tk_CreateOutline(&(polyPtr->outline));
@@ -288,14 +280,14 @@ CreatePolygon(interp, canvas, itemPtr, objc, objv)
polyPtr->activeFillStipple = None;
polyPtr->disabledFillStipple = None;
polyPtr->fillGC = None;
- polyPtr->smooth = (Tk_SmoothMethod *) NULL;
+ polyPtr->smooth = NULL;
polyPtr->splineSteps = 12;
polyPtr->autoClosed = 0;
/*
- * Count the number of points and then parse them into a point
- * array. Leading arguments are assumed to be points if they
- * start with a digit or a minus sign followed by a digit.
+ * Count the number of points and then parse them into a point array.
+ * Leading arguments are assumed to be points if they start with a digit
+ * or a minus sign followed by a digit.
*/
for (i = 0; i < objc; i++) {
@@ -313,7 +305,7 @@ CreatePolygon(interp, canvas, itemPtr, objc, objv)
return TCL_OK;
}
- error:
+ error:
DeletePolygon(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
return TCL_ERROR;
}
@@ -323,9 +315,8 @@ CreatePolygon(interp, canvas, itemPtr, objc, objv)
*
* PolygonCoords --
*
- * This procedure is invoked to process the "coords" widget
- * command on polygons. See the user documentation for details
- * on what it does.
+ * This function is invoked to process the "coords" widget command on
+ * polygons. See the user documentation for details on what it does.
*
* Results:
* Returns TCL_OK or TCL_ERROR, and sets the interp's result.
@@ -337,25 +328,25 @@ CreatePolygon(interp, canvas, itemPtr, objc, objv)
*/
static int
-PolygonCoords(interp, canvas, itemPtr, objc, objv)
- 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 objc; /* Number of coordinates supplied in
- * objv. */
- Tcl_Obj *CONST objv[]; /* Array of coordinates: x1, y1,
- * x2, y2, ... */
+PolygonCoords(
+ 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 objc, /* Number of coordinates supplied in objv. */
+ Tcl_Obj *CONST objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */
{
PolygonItem *polyPtr = (PolygonItem *) itemPtr;
int i, numPoints;
if (objc == 0) {
/*
- * Print the coords used to create the polygon. If we auto
- * closed the polygon then we don't report the last point.
+ * Print the coords used to create the polygon. If we auto closed the
+ * polygon then we don't report the last point.
*/
+
Tcl_Obj *subobj, *obj = Tcl_NewObj();
+
for (i = 0; i < 2*(polyPtr->numPoints - polyPtr->autoClosed); i++) {
subobj = Tcl_NewDoubleObj(polyPtr->coordPtr[i]);
Tcl_ListObjAppendElement(interp, obj, subobj);
@@ -371,6 +362,7 @@ PolygonCoords(interp, canvas, itemPtr, objc, objv)
}
if (objc & 1) {
char buf[64 + TCL_INTEGER_SPACE];
+
sprintf(buf, "wrong # coordinates: expected an even number, got %d",
objc);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
@@ -383,8 +375,8 @@ PolygonCoords(interp, canvas, itemPtr, objc, objv)
}
/*
- * One extra point gets allocated here, because we always
- * add another point to close the polygon.
+ * One extra point gets allocated here, because we always add
+ * another point to close the polygon.
*/
polyPtr->coordPtr = (double *) ckalloc((unsigned)
@@ -403,7 +395,7 @@ PolygonCoords(interp, canvas, itemPtr, objc, objv)
/*
* Close the polygon if it isn't already closed.
*/
-
+
if (objc>2 && ((polyPtr->coordPtr[objc-2] != polyPtr->coordPtr[0])
|| (polyPtr->coordPtr[objc-1] != polyPtr->coordPtr[1]))) {
polyPtr->autoClosed = 1;
@@ -421,28 +413,28 @@ PolygonCoords(interp, canvas, itemPtr, objc, objv)
*
* ConfigurePolygon --
*
- * This procedure is invoked to configure various aspects
- * of a polygon item such as its background color.
+ * This function is invoked to configure various aspects of a polygon
+ * item such as its background color.
*
* Results:
- * A standard Tcl result code. If an error occurs, then
- * an error message is left in the interp's result.
+ * A standard Tcl result code. If an error occurs, then an error message
+ * is left in the interp's result.
*
* Side effects:
- * Configuration information, such as colors and stipple
- * patterns, may be set for itemPtr.
+ * Configuration information, such as colors and stipple patterns, may be
+ * set for itemPtr.
*
*--------------------------------------------------------------
*/
static int
-ConfigurePolygon(interp, canvas, itemPtr, objc, objv, flags)
- Tcl_Interp *interp; /* Interpreter for error reporting. */
- Tk_Canvas canvas; /* Canvas containing itemPtr. */
- Tk_Item *itemPtr; /* Polygon item to reconfigure. */
- int objc; /* Number of elements in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing things to configure. */
- int flags; /* Flags to pass to Tk_ConfigureWidget. */
+ConfigurePolygon(
+ Tcl_Interp *interp, /* Interpreter for error reporting. */
+ Tk_Canvas canvas, /* Canvas containing itemPtr. */
+ Tk_Item *itemPtr, /* Polygon item to reconfigure. */
+ int objc, /* Number of elements in objv. */
+ Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */
+ int flags) /* Flags to pass to Tk_ConfigureWidget. */
{
PolygonItem *polyPtr = (PolygonItem *) itemPtr;
XGCValues gcValues;
@@ -460,8 +452,8 @@ ConfigurePolygon(interp, canvas, itemPtr, objc, objv, flags)
}
/*
- * A few of the options require additional processing, such as
- * graphics contexts.
+ * A few of the options require additional processing, such as graphics
+ * contexts.
*/
state = itemPtr->state;
@@ -562,8 +554,8 @@ ConfigurePolygon(interp, canvas, itemPtr, objc, objv, flags)
*
* DeletePolygon --
*
- * This procedure is called to clean up the data structure
- * associated with a polygon item.
+ * This function is called to clean up the data structure associated with
+ * a polygon item.
*
* Results:
* None.
@@ -575,11 +567,10 @@ ConfigurePolygon(interp, canvas, itemPtr, objc, objv, flags)
*/
static void
-DeletePolygon(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. */
+DeletePolygon(
+ Tk_Canvas canvas, /* Info about overall canvas widget. */
+ Tk_Item *itemPtr, /* Item that is being deleted. */
+ Display *display) /* Display containing window for canvas. */
{
PolygonItem *polyPtr = (PolygonItem *) itemPtr;
@@ -615,24 +606,22 @@ DeletePolygon(canvas, itemPtr, display)
*
* ComputePolygonBbox --
*
- * This procedure is invoked to compute the bounding box of
- * all the pixels that may be drawn as part of a polygon.
+ * This function is invoked to compute the bounding box of all the pixels
+ * that may be drawn as part of a polygon.
*
* Results:
* None.
*
* Side effects:
- * The fields x1, y1, x2, and y2 are updated in the header
- * for itemPtr.
+ * The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
*
*--------------------------------------------------------------
*/
static void
-ComputePolygonBbox(canvas, polyPtr)
- Tk_Canvas canvas; /* Canvas that contains item. */
- PolygonItem *polyPtr; /* Item whose bbox is to be
- * recomputed. */
+ComputePolygonBbox(
+ Tk_Canvas canvas, /* Canvas that contains item. */
+ PolygonItem *polyPtr) /* Item whose bbox is to be recomputed. */
{
double *coordPtr;
int i;
@@ -664,12 +653,11 @@ ComputePolygonBbox(canvas, polyPtr)
polyPtr->header.y1 = polyPtr->header.y2 = (int) coordPtr[1];
/*
- * Compute the bounding box of all the points in the polygon,
- * then expand in all directions by the outline's width to take
- * care of butting or rounded corners and projecting or
- * rounded caps. This expansion is an overestimate (worst-case
- * is square root of two over two) but it's simple. Don't do
- * anything special for curves. This causes an additional
+ * Compute the bounding box of all the points in the polygon, then expand
+ * in all directions by the outline's width to take care of butting or
+ * rounded corners and projecting or rounded caps. This expansion is an
+ * overestimate (worst-case is square root of two over two) but it's
+ * simple. Don't do anything special for curves. This causes an additional
* overestimate in the bounding box, but is faster.
*/
@@ -715,6 +703,7 @@ ComputePolygonBbox(canvas, polyPtr)
if (tsoffset) {
if (tsoffset->flags & TK_OFFSET_INDEX) {
int index = tsoffset->flags & ~TK_OFFSET_INDEX;
+
if (tsoffset->flags == INT_MAX) {
index = (polyPtr->numPoints - 1) * 2;
}
@@ -750,13 +739,14 @@ ComputePolygonBbox(canvas, polyPtr)
/*
* For mitered lines, make a second pass through all the points.
- * Compute the locations of the two miter vertex points and add
- * those into the bounding box.
+ * Compute the locations of the two miter vertex points and add those
+ * into the bounding box.
*/
if (polyPtr->joinStyle == JoinMiter) {
double miter[4];
int j;
+
coordPtr = polyPtr->coordPtr;
if (polyPtr->numPoints>3) {
if (TkGetMiterPoints(coordPtr+2*(polyPtr->numPoints-2),
@@ -767,9 +757,8 @@ ComputePolygonBbox(canvas, polyPtr)
}
}
}
- for (i = polyPtr->numPoints ; i >= 3;
- i--, coordPtr += 2) {
-
+ for (i = polyPtr->numPoints ; i >= 3; i--, coordPtr += 2) {
+
if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4,
width, miter, miter+2)) {
for (j = 0; j < 4; j += 2) {
@@ -781,8 +770,8 @@ ComputePolygonBbox(canvas, polyPtr)
}
/*
- * Add one more pixel of fudge factor just to be safe (e.g.
- * X may round differently than we do).
+ * Add one more pixel of fudge factor just to be safe (e.g. X may round
+ * differently than we do).
*/
polyPtr->header.x1 -= 1;
@@ -796,34 +785,33 @@ ComputePolygonBbox(canvas, polyPtr)
*
* TkFillPolygon --
*
- * This procedure is invoked to convert a polygon to screen
- * coordinates and display it using a particular GC.
+ * This function is invoked to convert a polygon to screen coordinates
+ * and display it using a particular GC.
*
* Results:
* None.
*
* Side effects:
- * ItemPtr is drawn in drawable using the transformation
- * information in canvas.
+ * ItemPtr is drawn in drawable using the transformation information in
+ * canvas.
*
*--------------------------------------------------------------
*/
void
-TkFillPolygon(canvas, coordPtr, numPoints, display, drawable, gc, outlineGC)
- Tk_Canvas canvas; /* Canvas whose coordinate system
- * is to be used for drawing. */
- double *coordPtr; /* Array of coordinates for polygon:
- * x1, y1, x2, y2, .... */
- int numPoints; /* Twice this many coordinates are
- * present at *coordPtr. */
- Display *display; /* Display on which to draw polygon. */
- Drawable drawable; /* Pixmap or window in which to draw
- * polygon. */
- GC gc; /* Graphics context for drawing. */
- GC outlineGC; /* If not None, use this to draw an
- * outline around the polygon after
- * filling it. */
+TkFillPolygon(
+ Tk_Canvas canvas, /* Canvas whose coordinate system is to be
+ * used for drawing. */
+ double *coordPtr, /* Array of coordinates for polygon: x1, y1,
+ * x2, y2, .... */
+ int numPoints, /* Twice this many coordinates are present at
+ * *coordPtr. */
+ Display *display, /* Display on which to draw polygon. */
+ Drawable drawable, /* Pixmap or window in which to draw
+ * polygon. */
+ GC gc, /* Graphics context for drawing. */
+ GC outlineGC) /* If not None, use this to draw an outline
+ * around the polygon after filling it. */
{
XPoint staticPoints[MAX_STATIC_POINTS];
XPoint *pointPtr;
@@ -831,9 +819,9 @@ TkFillPolygon(canvas, coordPtr, numPoints, display, drawable, gc, outlineGC)
int i;
/*
- * Build up an array of points in screen coordinates. Use a
- * static array unless the polygon has an enormous number of points;
- * in this case, dynamically allocate an array.
+ * Build up an array of points in screen coordinates. Use a static array
+ * unless the polygon has an enormous number of points; in this case,
+ * dynamically allocate an array.
*/
if (numPoints <= MAX_STATIC_POINTS) {
@@ -842,7 +830,7 @@ TkFillPolygon(canvas, coordPtr, numPoints, display, drawable, gc, outlineGC)
pointPtr = (XPoint *) ckalloc((unsigned) (numPoints * sizeof(XPoint)));
}
- for (i = 0, pPtr = pointPtr; i < numPoints; i += 1, coordPtr += 2, pPtr++) {
+ for (i=0, pPtr=pointPtr ; i<numPoints; i+=1, coordPtr+=2, pPtr++) {
Tk_CanvasDrawableCoords(canvas, coordPtr[0], coordPtr[1], &pPtr->x,
&pPtr->y);
}
@@ -870,28 +858,27 @@ TkFillPolygon(canvas, coordPtr, numPoints, display, drawable, gc, outlineGC)
*
* DisplayPolygon --
*
- * This procedure is invoked to draw a polygon item in a given
- * drawable.
+ * This function is invoked to draw a polygon item in a given drawable.
*
* Results:
* None.
*
* Side effects:
- * ItemPtr is drawn in drawable using the transformation
- * information in canvas.
+ * ItemPtr is drawn in drawable using the transformation information in
+ * canvas.
*
*--------------------------------------------------------------
*/
static void
-DisplayPolygon(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). */
+DisplayPolygon(
+ 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, int y, int width, int height)
+ /* Describes region of canvas that must be
+ * redisplayed (not used). */
{
PolygonItem *polyPtr = (PolygonItem *) itemPtr;
Tk_State state = itemPtr->state;
@@ -904,7 +891,7 @@ DisplayPolygon(canvas, itemPtr, display, drawable, x, y, width, height)
return;
}
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
@@ -922,16 +909,17 @@ DisplayPolygon(canvas, itemPtr, display, drawable, x, y, width, height)
stipple = polyPtr->disabledFillStipple;
}
}
+
/*
- * If we're stippling then modify the stipple offset in the GC. Be
- * sure to reset the offset when done, since the GC is supposed to be
- * read-only.
+ * If we're stippling then modify the stipple offset in the GC. Be sure to
+ * reset the offset when done, since the GC is supposed to be read-only.
*/
if ((stipple != None) && (polyPtr->fillGC != None)) {
Tk_TSOffset *tsoffset = &polyPtr->tsoffset;
int w=0; int h=0;
int flags = tsoffset->flags;
+
if (!(flags & TK_OFFSET_INDEX) && (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE))) {
Tk_SizeOfBitmap(display, stipple, &w, &h);
if (flags & TK_OFFSET_CENTER) {
@@ -956,6 +944,7 @@ DisplayPolygon(canvas, itemPtr, display, drawable, x, y, width, height)
if(polyPtr->numPoints < 3) {
short x,y;
int intLineWidth = (int) (linewidth + 0.5);
+
if (intLineWidth < 1) {
intLineWidth = 1;
}
@@ -974,13 +963,12 @@ DisplayPolygon(canvas, itemPtr, display, drawable, x, y, width, height)
XPoint *pointPtr;
/*
- * This is a smoothed polygon. Display using a set of generated
- * spline points rather than the original points.
+ * This is a smoothed polygon. Display using a set of generated spline
+ * points rather than the original points.
*/
- numPoints = polyPtr->smooth->coordProc(canvas, (double *) NULL,
- polyPtr->numPoints, polyPtr->splineSteps, (XPoint *) NULL,
- (double *) NULL);
+ numPoints = polyPtr->smooth->coordProc(canvas, NULL,
+ polyPtr->numPoints, polyPtr->splineSteps, NULL, NULL);
if (numPoints <= MAX_STATIC_POINTS) {
pointPtr = staticPoints;
} else {
@@ -988,8 +976,7 @@ DisplayPolygon(canvas, itemPtr, display, drawable, x, y, width, height)
(numPoints * sizeof(XPoint)));
}
numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr,
- polyPtr->numPoints, polyPtr->splineSteps, pointPtr,
- (double *) NULL);
+ polyPtr->numPoints, polyPtr->splineSteps, pointPtr, NULL);
if (polyPtr->fillGC != None) {
XFillPolygon(display, drawable, polyPtr->fillGC, pointPtr,
numPoints, Complex, CoordModeOrigin);
@@ -1025,118 +1012,134 @@ DisplayPolygon(canvas, itemPtr, display, drawable, x, y, width, height)
*/
static void
-PolygonInsert(canvas, itemPtr, beforeThis, obj)
- Tk_Canvas canvas; /* Canvas containing text item. */
- Tk_Item *itemPtr; /* Line item to be modified. */
- int beforeThis; /* Index before which new coordinates
- * are to be inserted. */
- Tcl_Obj *obj; /* New coordinates to be inserted. */
+PolygonInsert(
+ Tk_Canvas canvas, /* Canvas containing text item. */
+ Tk_Item *itemPtr, /* Line item to be modified. */
+ int beforeThis, /* Index before which new coordinates are to
+ * be inserted. */
+ Tcl_Obj *obj) /* New coordinates to be inserted. */
{
PolygonItem *polyPtr = (PolygonItem *) itemPtr;
int length, objc, i;
Tcl_Obj **objv;
- double *new;
+ double *newCoordPtr;
Tk_State state = itemPtr->state;
if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
- if (!obj || (Tcl_ListObjGetElements((Tcl_Interp *) NULL, obj, &objc, &objv) != TCL_OK)
+ if (!obj || (Tcl_ListObjGetElements(NULL, obj, &objc, &objv) != TCL_OK)
|| !objc || objc&1) {
return;
}
length = 2*(polyPtr->numPoints - polyPtr->autoClosed);
- while(beforeThis>length) beforeThis-=length;
- while(beforeThis<0) beforeThis+=length;
- new = (double *) ckalloc((unsigned)(sizeof(double) * (length + 2 + objc)));
+ while (beforeThis>length) {
+ beforeThis -= length;
+ }
+ while (beforeThis<0) {
+ beforeThis += length;
+ }
+ newCoordPtr = (double *)
+ ckalloc(sizeof(double) * (unsigned)(length + 2 + objc));
for (i=0; i<beforeThis; i++) {
- new[i] = polyPtr->coordPtr[i];
+ newCoordPtr[i] = polyPtr->coordPtr[i];
}
for (i=0; i<objc; i++) {
- if (Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,objv[i],
- new+(i+beforeThis))!=TCL_OK) {
- ckfree((char *) new);
+ if (Tcl_GetDoubleFromObj(NULL, objv[i],
+ &newCoordPtr[i+beforeThis]) != TCL_OK){
+ ckfree((char *) newCoordPtr);
return;
}
}
- for(i=beforeThis; i<length; i++) {
- new[i+objc] = polyPtr->coordPtr[i];
+ for (i=beforeThis; i<length; i++) {
+ newCoordPtr[i+objc] = polyPtr->coordPtr[i];
}
- if(polyPtr->coordPtr) ckfree((char *) polyPtr->coordPtr);
- length+=objc;
- polyPtr->coordPtr = new;
+ if (polyPtr->coordPtr) {
+ ckfree((char *) polyPtr->coordPtr);
+ }
+ length += objc;
+ polyPtr->coordPtr = newCoordPtr;
polyPtr->numPoints = (length/2) + polyPtr->autoClosed;
/*
- * Close the polygon if it isn't already closed, or remove autoclosing
- * if the user's coordinates are now closed.
+ * Close the polygon if it isn't already closed, or remove autoclosing if
+ * the user's coordinates are now closed.
*/
if (polyPtr->autoClosed) {
- if ((new[length-2] == new[0]) && (new[length-1] == new[1])) {
+ if ((newCoordPtr[length-2] == newCoordPtr[0])
+ && (newCoordPtr[length-1] == newCoordPtr[1])) {
polyPtr->autoClosed = 0;
polyPtr->numPoints--;
}
- }
- else {
- if ((new[length-2] != new[0]) || (new[length-1] != new[1])) {
+ } else {
+ if ((newCoordPtr[length-2] != newCoordPtr[0])
+ || (newCoordPtr[length-1] != newCoordPtr[1])) {
polyPtr->autoClosed = 1;
polyPtr->numPoints++;
}
}
- new[length] = new[0];
- new[length+1] = new[1];
+ newCoordPtr[length] = newCoordPtr[0];
+ newCoordPtr[length+1] = newCoordPtr[1];
if (((length-objc)>3) && (state != TK_STATE_HIDDEN)) {
/*
- * This is some optimizing code that will result that only the part
- * of the polygon that changed (and the objects that are overlapping
- * with that part) need to be redrawn. A special flag is set that
- * instructs the general canvas code not to redraw the whole
- * object. If this flag is not set, the canvas will do the redrawing,
- * otherwise I have to do it here.
+ * This is some optimizing code that will result that only the part of
+ * the polygon that changed (and the objects that are overlapping with
+ * that part) need to be redrawn. A special flag is set that instructs
+ * the general canvas code not to redraw the whole object. If this
+ * flag is not set, the canvas will do the redrawing, otherwise I have
+ * to do it here.
*/
+
double width;
int j;
itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;
/*
- * The header elements that normally are used for the
- * bounding box, are now used to calculate the bounding
- * box for only the part that has to be redrawn. That
- * doesn't matter, because afterwards the bounding
- * box has to be re-calculated anyway.
+ * The header elements that normally are used for the bounding box,
+ * are now used to calculate the bounding box for only the part that
+ * has to be redrawn. That doesn't matter, because afterwards the
+ * bounding box has to be re-calculated anyway.
*/
itemPtr->x1 = itemPtr->x2 = (int) polyPtr->coordPtr[beforeThis];
itemPtr->y1 = itemPtr->y2 = (int) polyPtr->coordPtr[beforeThis+1];
beforeThis-=2; objc+=4;
- if(polyPtr->smooth) {
- beforeThis-=2; objc+=4;
- } /* be carefull; beforeThis could now be negative */
- for(i=beforeThis; i<beforeThis+objc; i+=2) {
- j=i;
- if(j<0) j+=length;
- if(j>=length) j-=length;
- TkIncludePoint(itemPtr, polyPtr->coordPtr+j);
+ if (polyPtr->smooth) {
+ beforeThis-=2;
+ objc+=4;
+ }
+
+ /*
+ * Be careful; beforeThis could now be negative
+ */
+
+ for (i=beforeThis; i<beforeThis+objc; i+=2) {
+ j = i;
+ if (j<0) {
+ j += length;
+ } else if (j>=length) {
+ j -= length;
+ }
+ TkIncludePoint(itemPtr, polyPtr->coordPtr+j);
}
width = polyPtr->outline.width;
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
- if (polyPtr->outline.activeWidth>width) {
- width = polyPtr->outline.activeWidth;
- }
+ if (polyPtr->outline.activeWidth > width) {
+ width = polyPtr->outline.activeWidth;
+ }
} else if (state==TK_STATE_DISABLED) {
- if (polyPtr->outline.disabledWidth>0.0) {
- width = polyPtr->outline.disabledWidth;
- }
+ if (polyPtr->outline.disabledWidth > 0.0) {
+ width = polyPtr->outline.disabledWidth;
+ }
}
itemPtr->x1 -= (int) width; itemPtr->y1 -= (int) width;
itemPtr->x2 += (int) width; itemPtr->y2 += (int) width;
Tk_CanvasEventuallyRedraw(canvas,
- itemPtr->x1, itemPtr->y1,
- itemPtr->x2, itemPtr->y2);
+ itemPtr->x1, itemPtr->y1, itemPtr->x2, itemPtr->y2);
}
ComputePolygonBbox(canvas, polyPtr);
@@ -1153,37 +1156,47 @@ PolygonInsert(canvas, itemPtr, beforeThis, obj)
* None.
*
* Side effects:
- * Characters between "first" and "last", inclusive, get
- * deleted from itemPtr.
+ * Characters between "first" and "last", inclusive, get deleted from
+ * itemPtr.
*
*--------------------------------------------------------------
*/
static void
-PolygonDeleteCoords(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. */
+PolygonDeleteCoords(
+ 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. */
{
PolygonItem *polyPtr = (PolygonItem *) itemPtr;
int count, i;
int length = 2*(polyPtr->numPoints - polyPtr->autoClosed);
- while(first>=length) first-=length;
- while(first<0) first+=length;
- while(last>=length) last-=length;
- while(last<0) last+=length;
+ while (first>=length) {
+ first -= length;
+ }
+ while (first<0) {
+ first += length;
+ }
+ while (last>=length) {
+ last -= length;
+ }
+ while (last<0) {
+ last += length;
+ }
first &= -2;
last &= -2;
count = last + 2 - first;
- if(count<=0) count +=length;
+ if (count<=0) {
+ count += length;
+ }
- if(count >= length) {
+ if (count >= length) {
polyPtr->numPoints = 0;
- if(polyPtr->coordPtr != NULL) {
+ if (polyPtr->coordPtr != NULL) {
ckfree((char *) polyPtr->coordPtr);
polyPtr->coordPtr = NULL;
}
@@ -1191,7 +1204,7 @@ PolygonDeleteCoords(canvas, itemPtr, first, last)
return;
}
- if(last>=first) {
+ if (last>=first) {
for(i=last+2; i<length; i++) {
polyPtr->coordPtr[i-count] = polyPtr->coordPtr[i];
}
@@ -1211,14 +1224,14 @@ PolygonDeleteCoords(canvas, itemPtr, first, last)
*
* PolygonToPoint --
*
- * Computes the distance from a given point to a given
- * polygon, in canvas units.
+ * Computes the distance from a given point to a given polygon, in canvas
+ * units.
*
* Results:
- * The return value is 0 if the point whose x and y coordinates
- * are pointPtr[0] and pointPtr[1] is inside the polygon. If the
- * point isn't inside the polygon then the return value is the
- * distance from the point to the polygon.
+ * The return value is 0 if the point whose x and y coordinates are
+ * pointPtr[0] and pointPtr[1] is inside the polygon. If the point isn't
+ * inside the polygon then the return value is the distance from the
+ * point to the polygon.
*
* Side effects:
* None.
@@ -1228,10 +1241,10 @@ PolygonDeleteCoords(canvas, itemPtr, first, last)
/* ARGSUSED */
static double
-PolygonToPoint(canvas, itemPtr, pointPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against point. */
- double *pointPtr; /* Pointer to x and y coordinates. */
+PolygonToPoint(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against point. */
+ double *pointPtr) /* Pointer to x and y coordinates. */
{
PolygonItem *polyPtr = (PolygonItem *) itemPtr;
double *coordPtr, *polyPoints;
@@ -1240,15 +1253,15 @@ PolygonToPoint(canvas, itemPtr, pointPtr)
double radius;
double bestDist, dist;
int numPoints, count;
- int changedMiterToBevel; /* Non-zero means that a mitered corner
- * had to be treated as beveled after all
- * because the angle was < 11 degrees. */
+ int changedMiterToBevel; /* Non-zero means that a mitered corner had to
+ * be treated as beveled after all because the
+ * angle was < 11 degrees. */
double width;
Tk_State state = itemPtr->state;
bestDist = 1.0e36;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
width = polyPtr->outline.width;
@@ -1269,9 +1282,9 @@ PolygonToPoint(canvas, itemPtr, pointPtr)
*/
if ((polyPtr->smooth) && (polyPtr->numPoints>2)) {
- numPoints = polyPtr->smooth->coordProc(canvas, (double *) NULL,
- polyPtr->numPoints, polyPtr->splineSteps, (XPoint *) NULL,
- (double *) NULL);
+ numPoints = polyPtr->smooth->coordProc(canvas, NULL,
+ polyPtr->numPoints, polyPtr->splineSteps, NULL,
+ NULL);
if (numPoints <= MAX_STATIC_POINTS) {
polyPoints = staticSpace;
} else {
@@ -1279,7 +1292,7 @@ PolygonToPoint(canvas, itemPtr, pointPtr)
(2*numPoints*sizeof(double)));
}
numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr,
- polyPtr->numPoints, polyPtr->splineSteps, (XPoint *) NULL,
+ polyPtr->numPoints, polyPtr->splineSteps, NULL,
polyPoints);
} else {
numPoints = polyPtr->numPoints;
@@ -1300,22 +1313,23 @@ PolygonToPoint(canvas, itemPtr, pointPtr)
}
}
- if ((polyPtr->outline.gc == None) || (width <= 1)) goto donepoint;
+ if ((polyPtr->outline.gc == None) || (width <= 1)) {
+ goto donepoint;
+ }
/*
- * The overall idea is to iterate through all of the edges of
- * the line, computing a polygon for each edge and testing the
- * point against that polygon. In addition, there are additional
- * tests to deal with rounded joints and caps.
+ * The overall idea is to iterate through all of the edges of the line,
+ * computing a polygon for each edge and testing the point against that
+ * polygon. In addition, there are additional tests to deal with rounded
+ * joints and caps.
*/
changedMiterToBevel = 0;
for (count = numPoints, coordPtr = polyPoints; count >= 2;
count--, coordPtr += 2) {
-
/*
- * If rounding is done around the first point then compute
- * the distance between the point and the point.
+ * If rounding is done around the first point then compute the
+ * distance between the point and the point.
*/
if (polyPtr->joinStyle == JoinRound) {
@@ -1330,9 +1344,9 @@ PolygonToPoint(canvas, itemPtr, pointPtr)
}
/*
- * Compute the polygonal shape corresponding to this edge,
- * consisting of two points for the first point of the edge
- * and two points for the last point of the edge.
+ * Compute the polygonal shape corresponding to this edge, consisting
+ * of two points for the first point of the edge and two points for
+ * the last point of the edge.
*/
if (count == numPoints) {
@@ -1348,10 +1362,10 @@ PolygonToPoint(canvas, itemPtr, pointPtr)
poly, poly+2);
/*
- * If this line uses beveled joints, then check the distance
- * to a polygon comprising the last two points of the previous
- * polygon and the first two from this polygon; this checks
- * the wedges that fill the mitered joint.
+ * If this line uses beveled joints, then check the distance to a
+ * polygon comprising the last two points of the previous polygon
+ * and the first two from this polygon; this checks the wedges
+ * that fill the mitered joint.
*/
if ((polyPtr->joinStyle == JoinBevel) || changedMiterToBevel) {
@@ -1374,8 +1388,8 @@ PolygonToPoint(canvas, itemPtr, pointPtr)
if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4,
(double) width, poly+4, poly+6) == 0) {
changedMiterToBevel = 1;
- TkGetButtPoints(coordPtr, coordPtr+2, (double) width,
- 0, poly+4, poly+6);
+ TkGetButtPoints(coordPtr, coordPtr+2, (double) width, 0,
+ poly+4, poly+6);
}
} else {
TkGetButtPoints(coordPtr, coordPtr+2, (double) width, 0,
@@ -1392,7 +1406,7 @@ PolygonToPoint(canvas, itemPtr, pointPtr)
}
}
- donepoint:
+ donepoint:
if ((polyPoints != staticSpace) && polyPoints != polyPtr->coordPtr) {
ckfree((char *) polyPoints);
}
@@ -1404,14 +1418,13 @@ PolygonToPoint(canvas, itemPtr, pointPtr)
*
* PolygonToArea --
*
- * This procedure is called to determine whether an item
- * lies entirely inside, entirely outside, or overlapping
- * a given rectangular area.
+ * This function is called to determine whether an item lies entirely
+ * inside, entirely outside, or overlapping a given rectangular area.
*
* Results:
- * -1 is returned if the item is entirely outside the area
- * given by rectPtr, 0 if it overlaps, and 1 if it is entirely
- * inside the given area.
+ * -1 is returned if the item is entirely outside the area given by
+ * rectPtr, 0 if it overlaps, and 1 if it is entirely inside the given
+ * area.
*
* Side effects:
* None.
@@ -1421,12 +1434,12 @@ PolygonToPoint(canvas, itemPtr, pointPtr)
/* ARGSUSED */
static int
-PolygonToArea(canvas, itemPtr, rectPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against polygon. */
- double *rectPtr; /* Pointer to array of four coordinates
- * (x1, y1, x2, y2) describing rectangular
- * area. */
+PolygonToArea(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against polygon. */
+ double *rectPtr) /* Pointer to array of four coordinates
+ * (x1,y1,x2,y2) describing rectangular
+ * area. */
{
PolygonItem *polyPtr = (PolygonItem *) itemPtr;
double *coordPtr;
@@ -1434,19 +1447,18 @@ PolygonToArea(canvas, itemPtr, rectPtr)
double *polyPoints, poly[10];
double radius;
int numPoints, count;
- int changedMiterToBevel; /* Non-zero means that a mitered corner
- * had to be treated as beveled after all
- * because the angle was < 11 degrees. */
- int inside; /* Tentative guess about what to return,
- * based on all points seen so far: one
- * means everything seen so far was
- * inside the area; -1 means everything
- * was outside the area. 0 means overlap
- * has been found. */
+ int changedMiterToBevel; /* Non-zero means that a mitered corner had to
+ * be treated as beveled after all because the
+ * angle was < 11 degrees. */
+ int inside; /* Tentative guess about what to return, based
+ * on all points seen so far: one means
+ * everything seen so far was inside the area;
+ * -1 means everything was outside the area. 0
+ * means overlap has been found. */
double width;
Tk_State state = itemPtr->state;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
@@ -1468,60 +1480,62 @@ PolygonToArea(canvas, itemPtr, rectPtr)
return -1;
} else if (polyPtr->numPoints <3) {
double oval[4];
+
oval[0] = polyPtr->coordPtr[0]-radius;
oval[1] = polyPtr->coordPtr[1]-radius;
oval[2] = polyPtr->coordPtr[0]+radius;
oval[3] = polyPtr->coordPtr[1]+radius;
return TkOvalToArea(oval, rectPtr);
}
+
/*
* Handle smoothed polygons by generating an expanded set of points
* against which to do the check.
*/
if (polyPtr->smooth) {
- numPoints = polyPtr->smooth->coordProc(canvas, (double *) NULL,
- polyPtr->numPoints, polyPtr->splineSteps, (XPoint *) NULL,
- (double *) NULL);
+ numPoints = polyPtr->smooth->coordProc(canvas, NULL,
+ polyPtr->numPoints, polyPtr->splineSteps, NULL, NULL);
if (numPoints <= MAX_STATIC_POINTS) {
polyPoints = staticSpace;
} else {
- polyPoints = (double *) ckalloc((unsigned)
- (2*numPoints*sizeof(double)));
+ polyPoints = (double *)
+ ckalloc((unsigned) (2*numPoints*sizeof(double)));
}
numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr,
- polyPtr->numPoints, polyPtr->splineSteps, (XPoint *) NULL,
- polyPoints);
+ polyPtr->numPoints, polyPtr->splineSteps, NULL, polyPoints);
} else {
numPoints = polyPtr->numPoints;
polyPoints = polyPtr->coordPtr;
}
/*
- * Simple test to see if we are in the polygon. Polygons are
- * different from othe canvas items in that they register points
- * being inside even if it isn't filled.
+ * Simple test to see if we are in the polygon. Polygons are different
+ * from othe canvas items in that they register points being inside even
+ * if it isn't filled.
*/
+
inside = TkPolygonToArea(polyPoints, numPoints, rectPtr);
- if (inside==0) goto donearea;
+ if (inside==0) {
+ goto donearea;
+ }
- if (polyPtr->outline.gc == None) goto donearea ;
+ if (polyPtr->outline.gc == None) {
+ goto donearea;
+ }
/*
- * Iterate through all of the edges of the line, computing a polygon
- * for each edge and testing the area against that polygon. In
- * addition, there are additional tests to deal with rounded joints
- * and caps.
+ * Iterate through all of the edges of the line, computing a polygon for
+ * each edge and testing the area against that polygon. In addition, there
+ * are additional tests to deal with rounded joints and caps.
*/
changedMiterToBevel = 0;
for (count = numPoints, coordPtr = polyPoints; count >= 2;
count--, coordPtr += 2) {
-
/*
- * If rounding is done around the first point of the edge
- * then test a circular region around the point with the
- * area.
+ * If rounding is done around the first point of the edge then test a
+ * circular region around the point with the area.
*/
if (polyPtr->joinStyle == JoinRound) {
@@ -1536,28 +1550,26 @@ PolygonToArea(canvas, itemPtr, rectPtr)
}
/*
- * Compute the polygonal shape corresponding to this edge,
- * consisting of two points for the first point of the edge
- * and two points for the last point of the edge.
+ * Compute the polygonal shape corresponding to this edge, consisting
+ * of two points for the first point of the edge and two points for
+ * the last point of the edge.
*/
if (count == numPoints) {
- TkGetButtPoints(coordPtr+2, coordPtr, width,
- 0, poly, poly+2);
+ TkGetButtPoints(coordPtr+2, coordPtr, width, 0, poly, poly+2);
} else if ((polyPtr->joinStyle == JoinMiter) && !changedMiterToBevel) {
poly[0] = poly[6];
poly[1] = poly[7];
poly[2] = poly[4];
poly[3] = poly[5];
} else {
- TkGetButtPoints(coordPtr+2, coordPtr, width, 0,
- poly, poly+2);
+ TkGetButtPoints(coordPtr+2, coordPtr, width, 0, poly, poly+2);
/*
- * If the last joint was beveled, then also check a
- * polygon comprising the last two points of the previous
- * polygon and the first two from this polygon; this checks
- * the wedges that fill the beveled joint.
+ * If the last joint was beveled, then also check a polygon
+ * comprising the last two points of the previous polygon and the
+ * first two from this polygon; this checks the wedges that fill
+ * the beveled joint.
*/
if ((polyPtr->joinStyle == JoinBevel) || changedMiterToBevel) {
@@ -1571,18 +1583,15 @@ PolygonToArea(canvas, itemPtr, rectPtr)
}
}
if (count == 2) {
- TkGetButtPoints(coordPtr, coordPtr+2, width,
- 0, poly+4, poly+6);
+ TkGetButtPoints(coordPtr, coordPtr+2, width, 0, poly+4, poly+6);
} else if (polyPtr->joinStyle == JoinMiter) {
if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4,
width, poly+4, poly+6) == 0) {
changedMiterToBevel = 1;
- TkGetButtPoints(coordPtr, coordPtr+2, width,
- 0, poly+4, poly+6);
+ TkGetButtPoints(coordPtr, coordPtr+2, width,0, poly+4, poly+6);
}
} else {
- TkGetButtPoints(coordPtr, coordPtr+2, width, 0,
- poly+4, poly+6);
+ TkGetButtPoints(coordPtr, coordPtr+2, width, 0, poly+4, poly+6);
}
poly[8] = poly[0];
poly[9] = poly[1];
@@ -1592,7 +1601,7 @@ PolygonToArea(canvas, itemPtr, rectPtr)
}
}
- donearea:
+ donearea:
if ((polyPoints != staticSpace) && (polyPoints != polyPtr->coordPtr)) {
ckfree((char *) polyPoints);
}
@@ -1604,15 +1613,14 @@ PolygonToArea(canvas, itemPtr, rectPtr)
*
* ScalePolygon --
*
- * This procedure is invoked to rescale a polygon item.
+ * This function is invoked to rescale a polygon item.
*
* Results:
* None.
*
* Side effects:
- * The polygon referred to by itemPtr is rescaled so that the
- * following transformation is applied to all point
- * coordinates:
+ * The polygon referred to by itemPtr is rescaled so that the following
+ * transformation is applied to all point coordinates:
* x' = originX + scaleX*(x-originX)
* y' = originY + scaleY*(y-originY)
*
@@ -1620,12 +1628,13 @@ PolygonToArea(canvas, itemPtr, rectPtr)
*/
static void
-ScalePolygon(canvas, itemPtr, originX, originY, scaleX, scaleY)
- Tk_Canvas canvas; /* Canvas containing polygon. */
- Tk_Item *itemPtr; /* Polygon 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. */
+ScalePolygon(
+ Tk_Canvas canvas, /* Canvas containing polygon. */
+ Tk_Item *itemPtr, /* Polygon to be scaled. */
+ double originX, double originY,
+ /* Origin about which to scale rect. */
+ double scaleX, /* Amount to scale in X direction. */
+ double scaleY) /* Amount to scale in Y direction. */
{
PolygonItem *polyPtr = (PolygonItem *) itemPtr;
double *coordPtr;
@@ -1644,14 +1653,13 @@ ScalePolygon(canvas, itemPtr, originX, originY, scaleX, scaleY)
*
* GetPolygonIndex --
*
- * Parse an index into a polygon item and return either its value
- * or an error.
+ * Parse an index into a polygon item and return either its value or an
+ * error.
*
* Results:
- * 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.
+ * 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.
*
* Side effects:
* None.
@@ -1660,33 +1668,31 @@ ScalePolygon(canvas, itemPtr, originX, originY, scaleX, scaleY)
*/
static int
-GetPolygonIndex(interp, canvas, itemPtr, obj, indexPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item for which the index is being
+GetPolygonIndex(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item for which the index is being
* specified. */
- Tcl_Obj *obj; /* Specification of a particular coord
- * in itemPtr's line. */
- int *indexPtr; /* Where to store converted index. */
+ Tcl_Obj *obj, /* Specification of a particular coord in
+ * itemPtr's line. */
+ int *indexPtr) /* Where to store converted index. */
{
PolygonItem *polyPtr = (PolygonItem *) itemPtr;
int length;
char *string = Tcl_GetStringFromObj(obj, &length);
if (string[0] == 'e') {
- if (strncmp(string, "end", (unsigned) length) == 0) {
+ if (strncmp(string, "end", (unsigned)length) == 0) {
*indexPtr = 2*(polyPtr->numPoints - polyPtr->autoClosed);
} else {
- badIndex:
-
/*
- * Some of the paths here leave messages in interp->result,
- * so we have to clear it out before storing our own message.
+ * Some of the paths here leave messages in interp->result, so we
+ * have to clear it out before storing our own message.
*/
- Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);
- Tcl_AppendResult(interp, "bad index \"", string, "\"",
- (char *) NULL);
+ badIndex:
+ Tcl_SetResult(interp, NULL, TCL_STATIC);
+ Tcl_AppendResult(interp, "bad index \"", string, "\"", NULL);
return TCL_ERROR;
}
} else if (string[0] == '@') {
@@ -1717,6 +1723,7 @@ GetPolygonIndex(interp, canvas, itemPtr, obj, indexPtr)
}
} else {
int count = 2*(polyPtr->numPoints - polyPtr->autoClosed);
+
if (Tcl_GetIntFromObj(interp, obj, indexPtr) != TCL_OK) {
goto badIndex;
}
@@ -1739,26 +1746,24 @@ GetPolygonIndex(interp, canvas, itemPtr, obj, indexPtr)
*
* TranslatePolygon --
*
- * This procedure is called to move a polygon by a given
- * amount.
+ * This function is called to move a polygon by a given amount.
*
* Results:
* None.
*
* Side effects:
- * The position of the polygon is offset by (xDelta, yDelta),
- * and the bounding box is updated in the generic part of the
- * item structure.
+ * The position of the polygon is offset by (xDelta, yDelta), and the
+ * bounding box is updated in the generic part of the item structure.
*
*--------------------------------------------------------------
*/
static void
-TranslatePolygon(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. */
+TranslatePolygon(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item that is being moved. */
+ double deltaX, double deltaY)
+ /* Amount by which item is to be moved. */
{
PolygonItem *polyPtr = (PolygonItem *) itemPtr;
double *coordPtr;
@@ -1777,15 +1782,13 @@ TranslatePolygon(canvas, itemPtr, deltaX, deltaY)
*
* PolygonToPostscript --
*
- * This procedure is called to generate Postscript for
- * polygon items.
+ * This function is called to generate Postscript for polygon items.
*
* Results:
- * The return value is a standard Tcl result. If an error
- * occurs in generating Postscript then an error message is
- * 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.
+ * The return value is a standard Tcl result. If an error occurs in
+ * generating Postscript then an error message is 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.
*
* Side effects:
* None.
@@ -1794,15 +1797,13 @@ TranslatePolygon(canvas, itemPtr, deltaX, deltaY)
*/
static int
-PolygonToPostscript(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. */
+PolygonToPostscript(
+ 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. */
{
PolygonItem *polyPtr = (PolygonItem *) itemPtr;
char *style;
@@ -1868,17 +1869,17 @@ PolygonToPostscript(interp, canvas, itemPtr, prepass)
polyPtr->coordPtr[0], Tk_CanvasPsY(canvas, polyPtr->coordPtr[1]),
width/2.0, width/2.0);
Tcl_AppendResult(interp, "matrix currentmatrix\n",string,
- " scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", (char *) NULL);
+ " scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", NULL);
if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
return TCL_ERROR;
}
if (stipple != None) {
- Tcl_AppendResult(interp, "clip ", (char *) NULL);
+ Tcl_AppendResult(interp, "clip ", NULL);
if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
return TCL_ERROR;
}
} else {
- Tcl_AppendResult(interp, "fill\n", (char *) NULL);
+ Tcl_AppendResult(interp, "fill\n", NULL);
}
return TCL_OK;
}
@@ -1899,16 +1900,15 @@ PolygonToPostscript(interp, canvas, itemPtr, prepass)
return TCL_ERROR;
}
if (fillStipple != None) {
- Tcl_AppendResult(interp, "eoclip ", (char *) NULL);
- if (Tk_CanvasPsStipple(interp, canvas, fillStipple)
- != TCL_OK) {
+ Tcl_AppendResult(interp, "eoclip ", NULL);
+ if (Tk_CanvasPsStipple(interp, canvas, fillStipple) != TCL_OK) {
return TCL_ERROR;
}
if (color != NULL) {
- Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);
+ Tcl_AppendResult(interp, "grestore gsave\n", NULL);
}
} else {
- Tcl_AppendResult(interp, "eofill\n", (char *) NULL);
+ Tcl_AppendResult(interp, "eofill\n", NULL);
}
}
@@ -1917,13 +1917,12 @@ PolygonToPostscript(interp, canvas, itemPtr, prepass)
*/
if (color != NULL) {
-
if (!polyPtr->smooth || !polyPtr->smooth->postscriptProc) {
Tk_CanvasPsPath(interp, canvas, polyPtr->coordPtr,
- polyPtr->numPoints);
+ polyPtr->numPoints);
} else {
polyPtr->smooth->postscriptProc(interp, canvas, polyPtr->coordPtr,
- polyPtr->numPoints, polyPtr->splineSteps);
+ polyPtr->numPoints, polyPtr->splineSteps);
}
if (polyPtr->joinStyle == JoinRound) {
@@ -1933,8 +1932,7 @@ PolygonToPostscript(interp, canvas, itemPtr, prepass)
} else {
style = "0";
}
- Tcl_AppendResult(interp, style," setlinejoin 1 setlinecap\n",
- (char *) NULL);
+ Tcl_AppendResult(interp, style," setlinejoin 1 setlinecap\n", NULL);
if (Tk_CanvasPsOutline(canvas, itemPtr,
&(polyPtr->outline)) != TCL_OK) {
return TCL_ERROR;
@@ -1942,3 +1940,11 @@ PolygonToPostscript(interp, canvas, itemPtr, prepass)
}
return TCL_OK;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkCanvPs.c b/generic/tkCanvPs.c
index 88e106a..ac8f105 100644
--- a/generic/tkCanvPs.c
+++ b/generic/tkCanvPs.c
@@ -1,28 +1,28 @@
-/*
+/*
* tkCanvPs.c --
*
- * This module provides Postscript output support for canvases,
- * including the "postscript" widget command plus a few utility
- * procedures used for generating Postscript.
+ * This module provides Postscript output support for canvases, including
+ * the "postscript" widget command plus a few utility functions used for
+ * generating Postscript.
*
* Copyright (c) 1991-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
#include "tkCanvas.h"
-#include "tkPort.h"
+#include "tkFont.h"
/*
* See tkCanvas.h for key data structures used to implement canvases.
*/
/*
- * The following definition is used in generating postscript for images
- * and windows.
+ * The following definition is used in generating postscript for images and
+ * windows.
*/
typedef struct TkColormapData { /* Hold color information for a window */
@@ -36,11 +36,12 @@ typedef struct TkColormapData { /* Hold color information for a window */
/*
* One of the following structures is created to keep track of Postscript
- * output being generated. It consists mostly of information provided on
- * the widget command line.
+ * output being generated. It consists mostly of information provided on the
+ * widget command line.
*/
typedef struct TkPostscriptInfo {
+ Tk_Window tkwin; /* The canvas being printed. */
int x, y, width, height; /* Area to print, in canvas pixel
* coordinates. */
int x2, y2; /* x+width and y+height. */
@@ -55,93 +56,90 @@ typedef struct TkPostscriptInfo {
double scale; /* Scale factor for conversion: each pixel
* maps into this many points. */
Tk_Anchor pageAnchor; /* How to anchor bbox on Postscript page. */
- int rotate; /* Non-zero means output should be rotated
- * on page (landscape mode). */
+ int rotate; /* Non-zero means output should be rotated on
+ * page (landscape mode). */
char *fontVar; /* If non-NULL, gives name of global variable
* containing font mapping information.
* Malloc'ed. */
char *colorVar; /* If non-NULL, give name of global variable
* containing color mapping information.
* Malloc'ed. */
- char *colorMode; /* Mode for handling colors: "monochrome",
+ char *colorMode; /* Mode for handling colors: "monochrome",
* "gray", or "color". Malloc'ed. */
- int colorLevel; /* Numeric value corresponding to colorMode:
- * 0 for mono, 1 for gray, 2 for color. */
+ int colorLevel; /* Numeric value corresponding to colorMode: 0
+ * for mono, 1 for gray, 2 for color. */
char *fileName; /* Name of file in which to write Postscript;
* NULL means return Postscript info as
* result. Malloc'ed. */
- char *channelName; /* If -channel is specified, the name of
- * the channel to use. */
+ char *channelName; /* If -channel is specified, the name of the
+ * channel to use. */
Tcl_Channel chan; /* Open channel corresponding to fileName. */
Tcl_HashTable fontTable; /* Hash table containing names of all font
- * families used in output. The hash table
+ * families used in output. The hash table
* values are not used. */
- int prepass; /* Non-zero means that we're currently in
- * the pre-pass that collects font information,
- * so the Postscript generated isn't
- * relevant. */
- int prolog; /* Non-zero means output should contain
- the file prolog.ps in the header. */
+ int prepass; /* Non-zero means that we're currently in the
+ * pre-pass that collects font information, so
+ * the Postscript generated isn't relevant. */
+ int prolog; /* Non-zero means output should contain the
+ * prolog definitions in the header. */
} TkPostscriptInfo;
/*
- * The table below provides a template that's used to process arguments
- * to the canvas "postscript" command and fill in TkPostscriptInfo
- * structures.
+ * The table below provides a template that's used to process arguments to the
+ * canvas "postscript" command and fill in TkPostscriptInfo structures.
*/
static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_STRING, "-colormap", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_STRING, "-colormap", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, colorVar), 0},
- {TK_CONFIG_STRING, "-colormode", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_STRING, "-colormode", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, colorMode), 0},
- {TK_CONFIG_STRING, "-file", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_STRING, "-file", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, fileName), 0},
- {TK_CONFIG_STRING, "-channel", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_STRING, "-channel", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, channelName), 0},
- {TK_CONFIG_STRING, "-fontmap", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_STRING, "-fontmap", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, fontVar), 0},
- {TK_CONFIG_PIXELS, "-height", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_PIXELS, "-height", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, height), 0},
- {TK_CONFIG_ANCHOR, "-pageanchor", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_ANCHOR, "-pageanchor", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, pageAnchor), 0},
- {TK_CONFIG_STRING, "-pageheight", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_STRING, "-pageheight", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, pageHeightString), 0},
- {TK_CONFIG_STRING, "-pagewidth", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_STRING, "-pagewidth", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, pageWidthString), 0},
- {TK_CONFIG_STRING, "-pagex", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_STRING, "-pagex", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, pageXString), 0},
- {TK_CONFIG_STRING, "-pagey", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_STRING, "-pagey", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, pageYString), 0},
- {TK_CONFIG_BOOLEAN, "-prolog", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_BOOLEAN, "-prolog", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, prolog), 0},
- {TK_CONFIG_BOOLEAN, "-rotate", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_BOOLEAN, "-rotate", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, rotate), 0},
- {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_PIXELS, "-width", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, width), 0},
- {TK_CONFIG_PIXELS, "-x", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_PIXELS, "-x", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, x), 0},
- {TK_CONFIG_PIXELS, "-y", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_PIXELS, "-y", NULL, NULL,
"", Tk_Offset(TkPostscriptInfo, y), 0},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+ {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static int GetPostscriptPoints _ANSI_ARGS_((Tcl_Interp *interp,
- char *string, double *doublePtr));
+static int GetPostscriptPoints(Tcl_Interp *interp,
+ char *string, double *doublePtr);
/*
*--------------------------------------------------------------
*
* TkCanvPostscriptCmd --
*
- * This procedure is invoked to process the "postscript" options
- * of the widget command for canvas widgets. See the user
- * documentation for details on what it does.
+ * This function is invoked to process the "postscript" options of the
+ * widget command for canvas widgets. See the user documentation for
+ * details on what it does.
*
* Results:
* A standard Tcl result.
@@ -154,16 +152,15 @@ static int GetPostscriptPoints _ANSI_ARGS_((Tcl_Interp *interp,
/* ARGSUSED */
int
-TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
- TkCanvas *canvasPtr; /* Information about canvas widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. Caller has
- * already parsed this command enough
- * to know that argv[1] is
- * "postscript". */
+TkCanvPostscriptCmd(
+ TkCanvas *canvasPtr, /* Information about canvas widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ CONST char **argv) /* Argument strings. Caller has already parsed
+ * this command enough to know that argv[1] is
+ * "postscript". */
{
- TkPostscriptInfo psInfo;
+ TkPostscriptInfo psInfo, *psInfoPtr = &psInfo;
Tk_PostscriptInfo oldInfoPtr;
int result;
Tk_Item *itemPtr;
@@ -173,30 +170,28 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
time_t now;
size_t length;
Tk_Window tkwin = canvasPtr->tkwin;
- int deltaX = 0, deltaY = 0; /* Offset of lower-left corner of
- * area to be marked up, measured
- * in canvas units from the positioning
- * point on the page (reflects
- * anchor position). Initial values
- * needed only to stop compiler
- * warnings. */
Tcl_HashSearch search;
Tcl_HashEntry *hPtr;
Tcl_DString buffer;
- char psenccmd[]="::tk::ensure_psenc_is_loaded";
+ char psenccmd[] = "::tk::ensure_psenc_is_loaded";
+ int deltaX = 0, deltaY = 0; /* Offset of lower-left corner of area to be
+ * marked up, measured in canvas units from
+ * the positioning point on the page (reflects
+ * anchor position). Initial values needed
+ * only to stop compiler warnings. */
/*
- *----------------------------------------------------------------
- * Initialize the data structure describing Postscript generation,
- * then process all the arguments to fill the data structure in.
- *----------------------------------------------------------------
+ * Initialize the data structure describing Postscript generation, then
+ * process all the arguments to fill the data structure in.
*/
+
result = Tcl_EvalEx(interp,psenccmd,-1,TCL_EVAL_GLOBAL);
if (result != TCL_OK) {
return result;
}
oldInfoPtr = canvasPtr->psInfo;
- canvasPtr->psInfo = (Tk_PostscriptInfo) &psInfo;
+ canvasPtr->psInfo = (Tk_PostscriptInfo) psInfoPtr;
+ psInfo.tkwin = canvasPtr->tkwin;
psInfo.x = canvasPtr->xOrigin;
psInfo.y = canvasPtr->yOrigin;
psInfo.width = -1;
@@ -220,9 +215,8 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
psInfo.prepass = 0;
psInfo.prolog = 1;
Tcl_InitHashTable(&psInfo.fontTable, TCL_STRING_KEYS);
- result = Tk_ConfigureWidget(interp, tkwin,
- configSpecs, argc-2, argv+2, (char *) &psInfo,
- TK_CONFIG_ARGV_ONLY);
+ result = Tk_ConfigureWidget(interp, tkwin, configSpecs, argc-2, argv+2,
+ (char *) &psInfo, TK_CONFIG_ARGV_ONLY);
if (result != TCL_OK) {
goto cleanup;
}
@@ -265,38 +259,38 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
psInfo.scale /= WidthOfScreen(Tk_Screen(tkwin));
}
switch (psInfo.pageAnchor) {
- case TK_ANCHOR_NW:
- case TK_ANCHOR_W:
- case TK_ANCHOR_SW:
- deltaX = 0;
- break;
- case TK_ANCHOR_N:
- case TK_ANCHOR_CENTER:
- case TK_ANCHOR_S:
- deltaX = -psInfo.width/2;
- break;
- case TK_ANCHOR_NE:
- case TK_ANCHOR_E:
- case TK_ANCHOR_SE:
- deltaX = -psInfo.width;
- break;
+ case TK_ANCHOR_NW:
+ case TK_ANCHOR_W:
+ case TK_ANCHOR_SW:
+ deltaX = 0;
+ break;
+ case TK_ANCHOR_N:
+ case TK_ANCHOR_CENTER:
+ case TK_ANCHOR_S:
+ deltaX = -psInfo.width/2;
+ break;
+ case TK_ANCHOR_NE:
+ case TK_ANCHOR_E:
+ case TK_ANCHOR_SE:
+ deltaX = -psInfo.width;
+ break;
}
switch (psInfo.pageAnchor) {
- case TK_ANCHOR_NW:
- case TK_ANCHOR_N:
- case TK_ANCHOR_NE:
- deltaY = - psInfo.height;
- break;
- case TK_ANCHOR_W:
- case TK_ANCHOR_CENTER:
- case TK_ANCHOR_E:
- deltaY = -psInfo.height/2;
- break;
- case TK_ANCHOR_SW:
- case TK_ANCHOR_S:
- case TK_ANCHOR_SE:
- deltaY = 0;
- break;
+ case TK_ANCHOR_NW:
+ case TK_ANCHOR_N:
+ case TK_ANCHOR_NE:
+ deltaY = - psInfo.height;
+ break;
+ case TK_ANCHOR_W:
+ case TK_ANCHOR_CENTER:
+ case TK_ANCHOR_E:
+ deltaY = -psInfo.height/2;
+ break;
+ case TK_ANCHOR_SW:
+ case TK_ANCHOR_S:
+ case TK_ANCHOR_SE:
+ deltaY = 0;
+ break;
}
if (psInfo.colorMode == NULL) {
@@ -310,22 +304,20 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
} else if (strncmp(psInfo.colorMode, "color", length) == 0) {
psInfo.colorLevel = 2;
} else {
- Tcl_AppendResult(interp, "bad color mode \"",
- psInfo.colorMode, "\": must be monochrome, ",
- "gray, or color", (char *) NULL);
+ Tcl_AppendResult(interp, "bad color mode \"", psInfo.colorMode,
+ "\": must be monochrome, gray, or color", NULL);
goto cleanup;
}
}
if (psInfo.fileName != NULL) {
-
/*
* Check that -file and -channel are not both specified.
*/
if (psInfo.channelName != NULL) {
Tcl_AppendResult(interp, "can't specify both -file",
- " and -channel", (char *) NULL);
+ " and -channel", NULL);
result = TCL_ERROR;
goto cleanup;
}
@@ -337,11 +329,11 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
if (Tcl_IsSafe(interp)) {
Tcl_AppendResult(interp, "can't specify -file in a",
- " safe interpreter", (char *) NULL);
+ " safe interpreter", NULL);
result = TCL_ERROR;
goto cleanup;
}
-
+
p = Tcl_TranslateFileName(interp, psInfo.fileName, &buffer);
if (p == NULL) {
goto cleanup;
@@ -355,35 +347,31 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
if (psInfo.channelName != NULL) {
int mode;
-
+
/*
- * Check that the channel is found in this interpreter and that it
- * is open for writing.
+ * Check that the channel is found in this interpreter and that it is
+ * open for writing.
*/
- psInfo.chan = Tcl_GetChannel(interp, psInfo.channelName,
- &mode);
+ psInfo.chan = Tcl_GetChannel(interp, psInfo.channelName, &mode);
if (psInfo.chan == (Tcl_Channel) NULL) {
result = TCL_ERROR;
goto cleanup;
}
if ((mode & TCL_WRITABLE) == 0) {
- Tcl_AppendResult(interp, "channel \"",
- psInfo.channelName, "\" wasn't opened for writing",
- (char *) NULL);
+ Tcl_AppendResult(interp, "channel \"", psInfo.channelName,
+ "\" wasn't opened for writing", NULL);
result = TCL_ERROR;
goto cleanup;
}
}
-
+
/*
- *--------------------------------------------------------
- * Make a pre-pass over all of the items, generating Postscript
- * and then throwing it away. The purpose of this pass is just
- * to collect information about all the fonts in use, so that
- * we can output font information in the proper form required
- * by the Document Structuring Conventions.
- *--------------------------------------------------------
+ * Make a pre-pass over all of the items, generating Postscript and then
+ * throwing it away. The purpose of this pass is just to collect
+ * information about all the fonts in use, so that we can output font
+ * information in the proper form required by the Document Structuring
+ * Conventions.
*/
psInfo.prepass = 1;
@@ -401,11 +389,10 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
Tcl_ResetResult(interp);
if (result != TCL_OK) {
/*
- * An error just occurred. Just skip out of this loop.
- * There's no need to report the error now; it can be
- * reported later (errors can happen later that don't
- * happen now, so we still have to check for errors later
- * anyway).
+ * An error just occurred. Just skip out of this loop. There's no
+ * need to report the error now; it can be reported later (errors
+ * can happen later that don't happen now, so we still have to
+ * check for errors later anyway).
*/
break;
}
@@ -413,117 +400,109 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
psInfo.prepass = 0;
/*
- *--------------------------------------------------------
* Generate the header and prolog for the Postscript.
- *--------------------------------------------------------
*/
if (psInfo.prolog) {
- Tcl_AppendResult(interp, "%!PS-Adobe-3.0 EPSF-3.0\n",
- "%%Creator: Tk Canvas Widget\n", (char *) NULL);
+ Tcl_AppendResult(interp, "%!PS-Adobe-3.0 EPSF-3.0\n",
+ "%%Creator: Tk Canvas Widget\n", NULL);
#ifdef HAVE_PW_GECOS
- if (!Tcl_IsSafe(interp)) {
- struct passwd *pwPtr = getpwuid(getuid()); /* INTL: Native. */
- Tcl_AppendResult(interp, "%%For: ",
- (pwPtr != NULL) ? pwPtr->pw_gecos : "Unknown", "\n",
- (char *) NULL);
- endpwent();
- }
+ if (!Tcl_IsSafe(interp)) {
+ struct passwd *pwPtr = getpwuid(getuid()); /* INTL: Native. */
+
+ Tcl_AppendResult(interp, "%%For: ",
+ (pwPtr != NULL) ? pwPtr->pw_gecos : "Unknown", "\n", NULL);
+ endpwent();
+ }
#endif /* HAVE_PW_GECOS */
- Tcl_AppendResult(interp, "%%Title: Window ",
- Tk_PathName(tkwin), "\n", (char *) NULL);
- time(&now);
- Tcl_AppendResult(interp, "%%CreationDate: ",
- ctime(&now), (char *) NULL); /* INTL: Native. */
- if (!psInfo.rotate) {
- sprintf(string, "%d %d %d %d",
- (int) (psInfo.pageX + psInfo.scale*deltaX),
- (int) (psInfo.pageY + psInfo.scale*deltaY),
- (int) (psInfo.pageX + psInfo.scale*(deltaX + psInfo.width)
- + 1.0),
- (int) (psInfo.pageY + psInfo.scale*(deltaY + psInfo.height)
- + 1.0));
- } else {
- sprintf(string, "%d %d %d %d",
- (int) (psInfo.pageX - psInfo.scale*(deltaY + psInfo.height)),
- (int) (psInfo.pageY + psInfo.scale*deltaX),
- (int) (psInfo.pageX - psInfo.scale*deltaY + 1.0),
- (int) (psInfo.pageY + psInfo.scale*(deltaX + psInfo.width)
- + 1.0));
- }
- Tcl_AppendResult(interp, "%%BoundingBox: ", string,
- "\n", (char *) NULL);
- Tcl_AppendResult(interp, "%%Pages: 1\n",
- "%%DocumentData: Clean7Bit\n", (char *) NULL);
- Tcl_AppendResult(interp, "%%Orientation: ",
- psInfo.rotate ? "Landscape\n" : "Portrait\n", (char *) NULL);
- p = "%%DocumentNeededResources: font ";
- for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- Tcl_AppendResult(interp, p,
- Tcl_GetHashKey(&psInfo.fontTable, hPtr),
- "\n", (char *) NULL);
- p = "%%+ font ";
- }
- Tcl_AppendResult(interp, "%%EndComments\n\n", (char *) NULL);
+ Tcl_AppendResult(interp, "%%Title: Window ", Tk_PathName(tkwin), "\n",
+ NULL);
+ time(&now);
+ Tcl_AppendResult(interp, "%%CreationDate: ",
+ ctime(&now), NULL); /* INTL: Native. */
+ if (!psInfo.rotate) {
+ sprintf(string, "%d %d %d %d",
+ (int) (psInfo.pageX + psInfo.scale*deltaX),
+ (int) (psInfo.pageY + psInfo.scale*deltaY),
+ (int) (psInfo.pageX + psInfo.scale*(deltaX + psInfo.width)
+ + 1.0),
+ (int) (psInfo.pageY + psInfo.scale*(deltaY + psInfo.height)
+ + 1.0));
+ } else {
+ sprintf(string, "%d %d %d %d",
+ (int) (psInfo.pageX - psInfo.scale*(deltaY+psInfo.height)),
+ (int) (psInfo.pageY + psInfo.scale*deltaX),
+ (int) (psInfo.pageX - psInfo.scale*deltaY + 1.0),
+ (int) (psInfo.pageY + psInfo.scale*(deltaX + psInfo.width)
+ + 1.0));
+ }
+ Tcl_AppendResult(interp, "%%BoundingBox: ", string, "\n", NULL);
+ Tcl_AppendResult(interp, "%%Pages: 1\n",
+ "%%DocumentData: Clean7Bit\n", NULL);
+ Tcl_AppendResult(interp, "%%Orientation: ",
+ psInfo.rotate ? "Landscape\n" : "Portrait\n", NULL);
+ p = "%%DocumentNeededResources: font ";
+ for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search);
+ hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+ Tcl_AppendResult(interp, p,
+ Tcl_GetHashKey(&psInfo.fontTable, hPtr), "\n", NULL);
+ p = "%%+ font ";
+ }
+ Tcl_AppendResult(interp, "%%EndComments\n\n", NULL);
- /*
- * Insert the prolog
- */
- Tcl_AppendResult(interp, Tcl_GetVar(interp,"::tk::ps_preamable",
- TCL_GLOBAL_ONLY), (char *) NULL);
+ /*
+ * Insert the prolog
+ */
- if (psInfo.chan != NULL) {
- Tcl_Write(psInfo.chan, Tcl_GetStringResult(interp), -1);
- Tcl_ResetResult(canvasPtr->interp);
- }
+ Tcl_AppendResult(interp, Tcl_GetVar(interp,"::tk::ps_preamable",
+ TCL_GLOBAL_ONLY), NULL);
- /*
- *-----------------------------------------------------------
- * Document setup: set the color level and include fonts.
- *-----------------------------------------------------------
- */
+ if (psInfo.chan != NULL) {
+ Tcl_Write(psInfo.chan, Tcl_GetStringResult(interp), -1);
+ Tcl_ResetResult(canvasPtr->interp);
+ }
- sprintf(string, "/CL %d def\n", psInfo.colorLevel);
- Tcl_AppendResult(interp, "%%BeginSetup\n", string,
- (char *) NULL);
- for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- Tcl_AppendResult(interp, "%%IncludeResource: font ",
- Tcl_GetHashKey(&psInfo.fontTable, hPtr), "\n", (char *) NULL);
- }
- Tcl_AppendResult(interp, "%%EndSetup\n\n", (char *) NULL);
+ /*
+ * Document setup: set the color level and include fonts.
+ */
- /*
- *-----------------------------------------------------------
- * Page setup: move to page positioning point, rotate if
- * needed, set scale factor, offset for proper anchor position,
- * and set clip region.
- *-----------------------------------------------------------
- */
+ sprintf(string, "/CL %d def\n", psInfo.colorLevel);
+ Tcl_AppendResult(interp, "%%BeginSetup\n", string, NULL);
+ for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search);
+ hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+ Tcl_AppendResult(interp, "%%IncludeResource: font ",
+ Tcl_GetHashKey(&psInfo.fontTable, hPtr), "\n", NULL);
+ }
+ Tcl_AppendResult(interp, "%%EndSetup\n\n", NULL);
- Tcl_AppendResult(interp, "%%Page: 1 1\n", "save\n",
- (char *) NULL);
- sprintf(string, "%.1f %.1f translate\n", psInfo.pageX, psInfo.pageY);
- Tcl_AppendResult(interp, string, (char *) NULL);
- if (psInfo.rotate) {
- Tcl_AppendResult(interp, "90 rotate\n", (char *) NULL);
- }
- sprintf(string, "%.4g %.4g scale\n", psInfo.scale, psInfo.scale);
- Tcl_AppendResult(interp, string, (char *) NULL);
- sprintf(string, "%d %d translate\n", deltaX - psInfo.x, deltaY);
- Tcl_AppendResult(interp, string, (char *) NULL);
- sprintf(string, "%d %.15g moveto %d %.15g lineto %d %.15g lineto %d %.15g",
- psInfo.x,
- Tk_PostscriptY((double) psInfo.y, (Tk_PostscriptInfo) &psInfo),
- psInfo.x2,
- Tk_PostscriptY((double) psInfo.y, (Tk_PostscriptInfo) &psInfo),
- psInfo.x2,
- Tk_PostscriptY((double) psInfo.y2, (Tk_PostscriptInfo) &psInfo),
- psInfo.x,
- Tk_PostscriptY((double) psInfo.y2, (Tk_PostscriptInfo) &psInfo));
- Tcl_AppendResult(interp, string,
- " lineto closepath clip newpath\n", (char *) NULL);
+ /*
+ * Page setup: move to page positioning point, rotate if needed, set
+ * scale factor, offset for proper anchor position, and set clip
+ * region.
+ */
+
+ Tcl_AppendResult(interp, "%%Page: 1 1\n", "save\n", NULL);
+ sprintf(string, "%.1f %.1f translate\n", psInfo.pageX, psInfo.pageY);
+ Tcl_AppendResult(interp, string, NULL);
+ if (psInfo.rotate) {
+ Tcl_AppendResult(interp, "90 rotate\n", NULL);
+ }
+ sprintf(string, "%.4g %.4g scale\n", psInfo.scale, psInfo.scale);
+ Tcl_AppendResult(interp, string, NULL);
+ sprintf(string, "%d %d translate\n", deltaX - psInfo.x, deltaY);
+ Tcl_AppendResult(interp, string, NULL);
+ sprintf(string,
+ "%d %.15g moveto %d %.15g lineto %d %.15g lineto %d %.15g",
+ psInfo.x, Tk_PostscriptY((double)psInfo.y,
+ (Tk_PostscriptInfo)psInfoPtr),
+ psInfo.x2, Tk_PostscriptY((double)psInfo.y,
+ (Tk_PostscriptInfo)psInfoPtr),
+ psInfo.x2, Tk_PostscriptY((double)psInfo.y2,
+ (Tk_PostscriptInfo)psInfoPtr),
+ psInfo.x, Tk_PostscriptY((double)psInfo.y2,
+ (Tk_PostscriptInfo)psInfoPtr));
+ Tcl_AppendResult(interp, string,
+ " lineto closepath clip newpath\n", NULL);
}
if (psInfo.chan != NULL) {
Tcl_Write(psInfo.chan, Tcl_GetStringResult(interp), -1);
@@ -531,10 +510,8 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
}
/*
- *---------------------------------------------------------------------
* Iterate through all the items, having each relevant one draw itself.
* Quit if any of the items returns an error.
- *---------------------------------------------------------------------
*/
result = TCL_OK;
@@ -550,7 +527,7 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
if (itemPtr->state == TK_STATE_HIDDEN) {
continue;
}
- Tcl_AppendResult(interp, "gsave\n", (char *) NULL);
+ Tcl_AppendResult(interp, "gsave\n", NULL);
result = (*itemPtr->typePtr->postscriptProc)(interp,
(Tk_Canvas) canvasPtr, itemPtr, 0);
if (result != TCL_OK) {
@@ -561,7 +538,7 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
Tcl_AddErrorInfo(interp, msg);
goto cleanup;
}
- Tcl_AppendResult(interp, "grestore\n", (char *) NULL);
+ Tcl_AppendResult(interp, "grestore\n", NULL);
if (psInfo.chan != NULL) {
Tcl_Write(psInfo.chan, Tcl_GetStringResult(interp), -1);
Tcl_ResetResult(interp);
@@ -569,15 +546,13 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
}
/*
- *---------------------------------------------------------------------
- * Output page-end information, such as commands to print the page
- * and document trailer stuff.
- *---------------------------------------------------------------------
+ * Output page-end information, such as commands to print the page and
+ * document trailer stuff.
*/
if (psInfo.prolog) {
- Tcl_AppendResult(interp, "restore showpage\n\n",
- "%%Trailer\nend\n%%EOF\n", (char *) NULL);
+ Tcl_AppendResult(interp, "restore showpage\n\n",
+ "%%Trailer\nend\n%%EOF\n", NULL);
}
if (psInfo.chan != NULL) {
Tcl_Write(psInfo.chan, Tcl_GetStringResult(interp), -1);
@@ -588,7 +563,7 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
* Clean up psInfo to release malloc'ed stuff.
*/
- cleanup:
+ cleanup:
if (psInfo.pageXString != NULL) {
ckfree(psInfo.pageXString);
}
@@ -629,16 +604,15 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
*
* Tk_PostscriptColor --
*
- * This procedure is called by individual canvas items when
- * they want to set a color value for output. Given information
- * about an X color, this procedure will generate Postscript
- * commands to set up an appropriate color in Postscript.
+ * This function is called by individual canvas items when they want to
+ * set a color value for output. Given information about an X color, this
+ * function will generate Postscript commands to set up an appropriate
+ * color in Postscript.
*
* Results:
- * Returns a standard Tcl return value. If an error occurs
- * 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's result.
+ * Returns a standard Tcl return value. If an error occurs 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's result.
*
* Side effects:
* None.
@@ -647,10 +621,10 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv)
*/
int
-Tk_PostscriptColor(interp, psInfo, colorPtr)
- Tcl_Interp *interp;
- Tk_PostscriptInfo psInfo; /* Postscript info. */
- XColor *colorPtr; /* Information about color. */
+Tk_PostscriptColor(
+ Tcl_Interp *interp,
+ Tk_PostscriptInfo psInfo, /* Postscript info. */
+ XColor *colorPtr) /* Information about color. */
{
TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
int tmp;
@@ -662,9 +636,8 @@ Tk_PostscriptColor(interp, psInfo, colorPtr)
}
/*
- * If there is a color map defined, then look up the color's name
- * in the map and use the Postscript commands found there, if there
- * are any.
+ * If there is a color map defined, then look up the color's name in the
+ * map and use the Postscript commands found there, if there are any.
*/
if (psInfoPtr->colorVar != NULL) {
@@ -673,22 +646,21 @@ Tk_PostscriptColor(interp, psInfo, colorPtr)
cmdString = Tcl_GetVar2(interp, psInfoPtr->colorVar,
Tk_NameOfColor(colorPtr), 0);
if (cmdString != NULL) {
- Tcl_AppendResult(interp, cmdString, "\n", (char *) NULL);
+ Tcl_AppendResult(interp, cmdString, "\n", NULL);
return TCL_OK;
}
}
/*
- * No color map entry for this color. Grab the color's intensities
- * and output Postscript commands for them. Special note: X uses
- * a range of 0-65535 for intensities, but most displays only use
- * a range of 0-255, which maps to (0, 256, 512, ... 65280) in the
- * X scale. This means that there's no way to get perfect white,
- * since the highest intensity is only 65280 out of 65535. To
- * work around this problem, rescale the X intensity to a 0-255
- * scale and use that as the basis for the Postscript colors. This
- * scheme still won't work if the display only uses 4 bits per color,
- * but most diplays use at least 8 bits.
+ * No color map entry for this color. Grab the color's intensities and
+ * output Postscript commands for them. Special note: X uses a range of
+ * 0-65535 for intensities, but most displays only use a range of 0-255,
+ * which maps to (0, 256, 512, ... 65280) in the X scale. This means that
+ * there's no way to get perfect white, since the highest intensity is
+ * only 65280 out of 65535. To work around this problem, rescale the X
+ * intensity to a 0-255 scale and use that as the basis for the Postscript
+ * colors. This scheme still won't work if the display only uses 4 bits
+ * per color, but most diplays use at least 8 bits.
*/
tmp = colorPtr->red;
@@ -699,7 +671,7 @@ Tk_PostscriptColor(interp, psInfo, colorPtr)
blue = ((double) (tmp >> 8))/255.0;
sprintf(string, "%.3f %.3f %.3f setrgbcolor AdjustColor\n",
red, green, blue);
- Tcl_AppendResult(interp, string, (char *) NULL);
+ Tcl_AppendResult(interp, string, NULL);
return TCL_OK;
}
@@ -708,88 +680,89 @@ Tk_PostscriptColor(interp, psInfo, colorPtr)
*
* Tk_PostscriptFont --
*
- * This procedure is called by individual canvas items when
- * they want to output text. Given information about an X
- * font, this procedure will generate Postscript commands
- * to set up an appropriate font in Postscript.
+ * This function is called by individual canvas items when they want to
+ * output text. Given information about an X font, this function will
+ * generate Postscript commands to set up an appropriate font in
+ * Postscript.
*
* Results:
- * Returns a standard Tcl return value. If an error occurs
- * 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's result.
+ * Returns a standard Tcl return value. If an error occurs 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's result.
*
* Side effects:
- * The Postscript font name is entered into psInfoPtr->fontTable
- * if it wasn't already there.
+ * The Postscript font name is entered into psInfoPtr->fontTable if it
+ * wasn't already there.
*
*--------------------------------------------------------------
*/
int
-Tk_PostscriptFont(interp, psInfo, tkfont)
- Tcl_Interp *interp;
- Tk_PostscriptInfo psInfo; /* Postscript Info. */
- Tk_Font tkfont; /* Information about font in which text
- * is to be printed. */
+Tk_PostscriptFont(
+ Tcl_Interp *interp,
+ Tk_PostscriptInfo psInfo, /* Postscript Info. */
+ Tk_Font tkfont) /* Information about font in which text is to
+ * be printed. */
{
TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
- char *end;
char pointString[TCL_INTEGER_SPACE];
Tcl_DString ds;
int i, points;
/*
- * First, look up the font's name in the font map, if there is one.
- * If there is an entry for this font, it consists of a list
- * containing font name and size. Use this information.
+ * First, look up the font's name in the font map, if there is one. If
+ * there is an entry for this font, it consists of a list containing font
+ * name and size. Use this information.
*/
- Tcl_DStringInit(&ds);
-
if (psInfoPtr->fontVar != NULL) {
- CONST char *list;
- int argc;
+ CONST char *name = Tk_NameOfFont(tkfont);
+ Tcl_Obj **objv;
+ int objc;
double size;
- CONST char **argv;
- CONST char *name;
+ Tcl_Obj *list = Tcl_GetVar2Ex(interp, psInfoPtr->fontVar, name, 0);
- name = Tk_NameOfFont(tkfont);
- list = Tcl_GetVar2(interp, psInfoPtr->fontVar, name, 0);
if (list != NULL) {
- if (Tcl_SplitList(interp, list, &argc, &argv) != TCL_OK) {
- badMapEntry:
+ CONST char *fontname;
+
+ if (Tcl_ListObjGetElements(interp, list, &objc, &objv) != TCL_OK
+ || objc != 2
+ || Tcl_GetString(objv[0])[0]=='\0'
+ || Tcl_GetDoubleFromObj(interp, objv[1], &size) != TCL_OK
+ || size <= 0) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "bad font map entry for \"", name,
- "\": \"", list, "\"", (char *) NULL);
+ "\": \"", Tcl_GetString(list), "\"", NULL);
return TCL_ERROR;
}
- if (argc != 2) {
- goto badMapEntry;
- }
- size = strtod(argv[1], &end);
- if ((size <= 0) || (*end != 0)) {
- goto badMapEntry;
- }
- Tcl_DStringAppend(&ds, argv[0], -1);
- points = (int) size;
-
- ckfree((char *) argv);
- goto findfont;
+ fontname = Tcl_GetString(objv[0]);
+ sprintf(pointString, "%d", (int)size);
+
+ Tcl_AppendResult(interp, "/", fontname, " findfont ",
+ pointString, " scalefont ", NULL);
+ if (strncasecmp(fontname, "Symbol", 7) != 0) {
+ Tcl_AppendResult(interp, "ISOEncode ", NULL);
+ }
+ Tcl_AppendResult(interp, "setfont\n", NULL);
+ Tcl_CreateHashEntry(&psInfoPtr->fontTable, fontname, &i);
+ return TCL_OK;
}
- }
+ }
- points = Tk_PostscriptFontName(tkfont, &ds);
+ /*
+ * Nothing in the font map, so fall back to the old guessing technique.
+ */
- findfont:
- sprintf(pointString, "%d", points);
+ Tcl_DStringInit(&ds);
+ points = Tk_PostscriptFontName(tkfont, &ds);
+ sprintf(pointString, "%d", TkFontGetPoints(psInfoPtr->tkwin, points));
Tcl_AppendResult(interp, "/", Tcl_DStringValue(&ds), " findfont ",
- pointString, " scalefont ", (char *) NULL);
+ pointString, " scalefont ", NULL);
if (strncasecmp(Tcl_DStringValue(&ds), "Symbol", 7) != 0) {
- Tcl_AppendResult(interp, "ISOEncode ", (char *) NULL);
+ Tcl_AppendResult(interp, "ISOEncode ", NULL);
}
- Tcl_AppendResult(interp, "setfont\n", (char *) NULL);
+ Tcl_AppendResult(interp, "setfont\n", NULL);
Tcl_CreateHashEntry(&psInfoPtr->fontTable, Tcl_DStringValue(&ds), &i);
Tcl_DStringFree(&ds);
@@ -801,16 +774,14 @@ Tk_PostscriptFont(interp, psInfo, tkfont)
*
* Tk_PostscriptBitmap --
*
- * This procedure is called to output the contents of a
- * sub-region of a bitmap in proper image data format for
- * Postscript (i.e. data between angle brackets, one bit
- * per pixel).
+ * This function is called to output the contents of a sub-region of a
+ * bitmap in proper image data format for Postscript (i.e. data between
+ * angle brackets, one bit per pixel).
*
* Results:
- * Returns a standard Tcl return value. If an error occurs
- * 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's result.
+ * Returns a standard Tcl return value. If an error occurs 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's result.
*
* Side effects:
* None.
@@ -819,16 +790,14 @@ Tk_PostscriptFont(interp, psInfo, tkfont)
*/
int
-Tk_PostscriptBitmap(interp, tkwin, psInfo, bitmap, startX, startY, width,
- height)
- Tcl_Interp *interp;
- Tk_Window tkwin;
- Tk_PostscriptInfo psInfo; /* Postscript info. */
- Pixmap bitmap; /* Bitmap for which to generate
- * Postscript. */
- int startX, startY; /* Coordinates of upper-left corner
- * of rectangular region to output. */
- int width, height; /* Height of rectangular region. */
+Tk_PostscriptBitmap(
+ Tcl_Interp *interp,
+ Tk_Window tkwin,
+ Tk_PostscriptInfo psInfo, /* Postscript info. */
+ Pixmap bitmap, /* Bitmap for which to generate Postscript. */
+ int startX, int startY, /* Coordinates of upper-left corner of
+ * rectangular region to output. */
+ int width, int height) /* Height of rectangular region. */
{
TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
XImage *imagePtr;
@@ -845,10 +814,10 @@ Tk_PostscriptBitmap(interp, tkwin, psInfo, bitmap, startX, startY, width,
/*
* The following call should probably be a call to Tk_SizeOfBitmap
- * instead, but it seems that we are occasionally invoked by custom
- * item types that create their own bitmaps without registering them
- * with Tk. XGetGeometry is a bit slower than Tk_SizeOfBitmap, but
- * it shouldn't matter here.
+ * instead, but it seems that we are occasionally invoked by custom item
+ * types that create their own bitmaps without registering them with Tk.
+ * XGetGeometry is a bit slower than Tk_SizeOfBitmap, but it shouldn't
+ * matter here.
*/
XGetGeometry(Tk_Display(tkwin), bitmap, &dummyRoot,
@@ -856,7 +825,7 @@ Tk_PostscriptBitmap(interp, tkwin, psInfo, bitmap, startX, startY, width,
(unsigned int *) &totalHeight, &dummyBorderwidth, &dummyDepth);
imagePtr = XGetImage(Tk_Display(tkwin), bitmap, 0, 0,
totalWidth, totalHeight, 1, XYPixmap);
- Tcl_AppendResult(interp, "<", (char *) NULL);
+ Tcl_AppendResult(interp, "<", NULL);
mask = 0x80;
value = 0;
charsInLine = 0;
@@ -870,25 +839,25 @@ Tk_PostscriptBitmap(interp, tkwin, psInfo, bitmap, startX, startY, width,
mask >>= 1;
if (mask == 0) {
sprintf(string, "%02x", value);
- Tcl_AppendResult(interp, string, (char *) NULL);
+ Tcl_AppendResult(interp, string, NULL);
mask = 0x80;
value = 0;
charsInLine += 2;
if (charsInLine >= 60) {
- Tcl_AppendResult(interp, "\n", (char *) NULL);
+ Tcl_AppendResult(interp, "\n", NULL);
charsInLine = 0;
}
}
}
if (mask != 0x80) {
sprintf(string, "%02x", value);
- Tcl_AppendResult(interp, string, (char *) NULL);
+ Tcl_AppendResult(interp, string, NULL);
mask = 0x80;
value = 0;
charsInLine += 2;
}
}
- Tcl_AppendResult(interp, ">", (char *) NULL);
+ Tcl_AppendResult(interp, ">", NULL);
XDestroyImage(imagePtr);
return TCL_OK;
}
@@ -898,18 +867,16 @@ Tk_PostscriptBitmap(interp, tkwin, psInfo, bitmap, startX, startY, width,
*
* Tk_PostscriptStipple --
*
- * This procedure is called by individual canvas items when
- * they have created a path that they'd like to be filled with
- * a stipple pattern. Given information about an X bitmap,
- * this procedure will generate Postscript commands to fill
- * the current clip region using a stipple pattern defined by the
- * bitmap.
+ * This function is called by individual canvas items when they have
+ * created a path that they'd like to be filled with a stipple pattern.
+ * Given information about an X bitmap, this function will generate
+ * Postscript commands to fill the current clip region using a stipple
+ * pattern defined by the bitmap.
*
* Results:
- * Returns a standard Tcl return value. If an error occurs
- * 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's result.
+ * Returns a standard Tcl return value. If an error occurs 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's result.
*
* Side effects:
* None.
@@ -918,12 +885,12 @@ Tk_PostscriptBitmap(interp, tkwin, psInfo, bitmap, startX, startY, width,
*/
int
-Tk_PostscriptStipple(interp, tkwin, psInfo, bitmap)
- Tcl_Interp *interp;
- Tk_Window tkwin;
- Tk_PostscriptInfo psInfo; /* Interpreter for returning Postscript
- * or error message. */
- Pixmap bitmap; /* Bitmap to use for stippling. */
+Tk_PostscriptStipple(
+ Tcl_Interp *interp,
+ Tk_Window tkwin,
+ Tk_PostscriptInfo psInfo, /* Interpreter for returning Postscript or
+ * error message. */
+ Pixmap bitmap) /* Bitmap to use for stippling. */
{
TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
int width, height;
@@ -938,22 +905,22 @@ Tk_PostscriptStipple(interp, tkwin, psInfo, bitmap)
/*
* The following call should probably be a call to Tk_SizeOfBitmap
- * instead, but it seems that we are occasionally invoked by custom
- * item types that create their own bitmaps without registering them
- * with Tk. XGetGeometry is a bit slower than Tk_SizeOfBitmap, but
- * it shouldn't matter here.
+ * instead, but it seems that we are occasionally invoked by custom item
+ * types that create their own bitmaps without registering them with Tk.
+ * XGetGeometry is a bit slower than Tk_SizeOfBitmap, but it shouldn't
+ * matter here.
*/
XGetGeometry(Tk_Display(tkwin), bitmap, &dummyRoot,
(int *) &dummyX, (int *) &dummyY, (unsigned *) &width,
(unsigned *) &height, &dummyBorderwidth, &dummyDepth);
sprintf(string, "%d %d ", width, height);
- Tcl_AppendResult(interp, string, (char *) NULL);
+ Tcl_AppendResult(interp, string, NULL);
if (Tk_PostscriptBitmap(interp, tkwin, psInfo, bitmap, 0, 0,
width, height) != TCL_OK) {
return TCL_ERROR;
}
- Tcl_AppendResult(interp, " StippleFill\n", (char *) NULL);
+ Tcl_AppendResult(interp, " StippleFill\n", NULL);
return TCL_OK;
}
@@ -962,12 +929,13 @@ Tk_PostscriptStipple(interp, tkwin, psInfo, bitmap)
*
* Tk_PostscriptY --
*
- * Given a y-coordinate in local coordinates, this procedure
- * returns a y-coordinate to use for Postscript output.
+ * Given a y-coordinate in local coordinates, this function returns a
+ * y-coordinate to use for Postscript output. Required because canvases
+ * have their origin in the top-left, but postscript pages have their
+ * origin in the bottom left.
*
* Results:
- * Returns the Postscript coordinate that corresponds to
- * "y".
+ * Returns the Postscript coordinate that corresponds to "y".
*
* Side effects:
* None.
@@ -976,9 +944,9 @@ Tk_PostscriptStipple(interp, tkwin, psInfo, bitmap)
*/
double
-Tk_PostscriptY(y, psInfo)
- double y; /* Y-coordinate in canvas coords. */
- Tk_PostscriptInfo psInfo; /* Postscript info */
+Tk_PostscriptY(
+ double y, /* Y-coordinate in canvas coords. */
+ Tk_PostscriptInfo psInfo) /* Postscript info */
{
TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
@@ -990,8 +958,8 @@ Tk_PostscriptY(y, psInfo)
*
* Tk_PostscriptPath --
*
- * Given an array of points for a path, generate Postscript
- * commands to create the path.
+ * Given an array of points for a path, generate Postscript commands to
+ * create the path.
*
* Results:
* Postscript commands get appended to what's in the interp's result.
@@ -1003,14 +971,13 @@ Tk_PostscriptY(y, psInfo)
*/
void
-Tk_PostscriptPath(interp, psInfo, coordPtr, numPoints)
- Tcl_Interp *interp;
- Tk_PostscriptInfo psInfo; /* Canvas on whose behalf Postscript
- * is being generated. */
- double *coordPtr; /* Pointer to first in array of
- * 2*numPoints coordinates giving
- * points for path. */
- int numPoints; /* Number of points at *coordPtr. */
+Tk_PostscriptPath(
+ Tcl_Interp *interp,
+ Tk_PostscriptInfo psInfo, /* Canvas on whose behalf Postscript is being
+ * generated. */
+ double *coordPtr, /* Pointer to first in array of 2*numPoints
+ * coordinates giving points for path. */
+ int numPoints) /* Number of points at *coordPtr. */
{
TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
char buffer[200];
@@ -1020,12 +987,12 @@ Tk_PostscriptPath(interp, psInfo, coordPtr, numPoints)
}
sprintf(buffer, "%.15g %.15g moveto\n", coordPtr[0],
Tk_PostscriptY(coordPtr[1], psInfo));
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
for (numPoints--, coordPtr += 2; numPoints > 0;
numPoints--, coordPtr += 2) {
sprintf(buffer, "%.15g %.15g lineto\n", coordPtr[0],
Tk_PostscriptY(coordPtr[1], psInfo));
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
}
}
@@ -1034,15 +1001,14 @@ Tk_PostscriptPath(interp, psInfo, coordPtr, numPoints)
*
* GetPostscriptPoints --
*
- * Given a string, returns the number of Postscript points
- * corresponding to that string.
+ * Given a string, returns the number of Postscript points corresponding
+ * to that string.
*
* Results:
- * The return value is a standard Tcl return result. If
- * 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
- * the interp's result.
+ * The return value is a standard Tcl return result. If 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 the interp's result.
*
* Side effects:
* None.
@@ -1051,44 +1017,41 @@ Tk_PostscriptPath(interp, psInfo, coordPtr, numPoints)
*/
static int
-GetPostscriptPoints(interp, string, doublePtr)
- Tcl_Interp *interp; /* Use this for error reporting. */
- char *string; /* String describing a screen distance. */
- double *doublePtr; /* Place to store converted result. */
+GetPostscriptPoints(
+ Tcl_Interp *interp, /* Use this for error reporting. */
+ char *string, /* String describing a screen distance. */
+ double *doublePtr) /* Place to store converted result. */
{
char *end;
double d;
d = strtod(string, &end);
if (end == string) {
- error:
- Tcl_AppendResult(interp, "bad distance \"", string,
- "\"", (char *) NULL);
- return TCL_ERROR;
+ goto error;
}
while ((*end != '\0') && isspace(UCHAR(*end))) {
end++;
}
switch (*end) {
- case 'c':
- d *= 72.0/2.54;
- end++;
- break;
- case 'i':
- d *= 72.0;
- end++;
- break;
- case 'm':
- d *= 72.0/25.4;
- end++;
- break;
- case 0:
- break;
- case 'p':
- end++;
- break;
- default:
- goto error;
+ case 'c':
+ d *= 72.0/2.54;
+ end++;
+ break;
+ case 'i':
+ d *= 72.0;
+ end++;
+ break;
+ case 'm':
+ d *= 72.0/25.4;
+ end++;
+ break;
+ case 0:
+ break;
+ case 'p':
+ end++;
+ break;
+ default:
+ goto error;
}
while ((*end != '\0') && isspace(UCHAR(*end))) {
end++;
@@ -1098,34 +1061,37 @@ GetPostscriptPoints(interp, string, doublePtr)
}
*doublePtr = d;
return TCL_OK;
-}
+ error:
+ Tcl_AppendResult(interp, "bad distance \"", string, "\"", NULL);
+ return TCL_ERROR;
+}
+
/*
*--------------------------------------------------------------
*
* TkImageGetColor --
*
- * This procedure converts a pixel value to three floating
- * point numbers, representing the amount of red, green, and
- * blue in that pixel on the screen. It makes use of colormap
- * data passed as an argument, and should work for all Visual
- * types.
+ * This function converts a pixel value to three floating point numbers,
+ * representing the amount of red, green, and blue in that pixel on the
+ * screen. It makes use of colormap data passed as an argument, and
+ * should work for all Visual types.
*
- * This implementation is bogus on Windows because the colormap
- * data is never filled in. Instead all postscript generated
- * data coming through here is expected to be RGB color data.
- * To handle lower bit-depth images properly, XQueryColors
- * must be implemented for Windows.
+ * This implementation is bogus on Windows because the colormap data is
+ * never filled in. Instead all postscript generated data coming through
+ * here is expected to be RGB color data. To handle lower bit-depth
+ * images properly, XQueryColors must be implemented for Windows.
*
* Results:
- * Returns red, green, and blue color values in the range
- * 0 to 1. There are no error returns.
+ * Returns red, green, and blue color values in the range 0 to 1. There
+ * are no error returns.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
+
#ifdef WIN32
#include <windows.h>
@@ -1134,35 +1100,41 @@ GetPostscriptPoints(interp, string, doublePtr)
#define GetRValue(rgb) ((BYTE)(rgb))
#define GetGValue(rgb) ((BYTE)(((WORD)(rgb)) >> 8))
#define GetBValue(rgb) ((BYTE)((rgb)>>16))
-*/
-#else
+ */
+
+#else /* !WIN32 */
+
#define GetRValue(rgb) ((rgb & cdata->red_mask) >> cdata->red_shift)
#define GetGValue(rgb) ((rgb & cdata->green_mask) >> cdata->green_shift)
#define GetBValue(rgb) ((rgb & cdata->blue_mask) >> cdata->blue_shift)
-#endif
+
+#endif /* WIN32 */
#if defined(WIN32) || defined(MAC_OSX_TK)
static void
-TkImageGetColor(cdata, pixel, red, green, blue)
- TkColormapData *cdata; /* Colormap data */
- unsigned long pixel; /* Pixel value to look up */
- double *red, *green, *blue; /* Color data to return */
+TkImageGetColor(
+ TkColormapData *cdata, /* Colormap data */
+ unsigned long pixel, /* Pixel value to look up */
+ double *red, double *green, double *blue)
+ /* Color data to return */
{
*red = (double) GetRValue(pixel) / 255.0;
*green = (double) GetGValue(pixel) / 255.0;
*blue = (double) GetBValue(pixel) / 255.0;
}
-#else
+#else /* ! (WIN32 || MAC_OSX_TK) */
static void
-TkImageGetColor(cdata, pixel, red, green, blue)
- TkColormapData *cdata; /* Colormap data */
- unsigned long pixel; /* Pixel value to look up */
- double *red, *green, *blue; /* Color data to return */
+TkImageGetColor(
+ TkColormapData *cdata, /* Colormap data */
+ unsigned long pixel, /* Pixel value to look up */
+ double *red, double *green, double *blue)
+ /* Color data to return */
{
if (cdata->separated) {
int r = GetRValue(pixel);
int g = GetGValue(pixel);
int b = GetBValue(pixel);
+
*red = cdata->colors[r].red / 65535.0;
*green = cdata->colors[g].green / 65535.0;
*blue = cdata->colors[b].blue / 65535.0;
@@ -1172,24 +1144,22 @@ TkImageGetColor(cdata, pixel, red, green, blue)
*blue = cdata->colors[pixel].blue / 65535.0;
}
}
-#endif
-
+#endif /* WIN32 || MAC_OSX_TK */
+
/*
*--------------------------------------------------------------
*
* TkPostscriptImage --
*
- * This procedure is called to output the contents of an
- * image in Postscript, using a format appropriate for the
- * current color mode (i.e. one bit per pixel in monochrome,
- * one byte per pixel in gray, and three bytes per pixel in
- * color).
+ * This function is called to output the contents of an image in
+ * Postscript, using a format appropriate for the current color mode
+ * (i.e. one bit per pixel in monochrome, one byte per pixel in gray, and
+ * three bytes per pixel in color).
*
* Results:
- * Returns a standard Tcl return value. If an error occurs
- * then an error message will be left in interp->result.
- * If no error occurs, then additional Postscript will be
- * appended to interp->result.
+ * Returns a standard Tcl return value. If an error occurs then an error
+ * message will be left in interp->result. If no error occurs, then
+ * additional Postscript will be appended to interp->result.
*
* Side effects:
* None.
@@ -1198,13 +1168,13 @@ TkImageGetColor(cdata, pixel, red, green, blue)
*/
int
-TkPostscriptImage(interp, tkwin, psInfo, ximage, x, y, width, height)
- Tcl_Interp *interp;
- Tk_Window tkwin;
- Tk_PostscriptInfo psInfo; /* postscript info */
- XImage *ximage; /* Image to draw */
- int x, y; /* First pixel to output */
- int width, height; /* Width and height of area */
+TkPostscriptImage(
+ Tcl_Interp *interp,
+ Tk_Window tkwin,
+ Tk_PostscriptInfo psInfo, /* postscript info */
+ XImage *ximage, /* Image to draw */
+ int x, int y, /* First pixel to output */
+ int width, int height) /* Width and height of area */
{
TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
char buffer[256];
@@ -1225,9 +1195,8 @@ TkPostscriptImage(interp, tkwin, psInfo, ximage, x, y, width, height)
visual = Tk_Visual(tkwin);
/*
- * Obtain information about the colormap, ie the mapping between
- * pixel values and RGB values. The code below should work
- * for all Visual types.
+ * Obtain information about the colormap, ie the mapping between pixel
+ * values and RGB values. The code below should work for all Visual types.
*/
ncolors = visual->map_entries;
@@ -1242,33 +1211,42 @@ TkPostscriptImage(interp, tkwin, psInfo, ximage, x, y, width, height)
cdata.red_shift = 0;
cdata.green_shift = 0;
cdata.blue_shift = 0;
- while ((0x0001 & (cdata.red_mask >> cdata.red_shift)) == 0)
+
+ while ((0x0001 & (cdata.red_mask >> cdata.red_shift)) == 0) {
cdata.red_shift ++;
- while ((0x0001 & (cdata.green_mask >> cdata.green_shift)) == 0)
+ }
+ while ((0x0001 & (cdata.green_mask >> cdata.green_shift)) == 0) {
cdata.green_shift ++;
- while ((0x0001 & (cdata.blue_mask >> cdata.blue_shift)) == 0)
+ }
+ while ((0x0001 & (cdata.blue_mask >> cdata.blue_shift)) == 0) {
cdata.blue_shift ++;
- for (i = 0; i < ncolors; i ++)
+ }
+
+ for (i = 0; i < ncolors; i ++) {
cdata.colors[i].pixel =
- ((i << cdata.red_shift) & cdata.red_mask) |
- ((i << cdata.green_shift) & cdata.green_mask) |
- ((i << cdata.blue_shift) & cdata.blue_mask);
+ ((i << cdata.red_shift) & cdata.red_mask) |
+ ((i << cdata.green_shift) & cdata.green_mask) |
+ ((i << cdata.blue_shift) & cdata.blue_mask);
+ }
} else {
cdata.separated=0;
- for (i = 0; i < ncolors; i ++)
+ for (i = 0; i < ncolors; i ++) {
cdata.colors[i].pixel = i;
+ }
}
- if (visual->class == StaticGray || visual->class == GrayScale)
+
+ if (visual->class == StaticGray || visual->class == GrayScale) {
cdata.color = 0;
- else
+ } else {
cdata.color = 1;
+ }
XQueryColors(Tk_Display(tkwin), cmap, cdata.colors, ncolors);
/*
- * Figure out which color level to use (possibly lower than the
- * one specified by the user). For example, if the user specifies
- * color with monochrome screen, use gray or monochrome mode instead.
+ * Figure out which color level to use (possibly lower than the one
+ * specified by the user). For example, if the user specifies color with
+ * monochrome screen, use gray or monochrome mode instead.
*/
if (!cdata.color && level == 2) {
@@ -1280,15 +1258,15 @@ TkPostscriptImage(interp, tkwin, psInfo, ximage, x, y, width, height)
}
/*
- * Check that at least one row of the image can be represented
- * with a string less than 64 KB long (this is a limit in the
- * Postscript interpreter).
+ * Check that at least one row of the image can be represented with a
+ * string less than 64 KB long (this is a limit in the Postscript
+ * interpreter).
*/
switch (level) {
- case 0: bytesPerLine = (width + 7) / 8; maxWidth = 240000; break;
- case 1: bytesPerLine = width; maxWidth = 60000; break;
- case 2: bytesPerLine = 3 * width; maxWidth = 20000; break;
+ case 0: bytesPerLine = (width + 7) / 8; maxWidth = 240000; break;
+ case 1: bytesPerLine = width; maxWidth = 60000; break;
+ case 2: bytesPerLine = 3 * width; maxWidth = 20000; break;
}
if (bytesPerLine > 60000) {
@@ -1296,7 +1274,7 @@ TkPostscriptImage(interp, tkwin, psInfo, ximage, x, y, width, height)
sprintf(buffer,
"Can't generate Postscript for images more than %d pixels wide",
maxWidth);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
ckfree((char *) cdata.colors);
return TCL_ERROR;
}
@@ -1306,107 +1284,110 @@ TkPostscriptImage(interp, tkwin, psInfo, ximage, x, y, width, height)
for (band = height-1; band >= 0; band -= maxRows) {
int rows = (band >= maxRows) ? maxRows : band + 1;
int lineLen = 0;
+
switch (level) {
- case 0:
- sprintf(buffer, "%d %d 1 matrix {\n<", width, rows);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
- break;
- case 1:
- sprintf(buffer, "%d %d 8 matrix {\n<", width, rows);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
- break;
- case 2:
- sprintf(buffer, "%d %d 8 matrix {\n<",
- width, rows);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
- break;
+ case 0:
+ sprintf(buffer, "%d %d 1 matrix {\n<", width, rows);
+ Tcl_AppendResult(interp, buffer, NULL);
+ break;
+ case 1:
+ sprintf(buffer, "%d %d 8 matrix {\n<", width, rows);
+ Tcl_AppendResult(interp, buffer, NULL);
+ break;
+ case 2:
+ sprintf(buffer, "%d %d 8 matrix {\n<", width, rows);
+ Tcl_AppendResult(interp, buffer, NULL);
+ break;
}
for (yy = band; yy > band - rows; yy--) {
switch (level) {
- case 0: {
- /*
- * Generate data for image in monochrome mode.
- * No attempt at dithering is made--instead, just
- * set a threshold.
- */
- unsigned char mask=0x80;
- unsigned char data=0x00;
- for (xx = x; xx< x+width; xx++) {
- TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy),
- &red, &green, &blue);
- if (0.30 * red + 0.59 * green + 0.11 * blue > 0.5)
- data |= mask;
- mask >>= 1;
- if (mask == 0) {
- sprintf(buffer, "%02X", data);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
- lineLen += 2;
- if (lineLen > 60) {
- lineLen = 0;
- Tcl_AppendResult(interp, "\n", (char *) NULL);
- }
- mask=0x80;
- data=0x00;
- }
- }
- if ((width % 8) != 0) {
- sprintf(buffer, "%02X", data);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
- mask=0x80;
- data=0x00;
+ case 0: {
+ /*
+ * Generate data for image in monochrome mode. No attempt at
+ * dithering is made--instead, just set a threshold.
+ */
+
+ unsigned char mask = 0x80;
+ unsigned char data = 0x00;
+
+ for (xx = x; xx< x+width; xx++) {
+ TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy),
+ &red, &green, &blue);
+ if (0.30 * red + 0.59 * green + 0.11 * blue > 0.5) {
+ data |= mask;
}
- break;
- }
- case 1: {
- /*
- * Generate data in gray mode--in this case, take a
- * weighted sum of the red, green, and blue values.
- */
- for (xx = x; xx < x+width; xx ++) {
- TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy),
- &red, &green, &blue);
- sprintf(buffer, "%02X", (int) floor(0.5 + 255.0 *
- (0.30 * red + 0.59 * green + 0.11 * blue)));
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ mask >>= 1;
+ if (mask == 0) {
+ sprintf(buffer, "%02X", data);
+ Tcl_AppendResult(interp, buffer, NULL);
lineLen += 2;
if (lineLen > 60) {
lineLen = 0;
- Tcl_AppendResult(interp, "\n", (char *) NULL);
+ Tcl_AppendResult(interp, "\n", NULL);
}
+ mask=0x80;
+ data=0x00;
}
- break;
}
- case 2: {
- /*
- * Finally, color mode. Here, just output the red, green,
- * and blue values directly.
- */
- for (xx = x; xx < x+width; xx++) {
- TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy),
- &red, &green, &blue);
- sprintf(buffer, "%02X%02X%02X",
- (int) floor(0.5 + 255.0 * red),
- (int) floor(0.5 + 255.0 * green),
- (int) floor(0.5 + 255.0 * blue));
- Tcl_AppendResult(interp, buffer, (char *) NULL);
- lineLen += 6;
- if (lineLen > 60) {
- lineLen = 0;
- Tcl_AppendResult(interp, "\n", (char *) NULL);
- }
+ if ((width % 8) != 0) {
+ sprintf(buffer, "%02X", data);
+ Tcl_AppendResult(interp, buffer, NULL);
+ mask=0x80;
+ data=0x00;
+ }
+ break;
+ }
+ case 1:
+ /*
+ * Generate data in gray mode; in this case, take a weighted
+ * sum of the red, green, and blue values.
+ */
+
+ for (xx = x; xx < x+width; xx ++) {
+ TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy),
+ &red, &green, &blue);
+ sprintf(buffer, "%02X", (int) floor(0.5 + 255.0 *
+ (0.30 * red + 0.59 * green + 0.11 * blue)));
+ Tcl_AppendResult(interp, buffer, NULL);
+ lineLen += 2;
+ if (lineLen > 60) {
+ lineLen = 0;
+ Tcl_AppendResult(interp, "\n", NULL);
+ }
+ }
+ break;
+ case 2:
+ /*
+ * Finally, color mode. Here, just output the red, green, and
+ * blue values directly.
+ */
+
+ for (xx = x; xx < x+width; xx++) {
+ TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy),
+ &red, &green, &blue);
+ sprintf(buffer, "%02X%02X%02X",
+ (int) floor(0.5 + 255.0 * red),
+ (int) floor(0.5 + 255.0 * green),
+ (int) floor(0.5 + 255.0 * blue));
+ Tcl_AppendResult(interp, buffer, NULL);
+ lineLen += 6;
+ if (lineLen > 60) {
+ lineLen = 0;
+ Tcl_AppendResult(interp, "\n", NULL);
}
- break;
}
+ break;
}
}
switch (level) {
- case 0: sprintf(buffer, ">\n} image\n"); break;
- case 1: sprintf(buffer, ">\n} image\n"); break;
- case 2: sprintf(buffer, ">\n} false 3 colorimage\n"); break;
+ case 0: case 1:
+ sprintf(buffer, ">\n} image\n"); break;
+ case 2:
+ sprintf(buffer, ">\n} false 3 colorimage\n"); break;
}
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
sprintf(buffer, "0 %d translate\n", rows);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
}
ckfree((char *) cdata.colors);
return TCL_OK;
@@ -1417,28 +1398,28 @@ TkPostscriptImage(interp, tkwin, psInfo, ximage, x, y, width, height)
*
* Tk_PostscriptPhoto --
*
- * This procedure is called to output the contents of a
- * photo image in Postscript, using a format appropriate for
- * the requested postscript color mode (i.e. one byte per pixel
- * in gray, and three bytes per pixel in color).
+ * This function is called to output the contents of a photo image in
+ * Postscript, using a format appropriate for the requested postscript
+ * color mode (i.e. one byte per pixel in gray, and three bytes per pixel
+ * in color).
*
* Results:
- * Returns a standard Tcl return value. If an error occurs
- * then an error message will be left in interp->result.
- * If no error occurs, then additional Postscript will be
- * appended to the interpreter's result.
+ * Returns a standard Tcl return value. If an error occurs then an error
+ * message will be left in interp->result. If no error occurs, then
+ * additional Postscript will be appended to the interpreter's result.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
+
int
-Tk_PostscriptPhoto(interp, blockPtr, psInfo, width, height)
- Tcl_Interp *interp;
- Tk_PhotoImageBlock *blockPtr;
- Tk_PostscriptInfo psInfo;
- int width, height;
+Tk_PostscriptPhoto(
+ Tcl_Interp *interp,
+ Tk_PhotoImageBlock *blockPtr,
+ Tk_PostscriptInfo psInfo,
+ int width, int height)
{
TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo;
int colorLevel = psInfoPtr->colorLevel;
@@ -1462,20 +1443,20 @@ Tk_PostscriptPhoto(interp, blockPtr, psInfo, width, height)
}
/*
- * Define the "TkPhoto" function, which is a modified version
- * of the original "transparentimage" function posted
- * by ian@five-d.com (Ian Kemmish) to comp.lang.postscript.
- * For a monochrome colorLevel this is a slightly different
- * version that uses the imagemask command instead of image.
+ * Define the "TkPhoto" function, which is a modified version of the
+ * original "transparentimage" function posted by ian@five-d.com (Ian
+ * Kemmish) to comp.lang.postscript. For a monochrome colorLevel this is a
+ * slightly different version that uses the imagemask command instead of
+ * image.
*/
- if( !codeIncluded && (colorLevel != 0) ) {
+ if (!codeIncluded && (colorLevel != 0)) {
/*
* Color and gray-scale code.
*/
codeIncluded = !0;
- Tcl_AppendResult( interp,
+ Tcl_AppendResult(interp,
"/TkPhoto { \n",
" gsave \n",
" 32 dict begin \n",
@@ -1544,14 +1525,14 @@ Tk_PostscriptPhoto(interp, blockPtr, psInfo, width, height)
" } for \n",
" end \n",
" grestore \n",
- "} bind def \n\n\n", (char *) NULL);
- } else if( !codeIncluded && (colorLevel == 0) ) {
+ "} bind def \n\n\n", NULL);
+ } else if (!codeIncluded && (colorLevel == 0)) {
/*
* Monochrome-only code
*/
codeIncluded = !0;
- Tcl_AppendResult( interp,
+ Tcl_AppendResult(interp,
"/TkPhoto { \n",
" gsave \n",
" 32 dict begin \n",
@@ -1588,27 +1569,26 @@ Tk_PostscriptPhoto(interp, blockPtr, psInfo, width, height)
" } for \n",
" end \n",
" grestore \n",
- "} bind def \n\n\n", (char *) NULL);
+ "} bind def \n\n\n", NULL);
}
/*
- * Check that at least one row of the image can be represented
- * with a string less than 64 KB long (this is a limit in the
- * Postscript interpreter).
+ * Check that at least one row of the image can be represented with a
+ * string less than 64 KB long (this is a limit in the Postscript
+ * interpreter).
*/
- switch (colorLevel)
- {
- case 0: bytesPerLine = (width + 7) / 8; maxWidth = 240000; break;
- case 1: bytesPerLine = width; maxWidth = 60000; break;
- case 2: bytesPerLine = 3 * width; maxWidth = 20000; break;
- }
+ switch (colorLevel) {
+ case 0: bytesPerLine = (width + 7) / 8; maxWidth = 240000; break;
+ case 1: bytesPerLine = width; maxWidth = 60000; break;
+ case 2: bytesPerLine = 3 * width; maxWidth = 20000; break;
+ }
if (bytesPerLine > 60000) {
Tcl_ResetResult(interp);
sprintf(buffer,
"Can't generate Postscript for images more than %d pixels wide",
maxWidth);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
return TCL_ERROR;
}
@@ -1617,45 +1597,37 @@ Tk_PostscriptPhoto(interp, blockPtr, psInfo, width, height)
*/
switch (colorLevel) {
- case 0:
- strcpy( cspace, "/DeviceGray");
- strcpy( decode, "[1 0]");
- bpc = 1;
- break;
- case 1:
- strcpy( cspace, "/DeviceGray");
- strcpy( decode, "[0 1]");
- bpc = 8;
- break;
- default:
- strcpy( cspace, "/DeviceRGB");
- strcpy( decode, "[0 1 0 1 0 1]");
- bpc = 8;
- break;
+ case 0:
+ strcpy(cspace, "/DeviceGray");
+ strcpy(decode, "[1 0]");
+ bpc = 1;
+ break;
+ case 1:
+ strcpy(cspace, "/DeviceGray");
+ strcpy(decode, "[0 1]");
+ bpc = 8;
+ break;
+ default:
+ strcpy(cspace, "/DeviceRGB");
+ strcpy(decode, "[0 1 0 1 0 1]");
+ bpc = 8;
+ break;
}
- Tcl_AppendResult(interp,
- cspace, " setcolorspace\n\n", (char *) NULL);
+ Tcl_AppendResult(interp, cspace, " setcolorspace\n\n", NULL);
- sprintf(buffer,
- " /Width %d\n /Height %d\n /BitsPerComponent %d\n",
+ sprintf(buffer, " /Width %d\n /Height %d\n /BitsPerComponent %d\n",
width, height, bpc);
- Tcl_AppendResult(interp,
- "<<\n /ImageType 1\n", buffer,
- " /DataSource currentfile",
- " /ASCIIHexDecode filter\n", (char *) NULL);
-
-
- sprintf(buffer,
- " /ImageMatrix [1 0 0 -1 0 %d]\n", height);
- Tcl_AppendResult(interp, buffer,
- " /Decode ", decode, "\n>>\n1 TkPhoto\n", (char *) NULL);
+ Tcl_AppendResult(interp, "<<\n /ImageType 1\n", buffer,
+ " /DataSource currentfile /ASCIIHexDecode filter\n", NULL);
+ sprintf(buffer, " /ImageMatrix [1 0 0 -1 0 %d]\n", height);
+ Tcl_AppendResult(interp, buffer, " /Decode ", decode,
+ "\n>>\n1 TkPhoto\n", NULL);
/*
- * Check the PhotoImageBlock information.
- * We assume that:
+ * Check the PhotoImageBlock information. We assume that:
* if pixelSize is 1,2 or 4, the image is R,G,B,A;
* if pixelSize is 3, the image is R,G,B and offset[3] is bogus.
*/
@@ -1678,198 +1650,192 @@ Tk_PostscriptPhoto(interp, blockPtr, psInfo, width, height)
alphaOffset = blockPtr->offset[3];
}
-
for (yy = 0, lineLen=0; yy < height; yy++) {
switch (colorLevel) {
- case 0: {
- /*
- * Generate data for image in monochrome mode.
- * No attempt at dithering is made--instead, just
- * set a threshold.
- * To handle transparecies we need to output two lines:
- * one for the black pixels, one for the white ones.
- */
+ case 0: {
+ /*
+ * Generate data for image in monochrome mode. No attempt at
+ * dithering is made--instead, just set a threshold. To handle
+ * transparecies we need to output two lines: one for the black
+ * pixels, one for the white ones.
+ */
- unsigned char mask=0x80;
- unsigned char data=0x00;
- for (xx = 0; xx< width; xx ++) {
- pixelPtr = blockPtr->pixelPtr
- + (yy * blockPtr->pitch)
+ unsigned char mask = 0x80;
+ unsigned char data = 0x00;
+
+ for (xx = 0; xx< width; xx ++) {
+ pixelPtr = blockPtr->pixelPtr + (yy * blockPtr->pitch)
+ (xx *blockPtr->pixelSize);
- red = pixelPtr[blockPtr->offset[0]];
- green = pixelPtr[blockPtr->offset[1]];
- blue = pixelPtr[blockPtr->offset[2]];
+ red = pixelPtr[blockPtr->offset[0]];
+ green = pixelPtr[blockPtr->offset[1]];
+ blue = pixelPtr[blockPtr->offset[2]];
- alpha = *(alphaPtr + (yy * alphaPitch)
- + (xx * alphaIncr) + alphaOffset);
+ alpha = *(alphaPtr + (yy * alphaPitch)
+ + (xx * alphaIncr) + alphaOffset);
- /*
- * If pixel is less than threshold, then it is black.
- */
+ /*
+ * If pixel is less than threshold, then it is black.
+ */
- if ((alpha != 0) &&
- ( 0.3086 * red
- + 0.6094 * green
- + 0.082 * blue < 128)) {
- data |= mask;
- }
- mask >>= 1;
- if (mask == 0) {
- sprintf(buffer, "%02X", data);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
- lineLen += 2;
- if (lineLen >= 60) {
- lineLen = 0;
- Tcl_AppendResult(interp, "\n", (char *) NULL);
- }
- mask=0x80;
- data=0x00;
- }
+ if ((alpha != 0) &&
+ (0.3086*red + 0.6094*green + 0.082*blue < 128)) {
+ data |= mask;
}
- if ((width % 8) != 0) {
+ mask >>= 1;
+ if (mask == 0) {
sprintf(buffer, "%02X", data);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
- mask=0x80;
- data=0x00;
+ Tcl_AppendResult(interp, buffer, NULL);
+ lineLen += 2;
+ if (lineLen >= 60) {
+ lineLen = 0;
+ Tcl_AppendResult(interp, "\n", NULL);
+ }
+ mask = 0x80;
+ data = 0x00;
}
+ }
+ if ((width % 8) != 0) {
+ sprintf(buffer, "%02X", data);
+ Tcl_AppendResult(interp, buffer, NULL);
+ mask = 0x80;
+ data = 0x00;
+ }
- mask=0x80;
- data=0x00;
- for (xx = 0; xx< width; xx ++) {
- pixelPtr = blockPtr->pixelPtr
- + (yy * blockPtr->pitch)
+ mask = 0x80;
+ data = 0x00;
+ for (xx=0 ; xx<width ; xx++) {
+ pixelPtr = blockPtr->pixelPtr + (yy * blockPtr->pitch)
+ (xx *blockPtr->pixelSize);
- red = pixelPtr[blockPtr->offset[0]];
- green = pixelPtr[blockPtr->offset[1]];
- blue = pixelPtr[blockPtr->offset[2]];
-
- alpha = *(alphaPtr + (yy * alphaPitch)
- + (xx * alphaIncr) + alphaOffset);
-
- /*
- * If pixel is greater than threshold, then it is white.
- */
-
- if ((alpha != 0) &&
- ( 0.3086 * red
- + 0.6094 * green
- + 0.082 * blue >= 128)) {
- data |= mask;
- }
- mask >>= 1;
- if (mask == 0) {
- sprintf(buffer, "%02X", data);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
- lineLen += 2;
- if (lineLen >= 60) {
- lineLen = 0;
- Tcl_AppendResult(interp, "\n", (char *) NULL);
- }
- mask=0x80;
- data=0x00;
- }
- }
- if ((width % 8) != 0) {
- sprintf(buffer, "%02X", data);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
- mask=0x80;
- data=0x00;
- }
- break;
- }
- case 1: {
+ red = pixelPtr[blockPtr->offset[0]];
+ green = pixelPtr[blockPtr->offset[1]];
+ blue = pixelPtr[blockPtr->offset[2]];
+
+ alpha = *(alphaPtr + (yy * alphaPitch)
+ + (xx * alphaIncr) + alphaOffset);
+
/*
- * Generate transparency data.
- * We must prevent a transparent value of 0
- * because of a bug in some HP printers.
+ * If pixel is greater than threshold, then it is white.
*/
- for (xx = 0; xx < width; xx ++) {
- alpha = *(alphaPtr + (yy * alphaPitch)
- + (xx * alphaIncr) + alphaOffset);
- sprintf(buffer, "%02X", alpha | 0x01);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ if ((alpha != 0) &&
+ (0.3086*red + 0.6094*green + 0.082*blue >= 128)) {
+ data |= mask;
+ }
+ mask >>= 1;
+ if (mask == 0) {
+ sprintf(buffer, "%02X", data);
+ Tcl_AppendResult(interp, buffer, NULL);
lineLen += 2;
if (lineLen >= 60) {
lineLen = 0;
- Tcl_AppendResult(interp, "\n", (char *) NULL);
+ Tcl_AppendResult(interp, "\n", NULL);
}
+ mask = 0x80;
+ data = 0x00;
}
+ }
+ if ((width % 8) != 0) {
+ sprintf(buffer, "%02X", data);
+ Tcl_AppendResult(interp, buffer, NULL);
+ mask = 0x80;
+ data = 0x00;
+ }
+ break;
+ }
+ case 1: {
+ /*
+ * Generate transparency data. We must prevent a transparent value
+ * of 0 because of a bug in some HP printers.
+ */
+ for (xx = 0; xx < width; xx ++) {
+ alpha = *(alphaPtr + (yy * alphaPitch)
+ + (xx * alphaIncr) + alphaOffset);
+ sprintf(buffer, "%02X", alpha | 0x01);
+ Tcl_AppendResult(interp, buffer, NULL);
+ lineLen += 2;
+ if (lineLen >= 60) {
+ lineLen = 0;
+ Tcl_AppendResult(interp, "\n", NULL);
+ }
+ }
- /*
- * Generate data in gray mode--in this case, take a
- * weighted sum of the red, green, and blue values.
- */
+ /*
+ * Generate data in gray mode; in this case, take a weighted sum
+ * of the red, green, and blue values.
+ */
- for (xx = 0; xx < width; xx ++) {
- pixelPtr = blockPtr->pixelPtr
- + (yy * blockPtr->pitch)
+ for (xx = 0; xx < width; xx ++) {
+ pixelPtr = blockPtr->pixelPtr + (yy * blockPtr->pitch)
+ (xx *blockPtr->pixelSize);
- red = pixelPtr[blockPtr->offset[0]];
- green = pixelPtr[blockPtr->offset[1]];
- blue = pixelPtr[blockPtr->offset[2]];
-
- sprintf(buffer, "%02X", (int) floor(0.5 +
- ( 0.3086 * red + 0.6094 * green + 0.0820 * blue)));
- Tcl_AppendResult(interp, buffer, (char *) NULL);
- lineLen += 2;
- if (lineLen >= 60) {
- lineLen = 0;
- Tcl_AppendResult(interp, "\n", (char *) NULL);
- }
+ red = pixelPtr[blockPtr->offset[0]];
+ green = pixelPtr[blockPtr->offset[1]];
+ blue = pixelPtr[blockPtr->offset[2]];
+
+ sprintf(buffer, "%02X", (int) floor(0.5 +
+ ( 0.3086 * red + 0.6094 * green + 0.0820 * blue)));
+ Tcl_AppendResult(interp, buffer, NULL);
+ lineLen += 2;
+ if (lineLen >= 60) {
+ lineLen = 0;
+ Tcl_AppendResult(interp, "\n", NULL);
}
- break;
}
- default: {
- /*
- * Generate transparency data.
- * We must prevent a transparent value of 0
- * because of a bug in some HP printers.
- */
+ break;
+ }
+ default:
+ /*
+ * Generate transparency data. We must prevent a transparent value
+ * of 0 because of a bug in some HP printers.
+ */
- for (xx = 0; xx < width; xx ++) {
- alpha = *(alphaPtr + (yy * alphaPitch)
- + (xx * alphaIncr) + alphaOffset);
- sprintf(buffer, "%02X", alpha | 0x01);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
- lineLen += 2;
- if (lineLen >= 60) {
- lineLen = 0;
- Tcl_AppendResult(interp, "\n", (char *) NULL);
- }
+ for (xx = 0; xx < width; xx ++) {
+ alpha = *(alphaPtr + (yy * alphaPitch)
+ + (xx * alphaIncr) + alphaOffset);
+ sprintf(buffer, "%02X", alpha | 0x01);
+ Tcl_AppendResult(interp, buffer, NULL);
+ lineLen += 2;
+ if (lineLen >= 60) {
+ lineLen = 0;
+ Tcl_AppendResult(interp, "\n", NULL);
}
+ }
+ /*
+ * Finally, color mode. Here, just output the red, green, and blue
+ * values directly.
+ */
- /*
- * Finally, color mode. Here, just output the red, green,
- * and blue values directly.
- */
-
- for (xx = 0; xx < width; xx ++) {
- pixelPtr = blockPtr->pixelPtr
- + (yy * blockPtr->pitch)
- + (xx *blockPtr->pixelSize);
-
- sprintf(buffer, "%02X%02X%02X",
- pixelPtr[blockPtr->offset[0]],
- pixelPtr[blockPtr->offset[1]],
- pixelPtr[blockPtr->offset[2]]);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
- lineLen += 6;
- if (lineLen >= 60) {
- lineLen = 0;
- Tcl_AppendResult(interp, "\n", (char *) NULL);
- }
+ for (xx = 0; xx < width; xx ++) {
+ pixelPtr = blockPtr->pixelPtr + (yy * blockPtr->pitch)
+ + (xx * blockPtr->pixelSize);
+
+ sprintf(buffer, "%02X%02X%02X",
+ pixelPtr[blockPtr->offset[0]],
+ pixelPtr[blockPtr->offset[1]],
+ pixelPtr[blockPtr->offset[2]]);
+ Tcl_AppendResult(interp, buffer, NULL);
+ lineLen += 6;
+ if (lineLen >= 60) {
+ lineLen = 0;
+ Tcl_AppendResult(interp, "\n", NULL);
}
- break;
}
+ break;
}
}
- Tcl_AppendResult(interp, ">\n", (char *) NULL);
+ Tcl_AppendResult(interp, ">\n", NULL);
return TCL_OK;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkCanvText.c b/generic/tkCanvText.c
index 282482f..24c3c7f 100644
--- a/generic/tkCanvText.c
+++ b/generic/tkCanvText.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkCanvText.c --
*
* This file implements text items for canvas widgets.
@@ -6,33 +6,32 @@
* Copyright (c) 1991-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <stdio.h>
#include "tkInt.h"
#include "tkCanvas.h"
-#include "tkPort.h"
#include "default.h"
/*
* The structure below defines the record for each text item.
*/
-typedef struct TextItem {
+typedef struct TextItem {
Tk_Item header; /* Generic stuff that's the same for all
- * types. MUST BE FIRST IN STRUCTURE. */
+ * types. MUST BE FIRST IN STRUCTURE. */
Tk_CanvasTextInfo *textInfoPtr;
/* Pointer to a structure containing
* information about the selection and
- * insertion cursor. The structure is owned
- * by (and shared with) the generic canvas
+ * insertion cursor. The structure is owned by
+ * (and shared with) the generic canvas
* code. */
/*
* Fields that are set by widget commands other than "configure".
*/
-
+
double x, y; /* Positioning point for text. */
int insertPos; /* Character index of character just before
* which the insertion cursor is displayed. */
@@ -52,8 +51,10 @@ typedef struct TextItem {
Pixmap activeStipple; /* Stipple bitmap for text, or None. */
Pixmap disabledStipple; /* Stipple bitmap for text, or None. */
char *text; /* Text for item (malloc-ed). */
- int width; /* Width of lines for word-wrap, pixels.
- * Zero means no word-wrap. */
+ int width; /* Width of lines for word-wrap, pixels. Zero
+ * means no word-wrap. */
+ int underline; /* Index of character to put underline beneath
+ * or -1 for no underlining. */
/*
* Fields whose values are derived from the current values of the
@@ -63,18 +64,18 @@ typedef struct TextItem {
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
- * text layout is drawn. */
- int rightEdge; /* Pixel just to right of right edge of
- * area of text item. Used for selecting up
- * to end of line. */
+ int leftEdge; /* Pixel location of the left edge of the text
+ * item; where the left border of the text
+ * layout is drawn. */
+ int rightEdge; /* Pixel just to right of right edge of area
+ * of text item. Used for selecting up to end
+ * of line. */
GC gc; /* Graphics context for drawing text. */
GC selTextGC; /* Graphics context for selected text. */
GC cursorOffGC; /* If not None, this gives a graphics context
* to use to draw the insertion cursor when
- * it's off. Used if the selection and
- * insertion cursor colors are the same. */
+ * it's off. Used if the selection and
+ * insertion cursor colors are the same. */
} TextItem;
/*
@@ -95,89 +96,86 @@ static Tk_CustomOption offsetOption = {
};
static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_COLOR, "-activefill", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TextItem, activeColor), TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-activestipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TextItem, activeStipple), TK_CONFIG_NULL_OK},
- {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
- "center", Tk_Offset(TextItem, anchor),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_COLOR, "-disabledfill", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TextItem, disabledColor), TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-disabledstipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TextItem, disabledStipple), TK_CONFIG_NULL_OK},
- {TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
+ NULL, Tk_Offset(TextItem, activeColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
+ NULL, Tk_Offset(TextItem, activeStipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
+ "center", Tk_Offset(TextItem, anchor), TK_CONFIG_DONT_SET_DEFAULT},
+ {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
+ NULL, Tk_Offset(TextItem, disabledColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
+ NULL, Tk_Offset(TextItem, disabledStipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_COLOR, "-fill", NULL, NULL,
"black", Tk_Offset(TextItem, color), TK_CONFIG_NULL_OK},
- {TK_CONFIG_FONT, "-font", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_FONT, "-font", NULL, NULL,
DEF_CANVTEXT_FONT, Tk_Offset(TextItem, tkfont), 0},
- {TK_CONFIG_JUSTIFY, "-justify", (char *) NULL, (char *) NULL,
- "left", Tk_Offset(TextItem, justify),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_CUSTOM, "-offset", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_JUSTIFY, "-justify", NULL, NULL,
+ "left", Tk_Offset(TextItem, justify), TK_CONFIG_DONT_SET_DEFAULT},
+ {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
"0,0", Tk_Offset(TextItem, tsoffset),
TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
- {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
- &stateOption},
- {TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TextItem, stipple), TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
- {TK_CONFIG_STRING, "-text", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
+ NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
+ {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
+ NULL, Tk_Offset(TextItem, stipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
+ NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
+ {TK_CONFIG_STRING, "-text", NULL, NULL,
"", Tk_Offset(TextItem, text), 0},
- {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_INT, "-underline", NULL, NULL,
+ "-1", Tk_Offset(TextItem, underline), 0},
+ {TK_CONFIG_PIXELS, "-width", NULL, NULL,
"0", Tk_Offset(TextItem, width), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+ {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};
/*
- * Prototypes for procedures defined in this file:
+ * Prototypes for functions defined in this file:
*/
-static void ComputeTextBbox _ANSI_ARGS_((Tk_Canvas canvas,
- TextItem *textPtr));
-static int ConfigureText _ANSI_ARGS_((Tcl_Interp *interp,
+static void ComputeTextBbox(Tk_Canvas canvas, TextItem *textPtr);
+static int ConfigureText(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
- Tcl_Obj *CONST objv[], int flags));
-static int CreateText _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *CONST objv[], int flags);
+static int CreateText(Tcl_Interp *interp,
Tk_Canvas canvas, struct Tk_Item *itemPtr,
- int argc, Tcl_Obj *CONST objv[]));
-static void DeleteText _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, Display *display));
-static void DisplayCanvText _ANSI_ARGS_((Tk_Canvas canvas,
+ int argc, Tcl_Obj *CONST objv[]);
+static void DeleteText(Tk_Canvas canvas,
+ Tk_Item *itemPtr, Display *display);
+static void DisplayCanvText(Tk_Canvas canvas,
Tk_Item *itemPtr, Display *display, Drawable dst,
- int x, int y, int width, int height));
-static int GetSelText _ANSI_ARGS_((Tk_Canvas canvas,
+ int x, int y, int width, int height);
+static int GetSelText(Tk_Canvas canvas,
Tk_Item *itemPtr, int offset, char *buffer,
- int maxBytes));
-static int GetTextIndex _ANSI_ARGS_((Tcl_Interp *interp,
+ int maxBytes);
+static int GetTextIndex(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr,
- Tcl_Obj *obj, int *indexPtr));
-static void ScaleText _ANSI_ARGS_((Tk_Canvas canvas,
+ Tcl_Obj *obj, int *indexPtr);
+static void ScaleText(Tk_Canvas canvas,
Tk_Item *itemPtr, double originX, double originY,
- double scaleX, double scaleY));
-static void SetTextCursor _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, int index));
-static int TextCoords _ANSI_ARGS_((Tcl_Interp *interp,
+ double scaleX, double scaleY);
+static void SetTextCursor(Tk_Canvas canvas,
+ Tk_Item *itemPtr, int index);
+static int TextCoords(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr,
- int argc, Tcl_Obj *CONST objv[]));
-static void TextDeleteChars _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, int first, int last));
-static void TextInsert _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, int beforeThis, char *string));
-static int TextToArea _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *rectPtr));
-static double TextToPoint _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *pointPtr));
-static int TextToPostscript _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));
-static void TranslateText _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double deltaX, double deltaY));
+ int argc, Tcl_Obj *CONST objv[]);
+static void TextDeleteChars(Tk_Canvas canvas,
+ Tk_Item *itemPtr, int first, int last);
+static void TextInsert(Tk_Canvas canvas,
+ Tk_Item *itemPtr, int beforeThis, char *string);
+static int TextToArea(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double *rectPtr);
+static double TextToPoint(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double *pointPtr);
+static int TextToPostscript(Tcl_Interp *interp,
+ Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
+static void TranslateText(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double deltaX, double deltaY);
/*
- * The structures below defines the rectangle and oval item types
- * by means of procedures that can be invoked by generic item code.
+ * The structures below defines the rectangle and oval item types by means of
+ * functions that can be invoked by generic item code.
*/
Tk_ItemType tkTextType = {
@@ -200,7 +198,7 @@ Tk_ItemType tkTextType = {
GetSelText, /* selectionProc */
TextInsert, /* insertProc */
TextDeleteChars, /* dTextProc */
- (Tk_ItemType *) NULL, /* nextPtr */
+ NULL, /* nextPtr */
};
/*
@@ -208,14 +206,12 @@ Tk_ItemType tkTextType = {
*
* CreateText --
*
- * This procedure is invoked to create a new text item
- * in a canvas.
+ * This function is invoked to create a new text item in a canvas.
*
* Results:
- * A standard Tcl return value. If an error occurred in
- * creating the item then an error message is left in
- * the interp's result; in this case itemPtr is left uninitialized
- * so it can be safely freed by the caller.
+ * A standard Tcl return value. If an error occurred in creating the item
+ * then an error message is left in the interp's result; in this case
+ * itemPtr is left uninitialized so it can be safely freed by the caller.
*
* Side effects:
* A new text item is created.
@@ -224,24 +220,24 @@ Tk_ItemType tkTextType = {
*/
static int
-CreateText(interp, canvas, itemPtr, objc, objv)
- 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
+CreateText(
+ 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 objc; /* Number of arguments in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing rectangle. */
+ int objc, /* Number of arguments in objv. */
+ Tcl_Obj *CONST objv[]) /* Arguments describing rectangle. */
{
TextItem *textPtr = (TextItem *) itemPtr;
int i;
if (objc == 0) {
- panic("canvas did not pass any coords\n");
+ Tcl_Panic("canvas did not pass any coords\n");
}
/*
* Carry out initialization that is needed in order to clean up after
- * errors during the the remainder of this procedure.
+ * errors during the the remainder of this function.
*/
textPtr->textInfoPtr = Tk_CanvasGetTextInfo(canvas);
@@ -262,6 +258,7 @@ CreateText(interp, canvas, itemPtr, objc, objv)
textPtr->disabledStipple = None;
textPtr->text = NULL;
textPtr->width = 0;
+ textPtr->underline = -1;
textPtr->numChars = 0;
textPtr->numBytes = 0;
@@ -273,14 +270,15 @@ CreateText(interp, canvas, itemPtr, objc, objv)
textPtr->cursorOffGC = None;
/*
- * Process the arguments to fill in the item record.
- * Only 1 (list) or 2 (x y) coords are allowed.
+ * Process the arguments to fill in the item record. Only 1 (list) or 2 (x
+ * y) coords are allowed.
*/
if (objc == 1) {
i = 1;
} else {
char *arg = Tcl_GetString(objv[1]);
+
i = 2;
if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
i = 1;
@@ -293,7 +291,7 @@ CreateText(interp, canvas, itemPtr, objc, objv)
return TCL_OK;
}
- error:
+ error:
DeleteText(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
return TCL_ERROR;
}
@@ -303,9 +301,8 @@ CreateText(interp, canvas, itemPtr, objc, objv)
*
* TextCoords --
*
- * This procedure is invoked to process the "coords" widget
- * command on text items. See the user documentation for
- * details on what it does.
+ * This function is invoked to process the "coords" widget command on
+ * text items. See the user documentation for details on what it does.
*
* Results:
* Returns TCL_OK or TCL_ERROR, and sets the interp's result.
@@ -317,18 +314,19 @@ CreateText(interp, canvas, itemPtr, objc, objv)
*/
static int
-TextCoords(interp, canvas, itemPtr, objc, objv)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item whose coordinates are to be read or
+TextCoords(
+ 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 objc; /* Number of coordinates supplied in objv. */
- Tcl_Obj *CONST objv[]; /* Array of coordinates: x1, y1, x2, y2, ... */
+ int objc, /* Number of coordinates supplied in objv. */
+ Tcl_Obj *CONST objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */
{
TextItem *textPtr = (TextItem *) itemPtr;
if (objc == 0) {
Tcl_Obj *obj = Tcl_NewObj();
+
Tcl_Obj *subobj = Tcl_NewDoubleObj(textPtr->x);
Tcl_ListObjAppendElement(interp, obj, subobj);
subobj = Tcl_NewDoubleObj(textPtr->y);
@@ -347,15 +345,16 @@ TextCoords(interp, canvas, itemPtr, objc, objv)
return TCL_ERROR;
}
}
- if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0], &textPtr->x) != TCL_OK)
+ if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
+ &textPtr->x) != TCL_OK)
|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
- &textPtr->y) != TCL_OK)) {
+ &textPtr->y) != TCL_OK)) {
return TCL_ERROR;
}
ComputeTextBbox(canvas, textPtr);
} else {
char buf[64 + TCL_INTEGER_SPACE];
-
+
sprintf(buf, "wrong # coordinates: expected 0 or 2, got %d", objc);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_ERROR;
@@ -368,28 +367,28 @@ TextCoords(interp, canvas, itemPtr, objc, objv)
*
* ConfigureText --
*
- * This procedure is invoked to configure various aspects
- * of a text item, such as its border and background colors.
+ * This function is invoked to configure various aspects of a text item,
+ * such as its border and background colors.
*
* Results:
- * A standard Tcl result code. If an error occurs, then
- * an error message is left in the interp's result.
+ * A standard Tcl result code. If an error occurs, then an error message
+ * is left in the interp's result.
*
* Side effects:
- * Configuration information, such as colors and stipple
- * patterns, may be set for itemPtr.
+ * Configuration information, such as colors and stipple patterns, may be
+ * set for itemPtr.
*
*--------------------------------------------------------------
*/
static int
-ConfigureText(interp, canvas, itemPtr, objc, objv, flags)
- Tcl_Interp *interp; /* Interpreter for error reporting. */
- Tk_Canvas canvas; /* Canvas containing itemPtr. */
- Tk_Item *itemPtr; /* Rectangle item to reconfigure. */
- int objc; /* Number of elements in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing things to configure. */
- int flags; /* Flags to pass to Tk_ConfigureWidget. */
+ConfigureText(
+ Tcl_Interp *interp, /* Interpreter for error reporting. */
+ Tk_Canvas canvas, /* Canvas containing itemPtr. */
+ Tk_Item *itemPtr, /* Rectangle item to reconfigure. */
+ int objc, /* Number of elements in objv. */
+ Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */
+ int flags) /* Flags to pass to Tk_ConfigureWidget. */
{
TextItem *textPtr = (TextItem *) itemPtr;
XGCValues gcValues;
@@ -409,14 +408,13 @@ ConfigureText(interp, canvas, itemPtr, objc, objv, flags)
}
/*
- * A few of the options require additional processing, such as
- * graphics contexts.
+ * A few of the options require additional processing, such as graphics
+ * contexts.
*/
state = itemPtr->state;
- if (textPtr->activeColor != NULL ||
- textPtr->activeStipple != None) {
+ if (textPtr->activeColor != NULL || textPtr->activeStipple != None) {
itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
} else {
itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
@@ -497,14 +495,14 @@ ConfigureText(interp, canvas, itemPtr, objc, objv, flags)
/*
- * If the text was changed, move the selection and insertion indices
- * to keep them inside the item.
+ * If the text was changed, move the selection and insertion indices to
+ * keep them inside the item.
*/
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 {
@@ -530,8 +528,8 @@ ConfigureText(interp, canvas, itemPtr, objc, objv, flags)
*
* DeleteText --
*
- * This procedure is called to clean up the data structure
- * associated with a text item.
+ * This function is called to clean up the data structure associated with
+ * a text item.
*
* Results:
* None.
@@ -543,10 +541,10 @@ ConfigureText(interp, canvas, itemPtr, objc, objv, 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. */
+DeleteText(
+ 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;
@@ -590,26 +588,25 @@ DeleteText(canvas, itemPtr, display)
*
* ComputeTextBbox --
*
- * This procedure is invoked to compute the bounding box of
- * all the pixels that may be drawn as part of a text item.
- * In addition, it recomputes all of the geometry information
- * used to display a text item or check for mouse hits.
+ * This function is invoked to compute the bounding box of all the pixels
+ * that may be drawn as part of a text item. In addition, it recomputes
+ * all of the geometry information used to display a text item or check
+ * for mouse hits.
*
* Results:
* None.
*
* Side effects:
- * The fields x1, y1, x2, and y2 are updated in the header
- * for itemPtr, and the linePtr structure is regenerated
- * for itemPtr.
+ * The fields x1, y1, x2, and y2 are updated in the header for itemPtr,
+ * and the linePtr structure is regenerated for itemPtr.
*
*--------------------------------------------------------------
*/
static void
-ComputeTextBbox(canvas, textPtr)
- Tk_Canvas canvas; /* Canvas that contains item. */
- TextItem *textPtr; /* Item whose bbox is to be recomputed. */
+ComputeTextBbox(
+ 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;
@@ -629,57 +626,56 @@ ComputeTextBbox(canvas, textPtr)
}
/*
- * Use overall geometry information to compute the top-left corner
- * of the bounding box for the text item.
+ * Use overall geometry information to compute the top-left corner of the
+ * bounding box for the text item.
*/
leftX = (int) floor(textPtr->x + 0.5);
topY = (int) floor(textPtr->y + 0.5);
switch (textPtr->anchor) {
- case TK_ANCHOR_NW:
- case TK_ANCHOR_N:
- case TK_ANCHOR_NE:
- break;
-
- case TK_ANCHOR_W:
- case TK_ANCHOR_CENTER:
- case TK_ANCHOR_E:
- topY -= height / 2;
- break;
-
- case TK_ANCHOR_SW:
- case TK_ANCHOR_S:
- case TK_ANCHOR_SE:
- topY -= height;
- break;
+ case TK_ANCHOR_NW:
+ case TK_ANCHOR_N:
+ case TK_ANCHOR_NE:
+ break;
+
+ case TK_ANCHOR_W:
+ case TK_ANCHOR_CENTER:
+ case TK_ANCHOR_E:
+ topY -= height / 2;
+ break;
+
+ case TK_ANCHOR_SW:
+ case TK_ANCHOR_S:
+ case TK_ANCHOR_SE:
+ topY -= height;
+ break;
}
switch (textPtr->anchor) {
- case TK_ANCHOR_NW:
- case TK_ANCHOR_W:
- case TK_ANCHOR_SW:
- break;
+ case TK_ANCHOR_NW:
+ case TK_ANCHOR_W:
+ case TK_ANCHOR_SW:
+ break;
- case TK_ANCHOR_N:
- case TK_ANCHOR_CENTER:
- case TK_ANCHOR_S:
- leftX -= width / 2;
- break;
+ case TK_ANCHOR_N:
+ case TK_ANCHOR_CENTER:
+ case TK_ANCHOR_S:
+ leftX -= width / 2;
+ break;
- case TK_ANCHOR_NE:
- case TK_ANCHOR_E:
- case TK_ANCHOR_SE:
- leftX -= width;
- break;
+ case TK_ANCHOR_NE:
+ case TK_ANCHOR_E:
+ case TK_ANCHOR_SE:
+ leftX -= width;
+ break;
}
- textPtr->leftEdge = leftX;
+ textPtr->leftEdge = leftX;
textPtr->rightEdge = leftX + width;
/*
- * Last of all, update the bounding box for the item. The item's
- * bounding box includes the bounding box of all its lines, plus
- * an extra fudge factor for the cursor border (which could
- * potentially be quite large).
+ * Last of all, update the bounding box for the item. The item's bounding
+ * box includes the bounding box of all its lines, plus an extra fudge
+ * factor for the cursor border (which could potentially be quite large).
*/
textInfoPtr = textPtr->textInfoPtr;
@@ -698,26 +694,26 @@ ComputeTextBbox(canvas, textPtr)
*
* DisplayCanvText --
*
- * This procedure is invoked to draw a text item in a given
- * drawable.
+ * This function is invoked to draw a text item in a given drawable.
*
* Results:
* None.
*
* Side effects:
- * ItemPtr is drawn in drawable using the transformation
- * information in canvas.
+ * ItemPtr is drawn in drawable using the transformation information in
+ * canvas.
*
*--------------------------------------------------------------
*/
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
+DisplayCanvText(
+ 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, int y, int width, int height)
+ /* Describes region of canvas that must be
* redisplayed (not used). */
{
TextItem *textPtr;
@@ -749,8 +745,8 @@ DisplayCanvText(canvas, itemPtr, display, drawable, x, y, width, height)
}
/*
- * If we're stippling, then modify the stipple offset in the GC. Be
- * sure to reset the offset when done, since the GC is supposed to be
+ * If we're stippling, then modify the stipple offset in the GC. Be sure
+ * to reset the offset when done, since the GC is supposed to be
* read-only.
*/
@@ -792,7 +788,7 @@ DisplayCanvText(canvas, itemPtr, display, drawable, x, y, width, height)
for (y = yFirst ; y <= yLast; y += height) {
if (y == yLast) {
width = xLast + wLast - x;
- } else {
+ } else {
width = textPtr->rightEdge - textPtr->leftEdge - x;
}
Tk_CanvasDrawableCoords(canvas,
@@ -811,11 +807,11 @@ DisplayCanvText(canvas, itemPtr, display, drawable, x, y, width, height)
/*
* If the insertion point should be displayed, then draw a special
- * background for the cursor before drawing the text. Note: if
- * we're the cursor item but the cursor is turned off, then redraw
- * background over the area of the cursor. This guarantees that
- * the selection won't make the cursor invisible on mono displays,
- * where both are drawn in the same color.
+ * background for the cursor before drawing the text. Note: if we're the
+ * cursor item but the cursor is turned off, then redraw background over
+ * the area of the cursor. This guarantees that the selection won't make
+ * the cursor invisible on mono displays, where both are drawn in the same
+ * color.
*/
if ((textInfoPtr->focusItemPtr == itemPtr) && (textInfoPtr->gotFocus)) {
@@ -836,11 +832,10 @@ DisplayCanvText(canvas, itemPtr, display, drawable, x, y, width, height)
textInfoPtr->insertBorderWidth, TK_RELIEF_RAISED);
} else if (textPtr->cursorOffGC != None) {
/*
- * Redraw the background over the area of the cursor,
- * even though the cursor is turned off. This
- * guarantees that the selection won't make the cursor
- * invisible on mono displays, where both may be drawn
- * in the same color.
+ * Redraw the background over the area of the cursor, even
+ * though the cursor is turned off. This guarantees that the
+ * selection won't make the cursor invisible on mono displays,
+ * where both may be drawn in the same color.
*/
XFillRectangle(display, drawable, textPtr->cursorOffGC,
@@ -851,16 +846,14 @@ DisplayCanvText(canvas, itemPtr, display, drawable, x, y, width, height)
}
}
-
/*
- * If there is no selected text or the selected text foreground
- * is the same as the regular text foreground, then draw one
- * text string. If there is selected text and the foregrounds
- * differ, draw the regular text up to the selection, draw
- * the selection, then draw the rest of the regular text.
- * Drawing the regular text and then the selected text over
- * it would causes problems with anti-aliased text because the
- * two anti-aliasing colors would blend together.
+ * If there is no selected text or the selected text foreground is the
+ * same as the regular text foreground, then draw one text string. If
+ * there is selected text and the foregrounds differ, draw the regular
+ * text up to the selection, draw the selection, then draw the rest of the
+ * regular text. Drawing the regular text and then the selected text over
+ * it would causes problems with anti-aliased text because the two
+ * anti-aliasing colors would blend together.
*/
Tk_CanvasDrawableCoords(canvas, (double) textPtr->leftEdge,
@@ -878,6 +871,8 @@ DisplayCanvText(canvas, itemPtr, display, drawable, x, y, width, height)
Tk_DrawTextLayout(display, drawable, textPtr->gc, textPtr->textLayout,
drawableX, drawableY, 0, -1);
}
+ Tk_UnderlineTextLayout(display, drawable, textPtr->gc, textPtr->textLayout,
+ drawableX, drawableY, textPtr->underline);
if (stipple != None) {
XSetTSOrigin(display, textPtr->gc, 0, 0);
@@ -895,24 +890,23 @@ DisplayCanvText(canvas, itemPtr, display, drawable, x, y, width, height)
* None.
*
* Side effects:
- * The text in the given item is modified. The cursor and
- * selection positions are also modified to reflect the
- * insertion.
+ * The text in the given item is modified. The cursor and selection
+ * positions are also modified to reflect the insertion.
*
*--------------------------------------------------------------
*/
static void
-TextInsert(canvas, itemPtr, index, string)
- Tk_Canvas canvas; /* Canvas containing text item. */
- Tk_Item *itemPtr; /* Text item to be modified. */
- int index; /* Character index before which string is
- * to be inserted. */
- char *string; /* New characters to be inserted. */
+TextInsert(
+ Tk_Canvas canvas, /* Canvas containing text item. */
+ Tk_Item *itemPtr, /* Text item to be modified. */
+ int index, /* Character index before which string is to
+ * be inserted. */
+ char *string) /* New characters to be inserted. */
{
TextItem *textPtr = (TextItem *) itemPtr;
int byteIndex, byteCount, charsAdded;
- char *new, *text;
+ char *newStr, *text;
Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
string = Tcl_GetStringFromObj((Tcl_Obj *) string, &byteCount);
@@ -931,20 +925,20 @@ TextInsert(canvas, itemPtr, index, string)
return;
}
- new = (char *) ckalloc((unsigned) textPtr->numBytes + byteCount + 1);
- memcpy(new, text, (size_t) byteIndex);
- strcpy(new + byteIndex, string);
- strcpy(new + byteIndex + byteCount, text + byteIndex);
+ newStr = (char *) ckalloc((unsigned) textPtr->numBytes + byteCount + 1);
+ memcpy(newStr, text, (size_t) byteIndex);
+ strcpy(newStr + byteIndex, string);
+ strcpy(newStr + byteIndex + byteCount, text + byteIndex);
ckfree(text);
- textPtr->text = new;
+ textPtr->text = newStr;
charsAdded = Tcl_NumUtfChars(string, byteCount);
textPtr->numChars += charsAdded;
textPtr->numBytes += byteCount;
/*
* Inserting characters invalidates indices such as those for the
- * selection and cursor. Update the indices appropriately.
+ * selection and cursor. Update the indices appropriately.
*/
if (textInfoPtr->selItemPtr == itemPtr) {
@@ -976,25 +970,24 @@ TextInsert(canvas, itemPtr, index, string)
* None.
*
* Side effects:
- * Characters between "first" and "last", inclusive, get
- * deleted from itemPtr, and things like the selection
- * position get updated.
+ * Characters between "first" and "last", inclusive, get deleted from
+ * itemPtr, and things like the selection position get updated.
*
*--------------------------------------------------------------
*/
static void
-TextDeleteChars(canvas, itemPtr, first, last)
- Tk_Canvas canvas; /* Canvas containing itemPtr. */
- Tk_Item *itemPtr; /* Item in which to delete characters. */
- int first; /* Character index of first character to
+TextDeleteChars(
+ Tk_Canvas canvas, /* Canvas containing itemPtr. */
+ Tk_Item *itemPtr, /* Item in which to delete characters. */
+ int first, /* Character index of first character to
* delete. */
- int last; /* Character index of last character to
- * delete (inclusive). */
+ int last) /* Character index of last character to delete
+ * (inclusive). */
{
TextItem *textPtr = (TextItem *) itemPtr;
int byteIndex, byteCount, charsRemoved;
- char *new, *text;
+ char *newStr, *text;
Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
text = textPtr->text;
@@ -1012,19 +1005,19 @@ TextDeleteChars(canvas, itemPtr, first, last)
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);
+
+ newStr = (char *) ckalloc((unsigned) (textPtr->numBytes + 1 - byteCount));
+ memcpy(newStr, text, (size_t) byteIndex);
+ strcpy(newStr + byteIndex, text + byteIndex + byteCount);
ckfree(text);
- textPtr->text = new;
+ textPtr->text = newStr;
textPtr->numChars -= charsRemoved;
textPtr->numBytes -= byteCount;
/*
- * Update indexes for the selection and cursor to reflect the
- * renumbering of the remaining characters.
+ * Update indexes for the selection and cursor to reflect the renumbering
+ * of the remaining characters.
*/
if (textInfoPtr->selItemPtr == itemPtr) {
@@ -1066,14 +1059,14 @@ TextDeleteChars(canvas, itemPtr, first, last)
*
* TextToPoint --
*
- * Computes the distance from a given point to a given
- * text item, in canvas units.
+ * Computes the distance from a given point to a given text item, in
+ * canvas units.
*
* Results:
- * The return value is 0 if the point whose x and y coordinates
- * are pointPtr[0] and pointPtr[1] is inside the text item. If
- * the point isn't inside the text item then the return value
- * is the distance from the point to the text item.
+ * The return value is 0 if the point whose x and y coordinates are
+ * pointPtr[0] and pointPtr[1] is inside the text item. If the point
+ * isn't inside the text item then the return value is the distance from
+ * the point to the text item.
*
* Side effects:
* None.
@@ -1082,10 +1075,10 @@ TextDeleteChars(canvas, itemPtr, first, last)
*/
static double
-TextToPoint(canvas, itemPtr, pointPtr)
- Tk_Canvas canvas; /* Canvas containing itemPtr. */
- Tk_Item *itemPtr; /* Item to check against point. */
- double *pointPtr; /* Pointer to x and y coordinates. */
+TextToPoint(
+ Tk_Canvas canvas, /* Canvas containing itemPtr. */
+ Tk_Item *itemPtr, /* Item to check against point. */
+ double *pointPtr) /* Pointer to x and y coordinates. */
{
TextItem *textPtr;
Tk_State state = itemPtr->state;
@@ -1095,7 +1088,7 @@ TextToPoint(canvas, itemPtr, pointPtr)
state = ((TkCanvas *)canvas)->canvas_state;
}
textPtr = (TextItem *) itemPtr;
- value = (double) Tk_DistanceToTextLayout(textPtr->textLayout,
+ value = (double) Tk_DistanceToTextLayout(textPtr->textLayout,
(int) pointPtr[0] - textPtr->leftEdge,
(int) pointPtr[1] - textPtr->header.y1);
@@ -1111,14 +1104,13 @@ TextToPoint(canvas, itemPtr, pointPtr)
*
* TextToArea --
*
- * This procedure is called to determine whether an item
- * lies entirely inside, entirely outside, or overlapping
- * a given rectangle.
+ * This function is called to determine whether an item lies entirely
+ * inside, entirely outside, or overlapping a given rectangle.
*
* Results:
- * -1 is returned if the item is entirely outside the area
- * given by rectPtr, 0 if it overlaps, and 1 if it is entirely
- * inside the given area.
+ * -1 is returned if the item is entirely outside the area given by
+ * rectPtr, 0 if it overlaps, and 1 if it is entirely inside the given
+ * area.
*
* Side effects:
* None.
@@ -1127,12 +1119,12 @@ TextToPoint(canvas, itemPtr, pointPtr)
*/
static int
-TextToArea(canvas, itemPtr, rectPtr)
- Tk_Canvas canvas; /* Canvas containing itemPtr. */
- Tk_Item *itemPtr; /* Item to check against rectangle. */
- double *rectPtr; /* Pointer to array of four coordinates
- * (x1, y1, x2, y2) describing rectangular
- * area. */
+TextToArea(
+ Tk_Canvas canvas, /* Canvas containing itemPtr. */
+ Tk_Item *itemPtr, /* Item to check against rectangle. */
+ double *rectPtr) /* Pointer to array of four coordinates
+ * (x1,y1,x2,y2) describing rectangular
+ * area. */
{
TextItem *textPtr;
Tk_State state = itemPtr->state;
@@ -1154,26 +1146,27 @@ TextToArea(canvas, itemPtr, rectPtr)
*
* ScaleText --
*
- * This procedure is invoked to rescale a text item.
+ * This function is invoked to rescale a text item.
*
* Results:
* None.
*
* Side effects:
- * Scales the position of the text, but not the size
- * of the font for the text.
+ * Scales the position of the text, but not the size of the font for the
+ * text.
*
*--------------------------------------------------------------
*/
/* 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. */
+ScaleText(
+ Tk_Canvas canvas, /* Canvas containing rectangle. */
+ Tk_Item *itemPtr, /* Rectangle to be scaled. */
+ double originX, double 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;
@@ -1188,25 +1181,24 @@ ScaleText(canvas, itemPtr, originX, originY, scaleX, scaleY)
*
* TranslateText --
*
- * This procedure is called to move a text item by a
- * given amount.
+ * This function is called to move a text item by a given amount.
*
* Results:
* None.
*
* Side effects:
- * The position of the text item is offset by (xDelta, yDelta),
- * and the bounding box is updated in the generic part of the
- * item structure.
+ * The position of the text item is offset by (xDelta, yDelta), and the
+ * bounding box is updated in the generic part of the item structure.
*
*--------------------------------------------------------------
*/
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. */
+TranslateText(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item that is being moved. */
+ double deltaX, double deltaY)
+ /* Amount by which item is to be moved. */
{
TextItem *textPtr = (TextItem *) itemPtr;
@@ -1220,14 +1212,13 @@ TranslateText(canvas, itemPtr, deltaX, deltaY)
*
* GetTextIndex --
*
- * Parse an index into a text item and return either its value
- * or an error.
+ * Parse an index into a text item and return either its value or an
+ * error.
*
* Results:
- * 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
- * the interp's result.
+ * 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 the interp's result.
*
* Side effects:
* None.
@@ -1236,18 +1227,19 @@ TranslateText(canvas, itemPtr, deltaX, deltaY)
*/
static int
-GetTextIndex(interp, canvas, itemPtr, obj, indexPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item for which the index is being
+GetTextIndex(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item for which the index is being
* specified. */
- Tcl_Obj *obj; /* Specification of a particular character
- * in itemPtr's text. */
- int *indexPtr; /* Where to store converted character
+ Tcl_Obj *obj, /* Specification of a particular character in
+ * itemPtr's text. */
+ int *indexPtr) /* Where to store converted character
* index. */
{
TextItem *textPtr = (TextItem *) itemPtr;
- int c, length;
+ int length;
+ int c;
TkCanvas *canvasPtr = (TkCanvas *) canvas;
Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
char *string = Tcl_GetStringFromObj(obj, &length);
@@ -1256,17 +1248,18 @@ GetTextIndex(interp, canvas, itemPtr, obj, indexPtr)
if ((c == 'e') && (strncmp(string, "end", (unsigned) length) == 0)) {
*indexPtr = textPtr->numChars;
- } else if ((c=='i') && (strncmp(string, "insert", (unsigned) length)==0)) {
+ } else if ((c == 'i')
+ && (strncmp(string, "insert", (unsigned) length) == 0)) {
*indexPtr = textPtr->insertPos;
- } else if ((c=='s') && (strncmp(string, "sel.first", (unsigned) length)==0)
- && (length >= 5)) {
+ } else if ((c == 's') && (length >= 5)
+ && (strncmp(string, "sel.first", (unsigned) length) == 0)) {
if (textInfoPtr->selItemPtr != itemPtr) {
Tcl_SetResult(interp, "selection isn't in item", TCL_STATIC);
return TCL_ERROR;
}
*indexPtr = textInfoPtr->selectFirst;
- } else if ((c=='s') && (strncmp(string, "sel.last", (unsigned) length)==0)
- && (length >= 5)) {
+ } else if ((c == 's') && (length >= 5)
+ && (strncmp(string, "sel.last", (unsigned) length) == 0)) {
if (textInfoPtr->selItemPtr != itemPtr) {
Tcl_SetResult(interp, "selection isn't in item", TCL_STATIC);
return TCL_ERROR;
@@ -1292,7 +1285,7 @@ GetTextIndex(interp, canvas, itemPtr, obj, indexPtr)
*indexPtr = Tk_PointToChar(textPtr->textLayout,
x + canvasPtr->scrollX1 - textPtr->leftEdge,
y + canvasPtr->scrollY1 - textPtr->header.y1);
- } else if (Tcl_GetIntFromObj((Tcl_Interp *)NULL, obj, indexPtr) == TCL_OK) {
+ } else if (Tcl_GetIntFromObj(NULL, obj, indexPtr) == TCL_OK) {
if (*indexPtr < 0){
*indexPtr = 0;
} else if (*indexPtr > textPtr->numChars) {
@@ -1300,14 +1293,13 @@ GetTextIndex(interp, canvas, itemPtr, obj, indexPtr)
}
} else {
/*
- * Some of the paths here leave messages in the interp's result,
- * so we have to clear it out before storing our own message.
+ * Some of the paths here leave messages in the interp's result, so we
+ * have to clear it out before storing our own message.
*/
- badIndex:
- Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);
- Tcl_AppendResult(interp, "bad index \"", string, "\"",
- (char *) NULL);
+ badIndex:
+ Tcl_SetResult(interp, NULL, TCL_STATIC);
+ Tcl_AppendResult(interp, "bad index \"", string, "\"", NULL);
return TCL_ERROR;
}
return TCL_OK;
@@ -1331,18 +1323,18 @@ GetTextIndex(interp, canvas, itemPtr, obj, 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; /* Character index of character just before
+SetTextCursor(
+ 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;
if (index < 0) {
textPtr->insertPos = 0;
- } else if (index > textPtr->numChars) {
+ } else if (index > textPtr->numChars) {
textPtr->insertPos = textPtr->numChars;
} else {
textPtr->insertPos = index;
@@ -1354,15 +1346,14 @@ SetTextCursor(canvas, itemPtr, index)
*
* GetSelText --
*
- * This procedure is invoked to return the selected portion
- * of a text item. It is only called when this item has
- * the selection.
+ * This function is invoked to return the selected portion of a text
+ * item. It is only called when this item has the selection.
*
* Results:
- * The return value is the number of non-NULL bytes stored
- * at buffer. Buffer is filled (or partially filled) with a
- * NULL-terminated string containing part or all of the selection,
- * as given by offset and maxBytes.
+ * The return value is the number of non-NULL bytes stored at buffer.
+ * Buffer is filled (or partially filled) with a NULL-terminated string
+ * containing part or all of the selection, as given by offset and
+ * maxBytes.
*
* Side effects:
* None.
@@ -1371,18 +1362,18 @@ 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; /* Byte offset within selection of first
+GetSelText(
+ 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
+ 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 byteCount;
+ int byteCount;
char *text;
CONST char *selStart, *selEnd;
Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
@@ -1412,15 +1403,13 @@ GetSelText(canvas, itemPtr, offset, buffer, maxBytes)
*
* TextToPostscript --
*
- * This procedure is called to generate Postscript for
- * text items.
+ * This function is called to generate Postscript for text items.
*
* Results:
- * The return value is a standard Tcl result. If an error
- * occurs in generating Postscript then an error message is
- * 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.
+ * The return value is a standard Tcl result. If an error occurs in
+ * generating Postscript then an error message is 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.
*
* Side effects:
* None.
@@ -1429,13 +1418,13 @@ 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. */
+TextToPostscript(
+ 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;
@@ -1446,7 +1435,7 @@ TextToPostscript(interp, canvas, itemPtr, prepass)
Pixmap stipple;
Tk_State state = itemPtr->state;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
color = textPtr->color;
@@ -1480,41 +1469,53 @@ TextToPostscript(interp, canvas, itemPtr, prepass)
return TCL_ERROR;
}
if (stipple != None) {
- Tcl_AppendResult(interp, "/StippleText {\n ",
- (char *) NULL);
+ Tcl_AppendResult(interp, "/StippleText {\n ", NULL);
Tk_CanvasPsStipple(interp, canvas, stipple);
- Tcl_AppendResult(interp, "} bind def\n", (char *) NULL);
+ Tcl_AppendResult(interp, "} bind def\n", NULL);
}
sprintf(buffer, "%.15g %.15g [\n", textPtr->x,
Tk_CanvasPsY(canvas, textPtr->y));
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
Tk_TextLayoutToPostscript(interp, textPtr->textLayout);
x = 0; y = 0; justify = NULL; /* lint. */
switch (textPtr->anchor) {
- case TK_ANCHOR_NW: x = 0; y = 0; break;
- case TK_ANCHOR_N: x = 1; y = 0; break;
- case TK_ANCHOR_NE: x = 2; y = 0; break;
- case TK_ANCHOR_E: x = 2; y = 1; break;
- case TK_ANCHOR_SE: x = 2; y = 2; break;
- case TK_ANCHOR_S: x = 1; y = 2; break;
- case TK_ANCHOR_SW: x = 0; y = 2; break;
- case TK_ANCHOR_W: x = 0; y = 1; break;
- case TK_ANCHOR_CENTER: x = 1; y = 1; break;
+ case TK_ANCHOR_NW: x = 0; y = 0; break;
+ case TK_ANCHOR_N: x = 1; y = 0; break;
+ case TK_ANCHOR_NE: x = 2; y = 0; break;
+ case TK_ANCHOR_E: x = 2; y = 1; break;
+ case TK_ANCHOR_SE: x = 2; y = 2; break;
+ case TK_ANCHOR_S: x = 1; y = 2; break;
+ case TK_ANCHOR_SW: x = 0; y = 2; break;
+ case TK_ANCHOR_W: x = 0; y = 1; break;
+ case TK_ANCHOR_CENTER: x = 1; y = 1; break;
}
switch (textPtr->justify) {
- case TK_JUSTIFY_LEFT: justify = "0"; break;
- case TK_JUSTIFY_CENTER: justify = "0.5";break;
- case TK_JUSTIFY_RIGHT: justify = "1"; break;
+ case TK_JUSTIFY_LEFT: justify = "0"; break;
+ case TK_JUSTIFY_CENTER: justify = "0.5"; break;
+ case TK_JUSTIFY_RIGHT: justify = "1"; break;
}
Tk_GetFontMetrics(textPtr->tkfont, &fm);
- sprintf(buffer, "] %d %g %g %s %s DrawText\n",
- fm.linespace, x / -2.0, y / 2.0, justify,
- ((stipple == None) ? "false" : "true"));
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ sprintf(buffer, "] %d ", fm.linespace);
+ Tcl_AppendResult(interp, buffer, NULL);
+ Tcl_PrintDouble(NULL, x / -2.0, buffer);
+ Tcl_AppendResult(interp, buffer, NULL);
+ Tcl_PrintDouble(NULL, y / 2.0, buffer);
+ Tcl_AppendResult(interp, " ", buffer, NULL);
+ sprintf(buffer, " %s %s DrawText\n",
+ justify, ((stipple == None) ? "false" : "true"));
+ Tcl_AppendResult(interp, buffer, NULL);
return TCL_OK;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkCanvUtil.c b/generic/tkCanvUtil.c
index 8ad3b5c..eca3789 100644
--- a/generic/tkCanvUtil.c
+++ b/generic/tkCanvUtil.c
@@ -1,29 +1,64 @@
-/*
+/*
* tkCanvUtil.c --
*
- * This procedure contains a collection of utility procedures
- * used by the implementations of various canvas item types.
+ * This file contains a collection of utility functions used by the
+ * implementations of various canvas item types.
*
* Copyright (c) 1994 Sun Microsystems, Inc.
- * Copyright (c) 1994 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
#include "tkCanvas.h"
-#include "tkPort.h"
#include <assert.h>
+/*
+ * Structures defined only in this file.
+ */
+
+typedef struct SmoothAssocData {
+ struct SmoothAssocData *nextPtr;
+ /* Pointer to next SmoothAssocData. */
+ Tk_SmoothMethod smooth; /* Name and functions associated with this
+ * option. */
+} SmoothAssocData;
+
+Tk_SmoothMethod tkBezierSmoothMethod = {
+ "true",
+ TkMakeBezierCurve,
+ (void (*) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr,
+ int numPoints, int numSteps)) TkMakeBezierPostscript,
+};
+static Tk_SmoothMethod tkRawSmoothMethod = {
+ "raw",
+ TkMakeRawCurve,
+ (void (*) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr,
+ int numPoints, int numSteps)) TkMakeRawCurvePostscript,
+};
+
+/*
+ * Function forward-declarations.
+ */
+
+static void SmoothMethodCleanupProc(ClientData clientData,
+ Tcl_Interp *interp);
+static SmoothAssocData *InitSmoothMethods(Tcl_Interp *interp);
+static int DashConvert(char *l, CONST char *p, int n,
+ double width);
+static void TranslateAndAppendCoords(TkCanvas *canvPtr,
+ double x, double y, XPoint *outArr, int numOut);
+
+#define ABS(a) ((a>=0)?(a):(-(a)))
/*
*----------------------------------------------------------------------
*
* Tk_CanvasTkwin --
*
- * Given a token for a canvas, this procedure returns the
- * widget that represents the canvas.
+ * Given a token for a canvas, this function returns the widget that
+ * represents the canvas.
*
* Results:
* The return value is a handle for the widget.
@@ -35,8 +70,8 @@
*/
Tk_Window
-Tk_CanvasTkwin(canvas)
- Tk_Canvas canvas; /* Token for the canvas. */
+Tk_CanvasTkwin(
+ Tk_Canvas canvas) /* Token for the canvas. */
{
TkCanvas *canvasPtr = (TkCanvas *) canvas;
return canvasPtr->tkwin;
@@ -47,16 +82,15 @@ Tk_CanvasTkwin(canvas)
*
* Tk_CanvasDrawableCoords --
*
- * Given an (x,y) coordinate pair within a canvas, this procedure
+ * Given an (x,y) coordinate pair within a canvas, this function
* returns the corresponding coordinates at which the point should
* be drawn in the drawable used for display.
*
* Results:
- * There is no return value. The values at *drawableXPtr and
- * *drawableYPtr are filled in with the coordinates at which
- * x and y should be drawn. These coordinates are clipped
- * to fit within a "short", since this is what X uses in
- * most cases for drawing.
+ * There is no return value. The values at *drawableXPtr and
+ * *drawableYPtr are filled in with the coordinates at which x and y
+ * should be drawn. These coordinates are clipped to fit within a
+ * "short", since this is what X uses in most cases for drawing.
*
* Side effects:
* None.
@@ -65,11 +99,12 @@ Tk_CanvasTkwin(canvas)
*/
void
-Tk_CanvasDrawableCoords(canvas, x, y, drawableXPtr, drawableYPtr)
- Tk_Canvas canvas; /* Token for the canvas. */
- double x, y; /* Coordinates in canvas space. */
- short *drawableXPtr, *drawableYPtr; /* Screen coordinates are stored
- * here. */
+Tk_CanvasDrawableCoords(
+ Tk_Canvas canvas, /* Token for the canvas. */
+ double x, /* Coordinates in canvas space. */
+ double y,
+ short *drawableXPtr, /* Screen coordinates are stored here. */
+ short *drawableYPtr)
{
TkCanvas *canvasPtr = (TkCanvas *) canvas;
double tmp;
@@ -88,7 +123,7 @@ Tk_CanvasDrawableCoords(canvas, x, y, drawableXPtr, drawableYPtr)
*drawableXPtr = (short) tmp;
}
- tmp = y - canvasPtr->drawableYOrigin;
+ tmp = y - canvasPtr->drawableYOrigin;
if (tmp > 0) {
tmp += 0.5;
} else {
@@ -108,15 +143,14 @@ Tk_CanvasDrawableCoords(canvas, x, y, drawableXPtr, drawableYPtr)
*
* Tk_CanvasWindowCoords --
*
- * Given an (x,y) coordinate pair within a canvas, this procedure
- * returns the corresponding coordinates in the canvas's window.
+ * Given an (x,y) coordinate pair within a canvas, this function returns
+ * the corresponding coordinates in the canvas's window.
*
* Results:
- * There is no return value. The values at *screenXPtr and
- * *screenYPtr are filled in with the coordinates at which
- * (x,y) appears in the canvas's window. These coordinates
- * are clipped to fit within a "short", since this is what X
- * uses in most cases for drawing.
+ * There is no return value. The values at *screenXPtr and *screenYPtr
+ * are filled in with the coordinates at which (x,y) appears in the
+ * canvas's window. These coordinates are clipped to fit within a
+ * "short", since this is what X uses in most cases for drawing.
*
* Side effects:
* None.
@@ -125,11 +159,12 @@ Tk_CanvasDrawableCoords(canvas, x, y, drawableXPtr, drawableYPtr)
*/
void
-Tk_CanvasWindowCoords(canvas, x, y, screenXPtr, screenYPtr)
- Tk_Canvas canvas; /* Token for the canvas. */
- double x, y; /* Coordinates in canvas space. */
- short *screenXPtr, *screenYPtr; /* Screen coordinates are stored
- * here. */
+Tk_CanvasWindowCoords(
+ Tk_Canvas canvas, /* Token for the canvas. */
+ double x, /* Coordinates in canvas space. */
+ double y,
+ short *screenXPtr, /* Screen coordinates are stored here. */
+ short *screenYPtr)
{
TkCanvas *canvasPtr = (TkCanvas *) canvas;
double tmp;
@@ -148,7 +183,7 @@ Tk_CanvasWindowCoords(canvas, x, y, screenXPtr, screenYPtr)
*screenXPtr = (short) tmp;
}
- tmp = y - canvasPtr->yOrigin;
+ tmp = y - canvasPtr->yOrigin;
if (tmp > 0) {
tmp += 0.5;
} else {
@@ -172,11 +207,10 @@ Tk_CanvasWindowCoords(canvas, x, y, screenXPtr, screenYPtr)
* corresponding to that string.
*
* Results:
- * The return value is a standard Tcl return result. If
- * 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
- * the interp's result.
+ * The return value is a standard Tcl return result. If 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 the interp's result.
*
* Side effects:
* None.
@@ -185,14 +219,15 @@ Tk_CanvasWindowCoords(canvas, x, y, screenXPtr, screenYPtr)
*/
int
-Tk_CanvasGetCoord(interp, canvas, string, doublePtr)
- Tcl_Interp *interp; /* Interpreter for error reporting. */
- Tk_Canvas canvas; /* Canvas to which coordinate applies. */
- CONST char *string; /* Describes coordinate (any screen
- * coordinate form may be used here). */
- double *doublePtr; /* Place to store converted coordinate. */
+Tk_CanvasGetCoord(
+ Tcl_Interp *interp, /* Interpreter for error reporting. */
+ Tk_Canvas canvas, /* Canvas to which coordinate applies. */
+ CONST char *string, /* Describes coordinate (any screen coordinate
+ * form may be used here). */
+ double *doublePtr) /* Place to store converted coordinate. */
{
TkCanvas *canvasPtr = (TkCanvas *) canvas;
+
if (Tk_GetScreenMM(canvasPtr->interp, canvasPtr->tkwin, string,
doublePtr) != TCL_OK) {
return TCL_ERROR;
@@ -210,11 +245,10 @@ Tk_CanvasGetCoord(interp, canvas, string, doublePtr)
* corresponding to that string.
*
* Results:
- * The return value is a standard Tcl return result. If
- * 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 return value is a standard Tcl return result. If 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.
*
* Side effects:
* None.
@@ -223,20 +257,16 @@ Tk_CanvasGetCoord(interp, canvas, string, doublePtr)
*/
int
-Tk_CanvasGetCoordFromObj(interp, canvas, obj, doublePtr)
- Tcl_Interp *interp; /* Interpreter for error reporting. */
- Tk_Canvas canvas; /* Canvas to which coordinate applies. */
- Tcl_Obj *obj; /* Describes coordinate (any screen
- * coordinate form may be used here). */
- double *doublePtr; /* Place to store converted coordinate. */
+Tk_CanvasGetCoordFromObj(
+ Tcl_Interp *interp, /* Interpreter for error reporting. */
+ Tk_Canvas canvas, /* Canvas to which coordinate applies. */
+ Tcl_Obj *obj, /* Describes coordinate (any screen coordinate
+ * form may be used here). */
+ double *doublePtr) /* Place to store converted coordinate. */
{
TkCanvas *canvasPtr = (TkCanvas *) canvas;
- if (Tk_GetMMFromObj(canvasPtr->interp, canvasPtr->tkwin, obj,
- doublePtr) != TCL_OK) {
- return TCL_ERROR;
- }
- *doublePtr *= canvasPtr->pixelsPerMM;
- return TCL_OK;
+
+ return Tk_GetDoublePixelsFromObj(canvasPtr->interp, canvasPtr->tkwin, obj, doublePtr);
}
/*
@@ -244,9 +274,9 @@ Tk_CanvasGetCoordFromObj(interp, canvas, obj, doublePtr)
*
* Tk_CanvasSetStippleOrigin --
*
- * This procedure sets the stipple origin in a graphics context
- * so that stipples drawn with the GC will line up with other
- * stipples previously drawn in the canvas.
+ * This function sets the stipple origin in a graphics context so that
+ * stipples drawn with the GC will line up with other stipples previously
+ * drawn in the canvas.
*
* Results:
* None.
@@ -258,12 +288,11 @@ Tk_CanvasGetCoordFromObj(interp, canvas, obj, doublePtr)
*/
void
-Tk_CanvasSetStippleOrigin(canvas, gc)
- Tk_Canvas canvas; /* Token for a canvas. */
- GC gc; /* Graphics context that is about to be
- * used to draw a stippled pattern as
- * part of redisplaying the canvas. */
-
+Tk_CanvasSetStippleOrigin(
+ Tk_Canvas canvas, /* Token for a canvas. */
+ GC gc) /* Graphics context that is about to be used
+ * to draw a stippled pattern as part of
+ * redisplaying the canvas. */
{
TkCanvas *canvasPtr = (TkCanvas *) canvas;
@@ -276,9 +305,9 @@ Tk_CanvasSetStippleOrigin(canvas, gc)
*
* Tk_CanvasSetOffset--
*
- * This procedure sets the stipple offset in a graphics
- * context so that stipples drawn with the GC will
- * line up with other stipples with the same offset.
+ * This function sets the stipple offset in a graphics context so that
+ * stipples drawn with the GC will line up with other stipples with the
+ * same offset.
*
* Results:
* None.
@@ -290,12 +319,12 @@ Tk_CanvasSetStippleOrigin(canvas, gc)
*/
void
-Tk_CanvasSetOffset(canvas, gc, offset)
- Tk_Canvas canvas; /* Token for a canvas. */
- GC gc; /* Graphics context that is about to be
- * used to draw a stippled pattern as
- * part of redisplaying the canvas. */
- Tk_TSOffset *offset; /* offset (may be NULL pointer)*/
+Tk_CanvasSetOffset(
+ Tk_Canvas canvas, /* Token for a canvas. */
+ GC gc, /* Graphics context that is about to be used
+ * to draw a stippled pattern as part of
+ * redisplaying the canvas. */
+ Tk_TSOffset *offset) /* Offset (may be NULL pointer)*/
{
TkCanvas *canvasPtr = (TkCanvas *) canvas;
int flags = 0;
@@ -320,17 +349,16 @@ Tk_CanvasSetOffset(canvas, gc, offset)
*
* Tk_CanvasGetTextInfo --
*
- * This procedure returns a pointer to a structure containing
- * information about the selection and insertion cursor for
- * a canvas widget. Items such as text items save the pointer
- * and use it to share access to the information with the generic
- * canvas code.
+ * This function returns a pointer to a structure containing information
+ * about the selection and insertion cursor for a canvas widget. Items
+ * such as text items save the pointer and use it to share access to the
+ * information with the generic canvas code.
*
* Results:
* The return value is a pointer to the structure holding text
- * information for the canvas. Most of the fields should not
- * be modified outside the generic canvas code; see the user
- * documentation for details.
+ * information for the canvas. Most of the fields should not be modified
+ * outside the generic canvas code; see the user documentation for
+ * details.
*
* Side effects:
* None.
@@ -339,8 +367,8 @@ Tk_CanvasSetOffset(canvas, gc, offset)
*/
Tk_CanvasTextInfo *
-Tk_CanvasGetTextInfo(canvas)
- Tk_Canvas canvas; /* Token for the canvas widget. */
+Tk_CanvasGetTextInfo(
+ Tk_Canvas canvas) /* Token for the canvas widget. */
{
return &((TkCanvas *) canvas)->textInfo;
}
@@ -350,28 +378,27 @@ Tk_CanvasGetTextInfo(canvas)
*
* Tk_CanvasTagsParseProc --
*
- * This procedure is invoked during option processing to handle
- * "-tags" options for canvas items.
+ * This function is invoked during option processing to handle "-tags"
+ * options for canvas items.
*
* Results:
* A standard Tcl return value.
*
* Side effects:
- * The tags for a given item get replaced by those indicated
- * in the value argument.
+ * The tags for a given item get replaced by those indicated in the value
+ * argument.
*
*--------------------------------------------------------------
*/
int
-Tk_CanvasTagsParseProc(clientData, interp, tkwin, value, widgRec, offset)
- ClientData clientData; /* Not used.*/
- Tcl_Interp *interp; /* Used for reporting errors. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- CONST char *value; /* Value of option (list of tag
- * names). */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Offset into item (ignored). */
+Tk_CanvasTagsParseProc(
+ ClientData clientData, /* Not used.*/
+ Tcl_Interp *interp, /* Used for reporting errors. */
+ Tk_Window tkwin, /* Window containing canvas widget. */
+ CONST char *value, /* Value of option (list of tag names). */
+ char *widgRec, /* Pointer to record for item. */
+ int offset) /* Offset into item (ignored). */
{
register Tk_Item *itemPtr = (Tk_Item *) widgRec;
int argc, i;
@@ -387,8 +414,7 @@ Tk_CanvasTagsParseProc(clientData, interp, tkwin, value, widgRec, offset)
}
/*
- * Make sure that there's enough space in the item to hold the
- * tag names.
+ * Make sure that there's enough space in the item to hold the tag names.
*/
if (itemPtr->tagSpace < argc) {
@@ -415,16 +441,16 @@ Tk_CanvasTagsParseProc(clientData, interp, tkwin, value, widgRec, offset)
*
* Tk_CanvasTagsPrintProc --
*
- * This procedure is invoked by the Tk configuration code
- * to produce a printable string for the "-tags" configuration
- * option for canvas items.
+ * This function is invoked by the Tk configuration code to produce a
+ * printable string for the "-tags" configuration option for canvas
+ * items.
*
* Results:
- * The return value is a string describing all the tags for
- * the item referred to by "widgRec". In addition, *freeProcPtr
- * is filled in with the address of a procedure to call to free
- * the result string when it's no longer needed (or NULL to
- * indicate that the string doesn't need to be freed).
+ * The return value is a string describing all the tags for the item
+ * referred to by "widgRec". In addition, *freeProcPtr is filled in with
+ * the address of a function to call to free the result string when it's
+ * no longer needed (or NULL to indicate that the string doesn't need to
+ * be freed).
*
* Side effects:
* None.
@@ -433,61 +459,55 @@ Tk_CanvasTagsParseProc(clientData, interp, tkwin, value, widgRec, offset)
*/
char *
-Tk_CanvasTagsPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
- ClientData clientData; /* Ignored. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Ignored. */
- Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
- * information about how to reclaim
- * storage for return string. */
+Tk_CanvasTagsPrintProc(
+ ClientData clientData, /* Ignored. */
+ Tk_Window tkwin, /* Window containing canvas widget. */
+ char *widgRec, /* Pointer to record for item. */
+ int offset, /* Ignored. */
+ Tcl_FreeProc **freeProcPtr) /* Pointer to variable to fill in with
+ * information about how to reclaim storage
+ * for return string. */
{
register Tk_Item *itemPtr = (Tk_Item *) widgRec;
if (itemPtr->numTags == 0) {
- *freeProcPtr = (Tcl_FreeProc *) NULL;
+ *freeProcPtr = NULL;
return "";
}
if (itemPtr->numTags == 1) {
- *freeProcPtr = (Tcl_FreeProc *) NULL;
+ *freeProcPtr = NULL;
return (char *) itemPtr->tagPtr[0];
}
*freeProcPtr = TCL_DYNAMIC;
return Tcl_Merge(itemPtr->numTags, (CONST char **) itemPtr->tagPtr);
}
-
-static int DashConvert _ANSI_ARGS_((char *l, CONST char *p,
- int n, double width));
-#define ABS(a) ((a>=0)?(a):(-(a)))
-
/*
*--------------------------------------------------------------
*
* TkCanvasDashParseProc --
*
- * This procedure is invoked during option processing to handle
- * "-dash", "-activedash" and "-disableddash" options for canvas
- * objects.
+ * This function is invoked during option processing to handle "-dash",
+ * "-activedash" and "-disableddash" options for canvas objects.
*
* Results:
* A standard Tcl return value.
*
* Side effects:
- * The dash list for a given canvas object gets replaced by
- * those indicated in the value argument.
+ * The dash list for a given canvas object gets replaced by those
+ * indicated in the value argument.
*
*--------------------------------------------------------------
*/
int
-TkCanvasDashParseProc(clientData, interp, tkwin, value, widgRec, offset)
- ClientData clientData; /* Not used.*/
- Tcl_Interp *interp; /* Used for reporting errors. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- CONST char *value; /* Value of option. */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Offset into item. */
+TkCanvasDashParseProc(
+ ClientData clientData, /* Not used.*/
+ Tcl_Interp *interp, /* Used for reporting errors. */
+ Tk_Window tkwin, /* Window containing canvas widget. */
+ CONST char *value, /* Value of option. */
+ char *widgRec, /* Pointer to record for item. */
+ int offset) /* Offset into item. */
{
return Tk_GetDash(interp, value, (Tk_Dash *)(widgRec+offset));
}
@@ -497,16 +517,16 @@ TkCanvasDashParseProc(clientData, interp, tkwin, value, widgRec, offset)
*
* TkCanvasDashPrintProc --
*
- * This procedure is invoked by the Tk configuration code
- * to produce a printable string for the "-dash", "-activedash"
- * and "-disableddash" configuration options for canvas items.
+ * This function is invoked by the Tk configuration code to produce a
+ * printable string for the "-dash", "-activedash" and "-disableddash"
+ * configuration options for canvas items.
*
* Results:
- * The return value is a string describing all the dash list for
- * the item referred to by "widgRec"and "offset". In addition,
- * *freeProcPtr is filled in with the address of a procedure to
- * call to free the result string when it's no longer needed (or
- * NULL to indicate that the string doesn't need to be freed).
+ * The return value is a string describing all the dash list for the item
+ * referred to by "widgRec"and "offset". In addition, *freeProcPtr is
+ * filled in with the address of a function to call to free the result
+ * string when it's no longer needed (or NULL to indicate that the string
+ * doesn't need to be freed).
*
* Side effects:
* None.
@@ -515,14 +535,14 @@ TkCanvasDashParseProc(clientData, interp, tkwin, value, widgRec, offset)
*/
char *
-TkCanvasDashPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
- ClientData clientData; /* Ignored. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Offset in record for item. */
- Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
- * information about how to reclaim
- * storage for return string. */
+TkCanvasDashPrintProc(
+ ClientData clientData, /* Ignored. */
+ Tk_Window tkwin, /* Window containing canvas widget. */
+ char *widgRec, /* Pointer to record for item. */
+ int offset, /* Offset in record for item. */
+ Tcl_FreeProc **freeProcPtr) /* Pointer to variable to fill in with
+ * information about how to reclaim storage
+ * for return string. */
{
Tk_Dash *dash = (Tk_Dash *) (widgRec+offset);
char *buffer;
@@ -533,18 +553,18 @@ TkCanvasDashPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
i = -i;
*freeProcPtr = TCL_DYNAMIC;
buffer = (char *) ckalloc((unsigned int) (i+1));
- p = (i > sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
+ p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
memcpy(buffer, p, (unsigned int) i);
buffer[i] = 0;
return buffer;
} else if (!i) {
- *freeProcPtr = (Tcl_FreeProc *) NULL;
+ *freeProcPtr = NULL;
return "";
}
buffer = (char *)ckalloc((unsigned int) (4*i));
*freeProcPtr = TCL_DYNAMIC;
- p = (i > sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
+ p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
sprintf(buffer, "%d", *p++ & 0xff);
while(--i) {
sprintf(buffer+strlen(buffer), " %d", *p++ & 0xff);
@@ -555,46 +575,80 @@ TkCanvasDashPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
/*
*--------------------------------------------------------------
*
- * Tk_CreateSmoothMethod --
+ * InitSmoothMethods --
*
- * This procedure is invoked to add additional values
- * for the "-smooth" option to the list.
+ * This function is invoked to set up the initial state of the list of
+ * "-smooth" methods. It should only be called when the list installed
+ * in the interpreter is NULL.
*
* Results:
- * A standard Tcl return value.
+ * Pointer to the start of the list of default smooth methods.
*
* Side effects:
- * In the future "-smooth <name>" will be accepted as
- * smooth method for the line and polygon.
+ * A linked list of smooth methods is created and attached to the
+ * interpreter's association key "smoothMethod"
*
*--------------------------------------------------------------
*/
-Tk_SmoothMethod tkBezierSmoothMethod = {
- "bezier",
- TkMakeBezierCurve,
- (void (*) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas,
- double *coordPtr, int numPoints, int numSteps)))
- TkMakeBezierPostscript,
-};
+static SmoothAssocData *
+InitSmoothMethods(
+ Tcl_Interp *interp)
+{
+ SmoothAssocData *methods, *ptr;
-static void SmoothMethodCleanupProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp));
+ methods = (SmoothAssocData *) ckalloc(sizeof(SmoothAssocData));
+ methods->smooth.name = tkRawSmoothMethod.name;
+ methods->smooth.coordProc = tkRawSmoothMethod.coordProc;
+ methods->smooth.postscriptProc = tkRawSmoothMethod.postscriptProc;
-typedef struct SmoothAssocData {
- struct SmoothAssocData *nextPtr; /* pointer to next SmoothAssocData */
- Tk_SmoothMethod smooth; /* name and functions associated with this
- * option */
-} SmoothAssocData;
+ methods->nextPtr = (SmoothAssocData *) ckalloc(sizeof(SmoothAssocData));
+
+ ptr = methods->nextPtr;
+ ptr->smooth.name = tkBezierSmoothMethod.name;
+ ptr->smooth.coordProc = tkBezierSmoothMethod.coordProc;
+ ptr->smooth.postscriptProc = tkBezierSmoothMethod.postscriptProc;
+ ptr->nextPtr = NULL;
+
+ Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc,
+ (ClientData) methods);
+ return methods;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Tk_CreateSmoothMethod --
+ *
+ * This function is invoked to add additional values for the "-smooth"
+ * option to the list.
+ *
+ * Results:
+ * A standard Tcl return value.
+ *
+ * Side effects:
+ * In the future "-smooth <name>" will be accepted as smooth method for
+ * the line and polygon.
+ *
+ *--------------------------------------------------------------
+ */
void
-Tk_CreateSmoothMethod(interp, smooth)
- Tcl_Interp *interp;
- Tk_SmoothMethod *smooth;
+Tk_CreateSmoothMethod(
+ Tcl_Interp *interp,
+ Tk_SmoothMethod *smooth)
{
SmoothAssocData *methods, *typePtr2, *prevPtr, *ptr;
methods = (SmoothAssocData *) Tcl_GetAssocData(interp, "smoothMethod",
- (Tcl_InterpDeleteProc **) NULL);
+ NULL);
+
+ /*
+ * Initialize if we were not previously initialized.
+ */
+
+ if (methods == NULL) {
+ methods = InitSmoothMethods(interp);
+ }
/*
* If there's already a smooth method with the given name, remove it.
@@ -618,15 +672,16 @@ Tk_CreateSmoothMethod(interp, smooth)
ptr->smooth.postscriptProc = smooth->postscriptProc;
ptr->nextPtr = methods;
Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc,
- (ClientData) ptr);
+ (ClientData) ptr);
}
+
/*
*----------------------------------------------------------------------
*
* SmoothMethodCleanupProc --
*
- * This procedure is invoked whenever an interpreter is deleted
- * to cleanup the smooth methods.
+ * This function is invoked whenever an interpreter is deleted to
+ * cleanup the smooth methods.
*
* Results:
* None.
@@ -638,10 +693,10 @@ Tk_CreateSmoothMethod(interp, smooth)
*/
static void
-SmoothMethodCleanupProc(clientData, interp)
- ClientData clientData; /* Points to "smoothMethod" AssocData
- * for the interpreter. */
- Tcl_Interp *interp; /* Interpreter that is being deleted. */
+SmoothMethodCleanupProc(
+ ClientData clientData, /* Points to "smoothMethod" AssocData for the
+ * interpreter. */
+ Tcl_Interp *interp) /* Interpreter that is being deleted. */
{
SmoothAssocData *ptr, *methods = (SmoothAssocData *) clientData;
@@ -655,8 +710,8 @@ SmoothMethodCleanupProc(clientData, interp)
*
* TkSmoothParseProc --
*
- * This procedure is invoked during option processing to handle
- * the "-smooth" option.
+ * This function is invoked during option processing to handle the
+ * "-smooth" option.
*
* Results:
* A standard Tcl return value.
@@ -669,33 +724,54 @@ SmoothMethodCleanupProc(clientData, interp)
*/
int
-TkSmoothParseProc(clientData, interp, tkwin, value, widgRec, offset)
- ClientData clientData; /* some flags.*/
- Tcl_Interp *interp; /* Used for reporting errors. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- CONST char *value; /* Value of option. */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Offset into item. */
+TkSmoothParseProc(
+ ClientData clientData, /* some flags.*/
+ Tcl_Interp *interp, /* Used for reporting errors. */
+ Tk_Window tkwin, /* Window containing canvas widget. */
+ CONST char *value, /* Value of option. */
+ char *widgRec, /* Pointer to record for item. */
+ int offset) /* Offset into item. */
{
register Tk_SmoothMethod **smoothPtr =
- (Tk_SmoothMethod **) (widgRec + offset);
+ (Tk_SmoothMethod **) (widgRec + offset);
Tk_SmoothMethod *smooth = NULL;
int b;
size_t length;
SmoothAssocData *methods;
if (value == NULL || *value == 0) {
- *smoothPtr = (Tk_SmoothMethod *) NULL;
+ *smoothPtr = NULL;
return TCL_OK;
}
length = strlen(value);
methods = (SmoothAssocData *) Tcl_GetAssocData(interp, "smoothMethod",
- (Tcl_InterpDeleteProc **) NULL);
- while (methods != (SmoothAssocData *) NULL) {
+ NULL);
+
+ /*
+ * Not initialized yet; fix that now.
+ */
+
+ if (methods == NULL) {
+ methods = InitSmoothMethods(interp);
+ }
+
+ /*
+ * Backward compatability hack.
+ */
+
+ if (strncmp(value, "bezier", length) == 0) {
+ smooth = &tkBezierSmoothMethod;
+ }
+
+ /*
+ * Search the list of installed smooth methods.
+ */
+
+ while (methods != NULL) {
if (strncmp(value, methods->smooth.name, length) == 0) {
- if (smooth != (Tk_SmoothMethod *) NULL) {
- Tcl_AppendResult(interp, "ambigeous smooth method \"", value,
- "\"", (char *) NULL);
+ if (smooth != NULL) {
+ Tcl_AppendResult(interp, "ambiguous smooth method \"", value,
+ "\"", NULL);
return TCL_ERROR;
}
smooth = &methods->smooth;
@@ -705,19 +781,16 @@ TkSmoothParseProc(clientData, interp, tkwin, value, widgRec, offset)
if (smooth) {
*smoothPtr = smooth;
return TCL_OK;
- } else if (strncmp(value, tkBezierSmoothMethod.name, length) == 0) {
- /*
- * We need to do handle the built-in bezier method.
- */
- *smoothPtr = &tkBezierSmoothMethod;
- return TCL_OK;
}
+ /*
+ * Did not find it. Try parsing as a boolean instead.
+ */
if (Tcl_GetBoolean(interp, (char *) value, &b) != TCL_OK) {
return TCL_ERROR;
}
- *smoothPtr = b ? &tkBezierSmoothMethod : (Tk_SmoothMethod*) NULL;
+ *smoothPtr = b ? &tkBezierSmoothMethod : NULL;
return TCL_OK;
}
/*
@@ -725,16 +798,15 @@ TkSmoothParseProc(clientData, interp, tkwin, value, widgRec, offset)
*
* TkSmoothPrintProc --
*
- * This procedure is invoked by the Tk configuration code
- * to produce a printable string for the "-smooth"
- * configuration option.
+ * This function is invoked by the Tk configuration code to produce a
+ * printable string for the "-smooth" configuration option.
*
* Results:
- * The return value is a string describing the smooth option for
- * the item referred to by "widgRec". In addition, *freeProcPtr
- * is filled in with the address of a procedure to call to free
- * the result string when it's no longer needed (or NULL to
- * indicate that the string doesn't need to be freed).
+ * The return value is a string describing the smooth option for the item
+ * referred to by "widgRec". In addition, *freeProcPtr is filled in with
+ * the address of a function to call to free the result string when it's
+ * no longer needed (or NULL to indicate that the string doesn't need to
+ * be freed).
*
* Side effects:
* None.
@@ -743,16 +815,17 @@ TkSmoothParseProc(clientData, interp, tkwin, value, widgRec, offset)
*/
char *
-TkSmoothPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
- ClientData clientData; /* Ignored. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Offset into item. */
- Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
- * information about how to reclaim
- * storage for return string. */
+TkSmoothPrintProc(
+ ClientData clientData, /* Ignored. */
+ Tk_Window tkwin, /* Window containing canvas widget. */
+ char *widgRec, /* Pointer to record for item. */
+ int offset, /* Offset into item. */
+ Tcl_FreeProc **freeProcPtr) /* Pointer to variable to fill in with
+ * information about how to reclaim storage
+ * for return string. */
{
- register Tk_SmoothMethod **smoothPtr = (Tk_SmoothMethod **) (widgRec + offset);
+ register Tk_SmoothMethod **smoothPtr =
+ (Tk_SmoothMethod **) (widgRec + offset);
return (*smoothPtr) ? (*smoothPtr)->name : "0";
}
@@ -761,13 +834,12 @@ TkSmoothPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
*
* Tk_GetDash
*
- * This procedure is used to parse a string, assuming
- * it is dash information.
+ * This function is used to parse a string, assuming it is dash
+ * information.
*
* Results:
- * The return value is a standard Tcl result: TCL_OK means
- * that the dash information was parsed ok, and
- * TCL_ERROR means it couldn't be parsed.
+ * The return value is a standard Tcl result: TCL_OK means that the dash
+ * information was parsed ok, and TCL_ERROR means it couldn't be parsed.
*
* Side effects:
* Dash information in the dash structure is updated.
@@ -776,29 +848,34 @@ TkSmoothPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
*/
int
-Tk_GetDash(interp, value, dash)
- Tcl_Interp *interp; /* Used for error reporting. */
- CONST char *value; /* Textual specification of dash list. */
- Tk_Dash *dash; /* Pointer to record in which to
- * store dash information. */
+Tk_GetDash(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ CONST char *value, /* Textual specification of dash list. */
+ Tk_Dash *dash) /* Pointer to record in which to store dash
+ * information. */
{
int argc, i;
CONST char **largv, **argv = NULL;
char *pt;
- if ((value==(char *) NULL) || (*value==0) ) {
+ if ((value==NULL) || (*value==0) ) {
dash->number = 0;
return TCL_OK;
}
- if ((*value == '.') || (*value == ',') ||
- (*value == '-') || (*value == '_')) {
- i = DashConvert((char *) NULL, value, -1, 0.0);
+
+ /*
+ * switch is usually compiled more efficiently than a chain of conditions.
+ */
+
+ switch (*value) {
+ case '.': case ',': case '-': case '_':
+ i = DashConvert(NULL, value, -1, 0.0);
if (i>0) {
i = strlen(value);
} else {
goto badDashList;
}
- if (i > sizeof(char *)) {
+ if (i > (int)sizeof(char *)) {
dash->pattern.pt = pt = (char *) ckalloc(strlen(value));
} else {
pt = dash->pattern.array;
@@ -807,26 +884,16 @@ Tk_GetDash(interp, value, dash)
dash->number = -i;
return TCL_OK;
}
+
if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {
Tcl_ResetResult(interp);
- badDashList:
- Tcl_AppendResult(interp, "bad dash list \"", value,
- "\": must be a list of integers or a format like \"-..\"",
- (char *) NULL);
- syntaxError:
- if (argv != NULL) {
- ckfree((char *) argv);
- }
- if (ABS(dash->number) > sizeof(char *))
- ckfree((char *) dash->pattern.pt);
- dash->number = 0;
- return TCL_ERROR;
+ goto badDashList;
}
- if (ABS(dash->number) > sizeof(char *)) {
+ if ((unsigned int)ABS(dash->number) > sizeof(char *)) {
ckfree((char *) dash->pattern.pt);
}
- if (argc > sizeof(char *)) {
+ if (argc > (int)sizeof(char *)) {
dash->pattern.pt = pt = (char *) ckalloc((unsigned int) argc);
} else {
pt = dash->pattern.array;
@@ -834,23 +901,41 @@ Tk_GetDash(interp, value, dash)
dash->number = argc;
largv = argv;
- while(argc>0) {
- if (Tcl_GetInt(interp, *largv, &i) != TCL_OK ||
- i < 1 || i>255) {
+ while (argc>0) {
+ if (Tcl_GetInt(interp, *largv, &i) != TCL_OK || i < 1 || i>255) {
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "expected integer in the range 1..255 but got \"",
- *largv, "\"", (char *) NULL);
+ Tcl_AppendResult(interp,
+ "expected integer in the range 1..255 but got \"",
+ *largv, "\"", NULL);
goto syntaxError;
}
*pt++ = i;
- argc--; largv++;
+ argc--;
+ largv++;
}
-
+
if (argv != NULL) {
ckfree((char *) argv);
}
-
return TCL_OK;
+
+ /*
+ * Something went wrong. Generate error message, clean up and return.
+ */
+
+ badDashList:
+ Tcl_AppendResult(interp, "bad dash list \"", value,
+ "\": must be a list of integers or a format like \"-..\"",
+ NULL);
+ syntaxError:
+ if (argv != NULL) {
+ ckfree((char *) argv);
+ }
+ if ((unsigned int)ABS(dash->number) > sizeof(char *)) {
+ ckfree((char *) dash->pattern.pt);
+ }
+ dash->number = 0;
+ return TCL_ERROR;
}
/*
@@ -858,8 +943,8 @@ Tk_GetDash(interp, value, dash)
*
* Tk_CreateOutline
*
- * This procedure initializes the Tk_Outline structure
- * with default values.
+ * This function initializes the Tk_Outline structure with default
+ * values.
*
* Results:
* None
@@ -870,8 +955,9 @@ Tk_GetDash(interp, value, dash)
*--------------------------------------------------------------
*/
-void Tk_CreateOutline(outline)
- Tk_Outline *outline;
+void
+Tk_CreateOutline(
+ Tk_Outline *outline) /* Outline structure to be filled in. */
{
outline->gc = None;
outline->width = 1.0;
@@ -897,8 +983,8 @@ void Tk_CreateOutline(outline)
*
* Tk_DeleteOutline
*
- * This procedure frees all memory that might be
- * allocated and referenced in the Tk_Outline structure.
+ * This function frees all memory that might be allocated and referenced
+ * in the Tk_Outline structure.
*
* Results:
* None
@@ -909,20 +995,21 @@ void Tk_CreateOutline(outline)
*--------------------------------------------------------------
*/
-void Tk_DeleteOutline(display, outline)
- Display *display; /* Display containing window */
- Tk_Outline *outline;
+void
+Tk_DeleteOutline(
+ Display *display, /* Display containing window. */
+ Tk_Outline *outline)
{
if (outline->gc != None) {
Tk_FreeGC(display, outline->gc);
}
- if (ABS(outline->dash.number) > sizeof(char *)) {
+ if ((unsigned int)ABS(outline->dash.number) > sizeof(char *)) {
ckfree((char *) outline->dash.pattern.pt);
}
- if (ABS(outline->activeDash.number) > sizeof(char *)) {
+ if ((unsigned int)ABS(outline->activeDash.number) > sizeof(char *)) {
ckfree((char *) outline->activeDash.pattern.pt);
}
- if (ABS(outline->disabledDash.number) > sizeof(char *)) {
+ if ((unsigned int)ABS(outline->disabledDash.number) > sizeof(char *)) {
ckfree((char *) outline->disabledDash.pattern.pt);
}
if (outline->color != NULL) {
@@ -950,15 +1037,14 @@ void Tk_DeleteOutline(display, outline)
*
* Tk_ConfigOutlineGC
*
- * This procedure should be called in the canvas object
- * during the configure command. The graphics context
- * description in gcValues is updated according to the
- * information in the dash structure, as far as possible.
+ * This function should be called in the canvas object during the
+ * configure command. The graphics context description in gcValues is
+ * updated according to the information in the dash structure, as far as
+ * possible.
*
* Results:
- * The return-value is a mask, indicating which
- * elements of gcValues have been updated.
- * 0 means there is no outline.
+ * The return-value is a mask, indicating which elements of gcValues have
+ * been updated. 0 means there is no outline.
*
* Side effects:
* GC information in gcValues is updated.
@@ -966,11 +1052,12 @@ void Tk_DeleteOutline(display, outline)
*--------------------------------------------------------------
*/
-int Tk_ConfigOutlineGC(gcValues, canvas, item, outline)
- XGCValues *gcValues;
- Tk_Canvas canvas;
- Tk_Item *item;
- Tk_Outline *outline;
+int
+Tk_ConfigOutlineGC(
+ XGCValues *gcValues,
+ Tk_Canvas canvas,
+ Tk_Item *item,
+ Tk_Outline *outline)
{
int mask = 0;
double width;
@@ -1015,7 +1102,7 @@ int Tk_ConfigOutlineGC(gcValues, canvas, item, outline)
if (outline->activeStipple!=None) {
stipple = outline->activeStipple;
}
- } else if (state==TK_STATE_DISABLED) {
+ } else if (state == TK_STATE_DISABLED) {
if (outline->disabledWidth>0) {
width = outline->disabledWidth;
}
@@ -1047,12 +1134,10 @@ int Tk_ConfigOutlineGC(gcValues, canvas, item, outline)
if (mask && (dash->number != 0)) {
gcValues->line_style = LineOnOffDash;
gcValues->dash_offset = outline->offset;
- if (dash->number >= 2) {
- gcValues->dashes = 4;
- } else if (dash->number > 0) {
+ if (dash->number > 0) {
gcValues->dashes = dash->pattern.array[0];
} else {
- gcValues->dashes = (char) (4 * width);
+ gcValues->dashes = (char) (4 * width + 0.5);
}
mask |= GCLineStyle|GCDashList|GCDashOffset;
}
@@ -1064,15 +1149,12 @@ int Tk_ConfigOutlineGC(gcValues, canvas, item, outline)
*
* Tk_ChangeOutlineGC
*
- * Updates the GC to represent the full information of
- * the dash structure. Partly this is already done in
- * Tk_ConfigOutlineGC().
- * This function should be called just before drawing
- * the dashed item.
+ * Updates the GC to represent the full information of the dash
+ * structure. Partly this is already done in Tk_ConfigOutlineGC(). This
+ * function should be called just before drawing the dashed item.
*
* Results:
- * 1 if there is a stipple pattern.
- * 0 otherwise.
+ * 1 if there is a stipple pattern, and 0 otherwise.
*
* Side effects:
* GC is updated.
@@ -1081,10 +1163,10 @@ int Tk_ConfigOutlineGC(gcValues, canvas, item, outline)
*/
int
-Tk_ChangeOutlineGC(canvas, item, outline)
- Tk_Canvas canvas;
- Tk_Item *item;
- Tk_Outline *outline;
+Tk_ChangeOutlineGC(
+ Tk_Canvas canvas,
+ Tk_Item *item,
+ Tk_Outline *outline)
{
CONST char *p;
double width;
@@ -1134,25 +1216,30 @@ Tk_ChangeOutlineGC(canvas, item, outline)
return 0;
}
- if ((dash->number<-1) || ((dash->number == -1) && (dash->pattern.array[1]!=','))) {
+ if ((dash->number<-1) ||
+ ((dash->number == -1) && (dash->pattern.array[0] != ','))) {
char *q;
int i = -dash->number;
- p = (i > sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
+ p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
q = (char *) ckalloc(2*(unsigned int)i);
i = DashConvert(q, p, i, width);
- XSetDashes(((TkCanvas *)canvas)->display, outline->gc, outline->offset, q, i);
+ XSetDashes(((TkCanvas *)canvas)->display, outline->gc,
+ outline->offset, q, i);
ckfree(q);
- } else if ( dash->number>2 || (dash->number==2 &&
- (dash->pattern.array[0]!=dash->pattern.array[1]))) {
- p = (char *) (dash->number > sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
- XSetDashes(((TkCanvas *)canvas)->display, outline->gc, outline->offset, p, dash->number);
+ } else if (dash->number>2 || (dash->number==2 &&
+ (dash->pattern.array[0]!=dash->pattern.array[1]))) {
+ p = (dash->number > (int)sizeof(char *))
+ ? dash->pattern.pt : dash->pattern.array;
+ XSetDashes(((TkCanvas *)canvas)->display, outline->gc,
+ outline->offset, p, dash->number);
}
if (stipple!=None) {
int w=0; int h=0;
Tk_TSOffset *tsoffset = &outline->tsoffset;
int flags = tsoffset->flags;
- if (!(flags & TK_OFFSET_INDEX) && (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE))) {
+ if (!(flags & TK_OFFSET_INDEX) &&
+ (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE))) {
Tk_SizeOfBitmap(((TkCanvas *)canvas)->display, stipple, &w, &h);
if (flags & TK_OFFSET_CENTER) {
w /= 2;
@@ -1181,26 +1268,24 @@ Tk_ChangeOutlineGC(canvas, item, outline)
*
* Tk_ResetOutlineGC
*
- * Restores the GC to the situation before
- * Tk_ChangeDashGC() was called.
- * This function should be called just after the dashed
- * item is drawn, because the GC is supposed to be
- * read-only.
+ * Restores the GC to the situation before Tk_ChangeDashGC() was called.
+ * This function should be called just after the dashed item is drawn,
+ * because the GC is supposed to be read-only.
*
* Results:
- * 1 if there is a stipple pattern.
- * 0 otherwise.
+ * 1 if there is a stipple pattern, and 0 otherwise.
*
* Side effects:
* GC is updated.
*
*--------------------------------------------------------------
*/
+
int
-Tk_ResetOutlineGC(canvas, item, outline)
- Tk_Canvas canvas;
- Tk_Item *item;
- Tk_Outline *outline;
+Tk_ResetOutlineGC(
+ Tk_Canvas canvas,
+ Tk_Item *item,
+ Tk_Outline *outline)
{
char dashList;
double width;
@@ -1232,7 +1317,7 @@ Tk_ResetOutlineGC(canvas, item, outline)
if (outline->activeStipple!=None) {
stipple = outline->activeStipple;
}
- } else if (state==TK_STATE_DISABLED) {
+ } else if (state == TK_STATE_DISABLED) {
if (outline->disabledWidth>width) {
width = outline->disabledWidth;
}
@@ -1251,14 +1336,12 @@ Tk_ResetOutlineGC(canvas, item, outline)
}
if ((dash->number > 2) || (dash->number < -1) || (dash->number==2 &&
- (dash->pattern.array[0] != dash->pattern.array[1])) ||
- ((dash->number == -1) && (dash->pattern.array[1] != ','))) {
- if (dash->number < 0) {
- dashList = (int) (4 * width + 0.5);
- } else if (dash->number<3) {
+ (dash->pattern.array[0] != dash->pattern.array[1])) ||
+ ((dash->number == -1) && (dash->pattern.array[0] != ','))) {
+ if (dash->number > 0) {
dashList = dash->pattern.array[0];
} else {
- dashList = 4;
+ dashList = (char) (4 * width + 0.5);
}
XSetDashes(((TkCanvas *)canvas)->display, outline->gc,
outline->offset, &dashList , 1);
@@ -1269,30 +1352,30 @@ Tk_ResetOutlineGC(canvas, item, outline)
}
return 0;
}
-
/*
*--------------------------------------------------------------
*
* Tk_CanvasPsOutline
*
- * Creates the postscript command for the correct
- * Outline-information (width, dash, color and stipple).
+ * Creates the postscript command for the correct Outline-information
+ * (width, dash, color and stipple).
*
* Results:
* TCL_OK if succeeded, otherwise TCL_ERROR.
*
* Side effects:
- * canvas->interp->result contains the postscript string,
- * or an error message if the result was TCL_ERROR.
+ * canvas->interp->result contains the postscript string, or an error
+ * message if the result was TCL_ERROR.
*
*--------------------------------------------------------------
*/
+
int
-Tk_CanvasPsOutline(canvas, item, outline)
- Tk_Canvas canvas;
- Tk_Item *item;
- Tk_Outline *outline;
+Tk_CanvasPsOutline(
+ Tk_Canvas canvas,
+ Tk_Item *item,
+ Tk_Outline *outline)
{
char string[41];
char pattern[11];
@@ -1314,6 +1397,7 @@ Tk_CanvasPsOutline(canvas, item, outline)
if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
+
if (((TkCanvas *)canvas)->currentItemPtr == item) {
if (outline->activeWidth > width) {
width = outline->activeWidth;
@@ -1342,7 +1426,7 @@ Tk_CanvasPsOutline(canvas, item, outline)
}
}
sprintf(string, "%.15g setlinewidth\n", width);
- Tcl_AppendResult(interp, string, (char *) NULL);
+ Tcl_AppendResult(interp, string, NULL);
if (dash->number > 10) {
str = (char *)ckalloc((unsigned int) (1 + 4*dash->number));
@@ -1350,38 +1434,40 @@ Tk_CanvasPsOutline(canvas, item, outline)
str = (char *)ckalloc((unsigned int) (1 - 8*dash->number));
lptr = (char *)ckalloc((unsigned int) (1 - 2*dash->number));
}
- ptr = (char *) ((ABS(dash->number) > sizeof(char *)) ) ?
- dash->pattern.pt : dash->pattern.array;
+ ptr = ((unsigned int)ABS(dash->number) > sizeof(char *)) ?
+ dash->pattern.pt : dash->pattern.array;
if (dash->number > 0) {
char *ptr0 = ptr;
+
sprintf(str, "[%d", *ptr++ & 0xff);
i = dash->number-1;
while (i--) {
sprintf(str+strlen(str), " %d", *ptr++ & 0xff);
}
- Tcl_AppendResult(interp, str, (char *)NULL);
+ Tcl_AppendResult(interp, str, NULL);
if (dash->number&1) {
- Tcl_AppendResult(interp, " ", str+1, (char *)NULL);
+ Tcl_AppendResult(interp, " ", str+1, NULL);
}
sprintf(str, "] %d setdash\n", outline->offset);
- Tcl_AppendResult(interp, str, (char *)NULL);
+ Tcl_AppendResult(interp, str, NULL);
ptr = ptr0;
} else if (dash->number < 0) {
if ((i = DashConvert(lptr, ptr, -dash->number, width)) != 0) {
char *lptr0 = lptr;
+
sprintf(str, "[%d", *lptr++ & 0xff);
while (--i) {
sprintf(str+strlen(str), " %d", *lptr++ & 0xff);
}
- Tcl_AppendResult(interp, str, (char *)NULL);
+ Tcl_AppendResult(interp, str, NULL);
sprintf(str, "] %d setdash\n", outline->offset);
- Tcl_AppendResult(interp, str, (char *)NULL);
+ Tcl_AppendResult(interp, str, NULL);
lptr = lptr0;
} else {
- Tcl_AppendResult(interp, "[] 0 setdash\n", (char *)NULL);
+ Tcl_AppendResult(interp, "[] 0 setdash\n", NULL);
}
} else {
- Tcl_AppendResult(interp, "[] 0 setdash\n", (char *)NULL);
+ Tcl_AppendResult(interp, "[] 0 setdash\n", NULL);
}
if (str != string) {
ckfree(str);
@@ -1393,32 +1479,28 @@ Tk_CanvasPsOutline(canvas, item, outline)
return TCL_ERROR;
}
if (stipple != None) {
- Tcl_AppendResult(interp, "StrokeClip ", (char *) NULL);
+ Tcl_AppendResult(interp, "StrokeClip ", NULL);
if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
return TCL_ERROR;
}
} else {
- Tcl_AppendResult(interp, "stroke\n", (char *) NULL);
+ Tcl_AppendResult(interp, "stroke\n", NULL);
}
return TCL_OK;
}
-
/*
*--------------------------------------------------------------
*
* DashConvert
*
- * Converts a character-like dash-list (e.g. "-..")
- * into an X11-style. l must point to a string that
- * holds room to at least 2*n characters. if
- * l == NULL, this function can be used for
- * syntax checking only.
+ * Converts a character-like dash-list (e.g. "-..") into an X11-style. l
+ * must point to a string that holds room to at least 2*n characters. If
+ * l == NULL, this function can be used for syntax checking only.
*
* Results:
- * The length of the resulting X11 compatible
- * dash-list. -1 if failed.
+ * The length of the resulting X11 compatible dash-list. -1 if failed.
*
* Side effects:
* None
@@ -1427,11 +1509,13 @@ Tk_CanvasPsOutline(canvas, item, outline)
*/
static int
-DashConvert (l, p, n, width)
- char *l;
- CONST char *p;
- int n;
- double width;
+DashConvert(
+ char *l, /* Must be at least 2*n chars long, or NULL to
+ * indicate "just check syntax". */
+ CONST char *p, /* String to parse. */
+ int n, /* Length of string to parse, or -1 to
+ * indicate that strlen() should be used. */
+ double width) /* Width of line. */
{
int result = 0;
int size, intWidth;
@@ -1445,30 +1529,28 @@ DashConvert (l, p, n, width)
}
while (n-- && *p) {
switch (*p++) {
- case ' ':
- if (result) {
- if (l) {
- l[-1] += intWidth + 1;
- }
- continue;
- } else {
- return 0;
+ case ' ':
+ if (result) {
+ if (l) {
+ l[-1] += intWidth + 1;
}
- break;
- case '_':
- size = 8;
- break;
- case '-':
- size = 6;
- break;
- case ',':
- size = 4;
- break;
- case '.':
- size = 2;
- break;
- default:
- return -1;
+ continue;
+ }
+ return 0;
+ case '_':
+ size = 8;
+ break;
+ case '-':
+ size = 6;
+ break;
+ case ',':
+ size = 4;
+ break;
+ case '.':
+ size = 2;
+ break;
+ default:
+ return -1;
}
if (l) {
*l++ = size * intWidth;
@@ -1482,14 +1564,14 @@ DashConvert (l, p, n, width)
/*
*----------------------------------------------------------------------
*
- * translateAndAppendCoords --
+ * TranslateAndAppendCoords --
*
* This is a helper routine for TkCanvTranslatePath() below.
*
- * Given an (x,y) coordinate pair within a canvas, this procedure
- * computes the corresponding coordinates at which the point should
- * be drawn in the drawable used for display. Those coordinates are
- * then written into outArr[numOut*2] and outArr[numOut*2+1].
+ * Given an (x,y) coordinate pair within a canvas, this function computes
+ * the corresponding coordinates at which the point should be drawn in
+ * the drawable used for display. Those coordinates are then written into
+ * outArr[numOut*2] and outArr[numOut*2+1].
*
* Results:
* There is no return value.
@@ -1501,11 +1583,12 @@ DashConvert (l, p, n, width)
*/
static void
-translateAndAppendCoords(canvPtr, x, y, outArr, numOut)
- TkCanvas *canvPtr; /* The canvas. */
- double x, y; /* Coordinates in canvas space. */
- XPoint *outArr; /* Write results into this array */
- int numOut; /* Num of prior entries in outArr[] */
+TranslateAndAppendCoords(
+ TkCanvas *canvPtr, /* The canvas. */
+ double x, /* Coordinates in canvas space. */
+ double y,
+ XPoint *outArr, /* Write results into this array */
+ int numOut) /* Num of prior entries in outArr[] */
{
double tmp;
@@ -1517,7 +1600,7 @@ translateAndAppendCoords(canvPtr, x, y, outArr, numOut)
}
outArr[numOut].x = (short) tmp;
- tmp = y - canvPtr->drawableYOrigin;
+ tmp = y - canvPtr->drawableYOrigin;
if (tmp > 0) {
tmp += 0.5;
} else {
@@ -1531,225 +1614,262 @@ translateAndAppendCoords(canvPtr, x, y, outArr, numOut)
*
* TkCanvTranslatePath
*
- * Translate a line or polygon path so that all vertices are
- * within a rectangle that is 1000 pixels larger than the total
- * size of the canvas window. This will prevent pixel coordinates
- * from overflowing the 16-bit integer size limitation imposed by
- * most windowing systems.
- *
- * coordPtr must point to an array of doubles, two doubles per
- * vertex. There are a total of numVertex vertices, or 2*numVertex
- * entries in coordPtr. The result vertices written into outArr
- * have their coordinate origin shifted to canvPtr->drawableXOrigin
- * by canvPtr->drawableYOrigin. There might be as many as 3 times
- * more output vertices than there are input vertices. The calling
- * function should allocate space accordingly.
- *
- * This routine limits the width and height of a canvas window
- * to 31767 pixels. At the highest resolution display devices
- * available today (210 ppi in Jan 2003) that's a window that is
- * over 13 feet wide and tall. Should be enough for the near
- * future.
+ * Translate a line or polygon path so that all vertices are within a
+ * rectangle that is 1000 pixels larger than the total size of the canvas
+ * window. This will prevent pixel coordinates from overflowing the
+ * 16-bit integer size limitation imposed by most windowing systems.
+ *
+ * coordPtr must point to an array of doubles, two doubles per vertex.
+ * There are a total of numVertex vertices, or 2*numVertex entries in
+ * coordPtr. The result vertices written into outArr have their
+ * coordinate origin shifted to canvPtr->drawableXOrigin by
+ * canvPtr->drawableYOrigin. There might be as many as 3 times more
+ * output vertices than there are input vertices. The calling function
+ * should allocate space accordingly.
+ *
+ * This routine limits the width and height of a canvas window to 31767
+ * pixels. At the highest resolution display devices available today (210
+ * ppi in Jan 2003) that's a window that is over 13 feet wide and tall.
+ * Should be enough for the near future.
*
* Results:
- * Clipped and translated path vertices are written into outArr[].
- * There might be as many as twice the vertices in outArr[] as there
- * are in coordPtr[]. The return value is the number of vertices
- * actually written into outArr[].
+ * Clipped and translated path vertices are written into outArr[]. There
+ * might be as many as twice the vertices in outArr[] as there are in
+ * coordPtr[]. The return value is the number of vertices actually
+ * written into outArr[].
*
* Side effects:
* None
*
*--------------------------------------------------------------
*/
+
int
-TkCanvTranslatePath (canvPtr, numVertex, coordArr, closedPath, outArr)
- TkCanvas *canvPtr; /* The canvas */
- int numVertex; /* Number of vertices specified by coordArr[] */
- double *coordArr; /* X and Y coordinates for each vertex */
- int closedPath; /* True if this is a closed polygon */
- XPoint *outArr; /* Write results here, if not NULL */
+TkCanvTranslatePath(
+ TkCanvas *canvPtr, /* The canvas */
+ int numVertex, /* Number of vertices specified by
+ * coordArr[] */
+ double *coordArr, /* X and Y coordinates for each vertex */
+ int closedPath, /* True if this is a closed polygon */
+ XPoint *outArr) /* Write results here, if not NULL */
{
- int numOutput = 0; /* Number of output coordinates */
- double lft, rgh; /* Left and right sides of the bounding box */
- double top, btm; /* Top and bottom sizes of the bounding box */
- double *tempArr; /* Temporary storage used by the clipper */
- double *a, *b, *t; /* Pointers to parts of the temporary storage */
- int i, j; /* Loop counters */
- int maxOutput; /* Maximum number of outputs that we will allow */
- double limit[4]; /* Boundries at which clipping occurs */
- double staticSpace[480]; /* Temp space from the stack */
+ int numOutput = 0; /* Number of output coordinates */
+ double lft, rgh; /* Left and right sides of the bounding box */
+ double top, btm; /* Top and bottom sizes of the bounding box */
+ double *tempArr; /* Temporary storage used by the clipper */
+ double *a, *b, *t; /* Pointers to parts of the temporary
+ * storage */
+ int i, j; /* Loop counters */
+ int maxOutput; /* Maximum number of outputs that we will
+ * allow */
+ double limit[4]; /* Boundries at which clipping occurs */
+ double staticSpace[480]; /* Temp space from the stack */
/*
- ** Constrain all vertices of the path to be within a box that is no
- ** larger than 32000 pixels wide or height. The top-left corner of
- ** this clipping box is 1000 pixels above and to the left of the top
- ** left corner of the window on which the canvas is displayed.
- **
- ** This means that a canvas will not display properly on a canvas
- ** window that is larger than 31000 pixels wide or high. That is not
- ** a problem today, but might someday become a factor for ultra-high
- ** resolutions displays.
- **
- ** The X11 protocol allows us (in theory) to expand the size of the
- ** clipping box to 32767 pixels. But we have found experimentally that
- ** XFree86 sometimes fails to draw lines correctly if they are longer
- ** than about 32500 pixels. So we have left a little margin in the
- ** size to mask that bug.
- */
+ * Constrain all vertices of the path to be within a box that is no larger
+ * than 32000 pixels wide or height. The top-left corner of this clipping
+ * box is 1000 pixels above and to the left of the top left corner of the
+ * window on which the canvas is displayed.
+ *
+ * This means that a canvas will not display properly on a canvas window
+ * that is larger than 31000 pixels wide or high. That is not a problem
+ * today, but might someday become a factor for ultra-high resolutions
+ * displays.
+ *
+ * The X11 protocol allows us (in theory) to expand the size of the
+ * clipping box to 32767 pixels. But we have found experimentally that
+ * XFree86 sometimes fails to draw lines correctly if they are longer than
+ * about 32500 pixels. So we have left a little margin in the size to mask
+ * that bug.
+ */
+
lft = canvPtr->xOrigin - 1000.0;
top = canvPtr->yOrigin - 1000.0;
rgh = lft + 32000.0;
btm = top + 32000.0;
- /* Try the common case first - no clipping. Loop over the input
- ** coordinates and translate them into appropriate output coordinates.
- ** But if a vertex outside of the bounding box is seen, break out of
- ** the loop.
- **
- ** Most of the time, no clipping is needed, so this one loop is
- ** sufficient to do the translation.
- */
- for(i=0; i<numVertex; i++){
- double x, y;
- x = coordArr[i*2];
- y = coordArr[i*2+1];
- if( x<lft || x>rgh || y<top || y>btm ) break;
- translateAndAppendCoords(canvPtr, x, y, outArr, numOutput++);
- }
- if( i==numVertex ){
- assert( numOutput==numVertex );
- return numOutput;
- }
-
- /* If we reach this point, it means that some clipping is required.
- ** Begin by allocating some working storage - at least 6 times as much space
- ** as coordArr[] requires. Divide this space into two separate arrays
- ** a[] and b[]. Initialize a[] to be equal to coordArr[].
- */
- if( numVertex*12 <= sizeof(staticSpace)/sizeof(staticSpace[0]) ){
- tempArr = staticSpace;
+ /*
+ * Try the common case first - no clipping. Loop over the input
+ * coordinates and translate them into appropriate output coordinates.
+ * But if a vertex outside of the bounding box is seen, break out of the
+ * loop.
+ *
+ * Most of the time, no clipping is needed, so this one loop is sufficient
+ * to do the translation.
+ */
+
+ for (i=0; i<numVertex; i++){
+ double x, y;
+
+ x = coordArr[i*2];
+ y = coordArr[i*2+1];
+ if (x<lft || x>rgh || y<top || y>btm) {
+ break;
+ }
+ TranslateAndAppendCoords(canvPtr, x, y, outArr, numOutput++);
+ }
+ if (i == numVertex){
+ assert(numOutput == numVertex);
+ return numOutput;
+ }
+
+ /*
+ * If we reach this point, it means that some clipping is required. Begin
+ * by allocating some working storage - at least 6 times as much space as
+ * coordArr[] requires. Divide this space into two separate arrays a[] and
+ * b[]. Initialize a[] to be equal to coordArr[].
+ */
+
+ if (numVertex*12 <= (int)(sizeof(staticSpace)/sizeof(staticSpace[0]))) {
+ tempArr = staticSpace;
} else {
- tempArr = (double*)ckalloc( numVertex*12*sizeof(tempArr[0]) );
+ tempArr = (double *)ckalloc(numVertex*12*sizeof(tempArr[0]));
}
- for(i=0; i<numVertex*2; i++){
- tempArr[i] = coordArr[i];
+ for (i=0; i<numVertex*2; i++){
+ tempArr[i] = coordArr[i];
}
a = tempArr;
b = &tempArr[numVertex*6];
- /* We will make four passes through the input data. On each pass,
- ** we copy the contents of a[] over into b[]. As we copy, we clip
- ** any line segments that extend to the right past xClip then we
- ** rotate the coordinate system 90 degrees clockwise. After each
- ** pass is complete, we interchange a[] and b[] in preparation for
- ** the next pass.
- **
- ** Each pass clips line segments that extend beyond a single side
- ** of the bounding box, and four passes rotate the coordinate system
- ** back to its original value. I'm not an expert on graphics
- ** algorithms, but I think this is called Cohen-Sutherland polygon
- ** clipping.
- **
- ** The limit[] array contains the xClip value used for each of the
- ** four passes.
- */
+ /*
+ * We will make four passes through the input data. On each pass, we copy
+ * the contents of a[] over into b[]. As we copy, we clip any line
+ * segments that extend to the right past xClip then we rotate the
+ * coordinate system 90 degrees clockwise. After each pass is complete, we
+ * interchange a[] and b[] in preparation for the next pass.
+ *
+ * Each pass clips line segments that extend beyond a single side of the
+ * bounding box, and four passes rotate the coordinate system back to its
+ * original value. I'm not an expert on graphics algorithms, but I think
+ * this is called Cohen-Sutherland polygon clipping.
+ *
+ * The limit[] array contains the xClip value used for each of the four
+ * passes.
+ */
+
limit[0] = rgh;
limit[1] = -top;
limit[2] = -lft;
limit[3] = btm;
- /* This is the loop that makes the four passes through the data.
- */
+ /*
+ * This is the loop that makes the four passes through the data.
+ */
+
maxOutput = numVertex*3;
- for(j=0; j<4; j++){
- double xClip = limit[j];
- int inside = a[0]<xClip;
- double priorY = a[1];
- numOutput = 0;
-
- /* Clip everything to the right of xClip. Store the results in
- ** b[] rotated by 90 degrees clockwise.
- */
- for(i=0; i<numVertex; i++){
- double x = a[i*2];
- double y = a[i*2+1];
- if( x>=xClip ){
- /* The current vertex is to the right of xClip.
- */
- if( inside ){
- /* If the current vertex is to the right of xClip but
- ** the previous vertex was left of xClip, then draw a
- ** line segment from the previous vertex to until it
- ** intersects the vertical at xClip.
- */
- double x0, y0, yN;
- assert( i>0 );
- x0 = a[i*2-2];
- y0 = a[i*2-1];
- yN = y0 + (y - y0)*(xClip-x0)/(x-x0);
- b[numOutput*2] = -yN;
- b[numOutput*2+1] = xClip;
- numOutput++;
- assert( numOutput<=maxOutput );
- priorY = yN;
- inside = 0;
- }else if( i==0 ){
- /* If the first vertex is to the right of xClip, add
- ** a vertex that is the projection of the first vertex
- ** onto the vertical xClip line.
- */
- b[0] = -y;
- b[1] = xClip;
- numOutput = 1;
- priorY = y;
- }
- }else{
- /* The current vertex is to the left of xClip
- */
- if( !inside ){
- /* If the current vertex is on the left of xClip and
- ** one or more prior vertices where to the right, then
- ** we have to draw a line segment along xClip that extends
- ** from the spot where we first crossed from left to right
- ** to the spot where we cross back from right to left.
- */
- double x0, y0, yN;
- assert( i>0 );
- x0 = a[i*2-2];
- y0 = a[i*2-1];
- yN = y0 + (y - y0)*(xClip-x0)/(x-x0);
- if( yN!=priorY ){
- b[numOutput*2] = -yN;
- b[numOutput*2+1] = xClip;
- numOutput++;
- assert( numOutput<=maxOutput );
- }
- inside = 1;
- }
- b[numOutput*2] = -y;
- b[numOutput*2+1] = x;
- numOutput++;
- assert( numOutput<=maxOutput );
- }
- }
-
- /* Interchange a[] and b[] in preparation for the next pass.
- */
- t = a;
- a = b;
- b = t;
- numVertex = numOutput;
- }
-
- /* All clipping is now finished. Convert the coordinates from doubles
- ** into XPoints and translate the origin for the drawable.
- */
- for(i=0; i<numVertex; i++){
- translateAndAppendCoords(canvPtr, a[i*2], a[i*2+1], outArr, i);
- }
- if( tempArr!=staticSpace ){
- ckfree((char *) tempArr);
+ for (j=0; j<4; j++){
+ double xClip = limit[j];
+ int inside = a[0]<xClip;
+ double priorY = a[1];
+ numOutput = 0;
+
+ /*
+ * Clip everything to the right of xClip. Store the results in b[]
+ * rotated by 90 degrees clockwise.
+ */
+
+ for (i=0; i<numVertex; i++){
+ double x = a[i*2];
+ double y = a[i*2+1];
+
+ if (x >= xClip) {
+ /*
+ * The current vertex is to the right of xClip.
+ */
+
+ if (inside) {
+ /*
+ * If the current vertex is to the right of xClip but the
+ * previous vertex was left of xClip, then draw a line
+ * segment from the previous vertex to until it intersects
+ * the vertical at xClip.
+ */
+
+ double x0, y0, yN;
+
+ assert(i > 0);
+ x0 = a[i*2-2];
+ y0 = a[i*2-1];
+ yN = y0 + (y - y0)*(xClip-x0)/(x-x0);
+ b[numOutput*2] = -yN;
+ b[numOutput*2+1] = xClip;
+ numOutput++;
+ assert(numOutput <= maxOutput);
+ priorY = yN;
+ inside = 0;
+ } else if (i == 0) {
+ /*
+ * If the first vertex is to the right of xClip, add a
+ * vertex that is the projection of the first vertex onto
+ * the vertical xClip line.
+ */
+
+ b[0] = -y;
+ b[1] = xClip;
+ numOutput = 1;
+ priorY = y;
+ }
+ } else {
+ /*
+ * The current vertex is to the left of xClip
+ */
+ if (!inside) {
+ /* If the current vertex is on the left of xClip and one
+ * or more prior vertices where to the right, then we have
+ * to draw a line segment along xClip that extends from
+ * the spot where we first crossed from left to right to
+ * the spot where we cross back from right to left.
+ */
+
+ double x0, y0, yN;
+
+ assert(i > 0);
+ x0 = a[i*2-2];
+ y0 = a[i*2-1];
+ yN = y0 + (y - y0)*(xClip-x0)/(x-x0);
+ if (yN != priorY) {
+ b[numOutput*2] = -yN;
+ b[numOutput*2+1] = xClip;
+ numOutput++;
+ assert(numOutput <= maxOutput);
+ }
+ inside = 1;
+ }
+ b[numOutput*2] = -y;
+ b[numOutput*2+1] = x;
+ numOutput++;
+ assert(numOutput <= maxOutput);
+ }
+ }
+
+ /*
+ * Interchange a[] and b[] in preparation for the next pass.
+ */
+
+ t = a;
+ a = b;
+ b = t;
+ numVertex = numOutput;
+ }
+
+ /*
+ * All clipping is now finished. Convert the coordinates from doubles into
+ * XPoints and translate the origin for the drawable.
+ */
+
+ for (i=0; i<numVertex; i++){
+ TranslateAndAppendCoords(canvPtr, a[i*2], a[i*2+1], outArr, i);
+ }
+ if (tempArr != staticSpace) {
+ ckfree((char *) tempArr);
}
return numOutput;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkCanvWind.c b/generic/tkCanvWind.c
index 96fcadd..b62859c 100644
--- a/generic/tkCanvWind.c
+++ b/generic/tkCanvWind.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkCanvWind.c --
*
* This file implements window items for canvas widgets.
@@ -6,13 +6,12 @@
* Copyright (c) 1992-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <stdio.h>
#include "tkInt.h"
-#include "tkPort.h"
#include "tkCanvas.h"
/*
@@ -49,103 +48,99 @@ static Tk_CustomOption tagsOption = {
};
static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
"center", Tk_Offset(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_PIXELS, "-height", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_PIXELS, "-height", NULL, NULL,
"0", Tk_Offset(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
- &stateOption},
- {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
- {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
+ NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
+ {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
+ NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
+ {TK_CONFIG_PIXELS, "-width", NULL, NULL,
"0", Tk_Offset(WindowItem, width), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_WINDOW, "-window", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(WindowItem, tkwin), TK_CONFIG_NULL_OK},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+ {TK_CONFIG_WINDOW, "-window", NULL, NULL,
+ NULL, Tk_Offset(WindowItem, tkwin), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};
/*
- * Prototypes for procedures defined in this file:
+ * Prototypes for functions defined in this file:
*/
-static void ComputeWindowBbox _ANSI_ARGS_((Tk_Canvas canvas,
- WindowItem *winItemPtr));
-static int ConfigureWinItem _ANSI_ARGS_((Tcl_Interp *interp,
+static void ComputeWindowBbox(Tk_Canvas canvas,
+ WindowItem *winItemPtr);
+static int ConfigureWinItem(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
- Tcl_Obj *CONST objv[], int flags));
-static int CreateWinItem _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *CONST objv[], int flags);
+static int CreateWinItem(Tcl_Interp *interp,
Tk_Canvas canvas, struct Tk_Item *itemPtr,
- int objc, Tcl_Obj *CONST objv[]));
-static void DeleteWinItem _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, Display *display));
-static void DisplayWinItem _ANSI_ARGS_((Tk_Canvas canvas,
+ int objc, Tcl_Obj *CONST objv[]);
+static void DeleteWinItem(Tk_Canvas canvas,
+ Tk_Item *itemPtr, Display *display);
+static void DisplayWinItem(Tk_Canvas canvas,
Tk_Item *itemPtr, Display *display, Drawable dst,
- int x, int y, int width, int height));
-static void ScaleWinItem _ANSI_ARGS_((Tk_Canvas canvas,
+ int x, int y, int width, int height);
+static void ScaleWinItem(Tk_Canvas canvas,
Tk_Item *itemPtr, double originX, double originY,
- double scaleX, double scaleY));
-static void TranslateWinItem _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double deltaX, double deltaY));
-static int WinItemCoords _ANSI_ARGS_((Tcl_Interp *interp,
+ double scaleX, double scaleY);
+static void TranslateWinItem(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double deltaX, double deltaY);
+static int WinItemCoords(Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
- Tcl_Obj *CONST objv[]));
-static void WinItemLostSlaveProc _ANSI_ARGS_((
- ClientData clientData, Tk_Window tkwin));
-static void WinItemRequestProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin));
-static void WinItemStructureProc _ANSI_ARGS_((
- ClientData clientData, XEvent *eventPtr));
-static int WinItemToArea _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *rectPtr));
-static int WinItemToPostscript _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));
-static double WinItemToPoint _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *pointPtr));
+ Tcl_Obj *CONST objv[]);
+static void WinItemLostSlaveProc(ClientData clientData,
+ Tk_Window tkwin);
+static void WinItemRequestProc(ClientData clientData,
+ Tk_Window tkwin);
+static void WinItemStructureProc(ClientData clientData,
+ XEvent *eventPtr);
+static int WinItemToArea(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double *rectPtr);
+static int WinItemToPostscript(Tcl_Interp *interp,
+ Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
+static double WinItemToPoint(Tk_Canvas canvas,
+ Tk_Item *itemPtr, double *pointPtr);
#ifdef X_GetImage
-static int xerrorhandler _ANSI_ARGS_((ClientData clientData,
- XErrorEvent *e));
+static int xerrorhandler(ClientData clientData, XErrorEvent *e);
#endif
-static int CanvasPsWindow _ANSI_ARGS_((Tcl_Interp *interp,
+static int CanvasPsWindow(Tcl_Interp *interp,
Tk_Window tkwin, Tk_Canvas canvas, double x,
- double y, int width, int height));
+ double y, int width, int height);
/*
- * The structure below defines the window item type by means of procedures
+ * The structure below defines the window item type by means of functions
* that can be invoked by generic item code.
*/
Tk_ItemType tkWindowType = {
- "window", /* name */
- sizeof(WindowItem), /* itemSize */
- CreateWinItem, /* createProc */
- configSpecs, /* configSpecs */
- ConfigureWinItem, /* configureProc */
- WinItemCoords, /* coordProc */
- DeleteWinItem, /* deleteProc */
- DisplayWinItem, /* displayProc */
- 1|TK_CONFIG_OBJS, /* flags */
- WinItemToPoint, /* pointProc */
- WinItemToArea, /* areaProc */
- WinItemToPostscript, /* postscriptProc */
- ScaleWinItem, /* scaleProc */
- TranslateWinItem, /* translateProc */
- (Tk_ItemIndexProc *) NULL, /* indexProc */
- (Tk_ItemCursorProc *) NULL, /* cursorProc */
- (Tk_ItemSelectionProc *) NULL, /* selectionProc */
- (Tk_ItemInsertProc *) NULL, /* insertProc */
- (Tk_ItemDCharsProc *) NULL, /* dTextProc */
- (Tk_ItemType *) NULL, /* nextPtr */
+ "window", /* name */
+ sizeof(WindowItem), /* itemSize */
+ CreateWinItem, /* createProc */
+ configSpecs, /* configSpecs */
+ ConfigureWinItem, /* configureProc */
+ WinItemCoords, /* coordProc */
+ DeleteWinItem, /* deleteProc */
+ DisplayWinItem, /* displayProc */
+ 1|TK_CONFIG_OBJS, /* flags */
+ WinItemToPoint, /* pointProc */
+ WinItemToArea, /* areaProc */
+ WinItemToPostscript, /* postscriptProc */
+ ScaleWinItem, /* scaleProc */
+ TranslateWinItem, /* translateProc */
+ NULL, /* indexProc */
+ NULL, /* cursorProc */
+ NULL, /* selectionProc */
+ NULL, /* insertProc */
+ NULL, /* dTextProc */
+ NULL, /* nextPtr */
};
-
/*
- * The structure below defines the official type record for the
- * placer:
+ * The structure below defines the official type record for the canvas (as
+ * geometry manager):
*/
-static Tk_GeomMgr canvasGeomType = {
+static const Tk_GeomMgr canvasGeomType = {
"canvas", /* name */
WinItemRequestProc, /* requestProc */
WinItemLostSlaveProc, /* lostSlaveProc */
@@ -156,14 +151,12 @@ static Tk_GeomMgr canvasGeomType = {
*
* CreateWinItem --
*
- * This procedure is invoked to create a new window
- * item in a canvas.
+ * This function is invoked to create a new window item in a canvas.
*
* Results:
- * A standard Tcl return value. If an error occurred in
- * creating the item, then an error message is left in
- * the interp's result; in this case itemPtr is
- * left uninitialized, so it can be safely freed by the
+ * A standard Tcl return value. If an error occurred in creating the
+ * item, then an error message is left in the interp's result; in this
+ * case itemPtr is left uninitialized, so it can be safely freed by the
* caller.
*
* Side effects:
@@ -173,19 +166,19 @@ static Tk_GeomMgr canvasGeomType = {
*/
static int
-CreateWinItem(interp, canvas, itemPtr, objc, objv)
- 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 objc; /* Number of arguments in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing window. */
+CreateWinItem(
+ 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 objc, /* Number of arguments in objv. */
+ Tcl_Obj *CONST objv[]) /* Arguments describing window. */
{
WindowItem *winItemPtr = (WindowItem *) itemPtr;
int i;
if (objc == 0) {
- panic("canvas did not pass any coords\n");
+ Tcl_Panic("canvas did not pass any coords\n");
}
/*
@@ -199,8 +192,8 @@ CreateWinItem(interp, canvas, itemPtr, objc, objv)
winItemPtr->canvas = canvas;
/*
- * Process the arguments to fill in the item record.
- * Only 1 (list) or 2 (x y) coords are allowed.
+ * Process the arguments to fill in the item record. Only 1 (list) or 2 (x
+ * y) coords are allowed.
*/
if (objc == 1) {
@@ -220,7 +213,7 @@ CreateWinItem(interp, canvas, itemPtr, objc, objv)
return TCL_OK;
}
- error:
+ error:
DeleteWinItem(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
return TCL_ERROR;
}
@@ -230,9 +223,8 @@ CreateWinItem(interp, canvas, itemPtr, objc, objv)
*
* WinItemCoords --
*
- * This procedure is invoked to process the "coords" widget
- * command on window items. See the user documentation for
- * details on what it does.
+ * This function is invoked to process the "coords" widget command on
+ * window items. See the user documentation for details on what it does.
*
* Results:
* Returns TCL_OK or TCL_ERROR, and sets the interp's result.
@@ -244,15 +236,13 @@ CreateWinItem(interp, canvas, itemPtr, objc, objv)
*/
static int
-WinItemCoords(interp, canvas, itemPtr, objc, objv)
- 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 objc; /* Number of coordinates supplied in
- * objv. */
- Tcl_Obj *CONST objv[]; /* Array of coordinates: x1, y1,
- * x2, y2, ... */
+WinItemCoords(
+ 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 objc, /* Number of coordinates supplied in objv. */
+ Tcl_Obj *CONST objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */
{
WindowItem *winItemPtr = (WindowItem *) itemPtr;
@@ -297,12 +287,12 @@ WinItemCoords(interp, canvas, itemPtr, objc, objv)
*
* ConfigureWinItem --
*
- * This procedure is invoked to configure various aspects
- * of a window item, such as its anchor position.
+ * This function is invoked to configure various aspects of a window
+ * item, such as its anchor position.
*
* Results:
- * A standard Tcl result code. If an error occurs, then
- * an error message is left in the interp's result.
+ * A standard Tcl result code. If an error occurs, then an error message
+ * is left in the interp's result.
*
* Side effects:
* Configuration information may be set for itemPtr.
@@ -311,13 +301,13 @@ WinItemCoords(interp, canvas, itemPtr, objc, objv)
*/
static int
-ConfigureWinItem(interp, canvas, itemPtr, objc, objv, flags)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Canvas canvas; /* Canvas containing itemPtr. */
- Tk_Item *itemPtr; /* Window item to reconfigure. */
- int objc; /* Number of elements in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing things to configure. */
- int flags; /* Flags to pass to Tk_ConfigureWidget. */
+ConfigureWinItem(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_Canvas canvas, /* Canvas containing itemPtr. */
+ Tk_Item *itemPtr, /* Window item to reconfigure. */
+ int objc, /* Number of elements in objv. */
+ Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */
+ int flags) /* Flags to pass to Tk_ConfigureWidget. */
{
WindowItem *winItemPtr = (WindowItem *) itemPtr;
Tk_Window oldWindow;
@@ -338,8 +328,7 @@ ConfigureWinItem(interp, canvas, itemPtr, objc, objv, flags)
if (oldWindow != NULL) {
Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
WinItemStructureProc, (ClientData) winItemPtr);
- Tk_ManageGeometry(oldWindow, (Tk_GeomMgr *) NULL,
- (ClientData) NULL);
+ Tk_ManageGeometry(oldWindow, NULL, (ClientData) NULL);
Tk_UnmaintainGeometry(oldWindow, canvasTkwin);
Tk_UnmapWindow(oldWindow);
}
@@ -347,10 +336,10 @@ ConfigureWinItem(interp, canvas, itemPtr, objc, objv, flags)
Tk_Window ancestor, parent;
/*
- * Make sure that the canvas is either the parent of the
- * window associated with the item or a descendant of that
- * parent. Also, don't allow a top-of-hierarchy window to be
- * managed inside a canvas.
+ * Make sure that the canvas is either the parent of the window
+ * associated with the item or a descendant of that parent. Also,
+ * don't allow a top-of-hierarchy window to be managed inside a
+ * canvas.
*/
parent = Tk_Parent(winItemPtr->tkwin);
@@ -360,10 +349,10 @@ ConfigureWinItem(interp, canvas, itemPtr, objc, objv, flags)
break;
}
if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_HIERARCHY) {
- badWindow:
+ badWindow:
Tcl_AppendResult(interp, "can't use ",
Tk_PathName(winItemPtr->tkwin),
- " in a window item of this canvas", (char *) NULL);
+ " in a window item of this canvas", NULL);
winItemPtr->tkwin = NULL;
return TCL_ERROR;
}
@@ -399,8 +388,8 @@ ConfigureWinItem(interp, canvas, itemPtr, objc, objv, flags)
*
* DeleteWinItem --
*
- * This procedure is called to clean up the data structure
- * associated with a window item.
+ * This function is called to clean up the data structure associated with
+ * a window item.
*
* Results:
* None.
@@ -412,11 +401,10 @@ ConfigureWinItem(interp, canvas, itemPtr, objc, objv, flags)
*/
static void
-DeleteWinItem(canvas, itemPtr, display)
- Tk_Canvas canvas; /* Overall info about widget. */
- Tk_Item *itemPtr; /* Item that is being deleted. */
- Display *display; /* Display containing window for
- * canvas. */
+DeleteWinItem(
+ Tk_Canvas canvas, /* Overall info about widget. */
+ Tk_Item *itemPtr, /* Item that is being deleted. */
+ Display *display) /* Display containing window for canvas. */
{
WindowItem *winItemPtr = (WindowItem *) itemPtr;
Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);
@@ -424,7 +412,7 @@ DeleteWinItem(canvas, itemPtr, display)
if (winItemPtr->tkwin != NULL) {
Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
WinItemStructureProc, (ClientData) winItemPtr);
- Tk_ManageGeometry(winItemPtr->tkwin, (Tk_GeomMgr *) NULL,
+ Tk_ManageGeometry(winItemPtr->tkwin, NULL,
(ClientData) NULL);
if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
@@ -438,26 +426,23 @@ DeleteWinItem(canvas, itemPtr, display)
*
* ComputeWindowBbox --
*
- * This procedure is invoked to compute the bounding box of
- * all the pixels that may be drawn as part of a window item.
- * This procedure is where the child window's placement is
- * computed.
+ * This function is invoked to compute the bounding box of all the pixels
+ * that may be drawn as part of a window item. This function is where the
+ * child window's placement is computed.
*
* Results:
* None.
*
* Side effects:
- * The fields x1, y1, x2, and y2 are updated in the header
- * for itemPtr.
+ * The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
*
*--------------------------------------------------------------
*/
static void
-ComputeWindowBbox(canvas, winItemPtr)
- Tk_Canvas canvas; /* Canvas that contains item. */
- WindowItem *winItemPtr; /* Item whose bbox is to be
- * recomputed. */
+ComputeWindowBbox(
+ Tk_Canvas canvas, /* Canvas that contains item. */
+ WindowItem *winItemPtr) /* Item whose bbox is to be recomputed. */
{
int width, height, x, y;
Tk_State state = winItemPtr->header.state;
@@ -470,10 +455,10 @@ ComputeWindowBbox(canvas, winItemPtr)
}
if ((winItemPtr->tkwin == NULL) || (state == TK_STATE_HIDDEN)) {
/*
- * There is no window for this item yet. Just give it a 1x1
- * bounding box. Don't give it a 0x0 bounding box; there are
- * strange cases where this bounding box might be used as the
- * dimensions of the window, and 0x0 causes problems under X.
+ * There is no window for this item yet. Just give it a 1x1 bounding
+ * box. Don't give it a 0x0 bounding box; there are strange cases
+ * where this bounding box might be used as the dimensions of the
+ * window, and 0x0 causes problems under X.
*/
winItemPtr->header.x1 = x;
@@ -507,36 +492,36 @@ ComputeWindowBbox(canvas, winItemPtr)
*/
switch (winItemPtr->anchor) {
- case TK_ANCHOR_N:
- x -= width/2;
- break;
- case TK_ANCHOR_NE:
- x -= width;
- break;
- case TK_ANCHOR_E:
- x -= width;
- y -= height/2;
- break;
- case TK_ANCHOR_SE:
- x -= width;
- y -= height;
- break;
- case TK_ANCHOR_S:
- x -= width/2;
- y -= height;
- break;
- case TK_ANCHOR_SW:
- y -= height;
- break;
- case TK_ANCHOR_W:
- y -= height/2;
- break;
- case TK_ANCHOR_NW:
- break;
- case TK_ANCHOR_CENTER:
- x -= width/2;
- y -= height/2;
- break;
+ case TK_ANCHOR_N:
+ x -= width/2;
+ break;
+ case TK_ANCHOR_NE:
+ x -= width;
+ break;
+ case TK_ANCHOR_E:
+ x -= width;
+ y -= height/2;
+ break;
+ case TK_ANCHOR_SE:
+ x -= width;
+ y -= height;
+ break;
+ case TK_ANCHOR_S:
+ x -= width/2;
+ y -= height;
+ break;
+ case TK_ANCHOR_SW:
+ y -= height;
+ break;
+ case TK_ANCHOR_W:
+ y -= height/2;
+ break;
+ case TK_ANCHOR_NW:
+ break;
+ case TK_ANCHOR_CENTER:
+ x -= width/2;
+ y -= height/2;
+ break;
}
/*
@@ -554,36 +539,32 @@ ComputeWindowBbox(canvas, winItemPtr)
*
* DisplayWinItem --
*
- * This procedure is invoked to "draw" a window item in a given
- * drawable. Since the window draws itself, we needn't do any
- * actual redisplay here. However, this procedure takes care
- * of actually repositioning the child window so that it occupies
- * the correct screen position.
+ * This function is invoked to "draw" a window item in a given drawable.
+ * Since the window draws itself, we needn't do any actual redisplay
+ * here. However, this function takes care of actually repositioning the
+ * child window so that it occupies the correct screen position.
*
* Results:
* None.
*
* Side effects:
- * The child window's position may get changed. Note: this
- * procedure gets called both when a window needs to be displayed
- * and when it ceases to be visible on the screen (e.g. it was
- * scrolled or moved off-screen or the enclosing canvas is
- * unmapped).
+ * The child window's position may get changed. Note: this function gets
+ * called both when a window needs to be displayed and when it ceases to
+ * be visible on the screen (e.g. it was scrolled or moved off-screen or
+ * the enclosing canvas is unmapped).
*
*--------------------------------------------------------------
*/
static void
-DisplayWinItem(canvas, itemPtr, display, drawable, regionX, regionY,
- regionWidth, regionHeight)
- 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 regionX, regionY, regionWidth, regionHeight;
- /* Describes region of canvas that
- * must be redisplayed (not used). */
+DisplayWinItem(
+ 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 regionX, int regionY, int regionWidth, int regionHeight)
+ /* Describes region of canvas that must be
+ * redisplayed (not used). */
{
WindowItem *winItemPtr = (WindowItem *) itemPtr;
int width, height;
@@ -616,16 +597,16 @@ DisplayWinItem(canvas, itemPtr, display, drawable, regionX, regionY,
height = winItemPtr->header.y2 - winItemPtr->header.y1;
/*
- * If the window is completely out of the visible area of the canvas
- * then unmap it. This code used not to be present (why unmap the
- * window if it isn't visible anyway?) but this could cause the
- * window to suddenly reappear if the canvas window got resized.
+ * If the window is completely out of the visible area of the canvas then
+ * unmap it. This code used not to be present (why unmap the window if it
+ * isn't visible anyway?) but this could cause the window to suddenly
+ * reappear if the canvas window got resized.
*/
if (((x + width) <= 0) || ((y + height) <= 0)
|| (x >= Tk_Width(canvasTkwin)) || (y >= Tk_Height(canvasTkwin))) {
if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
- Tk_UnmapWindow(winItemPtr->tkwin);
+ Tk_UnmapWindow(winItemPtr->tkwin);
} else {
Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
}
@@ -633,8 +614,8 @@ DisplayWinItem(canvas, itemPtr, display, drawable, regionX, regionY,
}
/*
- * Reposition and map the window (but in different ways depending
- * on whether the canvas is the window's parent).
+ * Reposition and map the window (but in different ways depending on
+ * whether the canvas is the window's parent).
*/
if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
@@ -655,14 +636,14 @@ DisplayWinItem(canvas, itemPtr, display, drawable, regionX, regionY,
*
* WinItemToPoint --
*
- * Computes the distance from a given point to a given
- * window, in canvas units.
+ * Computes the distance from a given point to a given window, in canvas
+ * units.
*
* Results:
- * The return value is 0 if the point whose x and y coordinates
- * are coordPtr[0] and coordPtr[1] is inside the window. If the
- * point isn't inside the window then the return value is the
- * distance from the point to the window.
+ * The return value is 0 if the point whose x and y coordinates are
+ * coordPtr[0] and coordPtr[1] is inside the window. If the point isn't
+ * inside the window then the return value is the distance from the point
+ * to the window.
*
* Side effects:
* None.
@@ -671,10 +652,10 @@ DisplayWinItem(canvas, itemPtr, display, drawable, regionX, regionY,
*/
static double
-WinItemToPoint(canvas, itemPtr, pointPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against point. */
- double *pointPtr; /* Pointer to x and y coordinates. */
+WinItemToPoint(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against point. */
+ double *pointPtr) /* Pointer to x and y coordinates. */
{
WindowItem *winItemPtr = (WindowItem *) itemPtr;
double x1, x2, y1, y2, xDiff, yDiff;
@@ -712,14 +693,13 @@ WinItemToPoint(canvas, itemPtr, pointPtr)
*
* WinItemToArea --
*
- * This procedure is called to determine whether an item
- * lies entirely inside, entirely outside, or overlapping
- * a given rectangle.
+ * This function is called to determine whether an item lies entirely
+ * inside, entirely outside, or overlapping a given rectangle.
*
* Results:
- * -1 is returned if the item is entirely outside the area
- * given by rectPtr, 0 if it overlaps, and 1 if it is entirely
- * inside the given area.
+ * -1 is returned if the item is entirely outside the area given by
+ * rectPtr, 0 if it overlaps, and 1 if it is entirely inside the given
+ * area.
*
* Side effects:
* None.
@@ -728,11 +708,11 @@ WinItemToPoint(canvas, itemPtr, pointPtr)
*/
static int
-WinItemToArea(canvas, itemPtr, rectPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against rectangle. */
- double *rectPtr; /* Pointer to array of four coordinates
- * (x1, y1, x2, y2) describing rectangular
+WinItemToArea(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against rectangle. */
+ double *rectPtr) /* Pointer to array of four coordinates
+ * (x1,y1,x2,y2) describing rectangular
* area. */
{
WindowItem *winItemPtr = (WindowItem *) itemPtr;
@@ -757,8 +737,8 @@ WinItemToArea(canvas, itemPtr, rectPtr)
*
* xerrorhandler --
*
- * This is a dummy function to catch X11 errors during an
- * attempt to print a canvas window.
+ * This is a dummy function to catch X11 errors during an attempt to
+ * print a canvas window.
*
* Results:
* None.
@@ -771,11 +751,11 @@ WinItemToArea(canvas, itemPtr, rectPtr)
#ifdef X_GetImage
static int
-xerrorhandler(clientData, e)
- ClientData clientData;
- XErrorEvent *e;
+xerrorhandler(
+ ClientData clientData,
+ XErrorEvent *e)
{
- return 0;
+ return 0;
}
#endif
@@ -785,15 +765,13 @@ xerrorhandler(clientData, e)
*
* WinItemToPostscript --
*
- * This procedure is called to generate Postscript for
- * window items.
+ * This function is called to generate Postscript for window items.
*
* 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.
- * If no error occurs, then Postscript for the item is appended
- * to the result.
+ * 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. If no error occurs, then
+ * Postscript for the item is appended to the result.
*
* Side effects:
* None.
@@ -802,15 +780,13 @@ xerrorhandler(clientData, e)
*/
static int
-WinItemToPostscript(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.*/
+WinItemToPostscript(
+ 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. */
{
WindowItem *winItemPtr = (WindowItem *)itemPtr;
@@ -821,80 +797,75 @@ WinItemToPostscript(interp, canvas, itemPtr, prepass)
if (prepass || winItemPtr->tkwin == NULL) {
return TCL_OK;
}
-
+
width = Tk_Width(tkwin);
height = Tk_Height(tkwin);
/*
- * Compute the coordinates of the lower-left corner of the window,
- * taking into account the anchor position for the window.
+ * Compute the coordinates of the lower-left corner of the window, taking
+ * into account the anchor position for the window.
*/
x = winItemPtr->x;
y = Tk_CanvasPsY(canvas, winItemPtr->y);
-
+
switch (winItemPtr->anchor) {
- case TK_ANCHOR_NW: y -= height; break;
- case TK_ANCHOR_N: x -= width/2.0; y -= height; break;
- case TK_ANCHOR_NE: x -= width; y -= height; break;
- case TK_ANCHOR_E: x -= width; y -= height/2.0; break;
- case TK_ANCHOR_SE: x -= width; break;
- case TK_ANCHOR_S: x -= width/2.0; break;
- case TK_ANCHOR_SW: break;
- case TK_ANCHOR_W: y -= height/2.0; break;
- case TK_ANCHOR_CENTER: x -= width/2.0; y -= height/2.0; break;
+ case TK_ANCHOR_NW: y -= height; break;
+ case TK_ANCHOR_N: x -= width/2.0; y -= height; break;
+ case TK_ANCHOR_NE: x -= width; y -= height; break;
+ case TK_ANCHOR_E: x -= width; y -= height/2.0; break;
+ case TK_ANCHOR_SE: x -= width; break;
+ case TK_ANCHOR_S: x -= width/2.0; break;
+ case TK_ANCHOR_SW: break;
+ case TK_ANCHOR_W: y -= height/2.0; break;
+ case TK_ANCHOR_CENTER: x -= width/2.0; y -= height/2.0; break;
}
return CanvasPsWindow(interp, tkwin, canvas, x, y, width, height);
}
-
+
static int
-CanvasPsWindow(interp, tkwin, canvas, x, y, width, height)
- Tcl_Interp *interp; /* Leave Postscript or error message
- * here. */
- Tk_Window tkwin; /* window to be printed */
- Tk_Canvas canvas; /* Information about overall canvas. */
- double x, y; /* origin of window. */
- int width, height; /* width/height of window. */
+CanvasPsWindow(
+ Tcl_Interp *interp, /* Leave Postscript or error message here. */
+ Tk_Window tkwin, /* window to be printed */
+ Tk_Canvas canvas, /* Information about overall canvas. */
+ double x, double y, /* origin of window. */
+ int width, int height) /* width/height of window. */
{
char buffer[256];
XImage *ximage;
int result;
Tcl_DString buffer1, buffer2;
#ifdef X_GetImage
- Tk_ErrorHandler handle;
+ Tk_ErrorHandler handle;
#endif
sprintf(buffer, "\n%%%% %s item (%s, %d x %d)\n%.15g %.15g translate\n",
Tk_Class(tkwin), Tk_PathName(tkwin), width, height, x, y);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
- /* first try if the widget has its own "postscript" command. If it
- * exists, this will produce much better postscript than
- * when a pixmap is used.
+ /*
+ * First try if the widget has its own "postscript" command. If it exists,
+ * this will produce much better postscript than when a pixmap is used.
*/
Tcl_DStringInit(&buffer1);
Tcl_DStringInit(&buffer2);
Tcl_DStringGetResult(interp, &buffer2);
- sprintf (buffer, "%s postscript -prolog 0\n", Tk_PathName(tkwin));
+ sprintf(buffer, "%s postscript -prolog 0\n", Tk_PathName(tkwin));
result = Tcl_Eval(interp, buffer);
Tcl_DStringGetResult(interp, &buffer1);
Tcl_DStringResult(interp, &buffer2);
Tcl_DStringFree(&buffer2);
if (result == TCL_OK) {
- Tcl_AppendResult(interp,
- "50 dict begin\nsave\ngsave\n",
- (char *) NULL);
- sprintf (buffer,
- "0 %d moveto %d 0 rlineto 0 -%d rlineto -%d",
+ Tcl_AppendResult(interp, "50 dict begin\nsave\ngsave\n", NULL);
+ sprintf(buffer, "0 %d moveto %d 0 rlineto 0 -%d rlineto -%d",
height, width, height, width);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
Tcl_AppendResult(interp, " 0 rlineto closepath\n",
"1.000 1.000 1.000 setrgbcolor AdjustColor\nfill\ngrestore\n",
- Tcl_DStringValue(&buffer1), "\nrestore\nend\n\n\n",
- (char *) NULL);
+ Tcl_DStringValue(&buffer1), "\nrestore\nend\n\n\n", NULL);
Tcl_DStringFree(&buffer1);
return result;
@@ -902,17 +873,18 @@ CanvasPsWindow(interp, tkwin, canvas, x, y, width, height)
Tcl_DStringFree(&buffer1);
/*
- * If the window is off the screen it will generate an BadMatch/XError
- * We catch any BadMatch errors here
+ * If the window is off the screen it will generate a BadMatch/XError. We
+ * catch any BadMatch errors here
*/
+
#ifdef X_GetImage
handle = Tk_CreateErrorHandler(Tk_Display(tkwin), BadMatch,
X_GetImage, -1, xerrorhandler, (ClientData) tkwin);
#endif
/*
- * Generate an XImage from the window. We can then read pixel
- * values out of the XImage.
+ * Generate an XImage from the window. We can then read pixel values out
+ * of the XImage.
*/
ximage = XGetImage(Tk_Display(tkwin), Tk_WindowId(tkwin), 0, 0,
@@ -922,7 +894,7 @@ CanvasPsWindow(interp, tkwin, canvas, x, y, width, height)
Tk_DeleteErrorHandler(handle);
#endif
- if (ximage == (XImage*) NULL) {
+ if (ximage == NULL) {
return TCL_OK;
}
@@ -938,15 +910,14 @@ CanvasPsWindow(interp, tkwin, canvas, x, y, width, height)
*
* ScaleWinItem --
*
- * This procedure is invoked to rescale a window item.
+ * This function is invoked to rescale a window item.
*
* Results:
* None.
*
* Side effects:
- * The window referred to by itemPtr is rescaled
- * so that the following transformation is applied to all
- * point coordinates:
+ * The window referred to by itemPtr is rescaled so that the following
+ * transformation is applied to all point coordinates:
* x' = originX + scaleX*(x-originX)
* y' = originY + scaleY*(y-originY)
*
@@ -954,12 +925,13 @@ CanvasPsWindow(interp, tkwin, canvas, x, y, width, height)
*/
static void
-ScaleWinItem(canvas, itemPtr, originX, originY, scaleX, scaleY)
- Tk_Canvas canvas; /* Canvas containing window. */
- Tk_Item *itemPtr; /* Window to be scaled. */
- double originX, originY; /* Origin about which to scale window. */
- double scaleX; /* Amount to scale in X direction. */
- double scaleY; /* Amount to scale in Y direction. */
+ScaleWinItem(
+ Tk_Canvas canvas, /* Canvas containing window. */
+ Tk_Item *itemPtr, /* Window to be scaled. */
+ double originX, double originY,
+ /* Origin about which to scale window. */
+ double scaleX, /* Amount to scale in X direction. */
+ double scaleY) /* Amount to scale in Y direction. */
{
WindowItem *winItemPtr = (WindowItem *) itemPtr;
@@ -979,25 +951,24 @@ ScaleWinItem(canvas, itemPtr, originX, originY, scaleX, scaleY)
*
* TranslateWinItem --
*
- * This procedure is called to move a window by a given amount.
+ * This function is called to move a window by a given amount.
*
* Results:
* None.
*
* Side effects:
- * The position of the window is offset by (xDelta, yDelta),
- * and the bounding box is updated in the generic part of the
- * item structure.
+ * The position of the window is offset by (xDelta, yDelta), and the
+ * bounding box is updated in the generic part of the item structure.
*
*--------------------------------------------------------------
*/
static void
-TranslateWinItem(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. */
+TranslateWinItem(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item that is being moved. */
+ double deltaX, double deltaY)
+ /* Amount by which item is to be moved. */
{
WindowItem *winItemPtr = (WindowItem *) itemPtr;
@@ -1011,25 +982,23 @@ TranslateWinItem(canvas, itemPtr, deltaX, deltaY)
*
* WinItemStructureProc --
*
- * This procedure is invoked whenever StructureNotify events
- * occur for a window that's managed as part of a canvas window
- * item. This procudure's only purpose is to clean up when
- * windows are deleted.
+ * This function is invoked whenever StructureNotify events occur for a
+ * window that's managed as part of a canvas window item. This function's
+ * only purpose is to clean up when windows are deleted.
*
* Results:
* None.
*
* Side effects:
- * The window is disassociated from the window item when it is
- * deleted.
+ * The window is disassociated from the window item when it is deleted.
*
*--------------------------------------------------------------
*/
static void
-WinItemStructureProc(clientData, eventPtr)
- ClientData clientData; /* Pointer to record describing window item. */
- XEvent *eventPtr; /* Describes what just happened. */
+WinItemStructureProc(
+ ClientData clientData, /* Pointer to record describing window item. */
+ XEvent *eventPtr) /* Describes what just happened. */
{
WindowItem *winItemPtr = (WindowItem *) clientData;
@@ -1043,8 +1012,8 @@ WinItemStructureProc(clientData, eventPtr)
*
* WinItemRequestProc --
*
- * This procedure is invoked whenever a window that's associated
- * with a window canvas item changes its requested dimensions.
+ * This function is invoked whenever a window that's associated with a
+ * window canvas item changes its requested dimensions.
*
* Results:
* None.
@@ -1057,10 +1026,9 @@ WinItemStructureProc(clientData, eventPtr)
*/
static void
-WinItemRequestProc(clientData, tkwin)
- ClientData clientData; /* Pointer to record for window item. */
- Tk_Window tkwin; /* Window that changed its desired
- * size. */
+WinItemRequestProc(
+ ClientData clientData, /* Pointer to record for window item. */
+ Tk_Window tkwin) /* Window that changed its desired size. */
{
WindowItem *winItemPtr = (WindowItem *) clientData;
@@ -1080,8 +1048,8 @@ WinItemRequestProc(clientData, tkwin)
*
* WinItemLostSlaveProc --
*
- * This procedure is invoked by Tk whenever some other geometry
- * claims control over a slave that used to be managed by us.
+ * This function is invoked by Tk whenever some other geometry claims
+ * control over a slave that used to be managed by us.
*
* Results:
* None.
@@ -1094,10 +1062,10 @@ WinItemRequestProc(clientData, tkwin)
/* ARGSUSED */
static void
-WinItemLostSlaveProc(clientData, tkwin)
- ClientData clientData; /* WindowItem structure for slave window that
+WinItemLostSlaveProc(
+ ClientData clientData, /* WindowItem structure for slave window that
* was stolen away. */
- Tk_Window tkwin; /* Tk's handle for the slave window. */
+ Tk_Window tkwin) /* Tk's handle for the slave window. */
{
WindowItem *winItemPtr = (WindowItem *) clientData;
Tk_Window canvasTkwin = Tk_CanvasTkwin(winItemPtr->canvas);
@@ -1110,3 +1078,11 @@ WinItemLostSlaveProc(clientData, tkwin)
Tk_UnmapWindow(winItemPtr->tkwin);
winItemPtr->tkwin = NULL;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkCanvas.c b/generic/tkCanvas.c
index 8f9641f..14fe1ab 100644
--- a/generic/tkCanvas.c
+++ b/generic/tkCanvas.c
@@ -1,23 +1,22 @@
-/*
+/*
* tkCanvas.c --
*
- * This module implements canvas widgets for the Tk toolkit.
- * A canvas displays a background and a collection of graphical
- * objects such as rectangles, lines, and texts.
+ * This module implements canvas widgets for the Tk toolkit. A canvas
+ * displays a background and a collection of graphical objects such as
+ * rectangles, lines, and texts.
*
* Copyright (c) 1991-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
/* #define USE_OLD_TAG_SEARCH 1 */
#include "default.h"
#include "tkInt.h"
-#include "tkPort.h"
#include "tkCanvas.h"
#ifdef TK_NO_DOUBLE_BUFFERING
#ifdef MAC_OSX_TK
@@ -31,32 +30,29 @@
#ifdef USE_OLD_TAG_SEARCH
/*
- * The structure defined below is used to keep track of a tag search
- * in progress. No field should be accessed by anyone other than
- * StartTagSearch and NextItem.
+ * The structure defined below is used to keep track of a tag search in
+ * progress. No field should be accessed by anyone other than StartTagSearch
+ * and NextItem.
*/
typedef struct TagSearch {
TkCanvas *canvasPtr; /* Canvas widget being searched. */
- Tk_Uid tag; /* Tag to search for. 0 means return
- * all items. */
+ Tk_Uid tag; /* Tag to search for. 0 means return all
+ * items. */
Tk_Item *currentPtr; /* Pointer to last item returned. */
- Tk_Item *lastPtr; /* The item right before the currentPtr
- * is tracked so if the currentPtr is
- * deleted we don't have to start from the
- * beginning. */
+ Tk_Item *lastPtr; /* The item right before the currentPtr is
+ * tracked so if the currentPtr is deleted we
+ * don't have to start from the beginning. */
int searchOver; /* Non-zero means NextItem should always
* return NULL. */
} TagSearch;
#else /* USE_OLD_TAG_SEARCH */
/*
- * The structure defined below is used to keep track of a tag search
- * in progress. No field should be accessed by anyone other than
- * TagSearchScan, TagSearchFirst, TagSearchNext,
- * TagSearchScanExpr, TagSearchEvalExpr,
- * TagSearchExprInit, TagSearchExprDestroy,
- * TagSearchDestroy.
+ * The structure defined below is used to keep track of a tag search in
+ * progress. No field should be accessed by anyone other than TagSearchScan,
+ * TagSearchFirst, TagSearchNext, TagSearchScanExpr, TagSearchEvalExpr,
+ * TagSearchExprInit, TagSearchExprDestroy, TagSearchDestroy.
* (
* Not quite accurate: the TagSearch structure is also accessed from:
* CanvasWidgetCmd, FindItems, RelinkItems
@@ -72,24 +68,32 @@ typedef struct TagSearch {
typedef struct TagSearch {
TkCanvas *canvasPtr; /* Canvas widget being searched. */
Tk_Item *currentPtr; /* Pointer to last item returned. */
- Tk_Item *lastPtr; /* The item right before the currentPtr
- * is tracked so if the currentPtr is
- * deleted we don't have to start from the
- * beginning. */
+ Tk_Item *lastPtr; /* The item right before the currentPtr is
+ * tracked so if the currentPtr is deleted we
+ * don't have to start from the beginning. */
int searchOver; /* Non-zero means NextItem should always
* return NULL. */
- int type; /* search type */
- int id; /* item id for searches by id */
+ int type; /* Search type (see #defs below) */
+ int id; /* Item id for searches by id */
+ char *string; /* Tag expression string */
+ int stringIndex; /* Current position in string scan */
+ int stringLength; /* Length of tag expression string */
+ char *rewritebuffer; /* Tag string (after removing escapes) */
+ unsigned int rewritebufferAllocated;
+ /* Available space for rewrites. */
+ TagSearchExpr *expr; /* Compiled tag expression. */
+} TagSearch;
- char *string; /* tag expression string */
- int stringIndex; /* current position in string scan */
- int stringLength; /* length of tag expression string */
+/*
+ * Values for the TagSearch type field.
+ */
- char *rewritebuffer; /* tag string (after removing escapes) */
- unsigned int rewritebufferAllocated; /* available space for rewrites */
+#define SEARCH_TYPE_EMPTY 0 /* Looking for empty tag */
+#define SEARCH_TYPE_ID 1 /* Looking for an item by id */
+#define SEARCH_TYPE_ALL 2 /* Looking for all items */
+#define SEARCH_TYPE_TAG 3 /* Looking for an item by simple tag */
+#define SEARCH_TYPE_EXPR 4 /* Compound search */
- TagSearchExpr *expr; /* compiled tag expression */
-} TagSearch;
#endif /* USE_OLD_TAG_SEARCH */
/*
@@ -119,10 +123,8 @@ static Tk_ConfigSpec configSpecs[] = {
{TK_CONFIG_BORDER, "-background", "background", "Background",
DEF_CANVAS_BG_MONO, Tk_Offset(TkCanvas, 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_SYNONYM, "-bd", "borderWidth", NULL, NULL, 0, 0},
+ {TK_CONFIG_SYNONYM, "-bg", "background", NULL, NULL, 0, 0},
{TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
DEF_CANVAS_BORDER_WIDTH, Tk_Offset(TkCanvas, borderWidth), 0},
{TK_CONFIG_DOUBLE, "-closeenough", "closeEnough", "CloseEnough",
@@ -203,13 +205,12 @@ static Tk_ConfigSpec configSpecs[] = {
"ScrollIncrement",
DEF_CANVAS_Y_SCROLL_INCREMENT, Tk_Offset(TkCanvas, yScrollIncrement),
0},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+ {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};
/*
- * List of all the item types known at present. This is *global* and
- * is protected by typeListMutex.
+ * List of all the item types known at present. This is *global* and is
+ * protected by typeListMutex.
*/
static Tk_ItemType *typeList = NULL; /* NULL means initialization hasn't
@@ -218,9 +219,10 @@ TCL_DECLARE_MUTEX(typeListMutex)
#ifndef USE_OLD_TAG_SEARCH
/*
- * Uids for operands in compiled advanced tag search expressions
+ * Uids for operands in compiled advanced tag search expressions.
* Initialization is done by GetStaticUids()
*/
+
typedef struct {
Tk_Uid allUid;
Tk_Uid currentUid;
@@ -235,107 +237,89 @@ typedef struct {
} SearchUids;
static Tcl_ThreadDataKey dataKey;
-static SearchUids *GetStaticUids _ANSI_ARGS_((void));
+static SearchUids * GetStaticUids(void);
#endif /* USE_OLD_TAG_SEARCH */
/*
- * Standard item types provided by Tk:
+ * Prototypes for functions defined later in this file:
*/
-extern Tk_ItemType tkArcType, tkBitmapType, tkImageType, tkLineType;
-extern Tk_ItemType tkOvalType, tkPolygonType;
-extern Tk_ItemType tkRectangleType, tkTextType, tkWindowType;
-
-/*
- * Prototypes for procedures defined later in this file:
- */
-
-static void CanvasBindProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void CanvasBlinkProc _ANSI_ARGS_((ClientData clientData));
-static void CanvasCmdDeletedProc _ANSI_ARGS_((
- ClientData clientData));
-static void CanvasDoEvent _ANSI_ARGS_((TkCanvas *canvasPtr,
- XEvent *eventPtr));
-static void CanvasEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static int CanvasFetchSelection _ANSI_ARGS_((
- ClientData clientData, int offset,
- char *buffer, int maxBytes));
-static Tk_Item * CanvasFindClosest _ANSI_ARGS_((TkCanvas *canvasPtr,
- double coords[2]));
-static void CanvasFocusProc _ANSI_ARGS_((TkCanvas *canvasPtr,
- int gotFocus));
-static void CanvasLostSelection _ANSI_ARGS_((
- ClientData clientData));
-static void CanvasSelectTo _ANSI_ARGS_((TkCanvas *canvasPtr,
- Tk_Item *itemPtr, int index));
-static void CanvasSetOrigin _ANSI_ARGS_((TkCanvas *canvasPtr,
- int xOrigin, int yOrigin));
-static void CanvasUpdateScrollbars _ANSI_ARGS_((
- TkCanvas *canvasPtr));
-static int CanvasWidgetCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int argc, Tcl_Obj *CONST *argv));
-static void CanvasWorldChanged _ANSI_ARGS_((
- ClientData instanceData));
-static int ConfigureCanvas _ANSI_ARGS_((Tcl_Interp *interp,
- TkCanvas *canvasPtr, int argc, Tcl_Obj *CONST *argv,
- int flags));
-static void DestroyCanvas _ANSI_ARGS_((char *memPtr));
-static void DisplayCanvas _ANSI_ARGS_((ClientData clientData));
-static void DoItem _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Item *itemPtr, Tk_Uid tag));
-static void EventuallyRedrawItem _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr));
+static void CanvasBindProc(ClientData clientData,
+ XEvent *eventPtr);
+static void CanvasBlinkProc(ClientData clientData);
+static void CanvasCmdDeletedProc(ClientData clientData);
+static void CanvasDoEvent(TkCanvas *canvasPtr, XEvent *eventPtr);
+static void CanvasEventProc(ClientData clientData,
+ XEvent *eventPtr);
+static int CanvasFetchSelection(ClientData clientData, int offset,
+ char *buffer, int maxBytes);
+static Tk_Item * CanvasFindClosest(TkCanvas *canvasPtr,
+ double coords[2]);
+static void CanvasFocusProc(TkCanvas *canvasPtr, int gotFocus);
+static void CanvasLostSelection(ClientData clientData);
+static void CanvasSelectTo(TkCanvas *canvasPtr,
+ Tk_Item *itemPtr, int index);
+static void CanvasSetOrigin(TkCanvas *canvasPtr,
+ int xOrigin, int yOrigin);
+static void CanvasUpdateScrollbars(TkCanvas *canvasPtr);
+static int CanvasWidgetCmd(ClientData clientData,
+ Tcl_Interp *interp, int argc,
+ Tcl_Obj *CONST *argv);
+static void CanvasWorldChanged(
+ ClientData instanceData);
+static int ConfigureCanvas(Tcl_Interp *interp,
+ TkCanvas *canvasPtr, int argc,
+ Tcl_Obj *CONST *argv, int flags);
+static void DestroyCanvas(char *memPtr);
+static void DisplayCanvas(ClientData clientData);
+static void DoItem(Tcl_Interp *interp,
+ Tk_Item *itemPtr, Tk_Uid tag);
+static void EventuallyRedrawItem(Tk_Canvas canvas,
+ Tk_Item *itemPtr);
#ifdef USE_OLD_TAG_SEARCH
-static int FindItems _ANSI_ARGS_((Tcl_Interp *interp,
- TkCanvas *canvasPtr, int argc, Tcl_Obj *CONST *argv,
- Tcl_Obj *newTagObj, int first));
+static int FindItems(Tcl_Interp *interp, TkCanvas *canvasPtr,
+ int argc, Tcl_Obj *CONST *argv,
+ Tcl_Obj *newTagObj, int first);
#else /* USE_OLD_TAG_SEARCH */
-static int FindItems _ANSI_ARGS_((Tcl_Interp *interp,
- TkCanvas *canvasPtr, int argc, Tcl_Obj *CONST *argv,
+static int FindItems(Tcl_Interp *interp, TkCanvas *canvasPtr,
+ int argc, Tcl_Obj *CONST *argv,
Tcl_Obj *newTagObj, int first,
- TagSearch **searchPtrPtr));
+ TagSearch **searchPtrPtr);
#endif /* USE_OLD_TAG_SEARCH */
-static int FindArea _ANSI_ARGS_((Tcl_Interp *interp,
- TkCanvas *canvasPtr, Tcl_Obj *CONST *argv, Tk_Uid uid,
- int enclosed));
-static double GridAlign _ANSI_ARGS_((double coord, double spacing));
-static CONST char** GetStringsFromObjs _ANSI_ARGS_((int argc,
- Tcl_Obj *CONST *objv));
-static void InitCanvas _ANSI_ARGS_((void));
+static int FindArea(Tcl_Interp *interp, TkCanvas *canvasPtr,
+ Tcl_Obj *CONST *argv, Tk_Uid uid, int enclosed);
+static double GridAlign(double coord, double spacing);
+static CONST char** TkGetStringsFromObjs(int argc, Tcl_Obj *CONST *objv);
+static void InitCanvas(void);
#ifdef USE_OLD_TAG_SEARCH
-static Tk_Item * NextItem _ANSI_ARGS_((TagSearch *searchPtr));
+static Tk_Item * NextItem(TagSearch *searchPtr);
#endif /* USE_OLD_TAG_SEARCH */
-static void PickCurrentItem _ANSI_ARGS_((TkCanvas *canvasPtr,
- XEvent *eventPtr));
-static Tcl_Obj * ScrollFractions _ANSI_ARGS_((int screen1,
- int screen2, int object1, int object2));
+static void PickCurrentItem(TkCanvas *canvasPtr, XEvent *eventPtr);
+static Tcl_Obj * ScrollFractions(int screen1,
+ int screen2, int object1, int object2);
#ifdef USE_OLD_TAG_SEARCH
-static void RelinkItems _ANSI_ARGS_((TkCanvas *canvasPtr,
- Tcl_Obj *tag, Tk_Item *prevPtr));
-static Tk_Item * StartTagSearch _ANSI_ARGS_((TkCanvas *canvasPtr,
- Tcl_Obj *tag, TagSearch *searchPtr));
+static void RelinkItems(TkCanvas *canvasPtr,
+ Tcl_Obj *tag, Tk_Item *prevPtr);
+static Tk_Item * StartTagSearch(TkCanvas *canvasPtr,
+ Tcl_Obj *tag, TagSearch *searchPtr);
#else /* USE_OLD_TAG_SEARCH */
-static int RelinkItems _ANSI_ARGS_((TkCanvas *canvasPtr,
- Tcl_Obj *tag, Tk_Item *prevPtr,
- TagSearch **searchPtrPtr));
-static void TagSearchExprInit _ANSI_ARGS_ ((
- TagSearchExpr **exprPtrPtr));
-static void TagSearchExprDestroy _ANSI_ARGS_((TagSearchExpr *expr));
-static void TagSearchDestroy _ANSI_ARGS_((TagSearch *searchPtr));
-static int TagSearchScan _ANSI_ARGS_((TkCanvas *canvasPtr,
- Tcl_Obj *tag, TagSearch **searchPtrPtr));
-static int TagSearchScanExpr _ANSI_ARGS_((Tcl_Interp *interp,
- TagSearch *searchPtr, TagSearchExpr *expr));
-static int TagSearchEvalExpr _ANSI_ARGS_((TagSearchExpr *expr,
- Tk_Item *itemPtr));
-static Tk_Item * TagSearchFirst _ANSI_ARGS_((TagSearch *searchPtr));
-static Tk_Item * TagSearchNext _ANSI_ARGS_((TagSearch *searchPtr));
+static int RelinkItems(TkCanvas *canvasPtr, Tcl_Obj *tag,
+ Tk_Item *prevPtr, TagSearch **searchPtrPtr);
+static void TagSearchExprInit(TagSearchExpr **exprPtrPtr);
+static void TagSearchExprDestroy(TagSearchExpr *expr);
+static void TagSearchDestroy(TagSearch *searchPtr);
+static int TagSearchScan(TkCanvas *canvasPtr,
+ Tcl_Obj *tag, TagSearch **searchPtrPtr);
+static int TagSearchScanExpr(Tcl_Interp *interp,
+ TagSearch *searchPtr, TagSearchExpr *expr);
+static int TagSearchEvalExpr(TagSearchExpr *expr,
+ Tk_Item *itemPtr);
+static Tk_Item * TagSearchFirst(TagSearch *searchPtr);
+static Tk_Item * TagSearchNext(TagSearch *searchPtr);
#endif /* USE_OLD_TAG_SEARCH */
/*
- * The structure below defines canvas class behavior by means of procedures
+ * The structure below defines canvas class behavior by means of functions
* that can be invoked from generic window code.
*/
@@ -344,15 +328,38 @@ static Tk_ClassProcs canvasClass = {
CanvasWorldChanged, /* worldChangedProc */
};
+/*
+ * Macros that significantly simplify all code that finds items.
+ */
+
+#ifdef USE_OLD_TAG_SEARCH
+#define FIRST_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \
+ (itemPtr) = StartTagSearch(canvasPtr,(objPtr),&search)
+#define FOR_EVERY_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \
+ for ((itemPtr) = StartTagSearch(canvasPtr, (objPtr), &search); \
+ (itemPtr) != NULL; (itemPtr) = NextItem(&search))
+#else /* USE_OLD_TAG_SEARCH */
+#define FIRST_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \
+ if ((result=TagSearchScan(canvasPtr,(objPtr),(searchPtrPtr))) != TCL_OK){ \
+ errorExitClause; \
+ } \
+ itemPtr = TagSearchFirst(*(searchPtrPtr));
+#define FOR_EVERY_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \
+ if ((result=TagSearchScan(canvasPtr,(objPtr),(searchPtrPtr))) != TCL_OK){ \
+ errorExitClause; \
+ } \
+ for (itemPtr = TagSearchFirst(*(searchPtrPtr)); \
+ itemPtr != NULL; itemPtr = TagSearchNext(*(searchPtrPtr)))
+#endif /* USE_OLD_TAG_SEARCH */
+
/*
*--------------------------------------------------------------
*
* Tk_CanvasObjCmd --
*
- * This procedure is invoked to process the "canvas" Tcl
- * command. See the user documentation for details on what
- * it does.
+ * This function is invoked to process the "canvas" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -364,16 +371,15 @@ static Tk_ClassProcs canvasClass = {
*/
int
-Tk_CanvasObjCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- Tcl_Obj *CONST argv[]; /* Argument objects. */
+Tk_CanvasObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ Tcl_Obj *CONST argv[]) /* Argument objects. */
{
Tk_Window tkwin = (Tk_Window) clientData;
TkCanvas *canvasPtr;
- Tk_Window new;
+ Tk_Window newWin;
if (typeList == NULL) {
InitCanvas();
@@ -384,21 +390,20 @@ Tk_CanvasObjCmd(clientData, interp, argc, argv)
return TCL_ERROR;
}
- new = Tk_CreateWindowFromPath(interp, tkwin,
- Tcl_GetString(argv[1]), (char *) NULL);
- if (new == NULL) {
+ newWin = Tk_CreateWindowFromPath(interp,tkwin,Tcl_GetString(argv[1]),NULL);
+ if (newWin == NULL) {
return TCL_ERROR;
}
/*
- * Initialize fields that won't be initialized by ConfigureCanvas,
- * or which ConfigureCanvas expects to have reasonable values
- * (e.g. resource pointers).
+ * Initialize fields that won't be initialized by ConfigureCanvas, or
+ * which ConfigureCanvas expects to have reasonable values (e.g. resource
+ * pointers).
*/
canvasPtr = (TkCanvas *) ckalloc(sizeof(TkCanvas));
- canvasPtr->tkwin = new;
- canvasPtr->display = Tk_Display(new);
+ canvasPtr->tkwin = newWin;
+ canvasPtr->display = Tk_Display(newWin);
canvasPtr->interp = interp;
canvasPtr->widgetCmd = Tcl_CreateObjCommand(interp,
Tk_PathName(canvasPtr->tkwin), CanvasWidgetCmd,
@@ -460,8 +465,8 @@ Tk_CanvasObjCmd(clientData, interp, argc, argv)
canvasPtr->hotPrevPtr = NULL;
canvasPtr->cursor = None;
canvasPtr->takeFocus = NULL;
- canvasPtr->pixelsPerMM = WidthOfScreen(Tk_Screen(new));
- canvasPtr->pixelsPerMM /= WidthMMOfScreen(Tk_Screen(new));
+ canvasPtr->pixelsPerMM = WidthOfScreen(Tk_Screen(newWin));
+ canvasPtr->pixelsPerMM /= WidthMMOfScreen(Tk_Screen(newWin));
canvasPtr->flags = 0;
canvasPtr->nextId = 1;
canvasPtr->psInfo = NULL;
@@ -492,7 +497,7 @@ Tk_CanvasObjCmd(clientData, interp, argc, argv)
Tcl_SetResult(interp, Tk_PathName(canvasPtr->tkwin), TCL_STATIC);
return TCL_OK;
- error:
+ error:
Tk_DestroyWindow(canvasPtr->tkwin);
return TCL_ERROR;
}
@@ -502,9 +507,9 @@ Tk_CanvasObjCmd(clientData, interp, argc, argv)
*
* CanvasWidgetCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to a widget managed by this module.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the Tcl command that corresponds
+ * to a widget managed by this module. See the user documentation for
+ * details on what it does.
*
* Results:
* A standard Tcl result.
@@ -516,22 +521,21 @@ Tk_CanvasObjCmd(clientData, interp, argc, argv)
*/
static int
-CanvasWidgetCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Information about canvas
- * widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+CanvasWidgetCmd(
+ ClientData clientData, /* Information about canvas widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
TkCanvas *canvasPtr = (TkCanvas *) clientData;
- int c, length, result;
- Tk_Item *itemPtr = NULL; /* Initialization needed only to
- * prevent compiler warning. */
+ int c, result;
+ Tk_Item *itemPtr = NULL; /* Initialization needed only to prevent
+ * compiler warning. */
#ifdef USE_OLD_TAG_SEARCH
TagSearch search;
#else /* USE_OLD_TAG_SEARCH */
- TagSearch *searchPtr = NULL; /* Allocated by first TagSearchScan
- * Freed by TagSearchDestroy */
+ TagSearch *searchPtr = NULL;/* Allocated by first TagSearchScan, freed by
+ * TagSearchDestroy */
#endif /* USE_OLD_TAG_SEARCH */
int index;
@@ -569,7 +573,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
result = TCL_OK;
switch ((enum options) index) {
- case CANV_ADDTAG: {
+ case CANV_ADDTAG:
if (objc < 4) {
Tcl_WrongNumArgs(interp, 2, objv, "tag searchCommand ?arg arg ...?");
result = TCL_ERROR;
@@ -581,13 +585,12 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
result = FindItems(interp, canvasPtr, objc, objv, objv[2], 3, &searchPtr);
#endif /* USE_OLD_TAG_SEARCH */
break;
- }
- case CANV_BBOX: {
+ case CANV_BBOX: {
int i, gotAny;
- int x1 = 0, y1 = 0, x2 = 0, y2 = 0; /* Initializations needed
- * only to prevent compiler
- * warnings. */
+ int x1 = 0, y1 = 0, x2 = 0, y2 = 0; /* Initializations needed only
+ * to prevent overcautious
+ * compiler warnings. */
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?tagOrId ...?");
@@ -596,17 +599,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
gotAny = 0;
for (i = 2; i < objc; i++) {
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, objv[i], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[i], &searchPtr)) != TCL_OK) {
- goto done;
- }
- for (itemPtr = TagSearchFirst(searchPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(searchPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
-
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[i], &searchPtr, goto done) {
if ((itemPtr->x1 >= itemPtr->x2)
|| (itemPtr->y1 >= itemPtr->y2)) {
continue;
@@ -635,13 +628,13 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
if (gotAny) {
char buf[TCL_INTEGER_SPACE * 4];
-
+
sprintf(buf, "%d %d %d %d", x1, y1, x2, y2);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
}
break;
- }
- case CANV_BIND: {
+ }
+ case CANV_BIND: {
ClientData object;
if ((objc < 3) || (objc > 5)) {
@@ -651,8 +644,8 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
/*
- * Figure out what object to use for the binding (individual
- * item vs. tag).
+ * Figure out what object to use for the binding (individual item vs.
+ * tag).
*/
object = 0;
@@ -674,7 +667,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
if (object == 0) {
Tcl_AppendResult(interp, "item \"", Tcl_GetString(objv[2]),
- "\" doesn't exist", (char *) NULL);
+ "\" doesn't exist", NULL);
result = TCL_ERROR;
goto done;
}
@@ -683,13 +676,15 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
object = (ClientData) Tk_GetUid(Tcl_GetString(objv[2]));
}
#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[2], &searchPtr)) != TCL_OK) {
+ result = TagSearchScan(canvasPtr, objv[2], &searchPtr);
+ if (result != TCL_OK) {
goto done;
}
- if (searchPtr->type == 1) {
+ if (searchPtr->type == SEARCH_TYPE_ID) {
Tcl_HashEntry *entryPtr;
- entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char *) searchPtr->id);
+ entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable,
+ (char *) INT2PTR(searchPtr->id));
if (entryPtr != NULL) {
itemPtr = (Tk_Item *) Tcl_GetHashValue(entryPtr);
object = (ClientData) itemPtr;
@@ -697,7 +692,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
if (object == 0) {
Tcl_AppendResult(interp, "item \"", Tcl_GetString(objv[2]),
- "\" doesn't exist", (char *) NULL);
+ "\" doesn't exist", NULL);
result = TCL_ERROR;
goto done;
}
@@ -707,8 +702,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
#endif /* USE_OLD_TAG_SEARCH */
/*
- * Make a binding table if the canvas doesn't already have
- * one.
+ * Make a binding table if the canvas doesn't already have one.
*/
if (canvasPtr->bindingTable == NULL) {
@@ -718,18 +712,19 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
if (objc == 5) {
int append = 0;
unsigned long mask;
- char* argv4 = Tcl_GetStringFromObj(objv[4],NULL);
+ char* argv4 = Tcl_GetString(objv[4]);
if (argv4[0] == 0) {
result = Tk_DeleteBinding(interp, canvasPtr->bindingTable,
- object, Tcl_GetStringFromObj(objv[3], NULL));
+ object, Tcl_GetString(objv[3]));
goto done;
}
#ifndef USE_OLD_TAG_SEARCH
- if (searchPtr->type == 4) {
- /*
- * if new tag expression, then insert in linked list
- */
+ if (searchPtr->type == SEARCH_TYPE_EXPR) {
+ /*
+ * If new tag expression, then insert in linked list.
+ */
+
TagSearchExpr *expr, **lastPtr;
lastPtr = &(canvasPtr->bindTagExprs);
@@ -741,25 +736,27 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
if (!expr) {
/*
- * transfer ownership of expr to bindTagExprs list
+ * Transfer ownership of expr to bindTagExprs list.
*/
+
*lastPtr = searchPtr->expr;
searchPtr->expr->next = NULL;
/*
- * flag in TagSearch that expr has changed ownership
- * so that TagSearchDestroy doesn't try to free it
+ * Flag in TagSearch that expr has changed ownership so
+ * that TagSearchDestroy doesn't try to free it.
*/
+
searchPtr->expr = NULL;
}
- }
+ }
#endif /* not USE_OLD_TAG_SEARCH */
if (argv4[0] == '+') {
argv4++;
append = 1;
}
mask = Tk_CreateBinding(interp, canvasPtr->bindingTable,
- object, Tcl_GetStringFromObj(objv[3],NULL), argv4, append);
+ object, Tcl_GetString(objv[3]), argv4, append);
if (mask == 0) {
result = TCL_ERROR;
goto done;
@@ -770,27 +767,28 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
|EnterWindowMask|LeaveWindowMask|KeyPressMask
|KeyReleaseMask|PointerMotionMask|VirtualEventMask)) {
Tk_DeleteBinding(interp, canvasPtr->bindingTable,
- object, Tcl_GetStringFromObj(objv[3], NULL));
+ object, Tcl_GetString(objv[3]));
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "requested illegal events; ",
"only key, button, motion, enter, leave, and virtual ",
- "events may be used", (char *) NULL);
+ "events may be used", NULL);
result = TCL_ERROR;
goto done;
}
} else if (objc == 4) {
CONST char *command;
-
+
command = Tk_GetBinding(interp, canvasPtr->bindingTable,
- object, Tcl_GetStringFromObj(objv[3], NULL));
+ object, Tcl_GetString(objv[3]));
if (command == NULL) {
CONST char *string;
- string = Tcl_GetStringResult(interp);
+ 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.
+ * 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') {
@@ -806,8 +804,8 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
Tk_GetAllBindings(interp, canvasPtr->bindingTable, object);
}
break;
- }
- case CANV_CANVASX: {
+ }
+ case CANV_CANVASX: {
int x;
double grid;
char buf[TCL_DOUBLE_SPACE];
@@ -834,8 +832,8 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
Tcl_PrintDouble(interp, GridAlign((double) x, grid), buf);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
break;
- }
- case CANV_CANVASY: {
+ }
+ case CANV_CANVASY: {
int y;
double grid;
char buf[TCL_DOUBLE_SPACE];
@@ -862,8 +860,8 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
Tcl_PrintDouble(interp, GridAlign((double) y, grid), buf);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
break;
- }
- case CANV_CGET: {
+ }
+ case CANV_CGET:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "option");
result = TCL_ERROR;
@@ -872,11 +870,10 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
result = Tk_ConfigureValue(interp, canvasPtr->tkwin, configSpecs,
(char *) canvasPtr, Tcl_GetString(objv[2]), 0);
break;
- }
- case CANV_CONFIGURE: {
+ case CANV_CONFIGURE:
if (objc == 2) {
result = Tk_ConfigureInfo(interp, canvasPtr->tkwin, configSpecs,
- (char *) canvasPtr, (char *) NULL, 0);
+ (char *) canvasPtr, NULL, 0);
} else if (objc == 3) {
result = Tk_ConfigureInfo(interp, canvasPtr->tkwin, configSpecs,
(char *) canvasPtr, Tcl_GetString(objv[2]), 0);
@@ -885,43 +882,37 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
TK_CONFIG_ARGV_ONLY);
}
break;
- }
- case CANV_COORDS: {
+ case CANV_COORDS:
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?x y x y ...?");
result = TCL_ERROR;
goto done;
}
-#ifdef USE_OLD_TAG_SEARCH
- itemPtr = StartTagSearch(canvasPtr, objv[2], &search);
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[2], &searchPtr)) != TCL_OK) {
- goto done;
- }
- itemPtr = TagSearchFirst(searchPtr);
-#endif /* USE_OLD_TAG_SEARCH */
+ FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
if (itemPtr != NULL) {
if (objc != 3) {
EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
}
if (itemPtr->typePtr->coordProc != NULL) {
- if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
- result = (*itemPtr->typePtr->coordProc)(interp,
- (Tk_Canvas) canvasPtr, itemPtr, objc-3, objv+3);
- } else {
- CONST char **args = GetStringsFromObjs(objc-3, objv+3);
- result = (*itemPtr->typePtr->coordProc)(interp,
- (Tk_Canvas) canvasPtr, itemPtr, objc-3, (Tcl_Obj **) args);
- if (args) ckfree((char *) args);
- }
+ if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
+ result = (*itemPtr->typePtr->coordProc)(interp,
+ (Tk_Canvas) canvasPtr, itemPtr, objc-3, objv+3);
+ } else {
+ CONST char **args = TkGetStringsFromObjs(objc-3, objv+3);
+ result = (*itemPtr->typePtr->coordProc)(interp,
+ (Tk_Canvas) canvasPtr, itemPtr, objc-3,
+ (Tcl_Obj **) args);
+ if (args != NULL) {
+ ckfree((char *) args);
+ }
+ }
}
if (objc != 3) {
EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
}
}
break;
- }
- case CANV_CREATE: {
+ case CANV_CREATE: {
Tk_ItemType *typePtr;
Tk_ItemType *matchPtr = NULL;
Tk_Item *itemPtr;
@@ -929,6 +920,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
int isNew = 0;
Tcl_HashEntry *entryPtr;
char *arg;
+ int length;
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2, objv, "type coords ?arg arg ...?");
@@ -940,13 +932,12 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
Tcl_MutexLock(&typeListMutex);
for (typePtr = typeList; typePtr != NULL; typePtr = typePtr->nextPtr) {
if ((c == typePtr->name[0])
- && (strncmp(arg, typePtr->name, (unsigned) length) == 0)) {
+ && (strncmp(arg, typePtr->name, (unsigned)length) == 0)) {
if (matchPtr != NULL) {
Tcl_MutexUnlock(&typeListMutex);
- badType:
+ badType:
Tcl_AppendResult(interp,
- "unknown or ambiguous item type \"",
- arg, "\"", (char *) NULL);
+ "unknown or ambiguous item type \"",arg,"\"",NULL);
result = TCL_ERROR;
goto done;
}
@@ -984,10 +975,12 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
result = (*typePtr->createProc)(interp, (Tk_Canvas) canvasPtr,
itemPtr, objc-3, objv+3);
} else {
- CONST char **args = GetStringsFromObjs(objc-3, objv+3);
+ CONST char **args = TkGetStringsFromObjs(objc-3, objv+3);
result = (*typePtr->createProc)(interp, (Tk_Canvas) canvasPtr,
itemPtr, objc-3, (Tcl_Obj **) args);
- if (args) ckfree((char *) args);
+ if (args != NULL) {
+ ckfree((char *) args);
+ }
}
if (result != TCL_OK) {
ckfree((char *) itemPtr);
@@ -996,7 +989,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
itemPtr->nextPtr = NULL;
entryPtr = Tcl_CreateHashEntry(&canvasPtr->idTable,
- (char *) itemPtr->id, &isNew);
+ (char *) INT2PTR(itemPtr->id), &isNew);
Tcl_SetHashValue(entryPtr, itemPtr);
itemPtr->prevPtr = canvasPtr->lastItemPtr;
canvasPtr->hotPtr = itemPtr;
@@ -1013,8 +1006,8 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
sprintf(buf, "%d", itemPtr->id);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
break;
- }
- case CANV_DCHARS: {
+ }
+ case CANV_DCHARS: {
int first, last;
int x1,x2,y1,y2;
@@ -1023,37 +1016,32 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
result = TCL_ERROR;
goto done;
}
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, objv[2], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[2], &searchPtr)) != TCL_OK) {
- goto done;
- }
- for (itemPtr = TagSearchFirst(searchPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(searchPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
if ((itemPtr->typePtr->indexProc == NULL)
|| (itemPtr->typePtr->dCharsProc == NULL)) {
continue;
}
if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
- result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
- itemPtr, (char *) objv[3], &first);
+ result = itemPtr->typePtr->indexProc(interp,
+ (Tk_Canvas) canvasPtr, itemPtr, (char *) objv[3],
+ &first);
} else {
- result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
- itemPtr, Tcl_GetStringFromObj(objv[3], NULL), &first);
+ result = itemPtr->typePtr->indexProc(interp,
+ (Tk_Canvas) canvasPtr, itemPtr, Tcl_GetString(objv[3]),
+ &first);
}
if (result != TCL_OK) {
goto done;
}
if (objc == 5) {
if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
- result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
- itemPtr, (char *) objv[4], &last);
+ result = itemPtr->typePtr->indexProc(interp,
+ (Tk_Canvas) canvasPtr, itemPtr, (char *) objv[4],
+ &last);
} else {
- result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
- itemPtr, Tcl_GetStringFromObj(objv[4], NULL), &last);
+ result = itemPtr->typePtr->indexProc(interp,
+ (Tk_Canvas) canvasPtr, itemPtr,
+ Tcl_GetString(objv[4]), &last);
}
if (result != TCL_OK) {
goto done;
@@ -1063,10 +1051,10 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
/*
- * Redraw both item's old and new areas: it's possible
- * that a delete could result in a new area larger than
- * the old area. Except if the insertProc sets the
- * TK_ITEM_DONT_REDRAW flag, nothing more needs to be done.
+ * Redraw both item's old and new areas: it's possible that a
+ * delete could result in a new area larger than the old area.
+ * Except if the insertProc sets the TK_ITEM_DONT_REDRAW flag,
+ * nothing more needs to be done.
*/
x1 = itemPtr->x1; y1 = itemPtr->y1;
@@ -1082,22 +1070,13 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
}
break;
- }
- case CANV_DELETE: {
+ }
+ case CANV_DELETE: {
int i;
Tcl_HashEntry *entryPtr;
for (i = 2; i < objc; i++) {
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, objv[i], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[i], &searchPtr)) != TCL_OK) {
- goto done;
- }
- for (itemPtr = TagSearchFirst(searchPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(searchPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[i], &searchPtr, goto done) {
EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
if (canvasPtr->bindingTable != NULL) {
Tk_DeleteAllBindings(canvasPtr->bindingTable,
@@ -1109,7 +1088,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
ckfree((char *) itemPtr->tagPtr);
}
entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable,
- (char *) itemPtr->id);
+ (char *) INT2PTR(itemPtr->id));
Tcl_DeleteHashEntry(entryPtr);
if (itemPtr->nextPtr != NULL) {
itemPtr->nextPtr->prevPtr = itemPtr->prevPtr;
@@ -1148,8 +1127,8 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
}
break;
- }
- case CANV_DTAG: {
+ }
+ case CANV_DTAG: {
Tk_Uid tag;
int i;
@@ -1159,20 +1138,11 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
goto done;
}
if (objc == 4) {
- tag = Tk_GetUid(Tcl_GetStringFromObj(objv[3], NULL));
+ tag = Tk_GetUid(Tcl_GetString(objv[3]));
} else {
- tag = Tk_GetUid(Tcl_GetStringFromObj(objv[2], NULL));
+ tag = Tk_GetUid(Tcl_GetString(objv[2]));
}
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, objv[2], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[2], &searchPtr)) != TCL_OK) {
- goto done;
- }
- for (itemPtr = TagSearchFirst(searchPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(searchPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
for (i = itemPtr->numTags-1; i >= 0; i--) {
if (itemPtr->tagPtr[i] == tag) {
itemPtr->tagPtr[i] = itemPtr->tagPtr[itemPtr->numTags-1];
@@ -1181,22 +1151,21 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
}
break;
- }
- case CANV_FIND: {
+ }
+ case CANV_FIND:
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2, objv, "searchCommand ?arg arg ...?");
result = TCL_ERROR;
goto done;
}
#ifdef USE_OLD_TAG_SEARCH
- result = FindItems(interp, canvasPtr, objc, objv, (Tcl_Obj *) NULL, 2);
+ result = FindItems(interp, canvasPtr, objc, objv, NULL, 2);
#else /* USE_OLD_TAG_SEARCH */
- result = FindItems(interp, canvasPtr, objc, objv,
- (Tcl_Obj *) NULL, 2, &searchPtr);
+ result = FindItems(interp, canvasPtr, objc, objv, NULL, 2,
+ &searchPtr);
#endif /* USE_OLD_TAG_SEARCH */
break;
- }
- case CANV_FOCUS: {
+ case CANV_FOCUS:
if (objc > 3) {
Tcl_WrongNumArgs(interp, 2, objv, "?tagOrId?");
result = TCL_ERROR;
@@ -1206,7 +1175,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
if (objc == 2) {
if (itemPtr != NULL) {
char buf[TCL_INTEGER_SPACE];
-
+
sprintf(buf, "%d", itemPtr->id);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
}
@@ -1215,20 +1184,11 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
if ((itemPtr != NULL) && (canvasPtr->textInfo.gotFocus)) {
EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
}
- if (Tcl_GetStringFromObj(objv[2], NULL)[0] == 0) {
+ if (Tcl_GetString(objv[2])[0] == 0) {
canvasPtr->textInfo.focusItemPtr = NULL;
goto done;
}
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, objv[2], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[2], &searchPtr)) != TCL_OK) {
- goto done;
- }
- for (itemPtr = TagSearchFirst(searchPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(searchPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
if (itemPtr->typePtr->icursorProc != NULL) {
break;
}
@@ -1241,21 +1201,13 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
}
break;
- }
- case CANV_GETTAGS: {
+ case CANV_GETTAGS:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "tagOrId");
result = TCL_ERROR;
goto done;
}
-#ifdef USE_OLD_TAG_SEARCH
- itemPtr = StartTagSearch(canvasPtr, objv[2], &search);
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[2], &searchPtr)) != TCL_OK) {
- goto done;
- }
- itemPtr = TagSearchFirst(searchPtr);
-#endif /* USE_OLD_TAG_SEARCH */
+ FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
if (itemPtr != NULL) {
int i;
for (i = 0; i < itemPtr->numTags; i++) {
@@ -1263,8 +1215,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
}
break;
- }
- case CANV_ICURSOR: {
+ case CANV_ICURSOR: {
int index;
if (objc != 4) {
@@ -1272,26 +1223,19 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
result = TCL_ERROR;
goto done;
}
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, objv[2], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[2], &searchPtr)) != TCL_OK) {
- goto done;
- }
- for (itemPtr = TagSearchFirst(searchPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(searchPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
if ((itemPtr->typePtr->indexProc == NULL)
|| (itemPtr->typePtr->icursorProc == NULL)) {
goto done;
}
if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
- result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
- itemPtr, (char *) objv[3], &index);
+ result = itemPtr->typePtr->indexProc(interp,
+ (Tk_Canvas) canvasPtr, itemPtr, (char *) objv[3],
+ &index);
} else {
- result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
- itemPtr, Tcl_GetStringFromObj(objv[3], NULL), &index);
+ result = itemPtr->typePtr->indexProc(interp,
+ (Tk_Canvas) canvasPtr, itemPtr, Tcl_GetString(objv[3]),
+ &index);
}
if (result != TCL_OK) {
goto done;
@@ -1304,9 +1248,8 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
}
break;
- }
- case CANV_INDEX: {
-
+ }
+ case CANV_INDEX: {
int index;
char buf[TCL_INTEGER_SPACE];
@@ -1315,23 +1258,14 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
result = TCL_ERROR;
goto done;
}
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, objv[2], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[2], &searchPtr)) != TCL_OK) {
- goto done;
- }
- for (itemPtr = TagSearchFirst(searchPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(searchPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
if (itemPtr->typePtr->indexProc != NULL) {
break;
}
}
if (itemPtr == NULL) {
Tcl_AppendResult(interp, "can't find an indexable item \"",
- Tcl_GetStringFromObj(objv[2], NULL), "\"", (char *) NULL);
+ Tcl_GetString(objv[2]), "\"", NULL);
result = TCL_ERROR;
goto done;
}
@@ -1340,7 +1274,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
itemPtr, (char *) objv[3], &index);
} else {
result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
- itemPtr, Tcl_GetStringFromObj(objv[3], NULL), &index);
+ itemPtr, Tcl_GetString(objv[3]), &index);
}
if (result != TCL_OK) {
goto done;
@@ -1348,8 +1282,8 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
sprintf(buf, "%d", index);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
break;
- }
- case CANV_INSERT: {
+ }
+ case CANV_INSERT: {
int beforeThis;
int x1,x2,y1,y2;
@@ -1358,37 +1292,29 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
result = TCL_ERROR;
goto done;
}
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, objv[2], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[2], &searchPtr)) != TCL_OK) {
- goto done;
- }
- for (itemPtr = TagSearchFirst(searchPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(searchPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
if ((itemPtr->typePtr->indexProc == NULL)
|| (itemPtr->typePtr->insertProc == NULL)) {
continue;
}
if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
- result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
- itemPtr, (char *) objv[3], &beforeThis);
+ result = itemPtr->typePtr->indexProc(interp,
+ (Tk_Canvas) canvasPtr, itemPtr, (char *) objv[3],
+ &beforeThis);
} else {
- result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
- itemPtr, Tcl_GetStringFromObj(objv[3], NULL), &beforeThis);
+ result = itemPtr->typePtr->indexProc(interp,
+ (Tk_Canvas) canvasPtr, itemPtr, Tcl_GetString(objv[3]),
+ &beforeThis);
}
if (result != TCL_OK) {
goto done;
}
/*
- * Redraw both item's old and new areas: it's possible
- * that an insertion could result in a new area either
- * larger or smaller than the old area. Except if the
- * insertProc sets the TK_ITEM_DONT_REDRAW flag, nothing
- * more needs to be done.
+ * Redraw both item's old and new areas: it's possible that an
+ * insertion could result in a new area either larger or smaller
+ * than the old area. Except if the insertProc sets the
+ * TK_ITEM_DONT_REDRAW flag, nothing more needs to be done.
*/
x1 = itemPtr->x1; y1 = itemPtr->y1;
@@ -1399,7 +1325,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
itemPtr, beforeThis, (char *) objv[4]);
} else {
(*itemPtr->typePtr->insertProc)((Tk_Canvas) canvasPtr,
- itemPtr, beforeThis, Tcl_GetStringFromObj(objv[4], NULL));
+ itemPtr, beforeThis, Tcl_GetString(objv[4]));
}
if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) {
Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
@@ -1409,48 +1335,31 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
}
break;
- }
- case CANV_ITEMCGET: {
+ }
+ case CANV_ITEMCGET:
if (objc != 4) {
Tcl_WrongNumArgs(interp, 2, objv, "tagOrId option");
result = TCL_ERROR;
goto done;
}
-#ifdef USE_OLD_TAG_SEARCH
- itemPtr = StartTagSearch(canvasPtr, objv[2], &search);
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[2], &searchPtr)) != TCL_OK) {
- goto done;
- }
- itemPtr = TagSearchFirst(searchPtr);
-#endif /* USE_OLD_TAG_SEARCH */
+ FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
if (itemPtr != NULL) {
result = Tk_ConfigureValue(canvasPtr->interp, canvasPtr->tkwin,
itemPtr->typePtr->configSpecs, (char *) itemPtr,
- Tcl_GetStringFromObj(objv[3], NULL), 0);
+ Tcl_GetString(objv[3]), 0);
}
break;
- }
- case CANV_ITEMCONFIGURE: {
+ case CANV_ITEMCONFIGURE:
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?option value ...?");
result = TCL_ERROR;
goto done;
}
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, objv[2], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[2], &searchPtr)) != TCL_OK) {
- goto done;
- }
- for (itemPtr = TagSearchFirst(searchPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(searchPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
if (objc == 3) {
result = Tk_ConfigureInfo(canvasPtr->interp, canvasPtr->tkwin,
itemPtr->typePtr->configSpecs, (char *) itemPtr,
- (char *) NULL, 0);
+ NULL, 0);
} else if (objc == 4) {
result = Tk_ConfigureInfo(canvasPtr->interp, canvasPtr->tkwin,
itemPtr->typePtr->configSpecs, (char *) itemPtr,
@@ -1458,15 +1367,17 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
} else {
EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
- result = (*itemPtr->typePtr->configProc)(interp,
- (Tk_Canvas) canvasPtr, itemPtr, objc-3, objv+3,
- TK_CONFIG_ARGV_ONLY);
+ result = (*itemPtr->typePtr->configProc)(interp,
+ (Tk_Canvas) canvasPtr, itemPtr, objc-3, objv+3,
+ TK_CONFIG_ARGV_ONLY);
} else {
- CONST char **args = GetStringsFromObjs(objc-3, objv+3);
- result = (*itemPtr->typePtr->configProc)(interp,
- (Tk_Canvas) canvasPtr, itemPtr, objc-3, (Tcl_Obj **) args,
- TK_CONFIG_ARGV_ONLY);
- if (args) ckfree((char *) args);
+ CONST char **args = TkGetStringsFromObjs(objc-3, objv+3);
+ result = (*itemPtr->typePtr->configProc)(interp,
+ (Tk_Canvas) canvasPtr, itemPtr, objc-3,
+ (Tcl_Obj **) args, TK_CONFIG_ARGV_ONLY);
+ if (args != NULL) {
+ ckfree((char *) args);
+ }
}
EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
canvasPtr->flags |= REPICK_NEEDED;
@@ -1476,8 +1387,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
}
break;
- }
- case CANV_LOWER: {
+ case CANV_LOWER: {
Tk_Item *itemPtr;
if ((objc != 3) && (objc != 4)) {
@@ -1487,24 +1397,16 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
/*
- * First find the item just after which we'll insert the
- * named items.
+ * First find the item just after which we'll insert the named items.
*/
if (objc == 3) {
itemPtr = NULL;
} else {
-#ifdef USE_OLD_TAG_SEARCH
- itemPtr = StartTagSearch(canvasPtr, objv[3], &search);
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[3], &searchPtr)) != TCL_OK) {
- goto done;
- }
- itemPtr = TagSearchFirst(searchPtr);
-#endif /* USE_OLD_TAG_SEARCH */
+ FIRST_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done);
if (itemPtr == NULL) {
Tcl_AppendResult(interp, "tag \"", Tcl_GetString(objv[3]),
- "\" doesn't match any items", (char *) NULL);
+ "\" doesn't match any items", NULL);
result = TCL_ERROR;
goto done;
}
@@ -1513,13 +1415,11 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
#ifdef USE_OLD_TAG_SEARCH
RelinkItems(canvasPtr, objv[2], itemPtr);
#else /* USE_OLD_TAG_SEARCH */
- if ((result = RelinkItems(canvasPtr, objv[2], itemPtr, &searchPtr)) != TCL_OK) {
- goto done;
- }
+ result = RelinkItems(canvasPtr, objv[2], itemPtr, &searchPtr);
#endif /* USE_OLD_TAG_SEARCH */
break;
- }
- case CANV_MOVE: {
+ }
+ case CANV_MOVE: {
double xAmount, yAmount;
if (objc != 5) {
@@ -1533,16 +1433,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
result = TCL_ERROR;
goto done;
}
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, objv[2], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[2], &searchPtr)) != TCL_OK) {
- goto done;
- }
- for (itemPtr = TagSearchFirst(searchPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(searchPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
(void) (*itemPtr->typePtr->translateProc)((Tk_Canvas) canvasPtr,
itemPtr, xAmount, yAmount);
@@ -1550,14 +1441,17 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
canvasPtr->flags |= REPICK_NEEDED;
}
break;
- }
- case CANV_POSTSCRIPT: {
- CONST char **args = GetStringsFromObjs(objc, objv);
+ }
+ case CANV_POSTSCRIPT: {
+ CONST char **args = TkGetStringsFromObjs(objc, objv);
+
result = TkCanvPostscriptCmd(canvasPtr, interp, objc, args);
- if (args) ckfree((char *) args);
+ if (args != NULL) {
+ ckfree((char *) args);
+ }
break;
- }
- case CANV_RAISE: {
+ }
+ case CANV_RAISE: {
Tk_Item *prevPtr;
if ((objc != 3) && (objc != 4)) {
@@ -1567,29 +1461,19 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
/*
- * First find the item just after which we'll insert the
- * named items.
+ * First find the item just after which we'll insert the named items.
*/
if (objc == 3) {
prevPtr = canvasPtr->lastItemPtr;
} else {
prevPtr = NULL;
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, objv[3], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[3], &searchPtr)) != TCL_OK) {
- goto done;
- }
- for (itemPtr = TagSearchFirst(searchPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(searchPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done) {
prevPtr = itemPtr;
}
if (prevPtr == NULL) {
- Tcl_AppendResult(interp, "tagOrId \"", Tcl_GetStringFromObj(objv[3], NULL),
- "\" doesn't match any items", (char *) NULL);
+ Tcl_AppendResult(interp, "tagOrId \"", Tcl_GetString(objv[3]),
+ "\" doesn't match any items", NULL);
result = TCL_ERROR;
goto done;
}
@@ -1597,14 +1481,11 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
#ifdef USE_OLD_TAG_SEARCH
RelinkItems(canvasPtr, objv[2], prevPtr);
#else /* USE_OLD_TAG_SEARCH */
- result = RelinkItems(canvasPtr, objv[2], prevPtr, &searchPtr);
- if (result != TCL_OK) {
- goto done;
- }
+ result = RelinkItems(canvasPtr, objv[2], prevPtr, &searchPtr);
#endif /* USE_OLD_TAG_SEARCH */
break;
- }
- case CANV_SCALE: {
+ }
+ case CANV_SCALE: {
double xOrigin, yOrigin, xScale, yScale;
if (objc != 7) {
@@ -1626,16 +1507,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
result = TCL_ERROR;
goto done;
}
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, objv[2], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[2], &searchPtr)) != TCL_OK) {
- goto done;
- }
- for (itemPtr = TagSearchFirst(searchPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(searchPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
(void) (*itemPtr->typePtr->scaleProc)((Tk_Canvas) canvasPtr,
itemPtr, xOrigin, yOrigin, xScale, yScale);
@@ -1643,9 +1515,9 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
canvasPtr->flags |= REPICK_NEEDED;
}
break;
- }
- case CANV_SCAN: {
- int x, y, gain=10;
+ }
+ case CANV_SCAN: {
+ int x, y, gain = 10;
static CONST char *optionStrings[] = {
"mark", "dragto", NULL
};
@@ -1687,8 +1559,8 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
CanvasSetOrigin(canvasPtr, newXOrigin, newYOrigin);
}
break;
- }
- case CANV_SELECT: {
+ }
+ case CANV_SELECT: {
int index, optionindex;
static CONST char *optionStrings[] = {
"adjust", "clear", "from", "item", "to", NULL
@@ -1703,16 +1575,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
goto done;
}
if (objc >= 4) {
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, objv[3], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[3], &searchPtr)) != TCL_OK) {
- goto done;
- }
- for (itemPtr = TagSearchFirst(searchPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(searchPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done) {
if ((itemPtr->typePtr->indexProc != NULL)
&& (itemPtr->typePtr->selectionProc != NULL)){
break;
@@ -1721,30 +1584,32 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
if (itemPtr == NULL) {
Tcl_AppendResult(interp,
"can't find an indexable and selectable item \"",
- Tcl_GetStringFromObj(objv[3], NULL), "\"", (char *) NULL);
+ Tcl_GetString(objv[3]), "\"", NULL);
result = TCL_ERROR;
goto done;
}
}
if (objc == 5) {
if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
- result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
- itemPtr, (char *) objv[4], &index);
+ result = itemPtr->typePtr->indexProc(interp,
+ (Tk_Canvas) canvasPtr, itemPtr, (char *) objv[4],
+ &index);
} else {
- result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
- itemPtr, Tcl_GetStringFromObj(objv[4], NULL), &index);
+ result = itemPtr->typePtr->indexProc(interp,
+ (Tk_Canvas) canvasPtr, itemPtr, Tcl_GetString(objv[4]),
+ &index);
}
if (result != TCL_OK) {
goto done;
}
}
- if (Tcl_GetIndexFromObj(interp, objv[2], optionStrings, "select option", 0,
- &optionindex) != TCL_OK) {
+ if (Tcl_GetIndexFromObj(interp, objv[2], optionStrings,
+ "select option", 0, &optionindex) != TCL_OK) {
result = TCL_ERROR;
goto done;
}
switch ((enum options) optionindex) {
- case CANV_ADJUST: {
+ case CANV_ADJUST:
if (objc != 5) {
Tcl_WrongNumArgs(interp, 3, objv, "tagOrId index");
result = TCL_ERROR;
@@ -1762,10 +1627,9 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
CanvasSelectTo(canvasPtr, itemPtr, index);
break;
- }
- case CANV_CLEAR: {
+ case CANV_CLEAR:
if (objc != 3) {
- Tcl_AppendResult(interp, 3, objv, (char *) NULL);
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
result = TCL_ERROR;
goto done;
}
@@ -1776,8 +1640,7 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
goto done;
break;
- }
- case CANV_FROM: {
+ case CANV_FROM:
if (objc != 5) {
Tcl_WrongNumArgs(interp, 3, objv, "tagOrId index");
result = TCL_ERROR;
@@ -1786,22 +1649,18 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
canvasPtr->textInfo.anchorItemPtr = itemPtr;
canvasPtr->textInfo.selectAnchor = index;
break;
- }
- case CANV_ITEM: {
+ case CANV_ITEM:
if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL);
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
result = TCL_ERROR;
goto done;
}
if (canvasPtr->textInfo.selItemPtr != NULL) {
- char buf[TCL_INTEGER_SPACE];
-
- sprintf(buf, "%d", canvasPtr->textInfo.selItemPtr->id);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ Tcl_SetObjResult(interp,
+ Tcl_NewIntObj(canvasPtr->textInfo.selItemPtr->id));
}
break;
- }
- case CANV_TO: {
+ case CANV_TO:
if (objc != 5) {
Tcl_WrongNumArgs(interp, 2, objv, "tagOrId index");
result = TCL_ERROR;
@@ -1809,30 +1668,21 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
}
CanvasSelectTo(canvasPtr, itemPtr, index);
break;
- }
}
break;
- }
- case CANV_TYPE: {
+ }
+ case CANV_TYPE:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "tag");
result = TCL_ERROR;
goto done;
}
-#ifdef USE_OLD_TAG_SEARCH
- itemPtr = StartTagSearch(canvasPtr, objv[2], &search);
-#else /* USE_OLD_TAG_SEARCH */
- if ((result = TagSearchScan(canvasPtr, objv[2], &searchPtr)) != TCL_OK) {
- goto done;
- }
- itemPtr = TagSearchFirst(searchPtr);
-#endif /* USE_OLD_TAG_SEARCH */
+ FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
if (itemPtr != NULL) {
Tcl_SetResult(interp, itemPtr->typePtr->name, TCL_STATIC);
}
break;
- }
- case CANV_XVIEW: {
+ case CANV_XVIEW: {
int count, type;
int newX = 0; /* Initialization needed only to prevent
* gcc warnings. */
@@ -1845,84 +1695,89 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
- canvasPtr->inset, canvasPtr->scrollX1,
canvasPtr->scrollX2));
} else {
- CONST char **args = GetStringsFromObjs(objc, objv);
+ CONST char **args = TkGetStringsFromObjs(objc, objv);
type = Tk_GetScrollInfo(interp, objc, args, &fraction, &count);
- if (args) ckfree((char *) args);
+ if (args != NULL) {
+ ckfree((char *) args);
+ }
switch (type) {
- case TK_SCROLL_ERROR:
- result = TCL_ERROR;
- goto done;
- case TK_SCROLL_MOVETO:
- newX = canvasPtr->scrollX1 - canvasPtr->inset
- + (int) (fraction * (canvasPtr->scrollX2
- - canvasPtr->scrollX1) + 0.5);
- break;
- case TK_SCROLL_PAGES:
- newX = (int) (canvasPtr->xOrigin + count * .9
- * (Tk_Width(canvasPtr->tkwin) - 2*canvasPtr->inset));
- break;
- case TK_SCROLL_UNITS:
- if (canvasPtr->xScrollIncrement > 0) {
- newX = canvasPtr->xOrigin
- + count*canvasPtr->xScrollIncrement;
- } else {
- newX = (int) (canvasPtr->xOrigin + count * .1
- * (Tk_Width(canvasPtr->tkwin)
- - 2*canvasPtr->inset));
- }
- break;
+ case TK_SCROLL_ERROR:
+ result = TCL_ERROR;
+ goto done;
+ case TK_SCROLL_MOVETO:
+ newX = canvasPtr->scrollX1 - canvasPtr->inset
+ + (int) (fraction * (canvasPtr->scrollX2
+ - canvasPtr->scrollX1) + 0.5);
+ break;
+ case TK_SCROLL_PAGES:
+ newX = (int) (canvasPtr->xOrigin + count * .9
+ * (Tk_Width(canvasPtr->tkwin) - 2*canvasPtr->inset));
+ break;
+ case TK_SCROLL_UNITS:
+ if (canvasPtr->xScrollIncrement > 0) {
+ newX = canvasPtr->xOrigin
+ + count*canvasPtr->xScrollIncrement;
+ } else {
+ newX = (int) (canvasPtr->xOrigin + count * .1
+ * (Tk_Width(canvasPtr->tkwin)
+ - 2*canvasPtr->inset));
+ }
+ break;
}
CanvasSetOrigin(canvasPtr, newX, canvasPtr->yOrigin);
}
break;
- }
- case CANV_YVIEW: {
+ }
+ case CANV_YVIEW: {
int count, type;
int newY = 0; /* Initialization needed only to prevent
* gcc warnings. */
double fraction;
if (objc == 2) {
- Tcl_SetObjResult(interp,ScrollFractions(\
+ Tcl_SetObjResult(interp, ScrollFractions(
canvasPtr->yOrigin + canvasPtr->inset,
canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin)
- - canvasPtr->inset, canvasPtr->scrollY1,
- canvasPtr->scrollY2));
+ - canvasPtr->inset,
+ canvasPtr->scrollY1, canvasPtr->scrollY2));
} else {
- CONST char **args = GetStringsFromObjs(objc, objv);
+ CONST char **args = TkGetStringsFromObjs(objc, objv);
type = Tk_GetScrollInfo(interp, objc, args, &fraction, &count);
- if (args) ckfree((char *) args);
+ if (args != NULL) {
+ ckfree((char *) args);
+ }
switch (type) {
- case TK_SCROLL_ERROR:
- result = TCL_ERROR;
- goto done;
- case TK_SCROLL_MOVETO:
- newY = canvasPtr->scrollY1 - canvasPtr->inset
- + (int) (fraction*(canvasPtr->scrollY2
- - canvasPtr->scrollY1) + 0.5);
- break;
- case TK_SCROLL_PAGES:
- newY = (int) (canvasPtr->yOrigin + count * .9
+ case TK_SCROLL_ERROR:
+ result = TCL_ERROR;
+ goto done;
+ case TK_SCROLL_MOVETO:
+ newY = canvasPtr->scrollY1 - canvasPtr->inset
+ + (int) (fraction*(canvasPtr->scrollY2
+ - canvasPtr->scrollY1) + 0.5);
+ break;
+ case TK_SCROLL_PAGES:
+ newY = (int) (canvasPtr->yOrigin + count * .9
+ * (Tk_Height(canvasPtr->tkwin)
+ - 2*canvasPtr->inset));
+ break;
+ case TK_SCROLL_UNITS:
+ if (canvasPtr->yScrollIncrement > 0) {
+ newY = canvasPtr->yOrigin
+ + count*canvasPtr->yScrollIncrement;
+ } else {
+ newY = (int) (canvasPtr->yOrigin + count * .1
* (Tk_Height(canvasPtr->tkwin)
- 2*canvasPtr->inset));
- break;
- case TK_SCROLL_UNITS:
- if (canvasPtr->yScrollIncrement > 0) {
- newY = canvasPtr->yOrigin
- + count*canvasPtr->yScrollIncrement;
- } else {
- newY = (int) (canvasPtr->yOrigin + count * .1
- * (Tk_Height(canvasPtr->tkwin)
- - 2*canvasPtr->inset));
- }
- break;
+ }
+ break;
}
CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, newY);
}
break;
- }
}
- done:
+ }
+
+ done:
#ifndef USE_OLD_TAG_SEARCH
TagSearchDestroy(searchPtr);
#endif /* not USE_OLD_TAG_SEARCH */
@@ -1935,9 +1790,9 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
*
* DestroyCanvas --
*
- * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release
- * to clean up the internal structure of a canvas at a safe time
- * (when no-one is using it anymore).
+ * This function is invoked by Tcl_EventuallyFree or Tcl_Release to clean
+ * up the internal structure of a canvas at a safe time (when no-one is
+ * using it anymore).
*
* Results:
* None.
@@ -1949,8 +1804,8 @@ CanvasWidgetCmd(clientData, interp, objc, objv)
*/
static void
-DestroyCanvas(memPtr)
- char *memPtr; /* Info about canvas widget. */
+DestroyCanvas(
+ char *memPtr) /* Info about canvas widget. */
{
TkCanvas *canvasPtr = (TkCanvas *) memPtr;
Tk_Item *itemPtr;
@@ -1974,9 +1829,8 @@ DestroyCanvas(memPtr)
}
/*
- * Free up all the stuff that requires special handling,
- * then let Tk_FreeOptions handle all the standard option-related
- * stuff.
+ * Free up all the stuff that requires special handling, then let
+ * Tk_FreeOptions handle all the standard option-related stuff.
*/
Tcl_DeleteHashTable(&canvasPtr->idTable);
@@ -1990,7 +1844,7 @@ DestroyCanvas(memPtr)
TagSearchExprDestroy(expr);
expr = next;
}
-#endif
+#endif /* USE_OLD_TAG_SEARCH */
Tcl_DeleteTimerHandler(canvasPtr->insertBlinkHandler);
if (canvasPtr->bindingTable != NULL) {
Tk_DeleteBindingTable(canvasPtr->bindingTable);
@@ -2005,33 +1859,33 @@ DestroyCanvas(memPtr)
*
* ConfigureCanvas --
*
- * This procedure is called to process an objv/objc list, plus
- * the Tk option database, in order to configure (or
- * reconfigure) a canvas widget.
+ * This function is called to process an objv/objc list, plus the Tk
+ * option database, in order to configure (or reconfigure) a canvas
+ * widget.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message.
+ * 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 colors, border width,
- * etc. get set for canvasPtr; old resources get freed,
- * if there were any.
+ * Configuration information, such as colors, border width, etc. get set
+ * for canvasPtr; old resources get freed, if there were any.
*
*----------------------------------------------------------------------
*/
static int
-ConfigureCanvas(interp, canvasPtr, objc, objv, flags)
- Tcl_Interp *interp; /* Used for error reporting. */
- TkCanvas *canvasPtr; /* 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[]; /* Argument objects. */
- int flags; /* Flags to pass to Tk_ConfigureWidget. */
+ConfigureCanvas(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ TkCanvas *canvasPtr, /* 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[], /* Argument objects. */
+ int flags) /* Flags to pass to Tk_ConfigureWidget. */
{
XGCValues gcValues;
- GC new;
+ GC newGC;
+ Tk_State old_canvas_state=canvasPtr->canvas_state;
if (Tk_ConfigureWidget(interp, canvasPtr->tkwin, configSpecs,
objc, (CONST char **) objv, (char *) canvasPtr,
@@ -2040,9 +1894,8 @@ ConfigureCanvas(interp, canvasPtr, objc, objv, flags)
}
/*
- * A few options need special processing, such as setting the
- * background from a 3-D border and creating a GC for copying
- * bits to the screen.
+ * A few options need special processing, such as setting the background
+ * from a 3-D border and creating a GC for copying bits to the screen.
*/
Tk_SetBackgroundFromBorder(canvasPtr->tkwin, canvasPtr->bgBorder);
@@ -2055,12 +1908,33 @@ ConfigureCanvas(interp, canvasPtr, objc, objv, flags)
gcValues.function = GXcopy;
gcValues.graphics_exposures = False;
gcValues.foreground = Tk_3DBorderColor(canvasPtr->bgBorder)->pixel;
- new = Tk_GetGC(canvasPtr->tkwin,
+ newGC = Tk_GetGC(canvasPtr->tkwin,
GCFunction|GCGraphicsExposures|GCForeground, &gcValues);
if (canvasPtr->pixmapGC != None) {
Tk_FreeGC(canvasPtr->display, canvasPtr->pixmapGC);
}
- canvasPtr->pixmapGC = new;
+ canvasPtr->pixmapGC = newGC;
+
+ /*
+ * Reconfigure items to reflect changed state disabled/normal.
+ */
+
+ if ( old_canvas_state != canvasPtr->canvas_state ) {
+ Tk_Item *itemPtr;
+ int result;
+
+ for ( itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
+ itemPtr = itemPtr->nextPtr) {
+ if ( itemPtr->state == TK_STATE_NULL ) {
+ result = (*itemPtr->typePtr->configProc)(canvasPtr->interp,
+ (Tk_Canvas) canvasPtr, itemPtr, 0, NULL,
+ TK_CONFIG_ARGV_ONLY);
+ if (result != TCL_OK) {
+ Tcl_ResetResult(canvasPtr->interp);
+ }
+ }
+ }
+ }
/*
* Reset the desired dimensions for the window.
@@ -2070,8 +1944,8 @@ ConfigureCanvas(interp, canvasPtr, objc, objv, flags)
canvasPtr->height + 2*canvasPtr->inset);
/*
- * Restart the cursor timing sequence in case the on-time or off-time
- * just changed.
+ * Restart the cursor timing sequence in case the on-time or off-time just
+ * changed.
*/
if (canvasPtr->textInfo.gotFocus) {
@@ -2096,7 +1970,7 @@ ConfigureCanvas(interp, canvasPtr, objc, objv, flags)
}
if (argc2 != 4) {
Tcl_AppendResult(interp, "bad scrollRegion \"",
- canvasPtr->regionString, "\"", (char *) NULL);
+ canvasPtr->regionString, "\"", NULL);
badRegion:
ckfree(canvasPtr->regionString);
ckfree((char *) argv2);
@@ -2133,8 +2007,8 @@ ConfigureCanvas(interp, canvasPtr, objc, objv, flags)
}
/*
- * Reset the canvas's origin (this is a no-op unless confine
- * mode has just been turned on or the scroll region has changed).
+ * Reset the canvas's origin (this is a no-op unless confine mode has just
+ * been turned on or the scroll region has changed).
*/
CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, canvasPtr->yOrigin);
@@ -2151,24 +2025,24 @@ ConfigureCanvas(interp, canvasPtr, objc, objv, flags)
*
* CanvasWorldChanged --
*
- * This procedure is called when the world has changed in some
- * way and the widget needs to recompute all its graphics contexts
- * and determine its new geometry.
+ * This function is called when the world has changed in some way and the
+ * widget needs to recompute all its graphics contexts and determine its
+ * new geometry.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Configures all items in the canvas with a empty argc/argv, for
- * the side effect of causing all the items to recompute their
- * geometry and to be redisplayed.
+ * Configures all items in the canvas with a empty argc/argv, for the
+ * side effect of causing all the items to recompute their geometry and
+ * to be redisplayed.
*
*---------------------------------------------------------------------------
*/
-
+
static void
-CanvasWorldChanged(instanceData)
- ClientData instanceData; /* Information about widget. */
+CanvasWorldChanged(
+ ClientData instanceData) /* Information about widget. */
{
TkCanvas *canvasPtr;
Tk_Item *itemPtr;
@@ -2196,9 +2070,9 @@ CanvasWorldChanged(instanceData)
*
* DisplayCanvas --
*
- * This procedure redraws the contents of a canvas window.
- * It is invoked as a do-when-idle handler, so it only runs
- * when there's nothing else for the application to do.
+ * This function redraws the contents of a canvas window. It is invoked
+ * as a do-when-idle handler, so it only runs when there's nothing else
+ * for the application to do.
*
* Results:
* None.
@@ -2210,8 +2084,8 @@ CanvasWorldChanged(instanceData)
*/
static void
-DisplayCanvas(clientData)
- ClientData clientData; /* Information about widget. */
+DisplayCanvas(
+ ClientData clientData) /* Information about widget. */
{
TkCanvas *canvasPtr = (TkCanvas *) clientData;
Tk_Window tkwin = canvasPtr->tkwin;
@@ -2228,8 +2102,8 @@ DisplayCanvas(clientData)
}
/*
- * Choose a new current item if that is needed (this could cause
- * event handlers to be invoked).
+ * Choose a new current item if that is needed (this could cause event
+ * handlers to be invoked).
*/
while (canvasPtr->flags & REPICK_NEEDED) {
@@ -2244,9 +2118,9 @@ DisplayCanvas(clientData)
}
/*
- * Scan through the item list, registering the bounding box
- * for all items that didn't do that for the final coordinates
- * yet. This can be determined by the FORCE_REDRAW flag.
+ * Scan through the item list, registering the bounding box for all items
+ * that didn't do that for the final coordinates yet. This can be
+ * determined by the FORCE_REDRAW flag.
*/
for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
@@ -2258,8 +2132,8 @@ DisplayCanvas(clientData)
}
}
/*
- * Compute the intersection between the area that needs redrawing
- * and the area that's visible on the screen.
+ * Compute the intersection between the area that needs redrawing and the
+ * area that's visible on the screen.
*/
if ((canvasPtr->redrawX1 < canvasPtr->redrawX2)
@@ -2283,43 +2157,39 @@ DisplayCanvas(clientData)
if ((screenX1 >= screenX2) || (screenY1 >= screenY2)) {
goto borders;
}
-
+
width = screenX2 - screenX1;
height = screenY2 - screenY1;
#ifndef TK_NO_DOUBLE_BUFFERING
/*
- * Redrawing is done in a temporary pixmap that is allocated
- * here and freed at the end of the procedure. All drawing
- * is done to the pixmap, and the pixmap is copied to the
- * screen at the end of the procedure. The temporary pixmap
- * serves two purposes:
+ * Redrawing is done in a temporary pixmap that is allocated here and
+ * freed at the end of the function. All drawing is done to the
+ * pixmap, and the pixmap is copied to the screen at the end of the
+ * function. The temporary pixmap serves two purposes:
*
- * 1. It provides a smoother visual effect (no clearing and
- * gradual redraw will be visible to users).
- * 2. It allows us to redraw only the objects that overlap
- * the redraw area. Otherwise incorrect results could
- * occur from redrawing things that stick outside of
- * the redraw area (we'd have to redraw everything in
- * order to make the overlaps look right).
+ * 1. It provides a smoother visual effect (no clearing and gradual
+ * redraw will be visible to users).
+ * 2. It allows us to redraw only the objects that overlap the redraw
+ * area. Otherwise incorrect results could occur from redrawing
+ * things that stick outside of the redraw area (we'd have to
+ * redraw everything in order to make the overlaps look right).
*
* Some tricky points about the pixmap:
*
- * 1. We only allocate a large enough pixmap to hold the
- * area that has to be redisplayed. This saves time in
- * in the X server for large objects that cover much
- * more than the area being redisplayed: only the area
- * of the pixmap will actually have to be redrawn.
- * 2. Some X servers (e.g. the one for DECstations) have troubles
- * with characters that overlap an edge of the pixmap (on the
- * DEC servers, as of 8/18/92, such characters are drawn one
- * pixel too far to the right). To handle this problem,
- * make the pixmap a bit larger than is absolutely needed
- * so that for normal-sized fonts the characters that overlap
- * the edge of the pixmap will be outside the area we care
- * about.
+ * 1. We only allocate a large enough pixmap to hold the area that has
+ * to be redisplayed. This saves time in in the X server for large
+ * objects that cover much more than the area being redisplayed:
+ * only the area of the pixmap will actually have to be redrawn.
+ * 2. Some X servers (e.g. the one for DECstations) have troubles with
+ * with characters that overlap an edge of the pixmap (on the DEC
+ * servers, as of 8/18/92, such characters are drawn one pixel too
+ * far to the right). To handle this problem, make the pixmap a bit
+ * larger than is absolutely needed so that for normal-sized fonts
+ * the characters that overlap the edge of the pixmap will be
+ * outside the area we care about.
*/
-
+
canvasPtr->drawableXOrigin = screenX1 - 30;
canvasPtr->drawableYOrigin = screenY1 - 30;
pixmap = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin),
@@ -2334,24 +2204,24 @@ DisplayCanvas(clientData)
screenX1 - canvasPtr->xOrigin, screenY1 - canvasPtr->yOrigin,
width, height);
#endif /* TK_NO_DOUBLE_BUFFERING */
-
+
/*
* Clear the area to be redrawn.
*/
-
+
XFillRectangle(Tk_Display(tkwin), pixmap, canvasPtr->pixmapGC,
screenX1 - canvasPtr->drawableXOrigin,
screenY1 - canvasPtr->drawableYOrigin, (unsigned int) width,
(unsigned int) height);
-
+
/*
- * Scan through the item list, redrawing those items that need it.
- * An item must be redraw if either (a) it intersects the smaller
+ * Scan through the item list, redrawing those items that need it. An
+ * item must be redraw if either (a) it intersects the smaller
* on-screen area or (b) it intersects the full canvas area and its
- * type requests that it be redrawn always (e.g. so subwindows can
- * be unmapped when they move off-screen).
+ * type requests that it be redrawn always (e.g. so subwindows can be
+ * unmapped when they move off-screen).
*/
-
+
for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
itemPtr = itemPtr->nextPtr) {
if ((itemPtr->x1 >= screenX2)
@@ -2375,13 +2245,13 @@ DisplayCanvas(clientData)
canvasPtr->display, pixmap, screenX1, screenY1, width,
height);
}
-
+
#ifndef TK_NO_DOUBLE_BUFFERING
/*
- * Copy from the temporary pixmap to the screen, then free up
- * the temporary pixmap.
+ * Copy from the temporary pixmap to the screen, then free up the
+ * temporary pixmap.
*/
-
+
XCopyArea(Tk_Display(tkwin), pixmap, Tk_WindowId(tkwin),
canvasPtr->pixmapGC,
screenX1 - canvasPtr->drawableXOrigin,
@@ -2398,7 +2268,7 @@ DisplayCanvas(clientData)
* Draw the window borders, if needed.
*/
- borders:
+ borders:
if (canvasPtr->flags & REDRAW_BORDERS) {
canvasPtr->flags &= ~REDRAW_BORDERS;
if (canvasPtr->borderWidth > 0) {
@@ -2426,7 +2296,7 @@ DisplayCanvas(clientData)
}
}
- done:
+ done:
canvasPtr->flags &= ~(REDRAW_PENDING|BBOX_NOT_EMPTY);
canvasPtr->redrawX1 = canvasPtr->redrawX2 = 0;
canvasPtr->redrawY1 = canvasPtr->redrawY2 = 0;
@@ -2440,23 +2310,23 @@ DisplayCanvas(clientData)
*
* CanvasEventProc --
*
- * This procedure is invoked by the Tk dispatcher for various
- * events on canvases.
+ * This function is invoked by the Tk dispatcher for various events on
+ * canvases.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up.
+ * When it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-CanvasEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- XEvent *eventPtr; /* Information about event. */
+CanvasEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
TkCanvas *canvasPtr = (TkCanvas *) clientData;
@@ -2491,8 +2361,8 @@ CanvasEventProc(clientData, eventPtr)
canvasPtr->flags |= UPDATE_SCROLLBARS;
/*
- * The call below is needed in order to recenter the canvas if
- * it's confined and its scroll region is smaller than the window.
+ * The call below is needed in order to recenter the canvas if it's
+ * confined and its scroll region is smaller than the window.
*/
CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, canvasPtr->yOrigin);
@@ -2513,9 +2383,9 @@ CanvasEventProc(clientData, eventPtr)
Tk_Item *itemPtr;
/*
- * Special hack: if the canvas is unmapped, then must notify
- * all items with "alwaysRedraw" set, so that they know that
- * they are no longer displayed.
+ * Special hack: if the canvas is unmapped, then must notify all items
+ * with "alwaysRedraw" set, so that they know that they are no longer
+ * displayed.
*/
for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
@@ -2533,9 +2403,9 @@ CanvasEventProc(clientData, eventPtr)
*
* CanvasCmdDeletedProc --
*
- * 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.
+ * This function 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.
@@ -2547,17 +2417,17 @@ CanvasEventProc(clientData, eventPtr)
*/
static void
-CanvasCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+CanvasCmdDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
TkCanvas *canvasPtr = (TkCanvas *) clientData;
Tk_Window tkwin = canvasPtr->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.
+ * This function 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 function destroys the
+ * widget.
*/
if (tkwin != NULL) {
@@ -2571,8 +2441,8 @@ CanvasCmdDeletedProc(clientData)
*
* Tk_CanvasEventuallyRedraw --
*
- * Arrange for part or all of a canvas widget to redrawn at
- * some convenient time in the future.
+ * Arrange for part or all of a canvas widget to redrawn at some
+ * convenient time in the future.
*
* Results:
* None.
@@ -2584,18 +2454,20 @@ CanvasCmdDeletedProc(clientData)
*/
void
-Tk_CanvasEventuallyRedraw(canvas, x1, y1, x2, y2)
- Tk_Canvas canvas; /* Information about widget. */
- int x1, y1; /* Upper left corner of area to redraw.
- * Pixels on edge are redrawn. */
- int x2, y2; /* Lower right corner of area to redraw.
+Tk_CanvasEventuallyRedraw(
+ Tk_Canvas canvas, /* Information about widget. */
+ int x1, int y1, /* Upper left corner of area to redraw. Pixels
+ * on edge are redrawn. */
+ int x2, int y2) /* Lower right corner of area to redraw.
* Pixels on edge are not redrawn. */
{
TkCanvas *canvasPtr = (TkCanvas *) canvas;
+
/*
* If tkwin is NULL, the canvas has been destroyed, so we can't really
* redraw it.
*/
+
if (canvasPtr->tkwin == NULL) {
return;
}
@@ -2637,8 +2509,8 @@ Tk_CanvasEventuallyRedraw(canvas, x1, y1, x2, y2)
*
* EventuallyRedrawItem --
*
- * Arrange for part or all of a canvas widget to redrawn at
- * some convenient time in the future.
+ * Arrange for part or all of a canvas widget to redrawn at some
+ * convenient time in the future.
*
* Results:
* None.
@@ -2650,9 +2522,9 @@ Tk_CanvasEventuallyRedraw(canvas, x1, y1, x2, y2)
*/
static void
-EventuallyRedrawItem(canvas, itemPtr)
- Tk_Canvas canvas; /* Information about widget. */
- Tk_Item *itemPtr; /* item to be redrawn. */
+EventuallyRedrawItem(
+ Tk_Canvas canvas, /* Information about widget. */
+ Tk_Item *itemPtr) /* Item to be redrawn. */
{
TkCanvas *canvasPtr = (TkCanvas *) canvas;
if ((itemPtr->x1 >= itemPtr->x2) || (itemPtr->y1 >= itemPtr->y2) ||
@@ -2698,27 +2570,26 @@ EventuallyRedrawItem(canvas, itemPtr)
*
* Tk_CreateItemType --
*
- * This procedure may be invoked to add a new kind of canvas
- * element to the core item types supported by Tk.
+ * This function may be invoked to add a new kind of canvas element to
+ * the core item types supported by Tk.
*
* Results:
* None.
*
* Side effects:
- * From now on, the new item type will be useable in canvas
- * widgets (e.g. typePtr->name can be used as the item type
- * in "create" widget commands). If there was already a
- * type with the same name as in typePtr, it is replaced with
- * the new type.
+ * From now on, the new item type will be useable in canvas widgets
+ * (e.g. typePtr->name can be used as the item type in "create" widget
+ * commands). If there was already a type with the same name as in
+ * typePtr, it is replaced with the new type.
*
*--------------------------------------------------------------
*/
void
-Tk_CreateItemType(typePtr)
- Tk_ItemType *typePtr; /* Information about item type;
- * storage must be statically
- * allocated (must live forever). */
+Tk_CreateItemType(
+ Tk_ItemType *typePtr) /* Information about item type; storage must
+ * be statically allocated (must live
+ * forever). */
{
Tk_ItemType *typePtr2, *prevPtr;
@@ -2752,14 +2623,14 @@ Tk_CreateItemType(typePtr)
*
* Tk_GetItemTypes --
*
- * This procedure returns a pointer to the list of all item
- * types. Note that this is inherently thread-unsafe, but since
- * item types are only ever registered very rarely this is
- * unlikely to be a problem in practice.
+ * This function returns a pointer to the list of all item types. Note
+ * that this is inherently thread-unsafe, but since item types are only
+ * ever registered very rarely this is unlikely to be a problem in
+ * practice.
*
* Results:
- * The return value is a pointer to the first in the list
- * of item types currently supported by canvases.
+ * The return value is a pointer to the first in the list of item types
+ * currently supported by canvases.
*
* Side effects:
* None.
@@ -2768,7 +2639,7 @@ Tk_CreateItemType(typePtr)
*/
Tk_ItemType *
-Tk_GetItemTypes()
+Tk_GetItemTypes(void)
{
if (typeList == NULL) {
InitCanvas();
@@ -2777,13 +2648,12 @@ Tk_GetItemTypes()
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* InitCanvas --
*
- * This procedure is invoked to perform once-only-ever
- * initialization for the module, such as setting up the type
- * table.
+ * This function is invoked to perform once-only-ever initialization for
+ * the module, such as setting up the type table.
*
* Results:
* None.
@@ -2791,11 +2661,11 @@ Tk_GetItemTypes()
* Side effects:
* None.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static void
-InitCanvas()
+InitCanvas(void)
{
Tcl_MutexLock(&typeListMutex);
if (typeList != NULL) {
@@ -2821,33 +2691,30 @@ InitCanvas()
*
* StartTagSearch --
*
- * This procedure is called to initiate an enumeration of
- * all items in a given canvas that contain a given tag.
+ * This function is called to initiate an enumeration of all items in a
+ * given canvas that contain a given tag.
*
* Results:
- * The return value is a pointer to the first item in
- * canvasPtr that matches tag, or NULL if there is no
- * such item. The information at *searchPtr is initialized
- * such that successive calls to NextItem will return
- * successive items that match tag.
+ * The return value is a pointer to the first item in canvasPtr that
+ * matches tag, or NULL if there is no such item. The information at
+ * *searchPtr is initialized such that successive calls to NextItem will
+ * return successive items that match tag.
*
* Side effects:
- * SearchPtr is linked into a list of searches in progress
- * on canvasPtr, so that elements can safely be deleted
- * while the search is in progress. EndTagSearch must be
- * called at the end of the search to unlink searchPtr from
- * this list.
+ * SearchPtr is linked into a list of searches in progress on canvasPtr,
+ * so that elements can safely be deleted while the search is in
+ * progress. EndTagSearch must be called at the end of the search to
+ * unlink searchPtr from this list.
*
*--------------------------------------------------------------
*/
static Tk_Item *
-StartTagSearch(canvasPtr, tagObj, searchPtr)
- TkCanvas *canvasPtr; /* Canvas whose items are to be
- * searched. */
- Tcl_Obj *tagObj; /* Object giving tag value. */
- TagSearch *searchPtr; /* Record describing tag search;
- * will be initialized here. */
+StartTagSearch(
+ TkCanvas *canvasPtr, /* Canvas whose items are to be searched. */
+ Tcl_Obj *tagObj, /* Object giving tag value. */
+ TagSearch *searchPtr) /* Record describing tag search; will be
+ * initialized here. */
{
int id;
Tk_Item *itemPtr, *lastPtr;
@@ -2869,10 +2736,10 @@ StartTagSearch(canvasPtr, tagObj, searchPtr)
searchPtr->searchOver = 0;
/*
- * Find the first matching item in one of several ways. If the tag
- * is a number then it selects the single item with the matching
- * identifier. In this case see if the item being requested is the
- * hot item, in which case the search can be skipped.
+ * Find the first matching item in one of several ways. If the tag is a
+ * number then it selects the single item with the matching identifier.
+ * In this case see if the item being requested is the hot item, in which
+ * case the search can be skipped.
*/
if (isdigit(UCHAR(*tag))) {
@@ -2883,7 +2750,7 @@ StartTagSearch(canvasPtr, tagObj, searchPtr)
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)) {
dispPtr->numSlowSearches++;
@@ -2916,7 +2783,7 @@ StartTagSearch(canvasPtr, tagObj, searchPtr)
}
/*
- * None of the above. Search for an item with a matching tag.
+ * None of the above. Search for an item with a matching tag.
*/
for (lastPtr = NULL, itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
@@ -2940,15 +2807,15 @@ StartTagSearch(canvasPtr, tagObj, searchPtr)
*
* NextItem --
*
- * This procedure returns successive items that match a given
- * tag; it should be called only after StartTagSearch has been
- * used to begin a search.
+ * This function returns successive items that match a given tag; it
+ * should be called only after StartTagSearch has been used to begin a
+ * search.
*
* Results:
- * The return value is a pointer to the next item that matches
- * the tag specified to StartTagSearch, or NULL if no such
- * item exists. *SearchPtr is updated so that the next call
- * to this procedure will return the next item.
+ * The return value is a pointer to the next item that matches the tag
+ * specified to StartTagSearch, or NULL if no such item exists.
+ * *SearchPtr is updated so that the next call to this function will
+ * return the next item.
*
* Side effects:
* None.
@@ -2957,9 +2824,8 @@ StartTagSearch(canvasPtr, tagObj, searchPtr)
*/
static Tk_Item *
-NextItem(searchPtr)
- TagSearch *searchPtr; /* Record describing search in
- * progress. */
+NextItem(
+ TagSearch *searchPtr) /* Record describing search in progress. */
{
Tk_Item *itemPtr, *lastPtr;
int count;
@@ -2967,8 +2833,8 @@ NextItem(searchPtr)
Tk_Uid *tagPtr;
/*
- * Find next item in list (this may not actually be a suitable
- * one to return), and return if there are no items left.
+ * Find next item in list (this may not actually be a suitable one to
+ * return), and return if there are no items left.
*/
lastPtr = searchPtr->lastPtr;
@@ -2983,10 +2849,10 @@ NextItem(searchPtr)
}
if (itemPtr != searchPtr->currentPtr) {
/*
- * The structure of the list has changed. Probably the
- * previously-returned item was removed from the list.
- * In this case, don't advance lastPtr; just return
- * its new successor (i.e. do nothing here).
+ * The structure of the list has changed. Probably the previously-
+ * returned item was removed from the list. In this case, don't
+ * advance lastPtr; just return its new successor (i.e. do nothing
+ * here).
*/
} else {
lastPtr = itemPtr;
@@ -3023,29 +2889,28 @@ NextItem(searchPtr)
return NULL;
}
-#else /* USE_OLD_TAG_SEARCH */
+#else /* !USE_OLD_TAG_SEARCH */
/*
*----------------------------------------------------------------------
*
* GetStaticUids --
*
- *This procedure is invoked to return a structure filled with
- *the Uids used when doing tag searching. If it was never before
- *called in the current thread, it initializes the structure for
- *that thread (uids are only ever local to one thread [Bug
- *1114977]).
+ * This function is invoked to return a structure filled with the Uids
+ * used when doing tag searching. If it was never before called in the
+ * current thread, it initializes the structure for that thread (uids are
+ * only ever local to one thread [Bug 1114977]).
*
* Results:
- *None.
+ * None.
*
* Side effects:
- *None.
+ * None.
*
*----------------------------------------------------------------------
*/
static SearchUids *
-GetStaticUids()
+GetStaticUids(void)
{
SearchUids *searchUids = (SearchUids *)
Tcl_GetThreadData(&dataKey, sizeof(SearchUids));
@@ -3070,7 +2935,7 @@ GetStaticUids()
*
* TagSearchExprInit --
*
- * This procedure allocates and initializes one TagSearchExpr struct.
+ * This function allocates and initializes one TagSearchExpr struct.
*
* Results:
*
@@ -3080,8 +2945,8 @@ GetStaticUids()
*/
static void
-TagSearchExprInit(exprPtrPtr)
- TagSearchExpr **exprPtrPtr;
+TagSearchExprInit(
+ TagSearchExpr **exprPtrPtr)
{
TagSearchExpr* expr = *exprPtrPtr;
@@ -3096,67 +2961,63 @@ TagSearchExprInit(exprPtrPtr)
expr->length = 0;
*exprPtrPtr = expr;
}
-
+
/*
*--------------------------------------------------------------
*
* TagSearchExprDestroy --
*
- * This procedure destroys one TagSearchExpr structure.
+ * This function destroys one TagSearchExpr structure.
*
* Results:
*
* Side effects:
*
*--------------------------------------------------------------
- */
+ */
static void
-TagSearchExprDestroy(expr)
- TagSearchExpr *expr;
+TagSearchExprDestroy(
+ TagSearchExpr *expr)
{
if (expr) {
if (expr->uids) {
- ckfree((char *)expr->uids);
+ ckfree((char *)expr->uids);
}
- ckfree((char *)expr);
+ ckfree((char *)expr);
}
}
-
+
/*
*--------------------------------------------------------------
*
* TagSearchScan --
*
- * This procedure is called to initiate an enumeration of
- * all items in a given canvas that contain a tag that matches
- * the tagOrId expression.
+ * This function is called to initiate an enumeration of all items in a
+ * given canvas that contain a tag that matches the tagOrId expression.
*
* Results:
- * The return value indicates if the tagOrId expression
- * was successfully scanned (syntax).
- * The information at *searchPtr is initialized
- * such that a call to TagSearchFirst, followed by
- * successive calls to TagSearchNext will return items
- * that match tag.
+ * The return value indicates if the tagOrId expression was successfully
+ * scanned (syntax). The information at *searchPtr is initialized such
+ * that a call to TagSearchFirst, followed by successive calls to
+ * TagSearchNext will return items that match tag.
*
* Side effects:
- * SearchPtr is linked into a list of searches in progress
- * on canvasPtr, so that elements can safely be deleted
- * while the search is in progress.
+ * SearchPtr is linked into a list of searches in progress on canvasPtr,
+ * so that elements can safely be deleted while the search is in
+ * progress.
*
*--------------------------------------------------------------
*/
static int
-TagSearchScan(canvasPtr, tagObj, searchPtrPtr)
- TkCanvas *canvasPtr; /* Canvas whose items are to be
- * searched. */
- Tcl_Obj *tagObj; /* Object giving tag value. */
- TagSearch **searchPtrPtr; /* Record describing tag search;
- * will be initialized here. */
+TagSearchScan(
+ TkCanvas *canvasPtr, /* Canvas whose items are to be searched. */
+ Tcl_Obj *tagObj, /* Object giving tag value. */
+ TagSearch **searchPtrPtr) /* Record describing tag search; will be
+ * initialized here. */
{
- char *tag = Tcl_GetStringFromObj(tagObj,NULL);
+ char *tag = Tcl_GetString(tagObj);
int i;
TagSearch *searchPtr;
@@ -3165,61 +3026,78 @@ TagSearchScan(canvasPtr, tagObj, searchPtrPtr)
*/
if (*searchPtrPtr) {
- searchPtr = *searchPtrPtr;
+ searchPtr = *searchPtrPtr;
} else {
- /* Allocate primary search struct on first call */
- *searchPtrPtr = searchPtr = (TagSearch *) ckalloc(sizeof(TagSearch));
+ /*
+ * Allocate primary search struct on first call.
+ */
+
+ *searchPtrPtr = searchPtr = (TagSearch *) ckalloc(sizeof(TagSearch));
searchPtr->expr = NULL;
- /* Allocate buffer for rewritten tags (after de-escaping) */
- searchPtr->rewritebufferAllocated = 100;
- searchPtr->rewritebuffer =
- ckalloc(searchPtr->rewritebufferAllocated);
+ /*
+ * Allocate buffer for rewritten tags (after de-escaping).
+ */
+
+ searchPtr->rewritebufferAllocated = 100;
+ searchPtr->rewritebuffer = ckalloc(searchPtr->rewritebufferAllocated);
}
TagSearchExprInit(&(searchPtr->expr));
- /* How long is the tagOrId ? */
+ /*
+ * How long is the tagOrId?
+ */
+
searchPtr->stringLength = strlen(tag);
- /* Make sure there is enough buffer to hold rewritten tags */
+ /*
+ * Make sure there is enough buffer to hold rewritten tags.
+ */
+
if ((unsigned int)searchPtr->stringLength >=
searchPtr->rewritebufferAllocated) {
- searchPtr->rewritebufferAllocated = searchPtr->stringLength + 100;
- searchPtr->rewritebuffer =
- ckrealloc(searchPtr->rewritebuffer,
- searchPtr->rewritebufferAllocated);
+ searchPtr->rewritebufferAllocated = searchPtr->stringLength + 100;
+ searchPtr->rewritebuffer =
+ ckrealloc(searchPtr->rewritebuffer,
+ searchPtr->rewritebufferAllocated);
}
- /* Initialize search */
+ /*
+ * Initialize search.
+ */
+
searchPtr->canvasPtr = canvasPtr;
searchPtr->searchOver = 0;
- searchPtr->type = 0;
+ searchPtr->type = SEARCH_TYPE_EMPTY;
/*
- * Find the first matching item in one of several ways. If the tag
- * is a number then it selects the single item with the matching
- * identifier. In this case see if the item being requested is the
- * hot item, in which case the search can be skipped.
+ * Find the first matching item in one of several ways. If the tag is a
+ * number then it selects the single item with the matching identifier.
+ * In this case see if the item being requested is the hot item, in which
+ * case the search can be skipped.
*/
if (searchPtr->stringLength && isdigit(UCHAR(*tag))) {
- char *end;
+ char *end;
- searchPtr->id = strtoul(tag, &end, 0);
- if (*end == 0) {
- searchPtr->type = 1;
- return TCL_OK;
+ searchPtr->id = strtoul(tag, &end, 0);
+ if (*end == 0) {
+ searchPtr->type = SEARCH_TYPE_ID;
+ return TCL_OK;
}
}
/*
- * For all other tags and tag expressions convert to a UID.
- * This UID is kept forever, but this should be thought of
- * as a cache rather than as a memory leak.
+ * For all other tags and tag expressions convert to a UID. This UID is
+ * kept forever, but this should be thought of as a cache rather than as a
+ * memory leak.
*/
searchPtr->expr->uid = Tk_GetUid(tag);
- /* short circuit impossible searches for null tags */
+ /*
+ * Short circuit impossible searches for null tags.
+ */
+
if (searchPtr->stringLength == 0) {
return TCL_OK;
}
@@ -3228,55 +3106,58 @@ TagSearchScan(canvasPtr, tagObj, searchPtrPtr)
* Pre-scan tag for at least one unquoted "&&" "||" "^" "!"
* if not found then use string as simple tag
*/
+
for (i = 0; i < searchPtr->stringLength ; i++) {
- if (tag[i] == '"') {
- i++;
- for ( ; i < searchPtr->stringLength; i++) {
- if (tag[i] == '\\') {
- i++;
- continue;
- }
- if (tag[i] == '"') {
- break;
- }
- }
- } else {
- if ((tag[i] == '&' && tag[i+1] == '&')
- || (tag[i] == '|' && tag[i+1] == '|')
- || (tag[i] == '^')
- || (tag[i] == '!')) {
- searchPtr->type = 4;
- break;
- }
- }
+ if (tag[i] == '"') {
+ i++;
+ for ( ; i < searchPtr->stringLength; i++) {
+ if (tag[i] == '\\') {
+ i++;
+ continue;
+ }
+ if (tag[i] == '"') {
+ break;
+ }
+ }
+ } else if ((tag[i] == '&' && tag[i+1] == '&')
+ || (tag[i] == '|' && tag[i+1] == '|')
+ || (tag[i] == '^')
+ || (tag[i] == '!')) {
+ searchPtr->type = SEARCH_TYPE_EXPR;
+ break;
+ }
}
searchPtr->string = tag;
searchPtr->stringIndex = 0;
- if (searchPtr->type == 4) {
- /*
- * an operator was found in the prescan, so
- * now compile the tag expression into array of Tk_Uid
- * flagging any syntax errors found
- */
- if (TagSearchScanExpr(canvasPtr->interp, searchPtr, searchPtr->expr) != TCL_OK) {
- /* Syntax error in tag expression */
- /* Result message set by TagSearchScanExpr */
+ if (searchPtr->type == SEARCH_TYPE_EXPR) {
+ /*
+ * An operator was found in the prescan, so now compile the tag
+ * expression into array of Tk_Uid flagging any syntax errors found.
+ */
+
+ if (TagSearchScanExpr(canvasPtr->interp, searchPtr,
+ searchPtr->expr) != TCL_OK) {
+ /*
+ * Syntax error in tag expression. The result message was set by
+ * TagSearchScanExpr.
+ */
+
return TCL_ERROR;
}
searchPtr->expr->length = searchPtr->expr->index;
+ } else if (searchPtr->expr->uid == GetStaticUids()->allUid) {
+ /*
+ * All items match.
+ */
+
+ searchPtr->type = SEARCH_TYPE_ALL;
} else {
- if (searchPtr->expr->uid == GetStaticUids()->allUid) {
- /*
- * All items match.
- */
- searchPtr->type = 2;
- } else {
- /*
- * Optimized single-tag search
- */
- searchPtr->type = 3;
- }
+ /*
+ * Optimized single-tag search
+ */
+
+ searchPtr->type = SEARCH_TYPE_TAG;
}
return TCL_OK;
}
@@ -3286,24 +3167,26 @@ TagSearchScan(canvasPtr, tagObj, searchPtrPtr)
*
* TagSearchDestroy --
*
- * This procedure destroys any dynamic structures that
- * may have been allocated by TagSearchScan.
+ * This function destroys any dynamic structures that may have been
+ * allocated by TagSearchScan.
*
* Results:
+ * None
*
* Side effects:
+ * Deallocates memory.
*
*--------------------------------------------------------------
*/
static void
-TagSearchDestroy(searchPtr)
- TagSearch *searchPtr; /* Record describing tag search */
+TagSearchDestroy(
+ TagSearch *searchPtr) /* Record describing tag search */
{
if (searchPtr) {
- TagSearchExprDestroy(searchPtr->expr);
- ckfree((char *)searchPtr->rewritebuffer);
- ckfree((char *)searchPtr);
+ TagSearchExprDestroy(searchPtr->expr);
+ ckfree((char *)searchPtr->rewritebuffer);
+ ckfree((char *)searchPtr);
}
}
@@ -3312,16 +3195,14 @@ TagSearchDestroy(searchPtr)
*
* TagSearchScanExpr --
*
- * This recursive procedure is called to scan a tag expression
- * and compile it into an array of Tk_Uids.
+ * This recursive function is called to scan a tag expression and compile
+ * it into an array of Tk_Uids.
*
* Results:
- * The return value indicates if the tagOrId expression
- * was successfully scanned (syntax).
- * The information at *searchPtr is initialized
- * such that a call to TagSearchFirst, followed by
- * successive calls to TagSearchNext will return items
- * that match tag.
+ * The return value indicates if the tagOrId expression was successfully
+ * scanned (syntax). The information at *searchPtr is initialized such
+ * that a call to TagSearchFirst, followed by successive calls to
+ * TagSearchNext will return items that match tag.
*
* Side effects:
*
@@ -3329,216 +3210,233 @@ TagSearchDestroy(searchPtr)
*/
static int
-TagSearchScanExpr(interp, searchPtr, expr)
- Tcl_Interp *interp; /* Current interpreter. */
- TagSearch *searchPtr; /* Search data */
- TagSearchExpr *expr; /* compiled expression result */
+TagSearchScanExpr(
+ Tcl_Interp *interp, /* Current interpreter. */
+ TagSearch *searchPtr, /* Search data */
+ TagSearchExpr *expr) /* compiled expression result */
{
- int looking_for_tag; /* When true, scanner expects
- * next char(s) to be a tag,
- * else operand expected */
- int found_tag; /* One or more tags found */
- int found_endquote; /* For quoted tag string parsing */
- int negate_result; /* Pending negation of next tag value */
- char *tag; /* tag from tag expression string */
+ int looking_for_tag; /* When true, scanner expects next char(s) to
+ * be a tag, else operand expected */
+ int found_tag; /* One or more tags found */
+ int found_endquote; /* For quoted tag string parsing */
+ int negate_result; /* Pending negation of next tag value */
+ char *tag; /* Tag from tag expression string */
char c;
SearchUids *searchUids; /* Collection of uids for basic search
* expression terms. */
-
+
searchUids = GetStaticUids();
negate_result = 0;
found_tag = 0;
looking_for_tag = 1;
while (searchPtr->stringIndex < searchPtr->stringLength) {
- c = searchPtr->string[searchPtr->stringIndex++];
+ c = searchPtr->string[searchPtr->stringIndex++];
- if (expr->allocated == expr->index) {
- expr->allocated += 15;
+ /*
+ * Need two slots free at this point, not one. [Bug 2931374]
+ */
+
+ if (expr->index >= expr->allocated-1) {
+ expr->allocated += 15;
if (expr->uids) {
- expr->uids =
- (Tk_Uid *) ckrealloc((char *)(expr->uids),
- (expr->allocated)*sizeof(Tk_Uid));
+ expr->uids = (Tk_Uid *)
+ ckrealloc((char *)(expr->uids),
+ (expr->allocated)*sizeof(Tk_Uid));
} else {
- expr->uids =
- (Tk_Uid *) ckalloc((expr->allocated)*sizeof(Tk_Uid));
+ expr->uids = (Tk_Uid *)
+ ckalloc((expr->allocated)*sizeof(Tk_Uid));
}
- }
-
- if (looking_for_tag) {
-
- switch (c) {
- case ' ' : /* ignore unquoted whitespace */
- case '\t' :
- case '\n' :
- case '\r' :
- break;
-
- case '!' : /* negate next tag or subexpr */
- if (looking_for_tag > 1) {
- Tcl_AppendResult(interp,
- "Too many '!' in tag search expression",
- (char *) NULL);
- return TCL_ERROR;
- }
- looking_for_tag++;
- negate_result = 1;
- break;
-
- case '(' : /* scan (negated) subexpr recursively */
- if (negate_result) {
- expr->uids[expr->index++] = searchUids->negparenUid;
- negate_result = 0;
- } else {
- expr->uids[expr->index++] = searchUids->parenUid;
+ }
+
+ if (looking_for_tag) {
+
+ switch (c) {
+ case ' ': /* ignore unquoted whitespace */
+ case '\t':
+ case '\n':
+ case '\r':
+ break;
+
+ case '!': /* negate next tag or subexpr */
+ if (looking_for_tag > 1) {
+ Tcl_AppendResult(interp,
+ "Too many '!' in tag search expression",
+ NULL);
+ return TCL_ERROR;
+ }
+ looking_for_tag++;
+ negate_result = 1;
+ break;
+
+ case '(': /* scan (negated) subexpr recursively */
+ if (negate_result) {
+ expr->uids[expr->index++] = searchUids->negparenUid;
+ negate_result = 0;
+ } else {
+ expr->uids[expr->index++] = searchUids->parenUid;
+ }
+ if (TagSearchScanExpr(interp, searchPtr, expr) != TCL_OK) {
+ /*
+ * Result string should be already set by nested call to
+ * tag_expr_scan()
+ */
+
+ return TCL_ERROR;
+ }
+ looking_for_tag = 0;
+ found_tag = 1;
+ break;
+
+ case '"': /* quoted tag string */
+ if (negate_result) {
+ expr->uids[expr->index++] = searchUids->negtagvalUid;
+ negate_result = 0;
+ } else {
+ expr->uids[expr->index++] = searchUids->tagvalUid;
+ }
+ tag = searchPtr->rewritebuffer;
+ found_endquote = 0;
+ while (searchPtr->stringIndex < searchPtr->stringLength) {
+ c = searchPtr->string[searchPtr->stringIndex++];
+ if (c == '\\') {
+ c = searchPtr->string[searchPtr->stringIndex++];
}
- if (TagSearchScanExpr(interp, searchPtr, expr) != TCL_OK) {
- /* Result string should be already set
- * by nested call to tag_expr_scan() */
- return TCL_ERROR;
+ if (c == '"') {
+ found_endquote = 1;
+ break;
}
- looking_for_tag = 0;
- found_tag = 1;
- break;
-
- case '"' : /* quoted tag string */
- if (negate_result) {
- expr->uids[expr->index++] = searchUids->negtagvalUid;
- negate_result = 0;
- } else {
- expr->uids[expr->index++] = searchUids->tagvalUid;
+ *tag++ = c;
+ }
+ if (! found_endquote) {
+ Tcl_AppendResult(interp,
+ "Missing endquote in tag search expression",
+ NULL);
+ return TCL_ERROR;
+ }
+ if (! (tag - searchPtr->rewritebuffer)) {
+ Tcl_AppendResult(interp,
+ "Null quoted tag string in tag search expression",
+ NULL);
+ return TCL_ERROR;
+ }
+ *tag++ = '\0';
+ expr->uids[expr->index++] =
+ Tk_GetUid(searchPtr->rewritebuffer);
+ looking_for_tag = 0;
+ found_tag = 1;
+ break;
+
+ case '&': /* illegal chars when looking for tag */
+ case '|':
+ case '^':
+ case ')':
+ Tcl_AppendResult(interp,
+ "Unexpected operator in tag search expression",
+ NULL);
+ return TCL_ERROR;
+
+ default: /* unquoted tag string */
+ if (negate_result) {
+ expr->uids[expr->index++] = searchUids->negtagvalUid;
+ negate_result = 0;
+ } else {
+ expr->uids[expr->index++] = searchUids->tagvalUid;
+ }
+ tag = searchPtr->rewritebuffer;
+ *tag++ = c;
+
+ /*
+ * Copy rest of tag, including any embedded whitespace.
+ */
+
+ while (searchPtr->stringIndex < searchPtr->stringLength) {
+ c = searchPtr->string[searchPtr->stringIndex];
+ if (c == '!' || c == '&' || c == '|' || c == '^'
+ || c == '(' || c == ')' || c == '"') {
+ break;
}
- tag = searchPtr->rewritebuffer;
- found_endquote = 0;
- while (searchPtr->stringIndex < searchPtr->stringLength) {
- c = searchPtr->string[searchPtr->stringIndex++];
- if (c == '\\') {
- c = searchPtr->string[searchPtr->stringIndex++];
- }
- if (c == '"') {
- found_endquote = 1;
- break;
- }
- *tag++ = c;
- }
- if (! found_endquote) {
- Tcl_AppendResult(interp,
- "Missing endquote in tag search expression",
- (char *) NULL);
- return TCL_ERROR;
- }
- if (! (tag - searchPtr->rewritebuffer)) {
- Tcl_AppendResult(interp,
- "Null quoted tag string in tag search expression",
- (char *) NULL);
- return TCL_ERROR;
- }
- *tag++ = '\0';
- expr->uids[expr->index++] =
- Tk_GetUid(searchPtr->rewritebuffer);
- looking_for_tag = 0;
- found_tag = 1;
- break;
-
- case '&' : /* illegal chars when looking for tag */
- case '|' :
- case '^' :
- case ')' :
- Tcl_AppendResult(interp,
- "Unexpected operator in tag search expression",
- (char *) NULL);
- return TCL_ERROR;
-
- default : /* unquoted tag string */
- if (negate_result) {
- expr->uids[expr->index++] = searchUids->negtagvalUid;
- negate_result = 0;
- } else {
- expr->uids[expr->index++] = searchUids->tagvalUid;
- }
- tag = searchPtr->rewritebuffer;
- *tag++ = c;
- /* copy rest of tag, including any embedded whitespace */
- while (searchPtr->stringIndex < searchPtr->stringLength) {
- c = searchPtr->string[searchPtr->stringIndex];
- if (c == '!' || c == '&' || c == '|' || c == '^'
- || c == '(' || c == ')' || c == '"') {
- break;
- }
- *tag++ = c;
- searchPtr->stringIndex++;
- }
- /* remove trailing whitespace */
- while (1) {
- c = *--tag;
- /* there must have been one non-whitespace char,
- * so this will terminate */
- if (c != ' ' && c != '\t' && c != '\n' && c != '\r') {
- break;
- }
- }
- *++tag = '\0';
- expr->uids[expr->index++] =
- Tk_GetUid(searchPtr->rewritebuffer);
- looking_for_tag = 0;
- found_tag = 1;
- }
-
- } else { /* ! looking_for_tag */
-
- switch (c) {
- case ' ' : /* ignore whitespace */
- case '\t' :
- case '\n' :
- case '\r' :
- break;
-
- case '&' : /* AND operator */
- c = searchPtr->string[searchPtr->stringIndex++];
- if (c != '&') {
- Tcl_AppendResult(interp,
- "Singleton '&' in tag search expression",
- (char *) NULL);
- return TCL_ERROR;
- }
- expr->uids[expr->index++] = searchUids->andUid;
- looking_for_tag = 1;
- break;
-
- case '|' : /* OR operator */
- c = searchPtr->string[searchPtr->stringIndex++];
- if (c != '|') {
- Tcl_AppendResult(interp,
- "Singleton '|' in tag search expression",
- (char *) NULL);
- return TCL_ERROR;
- }
- expr->uids[expr->index++] = searchUids->orUid;
- looking_for_tag = 1;
- break;
-
- case '^' : /* XOR operator */
- expr->uids[expr->index++] = searchUids->xorUid;
- looking_for_tag = 1;
- break;
-
- case ')' : /* end subexpression */
- expr->uids[expr->index++] = searchUids->endparenUid;
- goto breakwhile;
-
- default : /* syntax error */
- Tcl_AppendResult(interp,
- "Invalid boolean operator in tag search expression",
- (char *) NULL);
- return TCL_ERROR;
- }
- }
- }
- breakwhile:
+ *tag++ = c;
+ searchPtr->stringIndex++;
+ }
+
+ /*
+ * Remove trailing whitespace.
+ */
+
+ while (1) {
+ c = *--tag;
+
+ /*
+ * There must have been one non-whitespace char, so this
+ * will terminate.
+ */
+
+ if (c != ' ' && c != '\t' && c != '\n' && c != '\r') {
+ break;
+ }
+ }
+ *++tag = '\0';
+ expr->uids[expr->index++] =
+ Tk_GetUid(searchPtr->rewritebuffer);
+ looking_for_tag = 0;
+ found_tag = 1;
+ }
+
+ } else { /* ! looking_for_tag */
+ switch (c) {
+ case ' ': /* ignore whitespace */
+ case '\t':
+ case '\n':
+ case '\r':
+ break;
+
+ case '&': /* AND operator */
+ c = searchPtr->string[searchPtr->stringIndex++];
+ if (c != '&') {
+ Tcl_AppendResult(interp,
+ "Singleton '&' in tag search expression",
+ NULL);
+ return TCL_ERROR;
+ }
+ expr->uids[expr->index++] = searchUids->andUid;
+ looking_for_tag = 1;
+ break;
+
+ case '|': /* OR operator */
+ c = searchPtr->string[searchPtr->stringIndex++];
+ if (c != '|') {
+ Tcl_AppendResult(interp,
+ "Singleton '|' in tag search expression",
+ NULL);
+ return TCL_ERROR;
+ }
+ expr->uids[expr->index++] = searchUids->orUid;
+ looking_for_tag = 1;
+ break;
+
+ case '^' : /* XOR operator */
+ expr->uids[expr->index++] = searchUids->xorUid;
+ looking_for_tag = 1;
+ break;
+
+ case ')' : /* end subexpression */
+ expr->uids[expr->index++] = searchUids->endparenUid;
+ goto breakwhile;
+
+ default: /* syntax error */
+ Tcl_AppendResult(interp,
+ "Invalid boolean operator in tag search expression",
+ NULL);
+ return TCL_ERROR;
+ }
+ }
+ }
+
+ breakwhile:
if (found_tag && ! looking_for_tag) {
- return TCL_OK;
+ return TCL_OK;
}
- Tcl_AppendResult(interp, "Missing tag in tag search expression",
- (char *) NULL);
+ Tcl_AppendResult(interp, "Missing tag in tag search expression", NULL);
return TCL_ERROR;
}
@@ -3547,11 +3445,11 @@ TagSearchScanExpr(interp, searchPtr, expr)
*
* TagSearchEvalExpr --
*
- * This recursive procedure is called to eval a tag expression.
+ * This recursive function is called to eval a tag expression.
*
* Results:
- * The return value indicates if the tagOrId expression
- * successfully matched the tags of the current item.
+ * The return value indicates if the tagOrId expression successfully
+ * matched the tags of the current item.
*
* Side effects:
*
@@ -3559,18 +3457,17 @@ TagSearchScanExpr(interp, searchPtr, expr)
*/
static int
-TagSearchEvalExpr(expr, itemPtr)
- TagSearchExpr *expr; /* Search expression */
- Tk_Item *itemPtr; /* Item being test for match */
+TagSearchEvalExpr(
+ TagSearchExpr *expr, /* Search expression */
+ Tk_Item *itemPtr) /* Item being test for match */
{
- int looking_for_tag; /* When true, scanner expects
- * next char(s) to be a tag,
- * else operand expected */
- int negate_result; /* Pending negation of next tag value */
+ int looking_for_tag; /* When true, scanner expects next char(s) to
+ * be a tag, else operand expected. */
+ int negate_result; /* Pending negation of next tag value */
Tk_Uid uid;
Tk_Uid *tagPtr;
int count;
- int result; /* Value of expr so far */
+ int result; /* Value of expr so far */
int parendepth;
SearchUids *searchUids; /* Collection of uids for basic search
* expression terms. */
@@ -3581,77 +3478,84 @@ TagSearchEvalExpr(expr, itemPtr)
negate_result = 0;
looking_for_tag = 1;
while (expr->index < expr->length) {
- uid = expr->uids[expr->index++];
- if (looking_for_tag) {
- if (uid == searchUids->tagvalUid) {
+ uid = expr->uids[expr->index++];
+ if (looking_for_tag) {
+ if (uid == searchUids->tagvalUid) {
/*
- * assert(expr->index < expr->length);
+ * assert(expr->index < expr->length);
*/
- uid = expr->uids[expr->index++];
- result = 0;
- /*
- * set result 1 if tag is found in item's tags
- */
- for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
- count > 0; tagPtr++, count--) {
- if (*tagPtr == uid) {
- result = 1;
- break;
- }
- }
-
- } else if (uid == searchUids->negtagvalUid) {
- negate_result = ! negate_result;
+ uid = expr->uids[expr->index++];
+ result = 0;
+
+ /*
+ * set result 1 if tag is found in item's tags
+ */
+
+ for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
+ count > 0; tagPtr++, count--) {
+ if (*tagPtr == uid) {
+ result = 1;
+ break;
+ }
+ }
+
+ } else if (uid == searchUids->negtagvalUid) {
+ negate_result = ! negate_result;
/*
- * assert(expr->index < expr->length);
+ * assert(expr->index < expr->length);
*/
- uid = expr->uids[expr->index++];
- result = 0;
- /*
- * set result 1 if tag is found in item's tags
- */
- for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
- count > 0; tagPtr++, count--) {
- if (*tagPtr == uid) {
- result = 1;
- break;
- }
- }
-
- } else if (uid == searchUids->parenUid) {
- /*
- * evaluate subexpressions with recursion
- */
- result = TagSearchEvalExpr(expr, itemPtr);
-
- } else if (uid == searchUids->negparenUid) {
- negate_result = ! negate_result;
- /*
- * evaluate subexpressions with recursion
- */
- result = TagSearchEvalExpr(expr, itemPtr);
+ uid = expr->uids[expr->index++];
+ result = 0;
+
+ /*
+ * set result 1 if tag is found in item's tags
+ */
+
+ for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
+ count > 0; tagPtr++, count--) {
+ if (*tagPtr == uid) {
+ result = 1;
+ break;
+ }
+ }
+
+ } else if (uid == searchUids->parenUid) {
+ /*
+ * Evaluate subexpressions with recursion
+ */
+
+ result = TagSearchEvalExpr(expr, itemPtr);
+
+ } else if (uid == searchUids->negparenUid) {
+ negate_result = ! negate_result;
+
+ /*
+ * Evaluate subexpressions with recursion
+ */
+
+ result = TagSearchEvalExpr(expr, itemPtr);
/*
- * } else {
- * assert(0);
+ * } else {
+ * assert(0);
*/
- }
- if (negate_result) {
- result = ! result;
- negate_result = 0;
- }
- looking_for_tag = 0;
- } else { /* ! looking_for_tag */
- if (((uid == searchUids->andUid) && (!result)) ||
+ }
+ if (negate_result) {
+ result = ! result;
+ negate_result = 0;
+ }
+ looking_for_tag = 0;
+ } else { /* ! looking_for_tag */
+ if (((uid == searchUids->andUid) && (!result)) ||
((uid == searchUids->orUid) && result)) {
- /*
- * short circuit expression evaluation
- *
- * if result before && is 0, or result before || is 1,
- * then the expression is decided and no further
- * evaluation is needed.
- */
-
- parendepth = 0;
+ /*
+ * Short circuit expression evaluation.
+ *
+ * if result before && is 0, or result before || is 1, then
+ * the expression is decided and no further evaluation is
+ * needed.
+ */
+
+ parendepth = 0;
while (expr->index < expr->length) {
uid = expr->uids[expr->index++];
if (uid == searchUids->tagvalUid ||
@@ -3663,7 +3567,7 @@ TagSearchEvalExpr(expr, itemPtr)
uid == searchUids->negparenUid) {
parendepth++;
continue;
- }
+ }
if (uid == searchUids->endparenUid) {
parendepth--;
if (parendepth < 0) {
@@ -3671,24 +3575,24 @@ TagSearchEvalExpr(expr, itemPtr)
}
}
}
- return result;
+ return result;
- } else if (uid == searchUids->xorUid) {
- /*
- * if the previous result was 1
- * then negate the next result
- */
- negate_result = result;
+ } else if (uid == searchUids->xorUid) {
+ /*
+ * If the previous result was 1 then negate the next result.
+ */
- } else if (uid == searchUids->endparenUid) {
- return result;
+ negate_result = result;
+
+ } else if (uid == searchUids->endparenUid) {
+ return result;
/*
- * } else {
- * assert(0);
+ * } else {
+ * assert(0);
*/
- }
- looking_for_tag = 1;
- }
+ }
+ looking_for_tag = 1;
+ }
}
/*
* assert(! looking_for_tag);
@@ -3701,104 +3605,103 @@ TagSearchEvalExpr(expr, itemPtr)
*
* TagSearchFirst --
*
- * This procedure is called to get the first item
- * item that matches a preestablished search predicate
- * that was set by TagSearchScan.
+ * This function is called to get the first item item that matches a
+ * preestablished search predicate that was set by TagSearchScan.
*
* Results:
- * The return value is a pointer to the first item, or NULL
- * if there is no such item. The information at *searchPtr
- * is updated such that successive calls to TagSearchNext
- * will return successive items.
+ * The return value is a pointer to the first item, or NULL if there is
+ * no such item. The information at *searchPtr is updated such that
+ * successive calls to TagSearchNext will return successive items.
*
* Side effects:
- * SearchPtr is linked into a list of searches in progress
- * on canvasPtr, so that elements can safely be deleted
- * while the search is in progress.
+ * SearchPtr is linked into a list of searches in progress on canvasPtr,
+ * so that elements can safely be deleted while the search is in
+ * progress.
*
*--------------------------------------------------------------
*/
static Tk_Item *
-TagSearchFirst(searchPtr)
- TagSearch *searchPtr; /* Record describing tag search */
+TagSearchFirst(
+ TagSearch *searchPtr) /* Record describing tag search */
{
Tk_Item *itemPtr, *lastPtr;
Tk_Uid uid, *tagPtr;
int count;
- /* short circuit impossible searches for null tags */
+ /*
+ * Short circuit impossible searches for null tags.
+ */
+
if (searchPtr->stringLength == 0) {
- return NULL;
+ return NULL;
}
/*
- * Find the first matching item in one of several ways. If the tag
- * is a number then it selects the single item with the matching
- * identifier. In this case see if the item being requested is the
- * hot item, in which case the search can be skipped.
+ * Find the first matching item in one of several ways. If the tag is a
+ * number then it selects the single item with the matching identifier.
+ * In this case see if the item being requested is the hot item, in which
+ * case the search can be skipped.
*/
- if (searchPtr->type == 1) {
- Tcl_HashEntry *entryPtr;
-
- itemPtr = searchPtr->canvasPtr->hotPtr;
- lastPtr = searchPtr->canvasPtr->hotPrevPtr;
- if ((itemPtr == NULL) || (itemPtr->id != searchPtr->id) ||
- (lastPtr == NULL) || (lastPtr->nextPtr != itemPtr)) {
- entryPtr = Tcl_FindHashEntry(&searchPtr->canvasPtr->idTable,
- (char *) searchPtr->id);
- if (entryPtr != NULL) {
- itemPtr = (Tk_Item *)Tcl_GetHashValue(entryPtr);
- lastPtr = itemPtr->prevPtr;
- } else {
- lastPtr = itemPtr = NULL;
- }
- }
- searchPtr->lastPtr = lastPtr;
- searchPtr->searchOver = 1;
- searchPtr->canvasPtr->hotPtr = itemPtr;
- searchPtr->canvasPtr->hotPrevPtr = lastPtr;
- return itemPtr;
- }
-
- if (searchPtr->type == 2) {
-
- /*
- * All items match.
- */
-
- searchPtr->lastPtr = NULL;
- searchPtr->currentPtr = searchPtr->canvasPtr->firstItemPtr;
- return searchPtr->canvasPtr->firstItemPtr;
- }
-
- if (searchPtr->type == 3) {
-
- /*
- * Optimized single-tag search
- */
-
- uid = searchPtr->expr->uid;
- for (lastPtr = NULL, itemPtr = searchPtr->canvasPtr->firstItemPtr;
- itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) {
- for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
- count > 0; tagPtr++, count--) {
- if (*tagPtr == uid) {
- searchPtr->lastPtr = lastPtr;
- searchPtr->currentPtr = itemPtr;
- return itemPtr;
- }
- }
- }
+ if (searchPtr->type == SEARCH_TYPE_ID) {
+ Tcl_HashEntry *entryPtr;
+
+ itemPtr = searchPtr->canvasPtr->hotPtr;
+ lastPtr = searchPtr->canvasPtr->hotPrevPtr;
+ if ((itemPtr == NULL) || (itemPtr->id != searchPtr->id)
+ || (lastPtr == NULL) || (lastPtr->nextPtr != itemPtr)) {
+ entryPtr = Tcl_FindHashEntry(&searchPtr->canvasPtr->idTable,
+ (char *) INT2PTR(searchPtr->id));
+ if (entryPtr != NULL) {
+ itemPtr = (Tk_Item *)Tcl_GetHashValue(entryPtr);
+ lastPtr = itemPtr->prevPtr;
+ } else {
+ lastPtr = itemPtr = NULL;
+ }
+ }
+ searchPtr->lastPtr = lastPtr;
+ searchPtr->searchOver = 1;
+ searchPtr->canvasPtr->hotPtr = itemPtr;
+ searchPtr->canvasPtr->hotPrevPtr = lastPtr;
+ return itemPtr;
+ }
+
+ if (searchPtr->type == SEARCH_TYPE_ALL) {
+ /*
+ * All items match.
+ */
+
+ searchPtr->lastPtr = NULL;
+ searchPtr->currentPtr = searchPtr->canvasPtr->firstItemPtr;
+ return searchPtr->canvasPtr->firstItemPtr;
+ }
+
+ if (searchPtr->type == SEARCH_TYPE_TAG) {
+ /*
+ * Optimized single-tag search
+ */
+
+ uid = searchPtr->expr->uid;
+ for (lastPtr = NULL, itemPtr = searchPtr->canvasPtr->firstItemPtr;
+ itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) {
+ for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
+ count > 0; tagPtr++, count--) {
+ if (*tagPtr == uid) {
+ searchPtr->lastPtr = lastPtr;
+ searchPtr->currentPtr = itemPtr;
+ return itemPtr;
+ }
+ }
+ }
} else {
/*
- * None of the above. Search for an item matching the tag expression.
+ * None of the above. Search for an item matching the tag expression.
*/
for (lastPtr = NULL, itemPtr = searchPtr->canvasPtr->firstItemPtr;
- itemPtr != NULL; lastPtr=itemPtr, itemPtr=itemPtr->nextPtr) {
+ itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) {
searchPtr->expr->index = 0;
if (TagSearchEvalExpr(searchPtr->expr, itemPtr)) {
searchPtr->lastPtr = lastPtr;
@@ -3817,89 +3720,86 @@ TagSearchFirst(searchPtr)
*
* TagSearchNext --
*
- * This procedure returns successive items that match a given
- * tag; it should be called only after TagSearchFirst has been
- * used to begin a search.
+ * This function returns successive items that match a given tag; it
+ * should be called only after TagSearchFirst has been used to begin a
+ * search.
*
* Results:
- * The return value is a pointer to the next item that matches
- * the tag expr specified to TagSearchScan, or NULL if no such
- * item exists. *SearchPtr is updated so that the next call
- * to this procedure will return the next item.
+ * The return value is a pointer to the next item that matches the tag
+ * expr specified to TagSearchScan, or NULL if no such item exists.
+ * *SearchPtr is updated so that the next call to this function will
+ * return the next item.
*
* Side effects:
- * None.
+ * None.
*
*--------------------------------------------------------------
*/
static Tk_Item *
-TagSearchNext(searchPtr)
- TagSearch *searchPtr; /* Record describing search in
- * progress. */
+TagSearchNext(
+ TagSearch *searchPtr) /* Record describing search in progress. */
{
Tk_Item *itemPtr, *lastPtr;
Tk_Uid uid, *tagPtr;
int count;
/*
- * Find next item in list (this may not actually be a suitable
- * one to return), and return if there are no items left.
+ * Find next item in list (this may not actually be a suitable one to
+ * return), and return if there are no items left.
*/
lastPtr = searchPtr->lastPtr;
if (lastPtr == NULL) {
- itemPtr = searchPtr->canvasPtr->firstItemPtr;
+ itemPtr = searchPtr->canvasPtr->firstItemPtr;
} else {
- itemPtr = lastPtr->nextPtr;
+ itemPtr = lastPtr->nextPtr;
}
if ((itemPtr == NULL) || (searchPtr->searchOver)) {
- searchPtr->searchOver = 1;
- return NULL;
+ searchPtr->searchOver = 1;
+ return NULL;
}
if (itemPtr != searchPtr->currentPtr) {
- /*
- * The structure of the list has changed. Probably the
- * previously-returned item was removed from the list.
- * In this case, don't advance lastPtr; just return
- * its new successor (i.e. do nothing here).
- */
+ /*
+ * The structure of the list has changed. Probably the previously-
+ * returned item was removed from the list. In this case, don't
+ * advance lastPtr; just return its new successor (i.e. do nothing
+ * here).
+ */
} else {
- lastPtr = itemPtr;
- itemPtr = lastPtr->nextPtr;
+ lastPtr = itemPtr;
+ itemPtr = lastPtr->nextPtr;
}
- if (searchPtr->type == 2) {
-
- /*
- * All items match.
- */
+ if (searchPtr->type == SEARCH_TYPE_ALL) {
+ /*
+ * All items match.
+ */
- searchPtr->lastPtr = lastPtr;
- searchPtr->currentPtr = itemPtr;
- return itemPtr;
+ searchPtr->lastPtr = lastPtr;
+ searchPtr->currentPtr = itemPtr;
+ return itemPtr;
}
- if (searchPtr->type == 3) {
-
- /*
- * Optimized single-tag search
- */
+ if (searchPtr->type == SEARCH_TYPE_TAG) {
+ /*
+ * Optimized single-tag search
+ */
- uid = searchPtr->expr->uid;
- for ( ; itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) {
- for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
- count > 0; tagPtr++, count--) {
- if (*tagPtr == uid) {
- searchPtr->lastPtr = lastPtr;
- searchPtr->currentPtr = itemPtr;
- return itemPtr;
- }
- }
- }
- searchPtr->lastPtr = lastPtr;
- searchPtr->searchOver = 1;
- return NULL;
+ uid = searchPtr->expr->uid;
+ for (; itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) {
+ for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
+ count > 0; tagPtr++, count--) {
+ if (*tagPtr == uid) {
+ searchPtr->lastPtr = lastPtr;
+ searchPtr->currentPtr = itemPtr;
+ return itemPtr;
+ }
+ }
+ }
+ searchPtr->lastPtr = lastPtr;
+ searchPtr->searchOver = 1;
+ return NULL;
}
/*
@@ -3907,12 +3807,12 @@ TagSearchNext(searchPtr)
*/
for ( ; itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) {
- searchPtr->expr->index = 0;
- if (TagSearchEvalExpr(searchPtr->expr, itemPtr)) {
- searchPtr->lastPtr = lastPtr;
- searchPtr->currentPtr = itemPtr;
- return itemPtr;
- }
+ searchPtr->expr->index = 0;
+ if (TagSearchEvalExpr(searchPtr->expr, itemPtr)) {
+ searchPtr->lastPtr = lastPtr;
+ searchPtr->currentPtr = itemPtr;
+ return itemPtr;
+ }
}
searchPtr->lastPtr = lastPtr;
searchPtr->searchOver = 1;
@@ -3925,29 +3825,27 @@ TagSearchNext(searchPtr)
*
* DoItem --
*
- * This is a utility procedure called by FindItems. It
- * either adds itemPtr's id to the result forming in interp,
- * or it adds a new tag to itemPtr, depending on the value
- * of tag.
+ * This is a utility function called by FindItems. It either adds
+ * itemPtr's id to the result forming in interp, or it adds a new tag to
+ * itemPtr, depending on the value of tag.
*
* Results:
* None.
*
* Side effects:
- * If tag is NULL then itemPtr's id is added as a list element
- * to the interp's result; otherwise tag is added to itemPtr's
- * list of tags.
+ * If tag is NULL then itemPtr's id is added as a list element to the
+ * interp's result; otherwise tag is added to itemPtr's list of tags.
*
*--------------------------------------------------------------
*/
static void
-DoItem(interp, itemPtr, tag)
- Tcl_Interp *interp; /* Interpreter in which to (possibly)
- * record item id. */
- Tk_Item *itemPtr; /* Item to (possibly) modify. */
- Tk_Uid tag; /* Tag to add to those already
- * present for item, or NULL. */
+DoItem(
+ Tcl_Interp *interp, /* Interpreter in which to (possibly) record
+ * item id. */
+ Tk_Item *itemPtr, /* Item to (possibly) modify. */
+ Tk_Uid tag) /* Tag to add to those already present for
+ * item, or NULL. */
{
Tk_Uid *tagPtr;
int count;
@@ -3972,18 +3870,17 @@ DoItem(interp, itemPtr, tag)
}
/*
- * Grow the tag space if there's no more room left in the current
- * block.
+ * Grow the tag space if there's no more room left in the current block.
*/
if (itemPtr->tagSpace == itemPtr->numTags) {
Tk_Uid *newTagPtr;
itemPtr->tagSpace += 5;
- newTagPtr = (Tk_Uid *) ckalloc((unsigned)
- (itemPtr->tagSpace * sizeof(Tk_Uid)));
- memcpy((VOID *) newTagPtr, (VOID *) itemPtr->tagPtr,
- (itemPtr->numTags * sizeof(Tk_Uid)));
+ newTagPtr = (Tk_Uid *)
+ ckalloc((unsigned) (itemPtr->tagSpace * sizeof(Tk_Uid)));
+ memcpy((void *) newTagPtr, itemPtr->tagPtr,
+ itemPtr->numTags * sizeof(Tk_Uid));
if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
ckfree((char *) itemPtr->tagPtr);
}
@@ -4004,57 +3901,51 @@ DoItem(interp, itemPtr, tag)
*
* FindItems --
*
- * This procedure does all the work of implementing the
- * "find" and "addtag" options of the canvas widget command,
- * which locate items that have certain features (location,
- * tags, position in display list, etc.).
+ * This function does all the work of implementing the "find" and
+ * "addtag" options of the canvas widget command, which locate items that
+ * have certain features (location, tags, position in display list, etc.)
*
* 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 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.
+ * A standard Tcl return value. If newTag is NULL, then a list of ids
+ * from all the items that match objc/objv 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:
- * If newTag is non-NULL, then all the items that match the
- * information in argc/argv have that tag added to their
- * lists of tags.
+ * If newTag is non-NULL, then all the items that match the information
+ * in objc/objv have that tag added to their lists of tags.
*
*--------------------------------------------------------------
*/
static int
-#ifdef USE_OLD_TAG_SEARCH
-FindItems(interp, canvasPtr, argc, argv, newTag, first)
-#else /* USE_OLD_TAG_SEARCH */
-FindItems(interp, canvasPtr, argc, argv, newTag, first, searchPtrPtr)
-#endif /* USE_OLD_TAG_SEARCH */
- Tcl_Interp *interp; /* Interpreter for error reporting. */
- TkCanvas *canvasPtr; /* Canvas whose items are to be
- * searched. */
- int argc; /* Number of entries in argv. Must be
- * greater than zero. */
- Tcl_Obj *CONST *argv; /* Arguments that describe what items
- * to search for (see user doc on
- * "find" and "addtag" options). */
- Tcl_Obj *newTag; /* If non-NULL, gives new tag to set
- * on all found items; if NULL, then
- * ids of found items are returned
- * in the interp's result. */
- int first; /* For error messages: gives number
- * of elements of argv which are already
- * handled. */
+FindItems(
+ Tcl_Interp *interp, /* Interpreter for error reporting. */
+ TkCanvas *canvasPtr, /* Canvas whose items are to be searched. */
+ int objc, /* Number of entries in argv. Must be greater
+ * than zero. */
+ Tcl_Obj *CONST *objv, /* Arguments that describe what items to
+ * search for (see user doc on "find" and
+ * "addtag" options). */
+ Tcl_Obj *newTag, /* If non-NULL, gives new tag to set on all
+ * found items; if NULL, then ids of found
+ * items are returned in the interp's
+ * result. */
+ int first /* For error messages: gives number of
+ * elements of objv which are already
+ * handled. */
#ifndef USE_OLD_TAG_SEARCH
- TagSearch **searchPtrPtr; /* From CanvasWidgetCmd local vars*/
+ ,TagSearch **searchPtrPtr /* From CanvasWidgetCmd local vars*/
#endif /* not USE_OLD_TAG_SEARCH */
+ )
{
#ifdef USE_OLD_TAG_SEARCH
TagSearch search;
#endif /* USE_OLD_TAG_SEARCH */
Tk_Item *itemPtr;
Tk_Uid uid;
- int index;
+ int index, result;
static CONST char *optionStrings[] = {
"above", "all", "below", "closest",
"enclosed", "overlapping", "withtag", NULL
@@ -4065,41 +3956,34 @@ FindItems(interp, canvasPtr, argc, argv, newTag, first, searchPtrPtr)
};
if (newTag != NULL) {
- uid = Tk_GetUid(Tcl_GetStringFromObj(newTag, NULL));
+ uid = Tk_GetUid(Tcl_GetString(newTag));
} else {
uid = NULL;
}
- if (Tcl_GetIndexFromObj(interp, argv[first], optionStrings, "search command", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObj(interp, objv[first], optionStrings,
+ "search command", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
switch ((enum options) index) {
- case CANV_ABOVE: {
+ case CANV_ABOVE: {
Tk_Item *lastPtr = NULL;
- if (argc != first+2) {
- Tcl_WrongNumArgs(interp, first+1, argv, "tagOrId");
+
+ if (objc != first+2) {
+ Tcl_WrongNumArgs(interp, first+1, objv, "tagOrId");
return TCL_ERROR;
}
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, argv[first+1], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if (TagSearchScan(canvasPtr, argv[first+1], searchPtrPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- for (itemPtr = TagSearchFirst(*searchPtrPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(*searchPtrPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[first+1], searchPtrPtr,
+ return TCL_ERROR) {
lastPtr = itemPtr;
}
if ((lastPtr != NULL) && (lastPtr->nextPtr != NULL)) {
DoItem(interp, lastPtr->nextPtr, uid);
}
break;
- }
- case CANV_ALL: {
- if (argc != first+1) {
- Tcl_WrongNumArgs(interp, first+1, argv, (char *) NULL);
+ }
+ case CANV_ALL:
+ if (objc != first+1) {
+ Tcl_WrongNumArgs(interp, first+1, objv, NULL);
return TCL_ERROR;
}
@@ -4108,52 +3992,43 @@ FindItems(interp, canvasPtr, argc, argv, newTag, first, searchPtrPtr)
DoItem(interp, itemPtr, uid);
}
break;
- }
- case CANV_BELOW: {
- Tk_Item *itemPtr;
- if (argc != first+2) {
- Tcl_WrongNumArgs(interp, first+1, argv, "tagOrId");
+ case CANV_BELOW:
+ if (objc != first+2) {
+ Tcl_WrongNumArgs(interp, first+1, objv, "tagOrId");
return TCL_ERROR;
}
-#ifdef USE_OLD_TAG_SEARCH
- itemPtr = StartTagSearch(canvasPtr, argv[first+1], &search);
-#else /* USE_OLD_TAG_SEARCH */
- if (TagSearchScan(canvasPtr, argv[first+1], searchPtrPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- itemPtr = TagSearchFirst(*searchPtrPtr);
-#endif /* USE_OLD_TAG_SEARCH */
+ FIRST_CANVAS_ITEM_MATCHING(objv[first+1], searchPtrPtr,
+ return TCL_ERROR);
if (itemPtr != NULL) {
if (itemPtr->prevPtr != NULL) {
DoItem(interp, itemPtr->prevPtr, uid);
}
}
break;
- }
- case CANV_CLOSEST: {
+ case CANV_CLOSEST: {
double closestDist;
Tk_Item *startPtr, *closestPtr;
double coords[2], halo;
int x1, y1, x2, y2;
- if ((argc < first+3) || (argc > first+5)) {
- Tcl_WrongNumArgs(interp, first+1, argv, "x y ?halo? ?start?");
+ if ((objc < first+3) || (objc > first+5)) {
+ Tcl_WrongNumArgs(interp, first+1, objv, "x y ?halo? ?start?");
return TCL_ERROR;
}
- if ((Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, argv[first+1],
+ if ((Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[first+1],
&coords[0]) != TCL_OK) || (Tk_CanvasGetCoordFromObj(interp,
- (Tk_Canvas) canvasPtr, argv[first+2], &coords[1]) != TCL_OK)) {
+ (Tk_Canvas) canvasPtr, objv[first+2], &coords[1]) != TCL_OK)) {
return TCL_ERROR;
}
- if (argc > first+3) {
- if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, argv[first+3],
+ if (objc > first+3) {
+ if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[first+3],
&halo) != TCL_OK) {
return TCL_ERROR;
}
if (halo < 0.0) {
Tcl_AppendResult(interp, "can't have negative halo value \"",
- Tcl_GetString(argv[3]), "\"", (char *) NULL);
+ Tcl_GetString(objv[3]), "\"", NULL);
return TCL_ERROR;
}
} else {
@@ -4165,31 +4040,26 @@ FindItems(interp, canvasPtr, argc, argv, newTag, first, searchPtrPtr)
*/
startPtr = canvasPtr->firstItemPtr;
- if (argc == first+5) {
-#ifdef USE_OLD_TAG_SEARCH
- itemPtr = StartTagSearch(canvasPtr, argv[first+4], &search);
-#else /* USE_OLD_TAG_SEARCH */
- if (TagSearchScan(canvasPtr, argv[first+4], searchPtrPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- itemPtr = TagSearchFirst(*searchPtrPtr);
-#endif /* USE_OLD_TAG_SEARCH */
+ if (objc == first+5) {
+ FIRST_CANVAS_ITEM_MATCHING(objv[first+4], searchPtrPtr,
+ return TCL_ERROR);
if (itemPtr != NULL) {
startPtr = itemPtr;
}
}
/*
- * The code below is optimized so that it can eliminate most
- * items without having to call their item-specific procedures.
- * This is done by keeping a bounding box (x1, y1, x2, y2) that
- * an item's bbox must overlap if the item is to have any
- * chance of being closer than the closest so far.
+ * The code below is optimized so that it can eliminate most items
+ * without having to call their item-specific functions. This is done
+ * by keeping a bounding box (x1, y1, x2, y2) that an item's bbox must
+ * overlap if the item is to have any chance of being closer than the
+ * closest so far.
*/
itemPtr = startPtr;
while(itemPtr && (itemPtr->state == TK_STATE_HIDDEN ||
- (itemPtr->state == TK_STATE_NULL && canvasPtr->canvas_state == TK_STATE_HIDDEN))) {
+ (itemPtr->state == TK_STATE_NULL &&
+ canvasPtr->canvas_state == TK_STATE_HIDDEN))) {
itemPtr = itemPtr->nextPtr;
}
if (itemPtr == NULL) {
@@ -4204,8 +4074,8 @@ FindItems(interp, canvasPtr, argc, argv, newTag, first, searchPtrPtr)
double newDist;
/*
- * Update the bounding box using itemPtr, which is the
- * new closest item.
+ * Update the bounding box using itemPtr, which is the new closest
+ * item.
*/
x1 = (int) (coords[0] - closestDist - halo - 1);
@@ -4215,9 +4085,9 @@ FindItems(interp, canvasPtr, argc, argv, newTag, first, searchPtrPtr)
closestPtr = itemPtr;
/*
- * Search for an item that beats the current closest one.
- * Work circularly through the canvas's item list until
- * getting back to the starting item.
+ * Search for an item that beats the current closest one. Work
+ * circularly through the canvas's item list until getting back to
+ * the starting item.
*/
while (1) {
@@ -4229,7 +4099,8 @@ FindItems(interp, canvasPtr, argc, argv, newTag, first, searchPtrPtr)
DoItem(interp, closestPtr, uid);
return TCL_OK;
}
- if (itemPtr->state == TK_STATE_HIDDEN || (itemPtr->state == TK_STATE_NULL &&
+ if (itemPtr->state == TK_STATE_HIDDEN ||
+ (itemPtr->state == TK_STATE_NULL &&
canvasPtr->canvas_state == TK_STATE_HIDDEN)) {
continue;
}
@@ -4249,39 +4120,28 @@ FindItems(interp, canvasPtr, argc, argv, newTag, first, searchPtrPtr)
}
}
break;
- }
- case CANV_ENCLOSED: {
- if (argc != first+5) {
- Tcl_WrongNumArgs(interp, first+1, argv, "x1 y1 x2 y2");
+ }
+ case CANV_ENCLOSED:
+ if (objc != first+5) {
+ Tcl_WrongNumArgs(interp, first+1, objv, "x1 y1 x2 y2");
return TCL_ERROR;
}
- return FindArea(interp, canvasPtr, argv+first+1, uid, 1);
- }
- case CANV_OVERLAPPING: {
- if (argc != first+5) {
- Tcl_WrongNumArgs(interp, first+1, argv, "x1 y1 x2 y2");
+ return FindArea(interp, canvasPtr, objv+first+1, uid, 1);
+ case CANV_OVERLAPPING:
+ if (objc != first+5) {
+ Tcl_WrongNumArgs(interp, first+1, objv, "x1 y1 x2 y2");
return TCL_ERROR;
}
- return FindArea(interp, canvasPtr, argv+first+1, uid, 0);
- }
- case CANV_WITHTAG: {
- if (argc != first+2) {
- Tcl_WrongNumArgs(interp, first+1, argv, "tagOrId");
+ return FindArea(interp, canvasPtr, objv+first+1, uid, 0);
+ case CANV_WITHTAG:
+ if (objc != first+2) {
+ Tcl_WrongNumArgs(interp, first+1, objv, "tagOrId");
return TCL_ERROR;
}
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, argv[first+1], &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if (TagSearchScan(canvasPtr, argv[first+1], searchPtrPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- for (itemPtr = TagSearchFirst(*searchPtrPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(*searchPtrPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(objv[first+1], searchPtrPtr,
+ return TCL_ERROR) {
DoItem(interp, itemPtr, uid);
}
- }
}
return TCL_OK;
}
@@ -4291,53 +4151,49 @@ FindItems(interp, canvasPtr, argc, argv, newTag, first, searchPtrPtr)
*
* FindArea --
*
- * This procedure implements area searches for the "find"
- * and "addtag" options.
+ * This function implements area searches for the "find" and "addtag"
+ * options.
*
* 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 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.
+ * 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
+ * objc 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:
- * If uid is non-NULL, then all the items overlapping
- * or enclosed by the area in argv have that tag added to
- * their lists of tags.
+ * If uid is non-NULL, then all the items overlapping or enclosed by the
+ * area in objv have that tag added to their lists of tags.
*
*--------------------------------------------------------------
*/
static int
-FindArea(interp, canvasPtr, argv, uid, enclosed)
- Tcl_Interp *interp; /* Interpreter for error reporting
- * and result storing. */
- TkCanvas *canvasPtr; /* Canvas whose items are to be
- * searched. */
- Tcl_Obj *CONST *argv; /* Array of four arguments that
- * give the coordinates of the
- * rectangular area to search. */
- 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 the interp's result. */
- int enclosed; /* 0 means overlapping or enclosed
- * items are OK, 1 means only enclosed
- * items are OK. */
+FindArea(
+ Tcl_Interp *interp, /* Interpreter for error reporting and result
+ * storing. */
+ TkCanvas *canvasPtr, /* Canvas whose items are to be searched. */
+ Tcl_Obj *CONST *objv, /* Array of four arguments that give the
+ * coordinates of the rectangular area to
+ * search. */
+ 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 the interp's
+ * result. */
+ int enclosed) /* 0 means overlapping or enclosed items are
+ * OK, 1 means only enclosed items are OK. */
{
double rect[4], tmp;
int x1, y1, x2, y2;
Tk_Item *itemPtr;
- if ((Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, argv[0],
+ if ((Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[0],
&rect[0]) != TCL_OK)
- || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, argv[1],
+ || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[1],
&rect[1]) != TCL_OK)
- || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, argv[2],
+ || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[2],
&rect[2]) != TCL_OK)
- || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, argv[3],
+ || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[3],
&rect[3]) != TCL_OK)) {
return TCL_ERROR;
}
@@ -4349,8 +4205,8 @@ FindArea(interp, canvasPtr, argv, uid, enclosed)
}
/*
- * Use an integer bounding box for a quick test, to avoid
- * calling item-specific code except for items that are close.
+ * Use an integer bounding box for a quick test, to avoid calling
+ * item-specific code except for items that are close.
*/
x1 = (int) (rect[0]-1.0);
@@ -4380,65 +4236,60 @@ FindArea(interp, canvasPtr, argv, uid, enclosed)
*
* RelinkItems --
*
- * Move one or more items to a different place in the
- * display order for a canvas.
+ * Move one or more items to a different place in the display order for a
+ * canvas.
*
* Results:
* None.
*
* Side effects:
- * The items identified by "tag" are moved so that they
- * are all together in the display list and immediately
- * after prevPtr. The order of the moved items relative
- * to each other is not changed.
+ * The items identified by "tag" are moved so that they are all together
+ * in the display list and immediately after prevPtr. The order of the
+ * moved items relative to each other is not changed.
*
*--------------------------------------------------------------
*/
#ifdef USE_OLD_TAG_SEARCH
static void
-RelinkItems(canvasPtr, tag, prevPtr)
+RelinkItems(
+ TkCanvas *canvasPtr, /* Canvas to be modified. */
+ Tcl_Obj *tag, /* Tag identifying items to be moved in the
+ * redisplay list. */
+ Tk_Item *prevPtr) /* Reposition the items so that they go just
+ * after this item (NULL means put at
+ * beginning of list). */
#else /* USE_OLD_TAG_SEARCH */
static int
-RelinkItems(canvasPtr, tag, prevPtr, searchPtrPtr)
+RelinkItems(
+ TkCanvas *canvasPtr, /* Canvas to be modified. */
+ Tcl_Obj *tag, /* Tag identifying items to be moved in the
+ * redisplay list. */
+ Tk_Item *prevPtr, /* Reposition the items so that they go just
+ * after this item (NULL means put at
+ * beginning of list). */
+ TagSearch **searchPtrPtr) /* From CanvasWidgetCmd local vars */
#endif /* USE_OLD_TAG_SEARCH */
- TkCanvas *canvasPtr; /* Canvas to be modified. */
- Tcl_Obj *tag; /* Tag identifying items to be moved
- * in the redisplay list. */
- Tk_Item *prevPtr; /* Reposition the items so that they
- * go just after this item (NULL means
- * put at beginning of list). */
-#ifndef USE_OLD_TAG_SEARCH
- TagSearch **searchPtrPtr; /* From CanvasWidgetCmd local vars */
-#endif /* not USE_OLD_TAG_SEARCH */
{
Tk_Item *itemPtr;
#ifdef USE_OLD_TAG_SEARCH
TagSearch search;
#endif /* USE_OLD_TAG_SEARCH */
Tk_Item *firstMovePtr, *lastMovePtr;
+ int result;
/*
- * Find all of the items to be moved and remove them from
- * the list, making an auxiliary list running from firstMovePtr
- * to lastMovePtr. Record their areas for redisplay.
+ * Find all of the items to be moved and remove them from the list, making
+ * an auxiliary list running from firstMovePtr to lastMovePtr. Record
+ * their areas for redisplay.
*/
firstMovePtr = lastMovePtr = NULL;
-#ifdef USE_OLD_TAG_SEARCH
- for (itemPtr = StartTagSearch(canvasPtr, tag, &search);
- itemPtr != NULL; itemPtr = NextItem(&search)) {
-#else /* USE_OLD_TAG_SEARCH */
- if (TagSearchScan(canvasPtr, tag, searchPtrPtr) != TCL_OK) {
- return TCL_ERROR;
- }
- for (itemPtr = TagSearchFirst(*searchPtrPtr);
- itemPtr != NULL; itemPtr = TagSearchNext(*searchPtrPtr)) {
-#endif /* USE_OLD_TAG_SEARCH */
+ FOR_EVERY_CANVAS_ITEM_MATCHING(tag, searchPtrPtr, return TCL_ERROR) {
if (itemPtr == prevPtr) {
/*
- * Item after which insertion is to occur is being
- * moved! Switch to insert after its predecessor.
+ * Item after which insertion is to occur is being moved! Switch
+ * to insert after its predecessor.
*/
prevPtr = prevPtr->prevPtr;
@@ -4470,15 +4321,15 @@ RelinkItems(canvasPtr, tag, prevPtr, searchPtrPtr)
}
/*
- * Insert the list of to-be-moved items back into the canvas's
- * at the desired position.
+ * Insert the list of to-be-moved items back into the canvas's at the
+ * desired position.
*/
if (firstMovePtr == NULL) {
#ifdef USE_OLD_TAG_SEARCH
return;
#else /* USE_OLD_TAG_SEARCH */
- return TCL_OK;
+ return TCL_OK;
#endif /* USE_OLD_TAG_SEARCH */
}
if (prevPtr == NULL) {
@@ -4510,24 +4361,23 @@ RelinkItems(canvasPtr, tag, prevPtr, searchPtrPtr)
*
* CanvasBindProc --
*
- * This procedure is invoked by the Tk dispatcher to handle
- * events associated with bindings on items.
+ * This function is invoked by the Tk dispatcher to handle events
+ * associated with bindings on items.
*
* Results:
* None.
*
* Side effects:
- * Depends on the command invoked as part of the binding
- * (if there was any).
+ * Depends on the command invoked as part of the binding (if there was
+ * any).
*
*--------------------------------------------------------------
*/
static void
-CanvasBindProc(clientData, eventPtr)
- ClientData clientData; /* Pointer to canvas structure. */
- XEvent *eventPtr; /* Pointer to X event that just
- * happened. */
+CanvasBindProc(
+ ClientData clientData, /* Pointer to canvas structure. */
+ XEvent *eventPtr) /* Pointer to X event that just happened. */
{
TkCanvas *canvasPtr = (TkCanvas *) clientData;
@@ -4535,47 +4385,46 @@ CanvasBindProc(clientData, eventPtr)
/*
* This code below keeps track of the current modifier state in
- * canvasPtr>state. This information is used to defer repicks of
- * the current item while buttons are down.
+ * canvasPtr>state. This information is used to defer repicks of the
+ * current item while buttons are down.
*/
if ((eventPtr->type == ButtonPress) || (eventPtr->type == ButtonRelease)) {
int mask;
switch (eventPtr->xbutton.button) {
- case Button1:
- mask = Button1Mask;
- break;
- case Button2:
- mask = Button2Mask;
- break;
- case Button3:
- mask = Button3Mask;
- break;
- case Button4:
- mask = Button4Mask;
- break;
- case Button5:
- mask = Button5Mask;
- break;
- default:
- mask = 0;
- break;
+ case Button1:
+ mask = Button1Mask;
+ break;
+ case Button2:
+ mask = Button2Mask;
+ break;
+ case Button3:
+ mask = Button3Mask;
+ break;
+ case Button4:
+ mask = Button4Mask;
+ break;
+ case Button5:
+ mask = Button5Mask;
+ break;
+ default:
+ mask = 0;
+ break;
}
/*
- * For button press events, repick the current item using the
- * button state before the event, then process the event. For
- * button release events, first process the event, then repick
- * the current item using the button state *after* the event
- * (the button has logically gone up before we change the
- * current item).
+ * For button press events, repick the current item using the button
+ * state before the event, then process the event. For button release
+ * events, first process the event, then repick the current item using
+ * the button state *after* the event (the button has logically gone
+ * up before we change the current item).
*/
if (eventPtr->type == ButtonPress) {
/*
- * On a button press, first repick the current item using
- * the button state before the event, the process the event.
+ * On a button press, first repick the current item using the
+ * button state before the event, the process the event.
*/
canvasPtr->state = eventPtr->xbutton.state;
@@ -4584,9 +4433,9 @@ CanvasBindProc(clientData, eventPtr)
CanvasDoEvent(canvasPtr, eventPtr);
} else {
/*
- * Button release: first process the event, with the button
- * still considered to be down. Then repick the current
- * item under the assumption that the button is no longer down.
+ * Button release: first process the event, with the button still
+ * considered to be down. Then repick the current item under the
+ * assumption that the button is no longer down.
*/
canvasPtr->state = eventPtr->xbutton.state;
@@ -4608,7 +4457,7 @@ CanvasBindProc(clientData, eventPtr)
}
CanvasDoEvent(canvasPtr, eventPtr);
- done:
+ done:
Tcl_Release((ClientData) canvasPtr);
}
@@ -4617,34 +4466,31 @@ CanvasBindProc(clientData, eventPtr)
*
* PickCurrentItem --
*
- * Find the topmost item in a canvas that contains a given
- * location and mark the the current item. If the current
- * item has changed, generate a fake exit event on the old
- * current item, a fake enter event on the new current item
- * item and force a redraw of the two items. Canvas items
- * that are hidden or disabled are ignored.
+ * Find the topmost item in a canvas that contains a given location and
+ * mark the the current item. If the current item has changed, generate a
+ * fake exit event on the old current item, a fake enter event on the new
+ * current item item and force a redraw of the two items. Canvas items
+ * that are hidden or disabled are ignored.
*
* Results:
* None.
*
* Side effects:
- * The current item for canvasPtr may change. If it does,
- * then the commands associated with item entry and exit
- * could do just about anything. A binding script could
- * delete the canvas, so callers should protect themselves
- * with Tcl_Preserve and Tcl_Release.
+ * The current item for canvasPtr may change. If it does, then the
+ * commands associated with item entry and exit could do just about
+ * anything. A binding script could delete the canvas, so callers should
+ * protect themselves with Tcl_Preserve and Tcl_Release.
*
*--------------------------------------------------------------
*/
static void
-PickCurrentItem(canvasPtr, eventPtr)
- TkCanvas *canvasPtr; /* Canvas widget in which to select
- * current item. */
- XEvent *eventPtr; /* Event describing location of
- * mouse cursor. Must be EnterWindow,
- * LeaveWindow, ButtonRelease, or
- * MotionNotify. */
+PickCurrentItem(
+ TkCanvas *canvasPtr, /* Canvas widget in which to select current
+ * item. */
+ XEvent *eventPtr) /* Event describing location of mouse cursor.
+ * Must be EnterWindow, LeaveWindow,
+ * ButtonRelease, or MotionNotify. */
{
double coords[2];
int buttonDown;
@@ -4654,23 +4500,24 @@ PickCurrentItem(canvasPtr, eventPtr)
#endif
/*
- * Check whether or not a button is down. If so, we'll log entry
- * and exit into and out of the current item, but not entry into
- * any other item. This implements a form of grabbing equivalent
- * to what the X server does for windows.
+ * Check whether or not a button is down. If so, we'll log entry and exit
+ * into and out of the current item, but not entry into any other item.
+ * This implements a form of grabbing equivalent to what the X server does
+ * for windows.
*/
buttonDown = canvasPtr->state
& (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask);
/*
- * Save information about this event in the canvas. The event in
- * the canvas is used for two purposes:
+ * Save information about this event in the canvas. The event in the
+ * canvas is used for two purposes:
*
* 1. Event bindings: if the current item changes, fake events are
* generated to allow item-enter and item-leave bindings to trigger.
- * 2. Reselection: if the current item gets deleted, can use the
- * saved event to find a new current item.
+ * 2. Reselection: if the current item gets deleted, can use the saved
+ * event to find a new current item.
+ *
* Translate MotionNotify events into EnterNotify events, since that's
* what gets reported to item handlers.
*/
@@ -4703,10 +4550,10 @@ PickCurrentItem(canvasPtr, eventPtr)
}
/*
- * If this is a recursive call (there's already a partially completed
- * call pending on the stack; it's in the middle of processing a
- * Leave event handler for the old current item) then just return;
- * the pending call will do everything that's needed.
+ * If this is a recursive call (there's already a partially completed call
+ * pending on the stack; it's in the middle of processing a Leave event
+ * handler for the old current item) then just return; the pending call
+ * will do everything that's needed.
*/
if (canvasPtr->flags & REPICK_IN_PROGRESS) {
@@ -4714,8 +4561,8 @@ PickCurrentItem(canvasPtr, eventPtr)
}
/*
- * A LeaveNotify event automatically means that there's no current
- * object, so the check for closest item can be skipped.
+ * A LeaveNotify event automatically means that there's no current object,
+ * so the check for closest item can be skipped.
*/
coords[0] = canvasPtr->pickEvent.xcrossing.x + canvasPtr->xOrigin;
@@ -4738,12 +4585,11 @@ PickCurrentItem(canvasPtr, eventPtr)
if (!buttonDown) {
canvasPtr->flags &= ~LEFT_GRABBED_ITEM;
}
-
+
/*
- * Simulate a LeaveNotify event on the previous current item and
- * an EnterNotify event on the new current item. Remove the "current"
- * tag from the previous current item and place it on the new current
- * item.
+ * Simulate a LeaveNotify event on the previous current item and an
+ * EnterNotify event on the new current item. Remove the "current" tag
+ * from the previous current item and place it on the new current item.
*/
if ((canvasPtr->newCurrentPtr != canvasPtr->currentItemPtr)
@@ -4757,9 +4603,9 @@ PickCurrentItem(canvasPtr, eventPtr)
event.type = LeaveNotify;
/*
- * If the event's detail happens to be NotifyInferior the
- * binding mechanism will discard the event. To be consistent,
- * always use NotifyAncestor.
+ * If the event's detail happens to be NotifyInferior the binding
+ * mechanism will discard the event. To be consistent, always use
+ * NotifyAncestor.
*/
event.xcrossing.detail = NotifyAncestor;
@@ -4768,28 +4614,29 @@ PickCurrentItem(canvasPtr, eventPtr)
canvasPtr->flags &= ~REPICK_IN_PROGRESS;
/*
- * The check below is needed because there could be an event
- * handler for <LeaveNotify> that deletes the current item.
+ * The check below is needed because there could be an event handler
+ * for <LeaveNotify> that deletes the current item.
*/
if ((itemPtr == canvasPtr->currentItemPtr) && !buttonDown) {
for (i = itemPtr->numTags-1; i >= 0; i--) {
#ifdef USE_OLD_TAG_SEARCH
- if (itemPtr->tagPtr[i] == Tk_GetUid("current")) {
+ if (itemPtr->tagPtr[i] == Tk_GetUid("current"))
#else /* USE_OLD_TAG_SEARCH */
- if (itemPtr->tagPtr[i] == searchUids->currentUid) {
+ if (itemPtr->tagPtr[i] == searchUids->currentUid)
#endif /* USE_OLD_TAG_SEARCH */
+ /* then */ {
itemPtr->tagPtr[i] = itemPtr->tagPtr[itemPtr->numTags-1];
itemPtr->numTags--;
break;
}
}
}
-
+
/*
- * Note: during CanvasDoEvent above, it's possible that
- * canvasPtr->newCurrentPtr got reset to NULL because the
- * item was deleted.
+ * Note: during CanvasDoEvent above, it's possible that
+ * canvasPtr->newCurrentPtr got reset to NULL because the item was
+ * deleted.
*/
}
if ((canvasPtr->newCurrentPtr != canvasPtr->currentItemPtr) && buttonDown) {
@@ -4798,9 +4645,9 @@ PickCurrentItem(canvasPtr, eventPtr)
}
/*
- * Special note: it's possible that canvasPtr->newCurrentPtr ==
- * canvasPtr->currentItemPtr here. This can happen, for example,
- * if LEFT_GRABBED_ITEM was set.
+ * Special note: it's possible that canvasPtr->newCurrentPtr ==
+ * canvasPtr->currentItemPtr here. This can happen, for example, if
+ * LEFT_GRABBED_ITEM was set.
*/
prevItemPtr = canvasPtr->currentItemPtr;
@@ -4810,23 +4657,21 @@ PickCurrentItem(canvasPtr, eventPtr)
(prevItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT)) {
EventuallyRedrawItem((Tk_Canvas) canvasPtr, prevItemPtr);
(*prevItemPtr->typePtr->configProc)(canvasPtr->interp,
- (Tk_Canvas) canvasPtr, prevItemPtr, 0, (Tcl_Obj **) NULL,
+ (Tk_Canvas) canvasPtr, prevItemPtr, 0, NULL,
TK_CONFIG_ARGV_ONLY);
}
if (canvasPtr->currentItemPtr != NULL) {
XEvent event;
#ifdef USE_OLD_TAG_SEARCH
- DoItem((Tcl_Interp *) NULL, canvasPtr->currentItemPtr,
- Tk_GetUid("current"));
+ DoItem(NULL, canvasPtr->currentItemPtr, Tk_GetUid("current"));
#else /* USE_OLD_TAG_SEARCH */
- DoItem((Tcl_Interp *) NULL, canvasPtr->currentItemPtr,
- searchUids->currentUid);
+ DoItem(NULL, canvasPtr->currentItemPtr, searchUids->currentUid);
#endif /* USE_OLD_TAG_SEA */
if ((canvasPtr->currentItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT &&
prevItemPtr != canvasPtr->currentItemPtr)) {
(*canvasPtr->currentItemPtr->typePtr->configProc)(canvasPtr->interp,
- (Tk_Canvas) canvasPtr, canvasPtr->currentItemPtr, 0, (Tcl_Obj **) NULL,
+ (Tk_Canvas) canvasPtr, canvasPtr->currentItemPtr, 0, NULL,
TK_CONFIG_ARGV_ONLY);
EventuallyRedrawItem((Tk_Canvas) canvasPtr,
canvasPtr->currentItemPtr);
@@ -4843,13 +4688,13 @@ PickCurrentItem(canvasPtr, eventPtr)
*
* CanvasFindClosest --
*
- * Given x and y coordinates, find the topmost canvas item that
- * is "close" to the coordinates. Canvas items that are hidden
- * or disabled are ignored.
+ * Given x and y coordinates, find the topmost canvas item that is
+ * "close" to the coordinates. Canvas items that are hidden or disabled
+ * are ignored.
*
* Results:
- * The return value is a pointer to the topmost item that is
- * close to (x,y), or NULL if no item is close.
+ * The return value is a pointer to the topmost item that is close to
+ * (x,y), or NULL if no item is close.
*
* Side effects:
* None.
@@ -4858,10 +4703,10 @@ PickCurrentItem(canvasPtr, eventPtr)
*/
static Tk_Item *
-CanvasFindClosest(canvasPtr, coords)
- TkCanvas *canvasPtr; /* Canvas widget to search. */
- double coords[2]; /* Desired x,y position in canvas,
- * not screen, coordinates.) */
+CanvasFindClosest(
+ TkCanvas *canvasPtr, /* Canvas widget to search. */
+ double coords[2]) /* Desired x,y position in canvas, not screen,
+ * coordinates.) */
{
Tk_Item *itemPtr;
Tk_Item *bestPtr;
@@ -4897,27 +4742,25 @@ CanvasFindClosest(canvasPtr, coords)
*
* CanvasDoEvent --
*
- * This procedure is called to invoke binding processing
- * for a new event that is associated with the current item
- * for a canvas.
+ * This function is called to invoke binding processing for a new event
+ * that is associated with the current item for a canvas.
*
* Results:
* None.
*
* Side effects:
- * Depends on the bindings for the canvas. A binding script
- * could delete the canvas, so callers should protect themselves
- * with Tcl_Preserve and Tcl_Release.
+ * Depends on the bindings for the canvas. A binding script could delete
+ * the canvas, so callers should protect themselves with Tcl_Preserve and
+ * Tcl_Release.
*
*--------------------------------------------------------------
*/
static void
-CanvasDoEvent(canvasPtr, eventPtr)
- TkCanvas *canvasPtr; /* Canvas widget in which event
- * occurred. */
- XEvent *eventPtr; /* Real or simulated X event that
- * is to be processed. */
+CanvasDoEvent(
+ TkCanvas *canvasPtr, /* Canvas widget in which event occurred. */
+ XEvent *eventPtr) /* Real or simulated X event that is to be
+ * processed. */
{
#define NUM_STATIC 3
ClientData staticObjects[NUM_STATIC];
@@ -4944,30 +4787,30 @@ CanvasDoEvent(canvasPtr, eventPtr)
#ifdef USE_OLD_TAG_SEARCH
/*
- * Set up an array with all the relevant objects for processing
- * this event. The relevant objects are (a) the event's item,
- * (b) the tags associated with the event's item, and (c) the
- * tag "all". If there are a lot of tags then malloc an array
- * to hold all of the objects.
+ * Set up an array with all the relevant objects for processing this
+ * event. The relevant objects are (a) the event's item, (b) the tags
+ * associated with the event's item, and (c) the tag "all". If there are a
+ * lot of tags then malloc an array to hold all of the objects.
*/
numObjects = itemPtr->numTags + 2;
#else /* USE_OLD_TAG_SEARCH */
/*
- * Set up an array with all the relevant objects for processing
- * this event. The relevant objects are:
+ * Set up an array with all the relevant objects for processing this
+ * event. The relevant objects are:
* (a) the event's item,
- * (b) the tags associated with the event's item,
+ * (b) the tags associated with the event's item,
* (c) the expressions that are true for the event's item's tags, and
- * (d) the tag "all".
+ * (d) the tag "all".
*
- * If there are a lot of tags then malloc an array to hold all of
- * the objects.
+ * If there are a lot of tags then malloc an array to hold all of the
+ * objects.
*/
/*
- * flag and count all expressions that match item's tags
+ * Flag and count all expressions that match item's tags.
*/
+
numExprs = 0;
expr = canvasPtr->bindTagExprs;
while (expr) {
@@ -4984,8 +4827,8 @@ CanvasDoEvent(canvasPtr, eventPtr)
if (numObjects <= NUM_STATIC) {
objectPtr = staticObjects;
} else {
- objectPtr = (ClientData *)
- ckalloc((unsigned) (numObjects * sizeof(ClientData)));
+ objectPtr = (ClientData *) ckalloc((unsigned)
+ (numObjects * sizeof(ClientData)));
}
#ifdef USE_OLD_TAG_SEARCH
objectPtr[0] = (ClientData) Tk_GetUid("all");
@@ -4996,10 +4839,12 @@ CanvasDoEvent(canvasPtr, eventPtr)
objectPtr[i+1] = (ClientData) itemPtr->tagPtr[i];
}
objectPtr[itemPtr->numTags+1] = (ClientData) itemPtr;
+
#ifndef USE_OLD_TAG_SEARCH
/*
- * copy uids of matching expressions into object array
+ * Copy uids of matching expressions into object array
*/
+
i = itemPtr->numTags+2;
expr = canvasPtr->bindTagExprs;
while (expr) {
@@ -5011,8 +4856,8 @@ CanvasDoEvent(canvasPtr, eventPtr)
#endif /* not USE_OLD_TAG_SEARCH */
/*
- * Invoke the binding system, then free up the object array if
- * it was malloc-ed.
+ * Invoke the binding system, then free up the object array if it was
+ * malloc-ed.
*/
if (canvasPtr->tkwin != NULL) {
@@ -5029,22 +4874,22 @@ CanvasDoEvent(canvasPtr, eventPtr)
*
* CanvasBlinkProc --
*
- * This procedure is called as a timer handler to blink the
- * insertion cursor off and on.
+ * This function is called as a timer handler to blink the insertion
+ * cursor off and on.
*
* Results:
* None.
*
* Side effects:
- * The cursor gets turned on or off, redisplay gets invoked,
- * and this procedure reschedules itself.
+ * The cursor gets turned on or off, redisplay gets invoked, and this
+ * function reschedules itself.
*
*----------------------------------------------------------------------
*/
static void
-CanvasBlinkProc(clientData)
- ClientData clientData; /* Pointer to record describing entry. */
+CanvasBlinkProc(
+ ClientData clientData) /* Pointer to record describing entry. */
{
TkCanvas *canvasPtr = (TkCanvas *) clientData;
@@ -5073,9 +4918,9 @@ CanvasBlinkProc(clientData)
*
* CanvasFocusProc --
*
- * This procedure is called whenever a canvas gets or loses the
- * input focus. It's also called whenever the window is
- * reconfigured while it has the focus.
+ * This function is called whenever a canvas gets or loses the input
+ * focus. It's also called whenever the window is reconfigured while it
+ * has the focus.
*
* Results:
* None.
@@ -5087,9 +4932,9 @@ CanvasBlinkProc(clientData)
*/
static void
-CanvasFocusProc(canvasPtr, gotFocus)
- TkCanvas *canvasPtr; /* Canvas that just got or lost focus. */
- int gotFocus; /* 1 means window is getting focus, 0 means
+CanvasFocusProc(
+ TkCanvas *canvasPtr, /* Canvas that just got or lost focus. */
+ int gotFocus) /* 1 means window is getting focus, 0 means
* it's losing it. */
{
Tcl_DeleteTimerHandler(canvasPtr->insertBlinkHandler);
@@ -5124,8 +4969,8 @@ CanvasFocusProc(canvasPtr, gotFocus)
*
* CanvasSelectTo --
*
- * Modify the selection by moving its un-anchored end. This could
- * make the selection either larger or smaller.
+ * Modify the selection by moving its un-anchored end. This could make
+ * the selection either larger or smaller.
*
* Results:
* None.
@@ -5137,10 +4982,10 @@ CanvasFocusProc(canvasPtr, gotFocus)
*/
static void
-CanvasSelectTo(canvasPtr, itemPtr, index)
- TkCanvas *canvasPtr; /* Information about widget. */
- Tk_Item *itemPtr; /* Item that is to hold selection. */
- int index; /* Index of element that is to become the
+CanvasSelectTo(
+ TkCanvas *canvasPtr, /* Information about widget. */
+ Tk_Item *itemPtr, /* Item that is to hold selection. */
+ int index) /* Index of element that is to become the
* "other" end of the selection. */
{
int oldFirst, oldLast;
@@ -5186,15 +5031,15 @@ CanvasSelectTo(canvasPtr, itemPtr, index)
*
* CanvasFetchSelection --
*
- * This procedure is invoked by Tk to return part or all of
- * the selection, when the selection is in a canvas widget.
- * This procedure always returns the selection as a STRING.
+ * This function is invoked by Tk to return part or all of the selection,
+ * when the selection is in a canvas widget. This function always returns
+ * the selection as a STRING.
*
* Results:
- * The return value is the number of non-NULL bytes stored
- * at buffer. Buffer is filled (or partially filled) with a
- * NULL-terminated string containing part or all of the selection,
- * as given by offset and maxBytes.
+ * The return value is the number of non-NULL bytes stored at buffer.
+ * Buffer is filled (or partially filled) with a NULL-terminated string
+ * containing part or all of the selection, as given by offset and
+ * maxBytes.
*
* Side effects:
* None.
@@ -5203,15 +5048,14 @@ CanvasSelectTo(canvasPtr, itemPtr, index)
*/
static int
-CanvasFetchSelection(clientData, offset, buffer, maxBytes)
- ClientData clientData; /* Information about canvas 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. */
+CanvasFetchSelection(
+ ClientData clientData, /* Information about canvas 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. */
{
TkCanvas *canvasPtr = (TkCanvas *) clientData;
@@ -5231,22 +5075,22 @@ CanvasFetchSelection(clientData, offset, buffer, maxBytes)
*
* CanvasLostSelection --
*
- * This procedure is called back by Tk when the selection is
- * grabbed away from a canvas widget.
+ * This function is called back by Tk when the selection is grabbed away
+ * from a canvas widget.
*
* Results:
* None.
*
* Side effects:
- * The existing selection is unhighlighted, and the window is
- * marked as not containing a selection.
+ * The existing selection is unhighlighted, and the window is marked as
+ * not containing a selection.
*
*----------------------------------------------------------------------
*/
static void
-CanvasLostSelection(clientData)
- ClientData clientData; /* Information about entry widget. */
+CanvasLostSelection(
+ ClientData clientData) /* Information about entry widget. */
{
TkCanvas *canvasPtr = (TkCanvas *) clientData;
@@ -5262,13 +5106,11 @@ CanvasLostSelection(clientData)
*
* GridAlign --
*
- * Given a coordinate and a grid spacing, this procedure
- * computes the location of the nearest grid line to the
- * coordinate.
+ * Given a coordinate and a grid spacing, this function computes the
+ * location of the nearest grid line to the coordinate.
*
* Results:
- * The return value is the location of the grid line nearest
- * to coord.
+ * The return value is the location of the grid line nearest to coord.
*
* Side effects:
* None.
@@ -5277,10 +5119,10 @@ CanvasLostSelection(clientData)
*/
static double
-GridAlign(coord, spacing)
- double coord; /* Coordinate to grid-align. */
- double spacing; /* Spacing between grid lines. If <= 0
- * then no alignment is done. */
+GridAlign(
+ double coord, /* Coordinate to grid-align. */
+ double spacing) /* Spacing between grid lines. If <= 0 then no
+ * alignment is done. */
{
if (spacing <= 0.0) {
return coord;
@@ -5296,15 +5138,14 @@ GridAlign(coord, spacing)
*
* ScrollFractions --
*
- * Given the range that's visible in the window and the "100%
- * range" for what's in the canvas, return a list of two
- * doubles representing the scroll fractions. This procedure
- * is used for both x and y scrolling.
+ * Given the range that's visible in the window and the "100% range" for
+ * what's in the canvas, return a list of two doubles representing the
+ * scroll fractions. This function is used for both x and y scrolling.
*
* Results:
- * The memory pointed to by string is modified to hold
- * two real numbers containing the scroll fractions (between
- * 0 and 1) corresponding to the other arguments.
+ * A List Tcl_Obj with two real numbers (Double Tcl_Objs) containing the
+ * scroll fractions (between 0 and 1) corresponding to the other
+ * arguments.
*
* Side effects:
* None.
@@ -5313,14 +5154,14 @@ GridAlign(coord, spacing)
*/
static Tcl_Obj *
-ScrollFractions(screen1, screen2, object1, object2)
- int screen1; /* Lowest coordinate visible in the window. */
- int screen2; /* Highest coordinate visible in the window. */
- int object1; /* Lowest coordinate in the object. */
- int object2; /* Highest coordinate in the object. */
+ScrollFractions(
+ int screen1, /* Lowest coordinate visible in the window. */
+ int screen2, /* Highest coordinate visible in the window. */
+ int object1, /* Lowest coordinate in the object. */
+ int object2) /* Highest coordinate in the object. */
{
+ Tcl_Obj *buffer[2];
double range, f1, f2;
- char buffer[2*TCL_DOUBLE_SPACE+2];
range = object2 - object1;
if (range <= 0) {
@@ -5339,8 +5180,9 @@ ScrollFractions(screen1, screen2, object1, object2)
f2 = f1;
}
}
- sprintf(buffer, "%g %g", f1, f2);
- return Tcl_NewStringObj(buffer, -1);
+ buffer[0] = Tcl_NewDoubleObj(f1);
+ buffer[1] = Tcl_NewDoubleObj(f2);
+ return Tcl_NewListObj(2, buffer);
}
/*
@@ -5348,46 +5190,45 @@ ScrollFractions(screen1, screen2, object1, object2)
*
* CanvasUpdateScrollbars --
*
- * This procedure is invoked whenever a canvas has changed in
- * a way that requires scrollbars to be redisplayed (e.g. the
- * view in the canvas has changed).
+ * This function is invoked whenever a canvas has changed in a way that
+ * requires scrollbars to be redisplayed (e.g. the view in the canvas has
+ * changed).
*
* Results:
* None.
*
* Side effects:
- * If there are scrollbars associated with the canvas, then
- * their scrolling commands are invoked to cause them to
- * redisplay. If errors occur, additional Tcl commands may
- * be invoked to process the errors.
+ * If there are scrollbars associated with the canvas, then their
+ * scrolling commands are invoked to cause them to redisplay. If errors
+ * occur, additional Tcl commands may be invoked to process the errors.
*
*--------------------------------------------------------------
*/
static void
-CanvasUpdateScrollbars(canvasPtr)
- TkCanvas *canvasPtr; /* Information about canvas. */
+CanvasUpdateScrollbars(
+ TkCanvas *canvasPtr) /* Information about canvas. */
{
int result;
Tcl_Interp *interp;
- int xOrigin, yOrigin, inset, width, height, scrollX1, scrollX2,
- scrollY1, scrollY2;
+ int xOrigin, yOrigin, inset, width, height;
+ int scrollX1, scrollX2, scrollY1, scrollY2;
char *xScrollCmd, *yScrollCmd;
/*
* Save all the relevant values from the canvasPtr, because it might be
* deleted as part of either of the two calls to Tcl_VarEval below.
*/
-
+
interp = canvasPtr->interp;
Tcl_Preserve((ClientData) interp);
xScrollCmd = canvasPtr->xScrollCmd;
- if (xScrollCmd != (char *) NULL) {
- Tcl_Preserve((ClientData) xScrollCmd);
+ if (xScrollCmd != NULL) {
+ Tcl_Preserve((ClientData) xScrollCmd);
}
yScrollCmd = canvasPtr->yScrollCmd;
- if (yScrollCmd != (char *) NULL) {
- Tcl_Preserve((ClientData) yScrollCmd);
+ if (yScrollCmd != NULL) {
+ Tcl_Preserve((ClientData) yScrollCmd);
}
xOrigin = canvasPtr->xOrigin;
yOrigin = canvasPtr->yOrigin;
@@ -5402,27 +5243,27 @@ CanvasUpdateScrollbars(canvasPtr)
if (canvasPtr->xScrollCmd != NULL) {
Tcl_Obj *fractions = ScrollFractions(xOrigin + inset,
xOrigin + width - inset, scrollX1, scrollX2);
- result = Tcl_VarEval(interp, xScrollCmd, " ",
- Tcl_GetString(fractions), (char *) NULL);
+ result = Tcl_VarEval(interp, xScrollCmd, " ", Tcl_GetString(fractions),
+ NULL);
Tcl_DecrRefCount(fractions);
if (result != TCL_OK) {
Tcl_BackgroundError(interp);
}
Tcl_ResetResult(interp);
- Tcl_Release((ClientData) xScrollCmd);
+ Tcl_Release((ClientData) xScrollCmd);
}
if (yScrollCmd != NULL) {
Tcl_Obj *fractions = ScrollFractions(yOrigin + inset,
yOrigin + height - inset, scrollY1, scrollY2);
- result = Tcl_VarEval(interp, yScrollCmd, " ",
- Tcl_GetString(fractions), (char *) NULL);
+ result = Tcl_VarEval(interp, yScrollCmd, " ", Tcl_GetString(fractions),
+ NULL);
Tcl_DecrRefCount(fractions);
if (result != TCL_OK) {
Tcl_BackgroundError(interp);
}
Tcl_ResetResult(interp);
- Tcl_Release((ClientData) yScrollCmd);
+ Tcl_Release((ClientData) yScrollCmd);
}
Tcl_Release((ClientData) interp);
}
@@ -5432,38 +5273,35 @@ CanvasUpdateScrollbars(canvasPtr)
*
* CanvasSetOrigin --
*
- * This procedure is invoked to change the mapping between
- * canvas coordinates and screen coordinates in the canvas
- * window.
+ * This function is invoked to change the mapping between canvas
+ * coordinates and screen coordinates in the canvas window.
*
* Results:
* None.
*
* Side effects:
- * The canvas will be redisplayed to reflect the change in
- * view. In addition, scrollbars will be updated if there
- * are any.
+ * The canvas will be redisplayed to reflect the change in view. In
+ * addition, scrollbars will be updated if there are any.
*
*--------------------------------------------------------------
*/
static void
-CanvasSetOrigin(canvasPtr, xOrigin, yOrigin)
- TkCanvas *canvasPtr; /* Information about canvas. */
- int xOrigin; /* New X origin for canvas (canvas x-coord
+CanvasSetOrigin(
+ TkCanvas *canvasPtr, /* Information about canvas. */
+ int xOrigin, /* New X origin for canvas (canvas x-coord
* corresponding to left edge of canvas
* window). */
- int yOrigin; /* New Y origin for canvas (canvas y-coord
+ int yOrigin) /* New Y origin for canvas (canvas y-coord
* corresponding to top edge of canvas
* window). */
{
int left, right, top, bottom, delta;
/*
- * If scroll increments have been set, round the window origin
- * to the nearest multiple of the increments. Remember, the
- * origin is the place just inside the borders, not the upper
- * left corner.
+ * If scroll increments have been set, round the window origin to the
+ * nearest multiple of the increments. Remember, the origin is the place
+ * just inside the borders, not the upper left corner.
*/
if (canvasPtr->xScrollIncrement > 0) {
@@ -5491,13 +5329,13 @@ CanvasSetOrigin(canvasPtr, xOrigin, yOrigin)
/*
* Adjust the origin if necessary to keep as much as possible of the
- * canvas in the view. The variables left, right, etc. keep track of
- * how much extra space there is on each side of the view before it
- * will stick out past the scroll region. If one side sticks out past
- * the edge of the scroll region, adjust the view to bring that side
- * back to the edge of the scrollregion (but don't move it so much that
- * the other side sticks out now). If scroll increments are in effect,
- * be sure to adjust only by full increments.
+ * canvas in the view. The variables left, right, etc. keep track of how
+ * much extra space there is on each side of the view before it will stick
+ * out past the scroll region. If one side sticks out past the edge of
+ * the scroll region, adjust the view to bring that side back to the edge
+ * of the scrollregion (but don't move it so much that the other side
+ * sticks out now). If scroll increments are in effect, be sure to adjust
+ * only by full increments.
*/
if ((canvasPtr->confine) && (canvasPtr->regionString != NULL)) {
@@ -5540,11 +5378,11 @@ CanvasSetOrigin(canvasPtr, xOrigin, yOrigin)
}
/*
- * Tricky point: must redisplay not only everything that's visible
- * in the window's final configuration, but also everything that was
- * visible in the initial configuration. This is needed because some
- * item types, like windows, need to know when they move off-screen
- * so they can explicitly undisplay themselves.
+ * Tricky point: must redisplay not only everything that's visible in the
+ * window's final configuration, but also everything that was visible in
+ * the initial configuration. This is needed because some item types, like
+ * windows, need to know when they move off-screen so they can explicitly
+ * undisplay themselves.
*/
Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
@@ -5559,37 +5397,38 @@ CanvasSetOrigin(canvasPtr, xOrigin, yOrigin)
canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin),
canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin));
}
-
+
/*
*----------------------------------------------------------------------
*
- * GetStringsFromObjs
+ * TkGetStringsFromObjs --
*
* Results:
* Converts object list into string list.
*
* Side effects:
- * Memory is allocated for the argv array, which must
- * be freed using ckfree() when no longer needed.
+ * Memory is allocated for the objv array, which must be freed using
+ * ckfree() when no longer needed.
*
*----------------------------------------------------------------------
*/
+
/* ARGSUSED */
static CONST char **
-GetStringsFromObjs(argc, objv)
- int argc;
- Tcl_Obj *CONST objv[];
+TkGetStringsFromObjs(
+ int objc,
+ Tcl_Obj *CONST objv[])
{
register int i;
CONST char **argv;
- if (argc <= 0) {
+ if (objc <= 0) {
return NULL;
}
- argv = (CONST char **) ckalloc((argc+1) * sizeof(char *));
- for (i = 0; i < argc; i++) {
- argv[i] = Tcl_GetStringFromObj(objv[i], NULL);
+ argv = (CONST char **) ckalloc((objc+1) * sizeof(char *));
+ for (i = 0; i < objc; i++) {
+ argv[i] = Tcl_GetString(objv[i]);
}
- argv[argc] = 0;
+ argv[objc] = 0;
return argv;
}
@@ -5598,16 +5437,15 @@ GetStringsFromObjs(argc, objv)
*
* Tk_CanvasPsColor --
*
- * This procedure is called by individual canvas items when
- * they want to set a color value for output. Given information
- * about an X color, this procedure will generate Postscript
- * commands to set up an appropriate color in Postscript.
+ * This function is called by individual canvas items when they want to
+ * set a color value for output. Given information about an X color, this
+ * function will generate Postscript commands to set up an appropriate
+ * color in Postscript.
*
* Results:
- * Returns a standard Tcl return value. If an error occurs
- * then an error message will be left in interp->result.
- * If no error occurs, then additional Postscript will be
- * appended to interp->result.
+ * Returns a standard Tcl return value. If an error occurs then an error
+ * message will be left in interp->result. If no error occurs, then
+ * additional Postscript will be appended to interp->result.
*
* Side effects:
* None.
@@ -5616,11 +5454,11 @@ GetStringsFromObjs(argc, objv)
*/
int
-Tk_CanvasPsColor(interp, canvas, colorPtr)
- Tcl_Interp *interp; /* Interpreter for returning Postscript
- * or error message. */
- Tk_Canvas canvas; /* Information about canvas. */
- XColor *colorPtr; /* Information about color. */
+Tk_CanvasPsColor(
+ Tcl_Interp *interp, /* Interpreter for returning Postscript or
+ * error message. */
+ Tk_Canvas canvas, /* Information about canvas. */
+ XColor *colorPtr) /* Information about color. */
{
return Tk_PostscriptColor(interp, ((TkCanvas *) canvas)->psInfo,
colorPtr);
@@ -5631,31 +5469,30 @@ Tk_CanvasPsColor(interp, canvas, colorPtr)
*
* Tk_CanvasPsFont --
*
- * This procedure is called by individual canvas items when
- * they want to output text. Given information about an X
- * font, this procedure will generate Postscript commands
- * to set up an appropriate font in Postscript.
+ * This function is called by individual canvas items when they want to
+ * output text. Given information about an X font, this function will
+ * generate Postscript commands to set up an appropriate font in
+ * Postscript.
*
* Results:
- * Returns a standard Tcl return value. If an error occurs
- * then an error message will be left in interp->result.
- * If no error occurs, then additional Postscript will be
- * appended to the interp->result.
+ * Returns a standard Tcl return value. If an error occurs then an error
+ * message will be left in interp->result. If no error occurs, then
+ * additional Postscript will be appended to the interp->result.
*
* Side effects:
- * The Postscript font name is entered into psInfoPtr->fontTable
- * if it wasn't already there.
+ * The Postscript font name is entered into psInfoPtr->fontTable if it
+ * wasn't already there.
*
*--------------------------------------------------------------
*/
int
-Tk_CanvasPsFont(interp, canvas, tkfont)
- Tcl_Interp *interp; /* Interpreter for returning Postscript
- * or error message. */
- Tk_Canvas canvas; /* Information about canvas. */
- Tk_Font tkfont; /* Information about font in which text
- * is to be printed. */
+Tk_CanvasPsFont(
+ Tcl_Interp *interp, /* Interpreter for returning Postscript or
+ * error message. */
+ Tk_Canvas canvas, /* Information about canvas. */
+ Tk_Font tkfont) /* Information about font in which text is to
+ * be printed. */
{
return Tk_PostscriptFont(interp, ((TkCanvas *) canvas)->psInfo, tkfont);
}
@@ -5665,16 +5502,14 @@ Tk_CanvasPsFont(interp, canvas, tkfont)
*
* Tk_CanvasPsBitmap --
*
- * This procedure is called to output the contents of a
- * sub-region of a bitmap in proper image data format for
- * Postscript (i.e. data between angle brackets, one bit
- * per pixel).
+ * This function is called to output the contents of a sub-region of a
+ * bitmap in proper image data format for Postscript (i.e. data between
+ * angle brackets, one bit per pixel).
*
* Results:
- * Returns a standard Tcl return value. If an error occurs
- * then an error message will be left in interp->result.
- * If no error occurs, then additional Postscript will be
- * appended to interp->result.
+ * Returns a standard Tcl return value. If an error occurs then an error
+ * message will be left in interp->result. If no error occurs, then
+ * additional Postscript will be appended to interp->result.
*
* Side effects:
* None.
@@ -5683,15 +5518,14 @@ Tk_CanvasPsFont(interp, canvas, tkfont)
*/
int
-Tk_CanvasPsBitmap(interp, canvas, bitmap, startX, startY, width, height)
- Tcl_Interp *interp; /* Interpreter for returning Postscript
- * or error message. */
- Tk_Canvas canvas; /* Information about canvas. */
- Pixmap bitmap; /* Bitmap for which to generate
- * Postscript. */
- int startX, startY; /* Coordinates of upper-left corner
- * of rectangular region to output. */
- int width, height; /* Height of rectangular region. */
+Tk_CanvasPsBitmap(
+ Tcl_Interp *interp, /* Interpreter for returning Postscript or
+ * error message. */
+ Tk_Canvas canvas, /* Information about canvas. */
+ Pixmap bitmap, /* Bitmap for which to generate Postscript. */
+ int startX, int startY, /* Coordinates of upper-left corner of
+ * rectangular region to output. */
+ int width, int height) /* Size of rectangular region. */
{
return Tk_PostscriptBitmap(interp, ((TkCanvas *) canvas)->tkwin,
((TkCanvas *) canvas)->psInfo, bitmap, startX, startY,
@@ -5703,18 +5537,16 @@ Tk_CanvasPsBitmap(interp, canvas, bitmap, startX, startY, width, height)
*
* Tk_CanvasPsStipple --
*
- * This procedure is called by individual canvas items when
- * they have created a path that they'd like to be filled with
- * a stipple pattern. Given information about an X bitmap,
- * this procedure will generate Postscript commands to fill
- * the current clip region using a stipple pattern defined by the
- * bitmap.
+ * This function is called by individual canvas items when they have
+ * created a path that they'd like to be filled with a stipple pattern.
+ * Given information about an X bitmap, this function will generate
+ * Postscript commands to fill the current clip region using a stipple
+ * pattern defined by the bitmap.
*
* Results:
- * Returns a standard Tcl return value. If an error occurs
- * then an error message will be left in interp->result.
- * If no error occurs, then additional Postscript will be
- * appended to interp->result.
+ * Returns a standard Tcl return value. If an error occurs then an error
+ * message will be left in interp->result. If no error occurs, then
+ * additional Postscript will be appended to interp->result.
*
* Side effects:
* None.
@@ -5723,11 +5555,11 @@ Tk_CanvasPsBitmap(interp, canvas, bitmap, startX, startY, width, height)
*/
int
-Tk_CanvasPsStipple(interp, canvas, bitmap)
- Tcl_Interp *interp; /* Interpreter for returning Postscript
- * or error message. */
- Tk_Canvas canvas; /* Information about canvas. */
- Pixmap bitmap; /* Bitmap to use for stippling. */
+Tk_CanvasPsStipple(
+ Tcl_Interp *interp, /* Interpreter for returning Postscript or
+ * error message. */
+ Tk_Canvas canvas, /* Information about canvas. */
+ Pixmap bitmap) /* Bitmap to use for stippling. */
{
return Tk_PostscriptStipple(interp, ((TkCanvas *) canvas)->tkwin,
((TkCanvas *) canvas)->psInfo, bitmap);
@@ -5738,12 +5570,11 @@ Tk_CanvasPsStipple(interp, canvas, bitmap)
*
* Tk_CanvasPsY --
*
- * Given a y-coordinate in canvas coordinates, this procedure
- * returns a y-coordinate to use for Postscript output.
+ * Given a y-coordinate in canvas coordinates, this function returns a
+ * y-coordinate to use for Postscript output.
*
* Results:
- * Returns the Postscript coordinate that corresponds to
- * "y".
+ * Returns the Postscript coordinate that corresponds to "y".
*
* Side effects:
* None.
@@ -5752,10 +5583,10 @@ Tk_CanvasPsStipple(interp, canvas, bitmap)
*/
double
-Tk_CanvasPsY(canvas, y)
- Tk_Canvas canvas; /* Token for canvas on whose behalf
- * Postscript is being generated. */
- double y; /* Y-coordinate in canvas coords. */
+Tk_CanvasPsY(
+ Tk_Canvas canvas, /* Token for canvas on whose behalf Postscript
+ * is being generated. */
+ double y) /* Y-coordinate in canvas coords. */
{
return Tk_PostscriptY(y, ((TkCanvas *) canvas)->psInfo);
}
@@ -5765,8 +5596,8 @@ Tk_CanvasPsY(canvas, y)
*
* Tk_CanvasPsPath --
*
- * Given an array of points for a path, generate Postscript
- * commands to create the path.
+ * Given an array of points for a path, generate Postscript commands to
+ * create the path.
*
* Results:
* Postscript commands get appended to what's in interp->result.
@@ -5778,16 +5609,23 @@ Tk_CanvasPsY(canvas, y)
*/
void
-Tk_CanvasPsPath(interp, canvas, coordPtr, numPoints)
- Tcl_Interp *interp; /* Put generated Postscript in this
- * interpreter's result field. */
- Tk_Canvas canvas; /* Canvas on whose behalf Postscript
- * is being generated. */
- double *coordPtr; /* Pointer to first in array of
- * 2*numPoints coordinates giving
- * points for path. */
- int numPoints; /* Number of points at *coordPtr. */
+Tk_CanvasPsPath(
+ Tcl_Interp *interp, /* Put generated Postscript in this
+ * interpreter's result field. */
+ Tk_Canvas canvas, /* Canvas on whose behalf Postscript is being
+ * generated. */
+ double *coordPtr, /* Pointer to first in array of 2*numPoints
+ * coordinates giving points for path. */
+ int numPoints) /* Number of points at *coordPtr. */
{
Tk_PostscriptPath(interp, ((TkCanvas *) canvas)->psInfo,
coordPtr, numPoints);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkCanvas.h b/generic/tkCanvas.h
index ad6c555..d009cfa 100644
--- a/generic/tkCanvas.h
+++ b/generic/tkCanvas.h
@@ -1,15 +1,14 @@
/*
* tkCanvas.h --
*
- * Declarations shared among all the files that implement
- * canvas widgets.
+ * Declarations shared among all the files that implement canvas widgets.
*
* Copyright (c) 1991-1994 The Regents of the University of California.
* Copyright (c) 1994-1995 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKCANVAS
@@ -23,36 +22,39 @@
typedef struct TagSearchExpr_s TagSearchExpr;
struct TagSearchExpr_s {
- TagSearchExpr *next; /* for linked lists of expressions - used in bindings */
- Tk_Uid uid; /* the uid of the whole expression */
- Tk_Uid *uids; /* expresion compiled to an array of uids */
- int allocated; /* available space for array of uids */
- int length; /* length of expression */
- int index; /* current position in expression evaluation */
- int match; /* this expression matches event's item's tags*/
+ TagSearchExpr *next; /* For linked lists of expressions - used in
+ * bindings. */
+ Tk_Uid uid; /* The uid of the whole expression. */
+ Tk_Uid *uids; /* Expresion compiled to an array of uids. */
+ int allocated; /* Available space for array of uids. */
+ int length; /* Length of expression. */
+ int index; /* Current position in expression
+ * evaluation. */
+ int match; /* This expression matches event's item's
+ * tags. */
};
#endif /* not USE_OLD_TAG_SEARCH */
/*
- * The record below describes a canvas widget. It is made available
- * to the item procedures so they can access certain shared fields such
- * as the overall displacement and scale factor for the canvas.
+ * The record below describes a canvas widget. It is made available to the
+ * item functions so they can access certain shared fields such as the overall
+ * displacement and scale factor for the canvas.
*/
typedef struct TkCanvas {
- Tk_Window tkwin; /* Window that embodies the canvas. NULL
- * means that the window has been destroyed
- * but the data structures haven't yet been
- * cleaned up.*/
- Display *display; /* Display containing widget; needed, among
+ Tk_Window tkwin; /* Window that embodies the canvas. NULL means
+ * that the window has been destroyed but the
+ * data structures haven't yet been cleaned
+ * up.*/
+ Display *display; /* Display containing widget; needed, among
* other things, to release resources after
* tkwin has already gone away. */
Tcl_Interp *interp; /* Interpreter associated with canvas. */
Tcl_Command widgetCmd; /* Token for canvas's widget command. */
- Tk_Item *firstItemPtr; /* First in list of all items in canvas,
- * or NULL if canvas empty. */
- Tk_Item *lastItemPtr; /* Last in list of all items in canvas,
- * or NULL if canvas empty. */
+ Tk_Item *firstItemPtr; /* First in list of all items in canvas, or
+ * NULL if canvas empty. */
+ Tk_Item *lastItemPtr; /* Last in list of all items in canvas, or
+ * NULL if canvas empty. */
/*
* Information used when displaying widget:
@@ -62,39 +64,39 @@ typedef struct TkCanvas {
Tk_3DBorder bgBorder; /* Used for canvas background. */
int relief; /* Indicates whether window as a whole is
* raised, sunken, or flat. */
- int highlightWidth; /* Width in pixels of highlight to draw
- * around widget when it has the focus.
- * <= 0 means don't draw a highlight. */
+ 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. */
+ /* Color for drawing traversal 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.
- * Indicates how much interior stuff must
- * be offset from outside edges to leave
- * room for borders. */
+ * Indicates how much interior stuff must be
+ * offset from outside edges to leave room for
+ * borders. */
GC pixmapGC; /* Used to copy bits from a pixmap to the
* screen and also to clear the pixmap. */
int width, height; /* Dimensions to request for canvas window,
* specified in pixels. */
- int redrawX1, redrawY1; /* Upper left corner of area to redraw,
- * in pixel coordinates. Border pixels
- * are included. Only valid if
- * REDRAW_PENDING flag is set. */
- int redrawX2, redrawY2; /* Lower right corner of area to redraw,
- * in integer canvas coordinates. Border
- * pixels will *not* be redrawn. */
- int confine; /* Non-zero means constrain view to keep
- * as much of canvas visible as possible. */
+ int redrawX1, redrawY1; /* Upper left corner of area to redraw, in
+ * pixel coordinates. Border pixels are
+ * included. Only valid if REDRAW_PENDING flag
+ * is set. */
+ int redrawX2, redrawY2; /* Lower right corner of area to redraw, in
+ * integer canvas coordinates. Border pixels
+ * will *not* be redrawn. */
+ int confine; /* Non-zero means constrain view to keep as
+ * much of canvas visible as possible. */
/*
* Information used to manage the selection and insertion cursor:
*/
- Tk_CanvasTextInfo textInfo; /* Contains lots of fields; see tk.h for
- * details. This structure is shared with
- * the code that implements individual items. */
+ Tk_CanvasTextInfo textInfo; /* Contains lots of fields; see tk.h for
+ * details. This structure is shared with the
+ * code that implements individual items. */
int insertOnTime; /* Number of milliseconds cursor should spend
* in "on" state for each blink. */
int insertOffTime; /* Number of milliseconds cursor should spend
@@ -104,7 +106,7 @@ typedef struct TkCanvas {
* off. */
/*
- * Transformation applied to canvas as a whole: to compute screen
+ * Transformation applied to canvas as a whole: to compute screen
* coordinates (X,Y) from canvas coordinates (x,y), do the following:
*
* X = x - xOrigin;
@@ -116,65 +118,63 @@ typedef struct TkCanvas {
* canvas pixel units. */
int drawableXOrigin, drawableYOrigin;
/* During redisplay, these fields give the
- * canvas coordinates corresponding to
- * the upper-left corner of the drawable
- * where items are actually being drawn
- * (typically a pixmap smaller than the
- * whole window). */
+ * canvas coordinates corresponding to the
+ * upper-left corner of the drawable where
+ * items are actually being drawn (typically a
+ * pixmap smaller than the whole window). */
/*
* Information used for event bindings associated with items.
*/
Tk_BindingTable bindingTable;
- /* Table of all bindings currently defined
- * for this canvas. NULL means that no
- * bindings exist, so the table hasn't been
- * created. Each "object" used for this
- * table is either a Tk_Uid for a tag or
- * the address of an item named by id. */
+ /* Table of all bindings currently defined for
+ * this canvas. NULL means that no bindings
+ * exist, so the table hasn't been created.
+ * Each "object" used for this table is either
+ * a Tk_Uid for a tag or the address of an
+ * item named by id. */
Tk_Item *currentItemPtr; /* The item currently containing the mouse
* pointer, or NULL if none. */
Tk_Item *newCurrentPtr; /* The item that is about to become the
- * current one, or NULL. This field is
- * used to detect deletions of the new
- * current item pointer that occur during
- * Leave processing of the previous current
- * item. */
- double closeEnough; /* The mouse is assumed to be inside an
- * item if it is this close to it. */
- XEvent pickEvent; /* The event upon which the current choice
- * of currentItem is based. Must be saved
- * so that if the currentItem is deleted,
- * can pick another. */
- int state; /* Last known modifier state. Used to
- * defer picking a new current object
- * while buttons are down. */
+ * current one, or NULL. This field is used to
+ * detect deletions of the new current item
+ * pointer that occur during Leave processing
+ * of the previous current item. */
+ double closeEnough; /* The mouse is assumed to be inside an item
+ * if it is this close to it. */
+ XEvent pickEvent; /* The event upon which the current choice of
+ * currentItem is based. Must be saved so that
+ * if the currentItem is deleted, can pick
+ * another. */
+ int state; /* Last known modifier state. Used to defer
+ * picking a new current object while buttons
+ * are down. */
/*
* Information used for managing scrollbars:
*/
char *xScrollCmd; /* Command prefix for communicating with
- * horizontal scrollbar. NULL means no
- * horizontal scrollbar. Malloc'ed*/
+ * horizontal scrollbar. NULL means no
+ * horizontal scrollbar. Malloc'ed. */
char *yScrollCmd; /* Command prefix for communicating with
- * vertical scrollbar. NULL means no
- * vertical scrollbar. Malloc'ed*/
+ * vertical scrollbar. NULL means no vertical
+ * scrollbar. Malloc'ed. */
int scrollX1, scrollY1, scrollX2, scrollY2;
/* These four coordinates define the region
* that is the 100% area for scrolling (i.e.
* these numbers determine the size and
* location of the sliders on scrollbars).
* Units are pixels in canvas coords. */
- char *regionString; /* The option string from which scrollX1
- * etc. are derived. Malloc'ed. */
+ char *regionString; /* The option string from which scrollX1 etc.
+ * are derived. Malloc'ed. */
int xScrollIncrement; /* If >0, defines a grid for horizontal
- * scrolling. This is the size of the "unit",
+ * scrolling. This is the size of the "unit",
* and the left edge of the screen will always
* lie on an even unit boundary. */
int yScrollIncrement; /* If >0, defines a grid for horizontal
- * scrolling. This is the size of the "unit",
+ * scrolling. This is the size of the "unit",
* and the left edge of the screen will always
* lie on an even unit boundary. */
@@ -195,11 +195,11 @@ typedef struct TkCanvas {
*/
Tk_Item *hotPtr; /* Pointer to "hot" item (one that's been
- * recently used. NULL means there's no
- * hot item. */
+ * recently used. NULL means there's no hot
+ * item. */
Tk_Item *hotPrevPtr; /* Pointer to predecessor to hotPtr (NULL
- * means item is first in list). This is
- * only a hint and may not really be hotPtr's
+ * means item is first in list). This is only
+ * a hint and may not really be hotPtr's
* predecessor. */
/*
@@ -207,61 +207,61 @@ typedef struct TkCanvas {
*/
Tk_Cursor cursor; /* Current cursor for window, or None. */
- char *takeFocus; /* Value of -takefocus option; not used in
- * the C code, but used by keyboard traversal
- * scripts. Malloc'ed, but may be NULL. */
- double pixelsPerMM; /* Scale factor between MM and pixels;
- * used when converting coordinates. */
- int flags; /* Various flags; see below for
+ char *takeFocus; /* Value of -takefocus option; not used in the
+ * C code, but used by keyboard traversal
+ * scripts. Malloc'ed, but may be NULL. */
+ double pixelsPerMM; /* Scale factor between MM and pixels; used
+ * when converting coordinates. */
+ int flags; /* Various flags; see below for
* definitions. */
- int nextId; /* Number to use as id for next item
- * created in widget. */
- Tk_PostscriptInfo psInfo;
- /* Pointer to information used for generating
- * Postscript for the canvas. NULL means
- * no Postscript is currently being
- * generated. */
+ int nextId; /* Number to use as id for next item created
+ * in widget. */
+ Tk_PostscriptInfo psInfo; /* Pointer to information used for generating
+ * Postscript for the canvas. NULL means no
+ * Postscript is currently being generated. */
Tcl_HashTable idTable; /* Table of integer indices. */
+
/*
* Additional information, added by the 'dash'-patch
*/
- VOID *reserved1;
- Tk_State canvas_state; /* state of canvas */
- VOID *reserved2;
- VOID *reserved3;
+
+ void *reserved1;
+ Tk_State canvas_state; /* State of canvas. */
+ void *reserved2;
+ void *reserved3;
Tk_TSOffset tsoffset;
#ifndef USE_OLD_TAG_SEARCH
- TagSearchExpr *bindTagExprs; /* linked list of tag expressions used in bindings */
+ TagSearchExpr *bindTagExprs;/* Linked list of tag expressions used in
+ * bindings. */
#endif
} TkCanvas;
/*
* Flag bits for canvases:
*
- * REDRAW_PENDING - 1 means a DoWhenIdle handler has already
- * been created to redraw some or all of the
- * canvas.
+ * REDRAW_PENDING - 1 means a DoWhenIdle handler has already been
+ * created to redraw some or all of the canvas.
* REDRAW_BORDERS - 1 means that the borders need to be redrawn
* during the next redisplay operation.
* REPICK_NEEDED - 1 means DisplayCanvas should pick a new
* current item before redrawing the canvas.
- * GOT_FOCUS - 1 means the focus is currently in this
- * widget, so should draw the insertion cursor
- * and traversal highlight.
+ * GOT_FOCUS - 1 means the focus is currently in this widget,
+ * so should draw the insertion cursor and
+ * traversal highlight.
* CURSOR_ON - 1 means the insertion cursor is in the "on"
- * phase of its blink cycle. 0 means either
- * we don't have the focus or the cursor is in
- * the "off" phase of its cycle.
- * UPDATE_SCROLLBARS - 1 means the scrollbars should get updated
- * as part of the next display operation.
- * LEFT_GRABBED_ITEM - 1 means that the mouse left the current
- * item while a grab was in effect, so we
- * didn't change canvasPtr->currentItemPtr.
+ * phase of its blink cycle. 0 means either we
+ * don't have the focus or the cursor is in the
+ * "off" phase of its cycle.
+ * UPDATE_SCROLLBARS - 1 means the scrollbars should get updated as
+ * part of the next display operation.
+ * LEFT_GRABBED_ITEM - 1 means that the mouse left the current item
+ * while a grab was in effect, so we didn't
+ * change canvasPtr->currentItemPtr.
* REPICK_IN_PROGRESS - 1 means PickCurrentItem is currently
- * executing. If it should be called recursively,
+ * executing. If it should be called recursively,
* it should simply return immediately.
- * BBOX_NOT_EMPTY - 1 means that the bounding box of the area
- * that should be redrawn is not empty.
+ * BBOX_NOT_EMPTY - 1 means that the bounding box of the area that
+ * should be redrawn is not empty.
*/
#define REDRAW_PENDING 1
@@ -277,8 +277,8 @@ typedef struct TkCanvas {
/*
* Flag bits for canvas items (redraw_flags):
*
- * FORCE_REDRAW - 1 means that the new coordinates of some
- * item are not yet registered using
+ * FORCE_REDRAW - 1 means that the new coordinates of some item
+ * are not yet registered using
* Tk_CanvasEventuallyRedraw(). It should still
* be done by the general canvas code.
*/
@@ -286,20 +286,21 @@ typedef struct TkCanvas {
#define FORCE_REDRAW 8
/*
- * Canvas-related procedures that are shared among Tk modules but not
- * exported to the outside world:
+ * Canvas-related functions that are shared among Tk modules but not exported
+ * to the outside world:
*/
-extern int TkCanvPostscriptCmd _ANSI_ARGS_((TkCanvas *canvasPtr,
- Tcl_Interp *interp, int argc, CONST char **argv));
-
+MODULE_SCOPE int TkCanvPostscriptCmd(TkCanvas *canvasPtr,
+ Tcl_Interp *interp, int argc, CONST char **argv);
+MODULE_SCOPE int TkCanvTranslatePath(TkCanvas *canvPtr,
+ int numVertex, double *coordPtr, int closed,
+ XPoint *outPtr);
/*
- * Other procedures that are shared among Tk canvas modules but not exported
- * to the outside world:
+ * Standard item types provided by Tk:
*/
-extern int TkCanvTranslatePath _ANSI_ARGS_((TkCanvas *canvPtr,
- int numVertex, double *coordPtr, int closed,
- XPoint *outPtr));
+MODULE_SCOPE Tk_ItemType tkArcType, tkBitmapType, tkImageType, tkLineType;
+MODULE_SCOPE Tk_ItemType tkOvalType, tkPolygonType;
+MODULE_SCOPE Tk_ItemType tkRectangleType, tkTextType, tkWindowType;
#endif /* _TKCANVAS */
diff --git a/generic/tkClipboard.c b/generic/tkClipboard.c
index e4d5c8e..c6748a1 100644
--- a/generic/tkClipboard.c
+++ b/generic/tkClipboard.c
@@ -1,48 +1,46 @@
/*
* tkClipboard.c --
*
- * This file manages the clipboard for the Tk toolkit,
- * maintaining a collection of data buffers that will be
- * supplied on demand to requesting applications.
+ * This file manages the clipboard for the Tk toolkit, maintaining a
+ * collection of data buffers that will be supplied on demand to
+ * requesting applications.
*
* Copyright (c) 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
-#include "tkPort.h"
#include "tkSelect.h"
/*
- * Prototypes for procedures used only in this file:
+ * Prototypes for functions used only in this file:
*/
-static int ClipboardAppHandler _ANSI_ARGS_((ClientData clientData,
- int offset, char *buffer, int maxBytes));
-static int ClipboardHandler _ANSI_ARGS_((ClientData clientData,
- int offset, char *buffer, int maxBytes));
-static int ClipboardWindowHandler _ANSI_ARGS_((
- ClientData clientData, int offset, char *buffer,
- int maxBytes));
-static void ClipboardLostSel _ANSI_ARGS_((ClientData clientData));
-static int ClipboardGetProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, char *portion));
+static int ClipboardAppHandler(ClientData clientData,
+ int offset, char *buffer, int maxBytes);
+static int ClipboardHandler(ClientData clientData,
+ int offset, char *buffer, int maxBytes);
+static int ClipboardWindowHandler(ClientData clientData,
+ int offset, char *buffer, int maxBytes);
+static void ClipboardLostSel(ClientData clientData);
+static int ClipboardGetProc(ClientData clientData,
+ Tcl_Interp *interp, char *portion);
/*
*----------------------------------------------------------------------
*
* ClipboardHandler --
*
- * This procedure acts as selection handler for the
- * clipboard manager. It extracts the required chunk of
- * data from the buffer chain for a given selection target.
+ * This function acts as selection handler for the clipboard manager. It
+ * extracts the required chunk of data from the buffer chain for a given
+ * selection target.
*
* Results:
- * The return value is a count of the number of bytes
- * actually stored at buffer.
+ * The return value is a count of the number of bytes actually stored at
+ * buffer.
*
* Side effects:
* None.
@@ -51,17 +49,17 @@ static int ClipboardGetProc _ANSI_ARGS_((ClientData clientData,
*/
static int
-ClipboardHandler(clientData, offset, buffer, maxBytes)
- ClientData clientData; /* Information about data to fetch. */
- int offset; /* Return selection bytes starting at this
+ClipboardHandler(
+ ClientData clientData, /* Information about data to fetch. */
+ int offset, /* Return selection bytes starting at this
* offset. */
- char *buffer; /* Place to store converted selection. */
- int maxBytes; /* Maximum # of bytes to store at buffer. */
+ char *buffer, /* Place to store converted selection. */
+ int maxBytes) /* Maximum # of bytes to store at buffer. */
{
TkClipboardTarget *targetPtr = (TkClipboardTarget*) clientData;
TkClipboardBuffer *cbPtr;
char *srcPtr, *destPtr;
- int count = 0;
+ size_t count = 0;
int scanned = 0;
size_t length, freeCount;
@@ -104,7 +102,7 @@ ClipboardHandler(clientData, offset, buffer, maxBytes)
srcPtr = cbPtr->buffer;
length = cbPtr->length;
}
- return count;
+ return (int)count;
}
/*
@@ -112,16 +110,15 @@ ClipboardHandler(clientData, offset, buffer, maxBytes)
*
* ClipboardAppHandler --
*
- * This procedure acts as selection handler for retrievals of type
- * TK_APPLICATION. It returns the name of the application that
- * owns the clipboard. Note: we can't use the default Tk
- * selection handler for this selection type, because the clipboard
- * window isn't a "real" window and doesn't have the necessary
- * information.
+ * This function acts as selection handler for retrievals of type
+ * TK_APPLICATION. It returns the name of the application that owns the
+ * clipboard. Note: we can't use the default Tk selection handler for
+ * this selection type, because the clipboard window isn't a "real"
+ * window and doesn't have the necessary information.
*
* Results:
- * The return value is a count of the number of bytes
- * actually stored at buffer.
+ * The return value is a count of the number of bytes actually stored at
+ * buffer.
*
* Side effects:
* None.
@@ -130,12 +127,12 @@ ClipboardHandler(clientData, offset, buffer, maxBytes)
*/
static int
-ClipboardAppHandler(clientData, offset, buffer, maxBytes)
- ClientData clientData; /* Pointer to TkDisplay structure. */
- int offset; /* Return selection bytes starting at this
+ClipboardAppHandler(
+ ClientData clientData, /* Pointer to TkDisplay structure. */
+ int offset, /* Return selection bytes starting at this
* offset. */
- char *buffer; /* Place to store converted selection. */
- int maxBytes; /* Maximum # of bytes to store at buffer. */
+ char *buffer, /* Place to store converted selection. */
+ int maxBytes) /* Maximum # of bytes to store at buffer. */
{
TkDisplay *dispPtr = (TkDisplay *) clientData;
size_t length;
@@ -151,7 +148,7 @@ ClipboardAppHandler(clientData, offset, buffer, maxBytes)
length = maxBytes;
}
strncpy(buffer, p, length);
- return length;
+ return (int)length;
}
/*
@@ -159,15 +156,13 @@ ClipboardAppHandler(clientData, offset, buffer, maxBytes)
*
* ClipboardWindowHandler --
*
- * This procedure acts as selection handler for retrievals of
- * type TK_WINDOW. Since the clipboard doesn't correspond to
- * any particular window, we just return ".". We can't use Tk's
- * default handler for this selection type, because the clipboard
- * window isn't a valid window.
+ * This function acts as selection handler for retrievals of type
+ * TK_WINDOW. Since the clipboard doesn't correspond to any particular
+ * window, we just return ".". We can't use Tk's default handler for this
+ * selection type, because the clipboard window isn't a valid window.
*
* Results:
- * The return value is 1, the number of non-null bytes stored
- * at buffer.
+ * The return value is 1, the number of non-null bytes stored at buffer.
*
* Side effects:
* None.
@@ -176,12 +171,12 @@ ClipboardAppHandler(clientData, offset, buffer, maxBytes)
*/
static int
-ClipboardWindowHandler(clientData, offset, buffer, maxBytes)
- ClientData clientData; /* Not used. */
- int offset; /* Return selection bytes starting at this
+ClipboardWindowHandler(
+ ClientData clientData, /* Not used. */
+ int offset, /* Return selection bytes starting at this
* offset. */
- char *buffer; /* Place to store converted selection. */
- int maxBytes; /* Maximum # of bytes to store at buffer. */
+ char *buffer, /* Place to store converted selection. */
+ int maxBytes) /* Maximum # of bytes to store at buffer. */
{
buffer[0] = '.';
buffer[1] = 0;
@@ -193,9 +188,9 @@ ClipboardWindowHandler(clientData, offset, buffer, maxBytes)
*
* ClipboardLostSel --
*
- * This procedure is invoked whenever clipboard ownership is
- * claimed by another window. It just sets a flag so that we
- * know the clipboard was taken away.
+ * This function is invoked whenever clipboard ownership is claimed by
+ * another window. It just sets a flag so that we know the clipboard was
+ * taken away.
*
* Results:
* None.
@@ -207,8 +202,8 @@ ClipboardWindowHandler(clientData, offset, buffer, maxBytes)
*/
static void
-ClipboardLostSel(clientData)
- ClientData clientData; /* Pointer to TkDisplay structure. */
+ClipboardLostSel(
+ ClientData clientData) /* Pointer to TkDisplay structure. */
{
TkDisplay *dispPtr = (TkDisplay*) clientData;
@@ -220,33 +215,31 @@ ClipboardLostSel(clientData)
*
* Tk_ClipboardClear --
*
- * Take control of the clipboard and clear out the previous
- * contents. This procedure must be invoked before any
- * calls to Tk_ClipboardAppend.
+ * Take control of the clipboard and clear out the previous contents.
+ * This function must be invoked before any calls to Tk_ClipboardAppend.
*
* Results:
- * A standard Tcl result. If an error occurs, an error message is
- * left in the interp's result.
+ * A standard Tcl result. If an error occurs, an error message is left in
+ * the interp's result.
*
* Side effects:
- * From now on, requests for the CLIPBOARD selection will be
- * directed to the clipboard manager routines associated with
- * clipWindow for the display of tkwin. In order to guarantee
- * atomicity, no event handling should occur between
- * Tk_ClipboardClear and the following Tk_ClipboardAppend
- * calls. This procedure may cause a user-defined LostSel command
- * to be invoked when the CLIPBOARD is claimed, so any calling
- * function should be reentrant at the point Tk_ClipboardClear is
+ * From now on, requests for the CLIPBOARD selection will be directed to
+ * the clipboard manager routines associated with clipWindow for the
+ * display of tkwin. In order to guarantee atomicity, no event handling
+ * should occur between Tk_ClipboardClear and the following
+ * Tk_ClipboardAppend calls. This function may cause a user-defined
+ * LostSel command to be invoked when the CLIPBOARD is claimed, so any
+ * calling function should be reentrant at the point Tk_ClipboardClear is
* invoked.
*
*----------------------------------------------------------------------
*/
int
-Tk_ClipboardClear(interp, tkwin)
- Tcl_Interp *interp; /* Interpreter to use for error reporting. */
- Tk_Window tkwin; /* Window in application that is clearing
- * clipboard; identifies application and
+Tk_ClipboardClear(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ Tk_Window tkwin) /* Window in application that is clearing
+ * clipboard; identifies application and
* display. */
{
TkWindow *winPtr = (TkWindow *) tkwin;
@@ -264,8 +257,8 @@ Tk_ClipboardClear(interp, tkwin)
}
/*
- * Discard any existing clipboard data and delete the selection
- * handler(s) associated with that data.
+ * Discard any existing clipboard data and delete the selection handler(s)
+ * associated with that data.
*/
for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
@@ -301,38 +294,37 @@ Tk_ClipboardClear(interp, tkwin)
*
* Tk_ClipboardAppend --
*
- * Append a buffer of data to the clipboard. The first buffer of
- * a given type determines the format for that type. Any successive
- * appends to that type must have the same format or an error will
- * be returned. Tk_ClipboardClear must be called before a sequence
- * of Tk_ClipboardAppend calls can be issued. In order to guarantee
+ * Append a buffer of data to the clipboard. The first buffer of a given
+ * type determines the format for that type. Any successive appends to
+ * that type must have the same format or an error will be returned.
+ * Tk_ClipboardClear must be called before a sequence of
+ * Tk_ClipboardAppend calls can be issued. In order to guarantee
* atomicity, no event handling should occur between Tk_ClipboardClear
* and the following Tk_ClipboardAppend calls.
*
* Results:
- * A standard Tcl result. If an error is returned, an error message
- * is left in the interp's result.
+ * A standard Tcl result. If an error is returned, an error message is
+ * left in the interp's result.
*
* Side effects:
- * The specified buffer will be copied onto the end of the clipboard.
- * The clipboard maintains a list of buffers which will be used to
- * supply the data for a selection get request. The first time a given
- * type is appended, Tk_ClipboardAppend will register a selection
- * handler of the appropriate type.
+ * The specified buffer will be copied onto the end of the clipboard.
+ * The clipboard maintains a list of buffers which will be used to supply
+ * the data for a selection get request. The first time a given type is
+ * appended, Tk_ClipboardAppend will register a selection handler of the
+ * appropriate type.
*
*----------------------------------------------------------------------
*/
int
-Tk_ClipboardAppend(interp, tkwin, type, format, buffer)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Window tkwin; /* Window that selects a display. */
- Atom type; /* The desired conversion type for this
+Tk_ClipboardAppend(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_Window tkwin, /* Window that selects a display. */
+ Atom type, /* The desired conversion type for this
* clipboard item, e.g. STRING or LENGTH. */
- Atom format; /* Format in which the selection
- * information should be returned to
- * the requestor. */
- char* buffer; /* NULL terminated string containing the data
+ Atom format, /* Format in which the selection information
+ * should be returned to the requestor. */
+ char* buffer) /* NULL terminated string containing the data
* to be added to the clipboard. */
{
TkWindow *winPtr = (TkWindow *) tkwin;
@@ -341,8 +333,8 @@ Tk_ClipboardAppend(interp, tkwin, type, format, buffer)
TkClipboardBuffer *cbPtr;
/*
- * If this application doesn't already own the clipboard, clear
- * the clipboard. If we don't own the clipboard selection, claim it.
+ * If this application doesn't already own the clipboard, clear the
+ * clipboard. If we don't own the clipboard selection, claim it.
*/
if (dispPtr->clipboardAppPtr != winPtr->mainPtr) {
@@ -355,14 +347,15 @@ Tk_ClipboardAppend(interp, tkwin, type, format, buffer)
/*
* Check to see if the specified target is already present on the
- * clipboard. If it isn't, we need to create a new target; otherwise,
- * we just append the new buffer to the clipboard list.
+ * clipboard. If it isn't, we need to create a new target; otherwise, we
+ * just append the new buffer to the clipboard list.
*/
for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
targetPtr = targetPtr->nextPtr) {
- if (targetPtr->type == type)
+ if (targetPtr->type == type) {
break;
+ }
}
if (targetPtr == NULL) {
targetPtr = (TkClipboardTarget*) ckalloc(sizeof(TkClipboardTarget));
@@ -377,7 +370,7 @@ Tk_ClipboardAppend(interp, tkwin, type, format, buffer)
Tcl_AppendResult(interp, "format \"", Tk_GetAtomName(tkwin, format),
"\" does not match current format \"",
Tk_GetAtomName(tkwin, targetPtr->format),"\" for ",
- Tk_GetAtomName(tkwin, type), (char *) NULL);
+ Tk_GetAtomName(tkwin, type), NULL);
return TCL_ERROR;
}
@@ -408,9 +401,8 @@ Tk_ClipboardAppend(interp, tkwin, type, format, buffer)
*
* Tk_ClipboardObjCmd --
*
- * This procedure is invoked to process the "clipboard" Tcl
- * command. See the user documentation for details on what
- * it does.
+ * This function is invoked to process the "clipboard" Tcl command. See
+ * the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -422,12 +414,11 @@ Tk_ClipboardAppend(interp, tkwin, type, format, buffer)
*/
int
-Tk_ClipboardObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument strings. */
+Tk_ClipboardObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument strings. */
{
Tk_Window tkwin = (Tk_Window) clientData;
char *path = NULL;
@@ -447,173 +438,173 @@ Tk_ClipboardObjCmd(clientData, interp, objc, objv)
}
switch ((enum options) index) {
- case CLIPBOARD_APPEND: {
- Atom target, format;
- char *targetName = NULL;
- char *formatName = NULL;
- char *string;
- static CONST char *appendOptionStrings[] = {
- "-displayof", "-format", "-type", NULL
- };
- enum appendOptions { APPEND_DISPLAYOF, APPEND_FORMAT,
- APPEND_TYPE };
- int subIndex, length;
-
- for (i = 2; i < objc - 1; i++) {
- string = Tcl_GetStringFromObj(objv[i], &length);
- if (string[0] != '-') {
- break;
- }
-
- /*
- * If the argument is "--", it signifies the end of arguments.
- */
- if (string[1] == '-' && length == 2) {
- i++;
- break;
- }
- if (Tcl_GetIndexFromObj(interp, objv[i], appendOptionStrings,
- "option", 0, &subIndex) != TCL_OK) {
- return TCL_ERROR;
- }
-
- /*
- * Increment i so that it points to the value for the flag
- * instead of the flag itself.
- */
+ case CLIPBOARD_APPEND: {
+ Atom target, format;
+ char *targetName = NULL;
+ char *formatName = NULL;
+ char *string;
+ static CONST char *appendOptionStrings[] = {
+ "-displayof", "-format", "-type", NULL
+ };
+ enum appendOptions { APPEND_DISPLAYOF, APPEND_FORMAT, APPEND_TYPE };
+ int subIndex, length;
+
+ for (i = 2; i < objc - 1; i++) {
+ string = Tcl_GetStringFromObj(objv[i], &length);
+ if (string[0] != '-') {
+ break;
+ }
+ /*
+ * If the argument is "--", it signifies the end of arguments.
+ */
+ if (string[1] == '-' && length == 2) {
i++;
- if (i >= objc) {
- Tcl_AppendResult(interp, "value for \"", string,
- "\" missing", (char *) NULL);
- return TCL_ERROR;
- }
- switch ((enum appendOptions) subIndex) {
- case APPEND_DISPLAYOF:
- path = Tcl_GetString(objv[i]);
- break;
- case APPEND_FORMAT:
- formatName = Tcl_GetString(objv[i]);
- break;
- case APPEND_TYPE:
- targetName = Tcl_GetString(objv[i]);
- break;
- }
+ break;
}
- if (objc - i != 1) {
- Tcl_WrongNumArgs(interp, 2, objv, "?options? data");
+ if (Tcl_GetIndexFromObj(interp, objv[i], appendOptionStrings,
+ "option", 0, &subIndex) != TCL_OK) {
return TCL_ERROR;
}
- if (path != NULL) {
- tkwin = Tk_NameToWindow(interp, path, tkwin);
- }
- if (tkwin == NULL) {
+
+ /*
+ * Increment i so that it points to the value for the flag instead
+ * of the flag itself.
+ */
+
+ i++;
+ if (i >= objc) {
+ Tcl_AppendResult(interp, "value for \"", string,
+ "\" missing", NULL);
return TCL_ERROR;
}
- if (targetName != NULL) {
- target = Tk_InternAtom(tkwin, targetName);
- } else {
- target = XA_STRING;
- }
- if (formatName != NULL) {
- format = Tk_InternAtom(tkwin, formatName);
- } else {
- format = XA_STRING;
+ switch ((enum appendOptions) subIndex) {
+ case APPEND_DISPLAYOF:
+ path = Tcl_GetString(objv[i]);
+ break;
+ case APPEND_FORMAT:
+ formatName = Tcl_GetString(objv[i]);
+ break;
+ case APPEND_TYPE:
+ targetName = Tcl_GetString(objv[i]);
+ break;
}
- return Tk_ClipboardAppend(interp, tkwin, target, format,
- Tcl_GetString(objv[i]));
}
- case CLIPBOARD_CLEAR: {
- static CONST char *clearOptionStrings[] = { "-displayof", NULL };
- enum clearOptions { CLEAR_DISPLAYOF };
- int subIndex;
- if (objc != 2 && objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
- return TCL_ERROR;
- }
+ if (objc - i != 1) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?options? data");
+ return TCL_ERROR;
+ }
+ if (path != NULL) {
+ tkwin = Tk_NameToWindow(interp, path, tkwin);
+ }
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+ if (targetName != NULL) {
+ target = Tk_InternAtom(tkwin, targetName);
+ } else {
+ target = XA_STRING;
+ }
+ if (formatName != NULL) {
+ format = Tk_InternAtom(tkwin, formatName);
+ } else {
+ format = XA_STRING;
+ }
+ return Tk_ClipboardAppend(interp, tkwin, target, format,
+ Tcl_GetString(objv[i]));
+ }
+ case CLIPBOARD_CLEAR: {
+ static CONST char *clearOptionStrings[] = { "-displayof", NULL };
+ enum clearOptions { CLEAR_DISPLAYOF };
+ int subIndex;
+
+ if (objc != 2 && objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
+ return TCL_ERROR;
+ }
- if (objc == 4) {
- if (Tcl_GetIndexFromObj(interp, objv[2], clearOptionStrings,
- "option", 0, &subIndex) != TCL_OK) {
- return TCL_ERROR;
- }
- if ((enum clearOptions) subIndex == CLEAR_DISPLAYOF) {
- path = Tcl_GetString(objv[3]);
- }
- }
- if (path != NULL) {
- tkwin = Tk_NameToWindow(interp, path, tkwin);
- }
- if (tkwin == NULL) {
+ if (objc == 4) {
+ if (Tcl_GetIndexFromObj(interp, objv[2], clearOptionStrings,
+ "option", 0, &subIndex) != TCL_OK) {
return TCL_ERROR;
}
- return Tk_ClipboardClear(interp, tkwin);
- }
- case CLIPBOARD_GET: {
- Atom target;
- char *targetName = NULL;
- Tcl_DString selBytes;
- int result;
- char *string;
- static CONST char *getOptionStrings[] = {
- "-displayof", "-type", NULL
- };
- enum getOptions { APPEND_DISPLAYOF, APPEND_TYPE };
- int subIndex;
-
- for (i = 2; i < objc; i++) {
- string = Tcl_GetString(objv[i]);
- if (string[0] != '-') {
- break;
- }
- if (Tcl_GetIndexFromObj(interp, objv[i], getOptionStrings,
- "option", 0, &subIndex) != TCL_OK) {
- return TCL_ERROR;
- }
- i++;
- if (i >= objc) {
- Tcl_AppendResult(interp, "value for \"", string,
- "\" missing", (char *) NULL);
- return TCL_ERROR;
- }
- switch ((enum getOptions) subIndex) {
- case APPEND_DISPLAYOF:
- path = Tcl_GetString(objv[i]);
- break;
- case APPEND_TYPE:
- targetName = Tcl_GetString(objv[i]);
- break;
- }
+ if ((enum clearOptions) subIndex == CLEAR_DISPLAYOF) {
+ path = Tcl_GetString(objv[3]);
}
- if (path != NULL) {
- tkwin = Tk_NameToWindow(interp, path, tkwin);
+ }
+ if (path != NULL) {
+ tkwin = Tk_NameToWindow(interp, path, tkwin);
+ }
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+ return Tk_ClipboardClear(interp, tkwin);
+ }
+ case CLIPBOARD_GET: {
+ Atom target;
+ char *targetName = NULL;
+ Tcl_DString selBytes;
+ int result;
+ char *string;
+ static CONST char *getOptionStrings[] = {
+ "-displayof", "-type", NULL
+ };
+ enum getOptions { APPEND_DISPLAYOF, APPEND_TYPE };
+ int subIndex;
+
+ for (i = 2; i < objc; i++) {
+ string = Tcl_GetString(objv[i]);
+ if (string[0] != '-') {
+ break;
}
- if (tkwin == NULL) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], getOptionStrings,
+ "option", 0, &subIndex) != TCL_OK) {
return TCL_ERROR;
}
- selection = Tk_InternAtom(tkwin, "CLIPBOARD");
-
- if (objc - i > 1) {
- Tcl_WrongNumArgs(interp, 2, objv, "?options?");
+ i++;
+ if (i >= objc) {
+ Tcl_AppendResult(interp, "value for \"", string,
+ "\" missing", NULL);
return TCL_ERROR;
- } else if (objc - i == 1) {
- target = Tk_InternAtom(tkwin, Tcl_GetString(objv[i]));
- } else if (targetName != NULL) {
- target = Tk_InternAtom(tkwin, targetName);
- } else {
- target = XA_STRING;
}
-
- Tcl_DStringInit(&selBytes);
- result = Tk_GetSelection(interp, tkwin, selection, target,
- ClipboardGetProc, (ClientData) &selBytes);
- if (result == TCL_OK) {
- Tcl_DStringResult(interp, &selBytes);
- } else {
- Tcl_DStringFree(&selBytes);
+ switch ((enum getOptions) subIndex) {
+ case APPEND_DISPLAYOF:
+ path = Tcl_GetString(objv[i]);
+ break;
+ case APPEND_TYPE:
+ targetName = Tcl_GetString(objv[i]);
+ break;
}
- return result;
}
+ if (path != NULL) {
+ tkwin = Tk_NameToWindow(interp, path, tkwin);
+ }
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+ selection = Tk_InternAtom(tkwin, "CLIPBOARD");
+
+ if (objc - i > 1) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?options?");
+ return TCL_ERROR;
+ } else if (objc - i == 1) {
+ target = Tk_InternAtom(tkwin, Tcl_GetString(objv[i]));
+ } else if (targetName != NULL) {
+ target = Tk_InternAtom(tkwin, targetName);
+ } else {
+ target = XA_STRING;
+ }
+
+ Tcl_DStringInit(&selBytes);
+ result = Tk_GetSelection(interp, tkwin, selection, target,
+ ClipboardGetProc, (ClientData) &selBytes);
+ if (result == TCL_OK) {
+ Tcl_DStringResult(interp, &selBytes);
+ } else {
+ Tcl_DStringFree(&selBytes);
+ }
+ return result;
+ }
}
return TCL_OK;
}
@@ -623,8 +614,8 @@ Tk_ClipboardObjCmd(clientData, interp, objc, objv)
*
* TkClipInit --
*
- * This procedure is called to initialize the window for claiming
- * clipboard ownership and for receiving selection get results. This
+ * This function is called to initialize the window for claiming
+ * clipboard ownership and for receiving selection get results. This
* function is called from tkSelect.c as well as tkClipboard.c.
*
* Results:
@@ -639,17 +630,16 @@ Tk_ClipboardObjCmd(clientData, interp, objc, objv)
*/
int
-TkClipInit(interp, dispPtr)
- Tcl_Interp *interp; /* Interpreter to use for error
- * reporting. */
- register TkDisplay *dispPtr;/* Display to initialize. */
+TkClipInit(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ register TkDisplay *dispPtr)/* Display to initialize. */
{
XSetWindowAttributes atts;
dispPtr->clipTargetPtr = NULL;
dispPtr->clipboardActive = 0;
dispPtr->clipboardAppPtr = NULL;
-
+
/*
* Create the window used for clipboard ownership and selection retrieval,
* and set up an event handler for it.
@@ -658,23 +648,25 @@ TkClipInit(interp, dispPtr)
dispPtr->clipWindow = (Tk_Window) TkAllocWindow(dispPtr,
DefaultScreen(dispPtr->display), NULL);
Tcl_Preserve((ClientData) dispPtr->clipWindow);
+ ((TkWindow *) dispPtr->clipWindow)->flags |= TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED;
+ TkWmNewWindow((TkWindow *) dispPtr->clipWindow);
atts.override_redirect = True;
Tk_ChangeWindowAttributes(dispPtr->clipWindow, CWOverrideRedirect, &atts);
Tk_MakeWindowExist(dispPtr->clipWindow);
if (dispPtr->multipleAtom == None) {
/*
- * Need to invoke selection initialization to make sure that
- * atoms we depend on below are defined.
+ * Need to invoke selection initialization to make sure that atoms we
+ * depend on below are defined.
*/
TkSelInit(dispPtr->clipWindow);
}
/*
- * Create selection handlers for types TK_APPLICATION and TK_WINDOW
- * on this window. Can't use the default handlers for these types
- * because this isn't a full-fledged window.
+ * Create selection handlers for types TK_APPLICATION and TK_WINDOW on
+ * this window. Can't use the default handlers for these types because
+ * this isn't a full-fledged window.
*/
Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
@@ -691,29 +683,37 @@ TkClipInit(interp, dispPtr)
*
* ClipboardGetProc --
*
- * This procedure is invoked to process pieces of the selection
- * as they arrive during "clipboard get" commands.
+ * This function is invoked to process pieces of the selection as they
+ * arrive during "clipboard get" commands.
*
* Results:
* Always returns TCL_OK.
*
* Side effects:
- * Bytes get appended to the dynamic string pointed to by the
- * clientData argument.
+ * Bytes get appended to the dynamic string pointed to by the clientData
+ * argument.
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static int
-ClipboardGetProc(clientData, interp, portion)
- ClientData clientData; /* Dynamic string holding partially
- * assembled selection. */
- Tcl_Interp *interp; /* Interpreter used for error
- * reporting (not used). */
- char *portion; /* New information to be appended. */
+ClipboardGetProc(
+ ClientData clientData, /* Dynamic string holding partially assembled
+ * selection. */
+ Tcl_Interp *interp, /* Interpreter used for error reporting (not
+ * used). */
+ char *portion) /* New information to be appended. */
{
Tcl_DStringAppend((Tcl_DString *) clientData, portion, -1);
return TCL_OK;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkCmds.c b/generic/tkCmds.c
index 1e830e2..a86ef84 100644
--- a/generic/tkCmds.c
+++ b/generic/tkCmds.c
@@ -1,48 +1,47 @@
-/*
+/*
* tkCmds.c --
*
- * This file contains a collection of Tk-related Tcl commands
- * that didn't fit in any particular file of the toolkit.
+ * This file contains a collection of Tk-related Tcl commands 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-1997 Sun Microsystems, Inc.
* Copyright (c) 2000 Scriptics Corporation.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
#if defined(WIN32)
#include "tkWinInt.h"
-#elif defined(MAC_OSX_TK)
+#elif defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#else
#include "tkUnixInt.h"
#endif
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static TkWindow * GetToplevel _ANSI_ARGS_((Tk_Window tkwin));
-static char * WaitVariableProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, CONST char *name1,
- CONST char *name2, int flags));
-static void WaitVisibilityProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void WaitWindowProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
+static TkWindow * GetTopHierarchy(Tk_Window tkwin);
+static char * WaitVariableProc(ClientData clientData,
+ Tcl_Interp *interp, const char *name1,
+ const char *name2, int flags);
+static void WaitVisibilityProc(ClientData clientData,
+ XEvent *eventPtr);
+static void WaitWindowProc(ClientData clientData,
+ XEvent *eventPtr);
/*
*----------------------------------------------------------------------
*
* Tk_BellObjCmd --
*
- * This procedure is invoked to process the "bell" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "bell" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -54,18 +53,21 @@ static void WaitWindowProc _ANSI_ARGS_((ClientData clientData,
*/
int
-Tk_BellObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_BellObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- static CONST char *bellOptions[] = {"-displayof", "-nice", (char *) NULL};
+ static const char *bellOptions[] = {
+ "-displayof", "-nice", NULL
+ };
enum options { TK_BELL_DISPLAYOF, TK_BELL_NICE };
Tk_Window tkwin = (Tk_Window) clientData;
int i, index, nice = 0;
if (objc > 4) {
+ wrongArgs:
Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?-nice?");
return TCL_ERROR;
}
@@ -76,20 +78,18 @@ Tk_BellObjCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
switch ((enum options) index) {
- case TK_BELL_DISPLAYOF:
- if (++i >= objc) {
- Tcl_WrongNumArgs(interp, 1, objv,
- "?-displayof window? ?-nice?");
- return TCL_ERROR;
- }
- tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[i]), tkwin);
- if (tkwin == NULL) {
- return TCL_ERROR;
- }
- break;
- case TK_BELL_NICE:
- nice = 1;
- break;
+ case TK_BELL_DISPLAYOF:
+ if (++i >= objc) {
+ goto wrongArgs;
+ }
+ tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[i]), tkwin);
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+ break;
+ case TK_BELL_NICE:
+ nice = 1;
+ break;
}
}
XBell(Tk_Display(tkwin), 0);
@@ -105,8 +105,8 @@ Tk_BellObjCmd(clientData, interp, objc, objv)
*
* Tk_BindObjCmd --
*
- * This procedure is invoked to process the "bind" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "bind" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -118,23 +118,23 @@ Tk_BellObjCmd(clientData, interp, objc, objv)
*/
int
-Tk_BindObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_BindObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
Tk_Window tkwin = (Tk_Window) clientData;
TkWindow *winPtr;
ClientData object;
char *string;
-
+
if ((objc < 2) || (objc > 4)) {
Tcl_WrongNumArgs(interp, 1, objv, "window ?pattern? ?command?");
return TCL_ERROR;
}
string = Tcl_GetString(objv[1]);
-
+
/*
* Bind tags either a window name or a tag name for the first argument.
* If the argument starts with ".", assume it is a window; otherwise, it
@@ -153,8 +153,8 @@ Tk_BindObjCmd(clientData, interp, objc, objv)
}
/*
- * If there are four arguments, the command is modifying a binding. If
- * there are three arguments, the command is querying a binding. If there
+ * If there are four arguments, the command is modifying a binding. If
+ * there are three arguments, the command is querying a binding. If there
* are only two arguments, the command is querying all the bindings for
* the given tag/window.
*/
@@ -165,7 +165,7 @@ Tk_BindObjCmd(clientData, interp, objc, objv)
char *sequence, *script;
sequence = Tcl_GetString(objv[2]);
script = Tcl_GetString(objv[3]);
-
+
/*
* If the script is null, just delete the binding.
*/
@@ -179,7 +179,7 @@ Tk_BindObjCmd(clientData, interp, objc, objv)
* If the script begins with "+", append this script to the existing
* binding.
*/
-
+
if (script[0] == '+') {
script++;
append = 1;
@@ -190,7 +190,7 @@ Tk_BindObjCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
} else if (objc == 3) {
- CONST char *command;
+ const char *command;
command = Tk_GetBinding(interp, winPtr->mainPtr->bindingTable,
object, Tcl_GetString(objv[2]));
@@ -210,8 +210,8 @@ Tk_BindObjCmd(clientData, interp, objc, objv)
*
* TkBindEventProc --
*
- * This procedure is invoked by Tk_HandleEvent for each event; it
- * causes any appropriate bindings for that event to be invoked.
+ * This function is invoked by Tk_HandleEvent for each event; it causes
+ * any appropriate bindings for that event to be invoked.
*
* Results:
* None.
@@ -224,9 +224,9 @@ Tk_BindObjCmd(clientData, interp, objc, objv)
*/
void
-TkBindEventProc(winPtr, eventPtr)
- TkWindow *winPtr; /* Pointer to info about window. */
- XEvent *eventPtr; /* Information about event. */
+TkBindEventProc(
+ TkWindow *winPtr, /* Pointer to info about window. */
+ XEvent *eventPtr) /* Information about event. */
{
#define MAX_OBJS 20
ClientData objects[MAX_OBJS], *objPtr;
@@ -242,8 +242,8 @@ TkBindEventProc(winPtr, eventPtr)
objPtr = objects;
if (winPtr->numTags != 0) {
/*
- * Make a copy of the tags for the window, replacing window names
- * with pointers to the pathName from the appropriate window.
+ * Make a copy of the tags for the window, replacing window names with
+ * pointers to the pathName from the appropriate window.
*/
if (winPtr->numTags > MAX_OBJS) {
@@ -291,8 +291,8 @@ TkBindEventProc(winPtr, eventPtr)
*
* Tk_BindtagsObjCmd --
*
- * This procedure is invoked to process the "bindtags" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "bindtags" Tcl command. See
+ * the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -304,18 +304,18 @@ TkBindEventProc(winPtr, eventPtr)
*/
int
-Tk_BindtagsObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_BindtagsObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
Tk_Window tkwin = (Tk_Window) clientData;
TkWindow *winPtr, *winPtr2;
int i, length;
char *p;
Tcl_Obj *listPtr, **tags;
-
+
if ((objc < 2) || (objc > 3)) {
Tcl_WrongNumArgs(interp, 1, objv, "window ?taglist?");
return TCL_ERROR;
@@ -373,9 +373,9 @@ Tk_BindtagsObjCmd(clientData, interp, objc, objv)
/*
* Handle names starting with "." specially: store a malloc'ed
- * string, rather than a Uid; at event time we'll look up the
- * name in the window table and use the corresponding window,
- * if there is one.
+ * string, rather than a Uid; at event time we'll look up the name
+ * in the window table and use the corresponding window, if there
+ * is one.
*/
copy = (char *) ckalloc((unsigned) (strlen(p) + 1));
@@ -393,9 +393,9 @@ Tk_BindtagsObjCmd(clientData, interp, objc, objv)
*
* TkFreeBindingTags --
*
- * This procedure is called to free all of the binding tags
- * associated with a window; typically it is only invoked where
- * there are window-specific tags.
+ * This function is called to free all of the binding tags associated
+ * with a window; typically it is only invoked where there are
+ * window-specific tags.
*
* Results:
* None.
@@ -407,8 +407,8 @@ Tk_BindtagsObjCmd(clientData, interp, objc, objv)
*/
void
-TkFreeBindingTags(winPtr)
- TkWindow *winPtr; /* Window whose tags are to be released. */
+TkFreeBindingTags(
+ TkWindow *winPtr) /* Window whose tags are to be released. */
{
int i;
char *p;
@@ -417,10 +417,10 @@ TkFreeBindingTags(winPtr)
p = (char *) (winPtr->tagPtr[i]);
if (*p == '.') {
/*
- * Names starting with "." are malloced rather than Uids, so
- * they have to be freed.
+ * Names starting with "." are malloced rather than Uids, so they
+ * have to be freed.
*/
-
+
ckfree(p);
}
}
@@ -434,8 +434,8 @@ TkFreeBindingTags(winPtr)
*
* Tk_DestroyObjCmd --
*
- * This procedure is invoked to process the "destroy" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "destroy" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -447,12 +447,11 @@ TkFreeBindingTags(winPtr)
*/
int
-Tk_DestroyObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_DestroyObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
Tk_Window window;
Tk_Window tkwin = (Tk_Window) clientData;
@@ -467,13 +466,12 @@ Tk_DestroyObjCmd(clientData, interp, objc, objv)
Tk_DestroyWindow(window);
if (window == tkwin) {
/*
- * We just deleted the main window for the application! This
- * makes it impossible to do anything more (tkwin isn't
- * valid anymore).
+ * We just deleted the main window for the application! This makes
+ * it impossible to do anything more (tkwin isn't valid anymore).
*/
break;
- }
+ }
}
return TCL_OK;
}
@@ -483,8 +481,8 @@ Tk_DestroyObjCmd(clientData, interp, objc, objv)
*
* Tk_LowerObjCmd --
*
- * This procedure is invoked to process the "lower" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "lower" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -497,12 +495,11 @@ Tk_DestroyObjCmd(clientData, interp, objc, objv)
/* ARGSUSED */
int
-Tk_LowerObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_LowerObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
Tk_Window mainwin = (Tk_Window) clientData;
Tk_Window tkwin, other;
@@ -527,7 +524,7 @@ Tk_LowerObjCmd(clientData, interp, objc, objv)
if (Tk_RestackWindow(tkwin, Below, other) != TCL_OK) {
Tcl_AppendResult(interp, "can't lower \"", Tcl_GetString(objv[1]),
"\" below \"", (other ? Tcl_GetString(objv[2]) : ""),
- "\"", (char *) NULL);
+ "\"", NULL);
return TCL_ERROR;
}
return TCL_OK;
@@ -538,8 +535,8 @@ Tk_LowerObjCmd(clientData, interp, objc, objv)
*
* Tk_RaiseObjCmd --
*
- * This procedure is invoked to process the "raise" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "raise" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -552,12 +549,11 @@ Tk_LowerObjCmd(clientData, interp, objc, objv)
/* ARGSUSED */
int
-Tk_RaiseObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_RaiseObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
Tk_Window mainwin = (Tk_Window) clientData;
Tk_Window tkwin, other;
@@ -582,7 +578,7 @@ Tk_RaiseObjCmd(clientData, interp, objc, objv)
if (Tk_RestackWindow(tkwin, Above, other) != TCL_OK) {
Tcl_AppendResult(interp, "can't raise \"", Tcl_GetString(objv[1]),
"\" above \"", (other ? Tcl_GetString(objv[2]) : ""),
- "\"", (char *) NULL);
+ "\"", NULL);
return TCL_ERROR;
}
return TCL_OK;
@@ -593,8 +589,8 @@ Tk_RaiseObjCmd(clientData, interp, objc, objv)
*
* Tk_TkObjCmd --
*
- * This procedure is invoked to process the "tk" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "tk" Tcl command. See the user
+ * documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -606,21 +602,21 @@ Tk_RaiseObjCmd(clientData, interp, objc, objv)
*/
int
-Tk_TkObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_TkObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
int index;
Tk_Window tkwin;
- static CONST char *optionStrings[] = {
+ static const char *optionStrings[] = {
"appname", "caret", "scaling", "useinputmethods",
- "windowingsystem", NULL
+ "windowingsystem", "inactive", NULL
};
enum options {
TK_APPNAME, TK_CARET, TK_SCALING, TK_USE_IM,
- TK_WINDOWINGSYSTEM
+ TK_WINDOWINGSYSTEM, TK_INACTIVE
};
tkwin = (Tk_Window) clientData;
@@ -635,214 +631,257 @@ Tk_TkObjCmd(clientData, interp, objc, objv)
}
switch ((enum options) index) {
- case TK_APPNAME: {
- TkWindow *winPtr;
- char *string;
-
- if (Tcl_IsSafe(interp)) {
- Tcl_SetResult(interp,
- "appname not accessible in a safe interpreter",
- TCL_STATIC);
- return TCL_ERROR;
- }
+ case TK_APPNAME: {
+ TkWindow *winPtr;
+ char *string;
+
+ if (Tcl_IsSafe(interp)) {
+ Tcl_SetResult(interp,
+ "appname not accessible in a safe interpreter",
+ TCL_STATIC);
+ return TCL_ERROR;
+ }
- winPtr = (TkWindow *) tkwin;
+ winPtr = (TkWindow *) tkwin;
- if (objc > 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?newName?");
- return TCL_ERROR;
- }
- if (objc == 3) {
- string = Tcl_GetStringFromObj(objv[2], NULL);
- winPtr->nameUid = Tk_GetUid(Tk_SetAppName(tkwin, string));
- }
- Tcl_AppendResult(interp, winPtr->nameUid, NULL);
- break;
+ if (objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?newName?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ string = Tcl_GetString(objv[2]);
+ winPtr->nameUid = Tk_GetUid(Tk_SetAppName(tkwin, string));
+ }
+ Tcl_AppendResult(interp, winPtr->nameUid, NULL);
+ break;
+ }
+ case TK_CARET: {
+ Tcl_Obj *objPtr;
+ TkCaret *caretPtr;
+ Tk_Window window;
+ static const char *caretStrings[] = {
+ "-x", "-y", "-height", NULL
+ };
+ enum caretOptions {
+ TK_CARET_X, TK_CARET_Y, TK_CARET_HEIGHT
+ };
+
+ if ((objc < 3) || ((objc > 4) && !(objc & 1))) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "window ?-x x? ?-y y? ?-height height?");
+ return TCL_ERROR;
}
- case TK_CARET: {
- Tcl_Obj *objPtr;
- TkCaret *caretPtr;
- Tk_Window window;
- static CONST char *caretStrings[]
- = { "-x", "-y", "-height", NULL };
- enum caretOptions
- { TK_CARET_X, TK_CARET_Y, TK_CARET_HEIGHT };
-
- if ((objc < 3) || ((objc > 4) && !(objc & 1))) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "window ?-x x? ?-y y? ?-height height?");
+ window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
+ if (window == NULL) {
+ return TCL_ERROR;
+ }
+ caretPtr = &(((TkWindow *) window)->dispPtr->caret);
+ if (objc == 3) {
+ /*
+ * Return all the current values
+ */
+
+ objPtr = Tcl_NewObj();
+ Tcl_ListObjAppendElement(interp, objPtr,
+ Tcl_NewStringObj("-height", 7));
+ Tcl_ListObjAppendElement(interp, objPtr,
+ Tcl_NewIntObj(caretPtr->height));
+ Tcl_ListObjAppendElement(interp, objPtr,
+ Tcl_NewStringObj("-x", 2));
+ Tcl_ListObjAppendElement(interp, objPtr,
+ Tcl_NewIntObj(caretPtr->x));
+ Tcl_ListObjAppendElement(interp, objPtr,
+ Tcl_NewStringObj("-y", 2));
+ Tcl_ListObjAppendElement(interp, objPtr,
+ Tcl_NewIntObj(caretPtr->y));
+ Tcl_SetObjResult(interp, objPtr);
+ } else if (objc == 4) {
+ int value;
+
+ /*
+ * Return the current value of the selected option
+ */
+
+ if (Tcl_GetIndexFromObj(interp, objv[3], caretStrings,
+ "caret option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
- window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
- if (window == NULL) {
- return TCL_ERROR;
+ if (index == TK_CARET_X) {
+ value = caretPtr->x;
+ } else if (index == TK_CARET_Y) {
+ value = caretPtr->y;
+ } else /* if (index == TK_CARET_HEIGHT) -- last case */ {
+ value = caretPtr->height;
}
- caretPtr = &(((TkWindow *) window)->dispPtr->caret);
- if (objc == 3) {
- /*
- * Return all the current values
- */
- objPtr = Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, objPtr,
- Tcl_NewStringObj("-height", 7));
- Tcl_ListObjAppendElement(interp, objPtr,
- Tcl_NewIntObj(caretPtr->height));
- Tcl_ListObjAppendElement(interp, objPtr,
- Tcl_NewStringObj("-x", 2));
- Tcl_ListObjAppendElement(interp, objPtr,
- Tcl_NewIntObj(caretPtr->x));
- Tcl_ListObjAppendElement(interp, objPtr,
- Tcl_NewStringObj("-y", 2));
- Tcl_ListObjAppendElement(interp, objPtr,
- Tcl_NewIntObj(caretPtr->y));
- Tcl_SetObjResult(interp, objPtr);
- } else if (objc == 4) {
- int value;
- /*
- * Return the current value of the selected option
- */
- if (Tcl_GetIndexFromObj(interp, objv[3], caretStrings,
- "caret option", 0, &index) != TCL_OK) {
+ Tcl_SetIntObj(Tcl_GetObjResult(interp), value);
+ } else {
+ int i, value, x = 0, y = 0, height = -1;
+
+ for (i = 3; i < objc; i += 2) {
+ if ((Tcl_GetIndexFromObj(interp, objv[i], caretStrings,
+ "caret option", 0, &index) != TCL_OK) ||
+ Tcl_GetIntFromObj(interp,objv[i+1],&value) != TCL_OK) {
return TCL_ERROR;
}
if (index == TK_CARET_X) {
- value = caretPtr->x;
+ x = value;
} else if (index == TK_CARET_Y) {
- value = caretPtr->y;
+ y = value;
} else /* if (index == TK_CARET_HEIGHT) -- last case */ {
- value = caretPtr->height;
- }
- Tcl_SetIntObj(Tcl_GetObjResult(interp), value);
- } else {
- int i, value, x = 0, y = 0, height = -1;
-
- for (i = 3; i < objc; i += 2) {
- if ((Tcl_GetIndexFromObj(interp, objv[i], caretStrings,
- "caret option", 0, &index) != TCL_OK) ||
- (Tcl_GetIntFromObj(interp, objv[i+1], &value)
- != TCL_OK)) {
- return TCL_ERROR;
- }
- if (index == TK_CARET_X) {
- x = value;
- } else if (index == TK_CARET_Y) {
- y = value;
- } else /* if (index == TK_CARET_HEIGHT) -- last case */ {
- height = value;
- }
- }
- if (height < 0) {
- height = Tk_Height(window);
+ height = value;
}
- Tk_SetCaretPos(window, x, y, height);
}
- break;
+ if (height < 0) {
+ height = Tk_Height(window);
+ }
+ Tk_SetCaretPos(window, x, y, height);
+ }
+ break;
+ }
+ case TK_SCALING: {
+ Screen *screenPtr;
+ int skip, width, height;
+ double d;
+
+ if (Tcl_IsSafe(interp)) {
+ Tcl_SetResult(interp,
+ "scaling not accessible in a safe interpreter",
+ TCL_STATIC);
+ return TCL_ERROR;
}
- case TK_SCALING: {
- Screen *screenPtr;
- int skip, width, height;
- double d;
- if (Tcl_IsSafe(interp)) {
- Tcl_SetResult(interp,
- "scaling not accessible in a safe interpreter",
- TCL_STATIC);
+ skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
+ if (skip < 0) {
+ return TCL_ERROR;
+ }
+ screenPtr = Tk_Screen(tkwin);
+ if (objc - skip == 2) {
+ d = 25.4 / 72;
+ d *= WidthOfScreen(screenPtr);
+ d /= WidthMMOfScreen(screenPtr);
+ Tcl_SetDoubleObj(Tcl_GetObjResult(interp), d);
+ } else if (objc - skip == 3) {
+ if (Tcl_GetDoubleFromObj(interp, objv[2+skip], &d) != TCL_OK) {
return TCL_ERROR;
}
-
- skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
- if (skip < 0) {
- return TCL_ERROR;
+ d = (25.4 / 72) / d;
+ width = (int) (d * WidthOfScreen(screenPtr) + 0.5);
+ if (width <= 0) {
+ width = 1;
}
- screenPtr = Tk_Screen(tkwin);
- if (objc - skip == 2) {
- d = 25.4 / 72;
- d *= WidthOfScreen(screenPtr);
- d /= WidthMMOfScreen(screenPtr);
- Tcl_SetDoubleObj(Tcl_GetObjResult(interp), d);
- } else if (objc - skip == 3) {
- if (Tcl_GetDoubleFromObj(interp, objv[2+skip], &d) != TCL_OK) {
- return TCL_ERROR;
- }
- d = (25.4 / 72) / d;
- width = (int) (d * WidthOfScreen(screenPtr) + 0.5);
- if (width <= 0) {
- width = 1;
- }
- height = (int) (d * HeightOfScreen(screenPtr) + 0.5);
- if (height <= 0) {
- height = 1;
- }
- WidthMMOfScreen(screenPtr) = width;
- HeightMMOfScreen(screenPtr) = height;
- } else {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-displayof window? ?factor?");
- return TCL_ERROR;
+ height = (int) (d * HeightOfScreen(screenPtr) + 0.5);
+ if (height <= 0) {
+ height = 1;
}
- break;
+ WidthMMOfScreen(screenPtr) = width;
+ HeightMMOfScreen(screenPtr) = height;
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-displayof window? ?factor?");
+ return TCL_ERROR;
+ }
+ break;
+ }
+ case TK_USE_IM: {
+ TkDisplay *dispPtr;
+ int skip;
+
+ if (Tcl_IsSafe(interp)) {
+ Tcl_SetResult(interp,
+ "useinputmethods not accessible in a safe interpreter",
+ TCL_STATIC);
+ return TCL_ERROR;
}
- case TK_USE_IM: {
- TkDisplay *dispPtr;
- int skip;
- if (Tcl_IsSafe(interp)) {
- Tcl_SetResult(interp,
- "useinputmethods not accessible in a safe interpreter",
- TCL_STATIC);
- return TCL_ERROR;
- }
+ skip = TkGetDisplayOf(interp, objc-2, objv+2, &tkwin);
+ if (skip < 0) {
+ return TCL_ERROR;
+ }
+ dispPtr = ((TkWindow *) tkwin)->dispPtr;
+ if ((objc - skip) == 3) {
+ /*
+ * In the case where TK_USE_INPUT_METHODS is not defined, this
+ * will be ignored and we will always return 0. That will indicate
+ * to the user that input methods are just not available.
+ */
- skip = TkGetDisplayOf(interp, objc-2, objv+2, &tkwin);
- if (skip < 0) {
+ int boolVal;
+
+ if (Tcl_GetBooleanFromObj(interp, objv[2+skip],
+ &boolVal) != TCL_OK) {
return TCL_ERROR;
}
- dispPtr = ((TkWindow *) tkwin)->dispPtr;
- if ((objc - skip) == 3) {
- /*
- * In the case where TK_USE_INPUT_METHODS is not defined,
- * this will be ignored and we will always return 0.
- * That will indicate to the user that input methods
- * are just not available.
- */
- int boolVal;
- if (Tcl_GetBooleanFromObj(interp, objv[2+skip], &boolVal)
- != TCL_OK) {
- return TCL_ERROR;
- }
#ifdef TK_USE_INPUT_METHODS
- if (boolVal) {
- dispPtr->flags |= TK_DISPLAY_USE_IM;
- } else {
- dispPtr->flags &= ~TK_DISPLAY_USE_IM;
- }
-#endif /* TK_USE_INPUT_METHODS */
- } else if ((objc - skip) != 2) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-displayof window? ?boolean?");
- return TCL_ERROR;
+ if (boolVal) {
+ dispPtr->flags |= TK_DISPLAY_USE_IM;
+ } else {
+ dispPtr->flags &= ~TK_DISPLAY_USE_IM;
}
- Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
- (int) (dispPtr->flags & TK_DISPLAY_USE_IM));
- break;
+#endif /* TK_USE_INPUT_METHODS */
+ } else if ((objc - skip) != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-displayof window? ?boolean?");
+ return TCL_ERROR;
+ }
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
+ (int) (dispPtr->flags & TK_DISPLAY_USE_IM));
+ break;
+ }
+ case TK_WINDOWINGSYSTEM: {
+ const char *windowingsystem;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
}
- case TK_WINDOWINGSYSTEM: {
- CONST char *windowingsystem;
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
- }
#if defined(WIN32)
- windowingsystem = "win32";
+ windowingsystem = "win32";
#elif defined(MAC_OSX_TK)
- windowingsystem = "aqua";
+ windowingsystem = "aqua";
#else
- windowingsystem = "x11";
+ windowingsystem = "x11";
#endif
- Tcl_SetStringObj(Tcl_GetObjResult(interp), windowingsystem, -1);
- break;
+ Tcl_SetStringObj(Tcl_GetObjResult(interp), windowingsystem, -1);
+ break;
+ }
+ case TK_INACTIVE: {
+ int skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
+
+ if (skip < 0) {
+ return TCL_ERROR;
+ }
+ if (objc - skip == 2) {
+ long inactive;
+
+ inactive = (Tcl_IsSafe(interp) ? -1 :
+ Tk_GetUserInactiveTime(Tk_Display(tkwin)));
+ Tcl_SetObjResult(interp, Tcl_NewLongObj(inactive));
+
+ } else if (objc - skip == 3) {
+ char *string;
+
+ string = Tcl_GetString(objv[objc-1]);
+ if (strcmp(string, "reset") != 0) {
+ Tcl_Obj *msg = Tcl_NewStringObj("bad option \"", -1);
+
+ Tcl_AppendStringsToObj(msg, string, "\": must be reset", NULL);
+ Tcl_SetObjResult(interp, msg);
+ return TCL_ERROR;
+ }
+ if (Tcl_IsSafe(interp)) {
+ Tcl_SetResult(interp,
+ "resetting the user inactivity timer "
+ "is not allowed in a safe interpreter", TCL_STATIC);
+ return TCL_ERROR;
+ }
+ Tk_ResetUserInactiveTime(Tk_Display(tkwin));
+ Tcl_ResetResult(interp);
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? ?reset?");
+ return TCL_ERROR;
}
+ break;
+ }
}
return TCL_OK;
}
@@ -852,8 +891,8 @@ Tk_TkObjCmd(clientData, interp, objc, objv)
*
* Tk_TkwaitObjCmd --
*
- * This procedure is invoked to process the "tkwait" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "tkwait" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -866,19 +905,21 @@ Tk_TkObjCmd(clientData, interp, objc, objv)
/* ARGSUSED */
int
-Tk_TkwaitObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_TkwaitObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
Tk_Window tkwin = (Tk_Window) clientData;
int done, index;
- static CONST char *optionStrings[] = { "variable", "visibility", "window",
- (char *) NULL };
- enum options { TKWAIT_VARIABLE, TKWAIT_VISIBILITY, TKWAIT_WINDOW };
-
+ static const char *optionStrings[] = {
+ "variable", "visibility", "window", NULL
+ };
+ enum options {
+ TKWAIT_VARIABLE, TKWAIT_VISIBILITY, TKWAIT_WINDOW
+ };
+
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "variable|visibility|window name");
return TCL_ERROR;
@@ -890,78 +931,78 @@ Tk_TkwaitObjCmd(clientData, interp, objc, objv)
}
switch ((enum options) index) {
- case TKWAIT_VARIABLE: {
- if (Tcl_TraceVar(interp, Tcl_GetString(objv[2]),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
- WaitVariableProc, (ClientData) &done) != TCL_OK) {
- return TCL_ERROR;
- }
- done = 0;
- while (!done) {
- Tcl_DoOneEvent(0);
- }
- Tcl_UntraceVar(interp, Tcl_GetString(objv[2]),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
- WaitVariableProc, (ClientData) &done);
- break;
+ case TKWAIT_VARIABLE:
+ if (Tcl_TraceVar(interp, Tcl_GetString(objv[2]),
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ WaitVariableProc, (ClientData) &done) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ done = 0;
+ while (!done) {
+ Tcl_DoOneEvent(0);
}
-
- case TKWAIT_VISIBILITY: {
- Tk_Window window;
+ Tcl_UntraceVar(interp, Tcl_GetString(objv[2]),
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ WaitVariableProc, (ClientData) &done);
+ break;
- window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
- if (window == NULL) {
- return TCL_ERROR;
- }
- Tk_CreateEventHandler(window,
- VisibilityChangeMask|StructureNotifyMask,
- WaitVisibilityProc, (ClientData) &done);
- done = 0;
- while (!done) {
- Tcl_DoOneEvent(0);
- }
- if (done != 1) {
- /*
- * Note that we do not delete the event handler because it
- * was deleted automatically when the window was destroyed.
- */
-
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "window \"", Tcl_GetString(objv[2]),
- "\" was deleted before its visibility changed",
- (char *) NULL);
- return TCL_ERROR;
- }
- Tk_DeleteEventHandler(window,
- VisibilityChangeMask|StructureNotifyMask,
- WaitVisibilityProc, (ClientData) &done);
- break;
+ case TKWAIT_VISIBILITY: {
+ Tk_Window window;
+
+ window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
+ if (window == NULL) {
+ return TCL_ERROR;
}
-
- case TKWAIT_WINDOW: {
- Tk_Window window;
-
- window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
- if (window == NULL) {
- return TCL_ERROR;
- }
- Tk_CreateEventHandler(window, StructureNotifyMask,
- WaitWindowProc, (ClientData) &done);
- done = 0;
- while (!done) {
- Tcl_DoOneEvent(0);
- }
+ Tk_CreateEventHandler(window,
+ VisibilityChangeMask|StructureNotifyMask,
+ WaitVisibilityProc, (ClientData) &done);
+ done = 0;
+ while (!done) {
+ Tcl_DoOneEvent(0);
+ }
+ if (done != 1) {
/*
- * Note: there's no need to delete the event handler. It was
+ * Note that we do not delete the event handler because it was
* deleted automatically when the window was destroyed.
*/
- break;
+
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "window \"", Tcl_GetString(objv[2]),
+ "\" was deleted before its visibility changed", NULL);
+ return TCL_ERROR;
}
+ Tk_DeleteEventHandler(window,
+ VisibilityChangeMask|StructureNotifyMask,
+ WaitVisibilityProc, (ClientData) &done);
+ break;
+ }
+
+ case TKWAIT_WINDOW: {
+ Tk_Window window;
+
+ window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
+ if (window == NULL) {
+ return TCL_ERROR;
+ }
+ Tk_CreateEventHandler(window, StructureNotifyMask,
+ WaitWindowProc, (ClientData) &done);
+ done = 0;
+ while (!done) {
+ Tcl_DoOneEvent(0);
+ }
+
+ /*
+ * Note: there's no need to delete the event handler. It was deleted
+ * automatically when the window was destroyed.
+ */
+
+ break;
+ }
}
/*
- * Clear out the interpreter's result, since it may have been set
- * by event handlers.
+ * Clear out the interpreter's result, since it may have been set by event
+ * handlers.
*/
Tcl_ResetResult(interp);
@@ -970,24 +1011,24 @@ Tk_TkwaitObjCmd(clientData, interp, objc, objv)
/* ARGSUSED */
static char *
-WaitVariableProc(clientData, interp, name1, name2, flags)
- ClientData clientData; /* Pointer to integer to set to 1. */
- Tcl_Interp *interp; /* Interpreter containing variable. */
- CONST char *name1; /* Name of variable. */
- CONST char *name2; /* Second part of variable name. */
- int flags; /* Information about what happened. */
+WaitVariableProc(
+ ClientData clientData, /* Pointer to integer to set to 1. */
+ Tcl_Interp *interp, /* Interpreter containing variable. */
+ const char *name1, /* Name of variable. */
+ const char *name2, /* Second part of variable name. */
+ int flags) /* Information about what happened. */
{
int *donePtr = (int *) clientData;
*donePtr = 1;
- return (char *) NULL;
+ return NULL;
}
/*ARGSUSED*/
static void
-WaitVisibilityProc(clientData, eventPtr)
- ClientData clientData; /* Pointer to integer to set to 1. */
- XEvent *eventPtr; /* Information about event (not used). */
+WaitVisibilityProc(
+ ClientData clientData, /* Pointer to integer to set to 1. */
+ XEvent *eventPtr) /* Information about event (not used). */
{
int *donePtr = (int *) clientData;
@@ -1000,9 +1041,9 @@ WaitVisibilityProc(clientData, eventPtr)
}
static void
-WaitWindowProc(clientData, eventPtr)
- ClientData clientData; /* Pointer to integer to set to 1. */
- XEvent *eventPtr; /* Information about event. */
+WaitWindowProc(
+ ClientData clientData, /* Pointer to integer to set to 1. */
+ XEvent *eventPtr) /* Information about event. */
{
int *donePtr = (int *) clientData;
@@ -1016,8 +1057,8 @@ WaitWindowProc(clientData, eventPtr)
*
* Tk_UpdateObjCmd --
*
- * This procedure is invoked to process the "update" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "update" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -1030,14 +1071,13 @@ WaitWindowProc(clientData, eventPtr)
/* ARGSUSED */
int
-Tk_UpdateObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_UpdateObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- static CONST char *updateOptions[] = {"idletasks", (char *) NULL};
+ static const char *updateOptions[] = {"idletasks", NULL};
int flags, index;
TkDisplay *dispPtr;
@@ -1050,19 +1090,18 @@ Tk_UpdateObjCmd(clientData, interp, objc, objv)
}
flags = TCL_IDLE_EVENTS;
} else {
- Tcl_WrongNumArgs(interp, 1, objv, "?idletasks?");
+ Tcl_WrongNumArgs(interp, 1, objv, "?idletasks?");
return TCL_ERROR;
}
/*
- * Handle all pending events, sync all displays, and repeat over
- * and over again until all pending events have been handled.
- * Special note: it's possible that the entire application could
- * be destroyed by an event handler that occurs during the update.
- * Thus, don't use any information from tkwin after calling
- * Tcl_DoOneEvent.
+ * Handle all pending events, sync all displays, and repeat over and over
+ * again until all pending events have been handled. Special note: it's
+ * possible that the entire application could be destroyed by an event
+ * handler that occurs during the update. Thus, don't use any information
+ * from tkwin after calling Tcl_DoOneEvent.
*/
-
+
while (1) {
while (Tcl_DoOneEvent(flags) != 0) {
/* Empty loop body */
@@ -1077,8 +1116,8 @@ Tk_UpdateObjCmd(clientData, interp, objc, objv)
}
/*
- * Must clear the interpreter's result because event handlers could
- * have executed commands.
+ * Must clear the interpreter's result because event handlers could have
+ * executed commands.
*/
Tcl_ResetResult(interp);
@@ -1090,8 +1129,8 @@ Tk_UpdateObjCmd(clientData, interp, objc, objv)
*
* Tk_WinfoObjCmd --
*
- * This procedure is invoked to process the "winfo" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "winfo" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -1103,12 +1142,11 @@ Tk_UpdateObjCmd(clientData, interp, objc, objv)
*/
int
-Tk_WinfoObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_WinfoObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
int index, x, y, width, height, useX, useY, class, skip;
char *string;
@@ -1116,7 +1154,7 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv)
Tk_Window tkwin;
Tcl_Obj *resultPtr;
- static TkStateMap visualMap[] = {
+ static const TkStateMap visualMap[] = {
{PseudoColor, "pseudocolor"},
{GrayScale, "grayscale"},
{DirectColor, "directcolor"},
@@ -1125,7 +1163,7 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv)
{StaticGray, "staticgray"},
{-1, NULL}
};
- static CONST char *optionStrings[] = {
+ static const char *optionStrings[] = {
"cells", "children", "class", "colormapfull",
"depth", "geometry", "height", "id",
"ismapped", "manager", "name", "parent",
@@ -1136,7 +1174,7 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv)
"toplevel", "viewable", "visual", "visualid",
"vrootheight", "vrootwidth", "vrootx", "vrooty",
"width", "x", "y",
-
+
"atom", "atomname", "containing", "interps",
"pathname",
@@ -1156,7 +1194,7 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv)
WIN_TOPLEVEL, WIN_VIEWABLE, WIN_VISUAL, WIN_VISUALID,
WIN_VROOTHEIGHT,WIN_VROOTWIDTH, WIN_VROOTX, WIN_VROOTY,
WIN_WIDTH, WIN_X, WIN_Y,
-
+
WIN_ATOM, WIN_ATOMNAME, WIN_CONTAINING, WIN_INTERPS,
WIN_PATHNAME,
@@ -1165,7 +1203,7 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv)
};
tkwin = (Tk_Window) clientData;
-
+
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
return TCL_ERROR;
@@ -1180,7 +1218,7 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv)
Tcl_WrongNumArgs(interp, 2, objv, "window");
return TCL_ERROR;
}
- string = Tcl_GetStringFromObj(objv[2], NULL);
+ string = Tcl_GetString(objv[2]);
tkwin = Tk_NameToWindow(interp, string, tkwin);
if (tkwin == NULL) {
return TCL_ERROR;
@@ -1190,502 +1228,468 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv)
resultPtr = Tcl_GetObjResult(interp);
switch ((enum options) index) {
- case WIN_CELLS: {
- Tcl_SetIntObj(resultPtr, Tk_Visual(tkwin)->map_entries);
- break;
- }
- case WIN_CHILDREN: {
- Tcl_Obj *strPtr;
-
- winPtr = winPtr->childList;
- for ( ; winPtr != NULL; winPtr = winPtr->nextPtr) {
- if (!(winPtr->flags & TK_ANONYMOUS_WINDOW)) {
- strPtr = Tcl_NewStringObj(winPtr->pathName, -1);
- Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
- }
+ case WIN_CELLS:
+ Tcl_SetIntObj(resultPtr, Tk_Visual(tkwin)->map_entries);
+ break;
+ case WIN_CHILDREN: {
+ Tcl_Obj *strPtr;
+
+ winPtr = winPtr->childList;
+ for ( ; winPtr != NULL; winPtr = winPtr->nextPtr) {
+ if (!(winPtr->flags & TK_ANONYMOUS_WINDOW)) {
+ strPtr = Tcl_NewStringObj(winPtr->pathName, -1);
+ Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
}
- break;
- }
- case WIN_CLASS: {
- Tcl_SetStringObj(resultPtr, Tk_Class(tkwin), -1);
- break;
- }
- case WIN_COLORMAPFULL: {
- Tcl_SetBooleanObj(resultPtr,
- TkpCmapStressed(tkwin, Tk_Colormap(tkwin)));
- break;
}
- case WIN_DEPTH: {
- Tcl_SetIntObj(resultPtr, Tk_Depth(tkwin));
- break;
- }
- case WIN_GEOMETRY: {
- char buf[16 + TCL_INTEGER_SPACE * 4];
+ break;
+ }
+ case WIN_CLASS:
+ Tcl_SetStringObj(resultPtr, Tk_Class(tkwin), -1);
+ break;
+ case WIN_COLORMAPFULL:
+ Tcl_SetBooleanObj(resultPtr,
+ TkpCmapStressed(tkwin, Tk_Colormap(tkwin)));
+ break;
+ case WIN_DEPTH:
+ Tcl_SetIntObj(resultPtr, Tk_Depth(tkwin));
+ break;
+ case WIN_GEOMETRY: {
+ 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(resultPtr, buf, -1);
+ break;
+ }
+ case WIN_HEIGHT:
+ Tcl_SetIntObj(resultPtr, Tk_Height(tkwin));
+ break;
+ case WIN_ID: {
+ char buf[TCL_INTEGER_SPACE];
- sprintf(buf, "%dx%d+%d+%d", Tk_Width(tkwin), Tk_Height(tkwin),
- Tk_X(tkwin), Tk_Y(tkwin));
- Tcl_SetStringObj(resultPtr, buf, -1);
- break;
- }
- case WIN_HEIGHT: {
- Tcl_SetIntObj(resultPtr, Tk_Height(tkwin));
- break;
+ Tk_MakeWindowExist(tkwin);
+ TkpPrintWindowId(buf, Tk_WindowId(tkwin));
+
+ /*
+ * interp result may have changed, refetch it
+ */
+
+ resultPtr = Tcl_GetObjResult(interp);
+ Tcl_SetStringObj(resultPtr, buf, -1);
+ break;
+ }
+ case WIN_ISMAPPED:
+ Tcl_SetBooleanObj(resultPtr, (int) Tk_IsMapped(tkwin));
+ break;
+ case WIN_MANAGER:
+ if (winPtr->geomMgrPtr != NULL) {
+ Tcl_SetStringObj(resultPtr, winPtr->geomMgrPtr->name, -1);
+ }
+ break;
+ case WIN_NAME:
+ Tcl_SetStringObj(resultPtr, Tk_Name(tkwin), -1);
+ break;
+ case WIN_PARENT:
+ if (winPtr->parentPtr != NULL) {
+ Tcl_SetStringObj(resultPtr, winPtr->parentPtr->pathName, -1);
+ }
+ break;
+ case WIN_POINTERX:
+ useX = 1;
+ useY = 0;
+ goto pointerxy;
+ case WIN_POINTERY:
+ useX = 0;
+ useY = 1;
+ goto pointerxy;
+ case WIN_POINTERXY:
+ useX = 1;
+ useY = 1;
+
+ pointerxy:
+ winPtr = GetTopHierarchy(tkwin);
+ if (winPtr == NULL) {
+ x = -1;
+ y = -1;
+ } else {
+ TkGetPointerCoords((Tk_Window) winPtr, &x, &y);
}
- case WIN_ID: {
- char buf[TCL_INTEGER_SPACE];
-
- Tk_MakeWindowExist(tkwin);
- TkpPrintWindowId(buf, Tk_WindowId(tkwin));
- /*
- * interp result may have changed, refetch it
- */
- resultPtr = Tcl_GetObjResult(interp);
+ if (useX & useY) {
+ char buf[TCL_INTEGER_SPACE * 2];
+
+ sprintf(buf, "%d %d", x, y);
Tcl_SetStringObj(resultPtr, buf, -1);
- break;
- }
- case WIN_ISMAPPED: {
- Tcl_SetBooleanObj(resultPtr, (int) Tk_IsMapped(tkwin));
- break;
- }
- case WIN_MANAGER: {
- if (winPtr->geomMgrPtr != NULL) {
- Tcl_SetStringObj(resultPtr, winPtr->geomMgrPtr->name, -1);
- }
- break;
- }
- case WIN_NAME: {
- Tcl_SetStringObj(resultPtr, Tk_Name(tkwin), -1);
- break;
- }
- case WIN_PARENT: {
- if (winPtr->parentPtr != NULL) {
- Tcl_SetStringObj(resultPtr, winPtr->parentPtr->pathName, -1);
- }
- break;
+ } else if (useX) {
+ Tcl_SetIntObj(resultPtr, x);
+ } else {
+ Tcl_SetIntObj(resultPtr, y);
}
- case WIN_POINTERX: {
- useX = 1;
- useY = 0;
- goto pointerxy;
- }
- case WIN_POINTERY: {
- useX = 0;
- useY = 1;
- goto pointerxy;
- }
- case WIN_POINTERXY: {
- useX = 1;
- useY = 1;
-
- pointerxy:
- winPtr = GetToplevel(tkwin);
- if (winPtr == NULL) {
- x = -1;
- y = -1;
- } else {
- TkGetPointerCoords((Tk_Window) winPtr, &x, &y);
+ break;
+ case WIN_REQHEIGHT:
+ Tcl_SetIntObj(resultPtr, Tk_ReqHeight(tkwin));
+ break;
+ case WIN_REQWIDTH:
+ Tcl_SetIntObj(resultPtr, Tk_ReqWidth(tkwin));
+ break;
+ case WIN_ROOTX:
+ Tk_GetRootCoords(tkwin, &x, &y);
+ Tcl_SetIntObj(resultPtr, x);
+ break;
+ case WIN_ROOTY:
+ Tk_GetRootCoords(tkwin, &x, &y);
+ Tcl_SetIntObj(resultPtr, y);
+ break;
+ case WIN_SCREEN: {
+ char buf[TCL_INTEGER_SPACE];
+
+ sprintf(buf, "%d", Tk_ScreenNumber(tkwin));
+ Tcl_AppendStringsToObj(resultPtr, Tk_DisplayName(tkwin),".",buf, NULL);
+ break;
+ }
+ case WIN_SCREENCELLS:
+ Tcl_SetIntObj(resultPtr, CellsOfScreen(Tk_Screen(tkwin)));
+ break;
+ case WIN_SCREENDEPTH:
+ Tcl_SetIntObj(resultPtr, DefaultDepthOfScreen(Tk_Screen(tkwin)));
+ break;
+ case WIN_SCREENHEIGHT:
+ Tcl_SetIntObj(resultPtr, HeightOfScreen(Tk_Screen(tkwin)));
+ break;
+ case WIN_SCREENWIDTH:
+ Tcl_SetIntObj(resultPtr, WidthOfScreen(Tk_Screen(tkwin)));
+ break;
+ case WIN_SCREENMMHEIGHT:
+ Tcl_SetIntObj(resultPtr, HeightMMOfScreen(Tk_Screen(tkwin)));
+ break;
+ case WIN_SCREENMMWIDTH:
+ Tcl_SetIntObj(resultPtr, WidthMMOfScreen(Tk_Screen(tkwin)));
+ break;
+ case WIN_SCREENVISUAL:
+ class = DefaultVisualOfScreen(Tk_Screen(tkwin))->class;
+ goto visual;
+ case WIN_SERVER:
+ TkGetServerInfo(interp, tkwin);
+ break;
+ case WIN_TOPLEVEL:
+ winPtr = GetTopHierarchy(tkwin);
+ if (winPtr != NULL) {
+ Tcl_SetStringObj(resultPtr, winPtr->pathName, -1);
+ }
+ break;
+ case WIN_VIEWABLE: {
+ int viewable = 0;
+
+ for ( ; ; winPtr = winPtr->parentPtr) {
+ if ((winPtr == NULL) || !(winPtr->flags & TK_MAPPED)) {
+ break;
}
- if (useX & useY) {
- char buf[TCL_INTEGER_SPACE * 2];
-
- sprintf(buf, "%d %d", x, y);
- Tcl_SetStringObj(resultPtr, buf, -1);
- } else if (useX) {
- Tcl_SetIntObj(resultPtr, x);
- } else {
- Tcl_SetIntObj(resultPtr, y);
+ if (winPtr->flags & TK_TOP_HIERARCHY) {
+ viewable = 1;
+ break;
}
- break;
}
- case WIN_REQHEIGHT: {
- Tcl_SetIntObj(resultPtr, Tk_ReqHeight(tkwin));
- break;
- }
- case WIN_REQWIDTH: {
- Tcl_SetIntObj(resultPtr, Tk_ReqWidth(tkwin));
- break;
- }
- case WIN_ROOTX: {
- Tk_GetRootCoords(tkwin, &x, &y);
- Tcl_SetIntObj(resultPtr, x);
- break;
- }
- case WIN_ROOTY: {
- Tk_GetRootCoords(tkwin, &x, &y);
- Tcl_SetIntObj(resultPtr, y);
- break;
+
+ Tcl_SetBooleanObj(resultPtr, viewable);
+ break;
+ }
+ case WIN_VISUAL:
+ class = Tk_Visual(tkwin)->class;
+
+ visual:
+ string = TkFindStateString(visualMap, class);
+ if (string == NULL) {
+ string = "unknown";
+ }
+ Tcl_SetStringObj(resultPtr, string, -1);
+ break;
+ case WIN_VISUALID: {
+ char buf[TCL_INTEGER_SPACE];
+
+ sprintf(buf, "0x%x",
+ (unsigned int) XVisualIDFromVisual(Tk_Visual(tkwin)));
+ Tcl_SetStringObj(resultPtr, buf, -1);
+ break;
+ }
+ case WIN_VROOTHEIGHT:
+ Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
+ Tcl_SetIntObj(resultPtr, height);
+ break;
+ case WIN_VROOTWIDTH:
+ Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
+ Tcl_SetIntObj(resultPtr, width);
+ break;
+ case WIN_VROOTX:
+ Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
+ Tcl_SetIntObj(resultPtr, x);
+ break;
+ case WIN_VROOTY:
+ Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
+ Tcl_SetIntObj(resultPtr, y);
+ break;
+ case WIN_WIDTH:
+ Tcl_SetIntObj(resultPtr, Tk_Width(tkwin));
+ break;
+ case WIN_X:
+ Tcl_SetIntObj(resultPtr, Tk_X(tkwin));
+ break;
+ case WIN_Y:
+ Tcl_SetIntObj(resultPtr, Tk_Y(tkwin));
+ break;
+
+ /*
+ * Uses -displayof.
+ */
+
+ case WIN_ATOM:
+ skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
+ if (skip < 0) {
+ return TCL_ERROR;
}
- case WIN_SCREEN: {
- char buf[TCL_INTEGER_SPACE];
-
- sprintf(buf, "%d", Tk_ScreenNumber(tkwin));
- Tcl_AppendStringsToObj(resultPtr, Tk_DisplayName(tkwin), ".",
- buf, NULL);
- break;
+ if (objc - skip != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? name");
+ return TCL_ERROR;
}
- case WIN_SCREENCELLS: {
- Tcl_SetIntObj(resultPtr, CellsOfScreen(Tk_Screen(tkwin)));
- break;
+ objv += skip;
+ string = Tcl_GetString(objv[2]);
+ Tcl_SetLongObj(resultPtr, (long) Tk_InternAtom(tkwin, string));
+ break;
+ case WIN_ATOMNAME: {
+ const char *name;
+ long id;
+
+ skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
+ if (skip < 0) {
+ return TCL_ERROR;
}
- case WIN_SCREENDEPTH: {
- Tcl_SetIntObj(resultPtr, DefaultDepthOfScreen(Tk_Screen(tkwin)));
- break;
+ if (objc - skip != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? id");
+ return TCL_ERROR;
}
- case WIN_SCREENHEIGHT: {
- Tcl_SetIntObj(resultPtr, HeightOfScreen(Tk_Screen(tkwin)));
- break;
+ objv += skip;
+ if (Tcl_GetLongFromObj(interp, objv[2], &id) != TCL_OK) {
+ return TCL_ERROR;
}
- case WIN_SCREENWIDTH: {
- Tcl_SetIntObj(resultPtr, WidthOfScreen(Tk_Screen(tkwin)));
- break;
+ name = Tk_GetAtomName(tkwin, (Atom) id);
+ if (strcmp(name, "?bad atom?") == 0) {
+ string = Tcl_GetString(objv[2]);
+ Tcl_AppendStringsToObj(resultPtr,
+ "no atom exists with id \"", string, "\"", NULL);
+ return TCL_ERROR;
}
- case WIN_SCREENMMHEIGHT: {
- Tcl_SetIntObj(resultPtr, HeightMMOfScreen(Tk_Screen(tkwin)));
- break;
+ Tcl_SetStringObj(resultPtr, name, -1);
+ break;
+ }
+ case WIN_CONTAINING:
+ skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
+ if (skip < 0) {
+ return TCL_ERROR;
}
- case WIN_SCREENMMWIDTH: {
- Tcl_SetIntObj(resultPtr, WidthMMOfScreen(Tk_Screen(tkwin)));
- break;
+ if (objc - skip != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-displayof window? rootX rootY");
+ return TCL_ERROR;
}
- case WIN_SCREENVISUAL: {
- class = DefaultVisualOfScreen(Tk_Screen(tkwin))->class;
- goto visual;
+ objv += skip;
+ string = Tcl_GetString(objv[2]);
+ if (Tk_GetPixels(interp, tkwin, string, &x) != TCL_OK) {
+ return TCL_ERROR;
}
- case WIN_SERVER: {
- TkGetServerInfo(interp, tkwin);
- break;
+ string = Tcl_GetString(objv[3]);
+ if (Tk_GetPixels(interp, tkwin, string, &y) != TCL_OK) {
+ return TCL_ERROR;
}
- case WIN_TOPLEVEL: {
- winPtr = GetToplevel(tkwin);
- if (winPtr != NULL) {
- Tcl_SetStringObj(resultPtr, winPtr->pathName, -1);
- }
- break;
+ tkwin = Tk_CoordsToWindow(x, y, tkwin);
+ if (tkwin != NULL) {
+ Tcl_SetStringObj(resultPtr, Tk_PathName(tkwin), -1);
}
- case WIN_VIEWABLE: {
- int viewable = 0;
- for ( ; ; winPtr = winPtr->parentPtr) {
- if ((winPtr == NULL) || !(winPtr->flags & TK_MAPPED)) {
- break;
- }
- if (winPtr->flags & TK_TOP_HIERARCHY) {
- viewable = 1;
- break;
- }
- }
+ break;
+ case WIN_INTERPS: {
+ int result;
- Tcl_SetBooleanObj(resultPtr, viewable);
- break;
+ skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
+ if (skip < 0) {
+ return TCL_ERROR;
}
- case WIN_VISUAL: {
- class = Tk_Visual(tkwin)->class;
-
- visual:
- string = TkFindStateString(visualMap, class);
- if (string == NULL) {
- string = "unknown";
- }
- Tcl_SetStringObj(resultPtr, string, -1);
- break;
+ if (objc - skip != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
+ return TCL_ERROR;
}
- case WIN_VISUALID: {
- char buf[TCL_INTEGER_SPACE];
+ result = TkGetInterpNames(interp, tkwin);
+ return result;
+ }
+ case WIN_PATHNAME: {
+ Window id;
- sprintf(buf, "0x%x",
- (unsigned int) XVisualIDFromVisual(Tk_Visual(tkwin)));
- Tcl_SetStringObj(resultPtr, buf, -1);
- break;
- }
- case WIN_VROOTHEIGHT: {
- Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
- Tcl_SetIntObj(resultPtr, height);
- break;
- }
- case WIN_VROOTWIDTH: {
- Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
- Tcl_SetIntObj(resultPtr, width);
- break;
- }
- case WIN_VROOTX: {
- Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
- Tcl_SetIntObj(resultPtr, x);
- break;
- }
- case WIN_VROOTY: {
- Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
- Tcl_SetIntObj(resultPtr, y);
- break;
+ skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
+ if (skip < 0) {
+ return TCL_ERROR;
}
- case WIN_WIDTH: {
- Tcl_SetIntObj(resultPtr, Tk_Width(tkwin));
- break;
+ if (objc - skip != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? id");
+ return TCL_ERROR;
}
- case WIN_X: {
- Tcl_SetIntObj(resultPtr, Tk_X(tkwin));
- break;
+ string = Tcl_GetString(objv[2 + skip]);
+ if (TkpScanWindowId(interp, string, &id) != TCL_OK) {
+ return TCL_ERROR;
}
- case WIN_Y: {
- Tcl_SetIntObj(resultPtr, Tk_Y(tkwin));
- break;
+ winPtr = (TkWindow *)Tk_IdToWindow(Tk_Display(tkwin), id);
+ if ((winPtr == NULL) ||
+ (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr)) {
+ Tcl_AppendStringsToObj(resultPtr, "window id \"", string,
+ "\" doesn't exist in this application", NULL);
+ return TCL_ERROR;
}
/*
- * Uses -displayof.
+ * If the window is a utility window with no associated path (such as
+ * a wrapper window or send communication window), just return an
+ * empty string.
*/
-
- case WIN_ATOM: {
- skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
- if (skip < 0) {
- return TCL_ERROR;
- }
- if (objc - skip != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? name");
- return TCL_ERROR;
- }
- objv += skip;
- string = Tcl_GetStringFromObj(objv[2], NULL);
- Tcl_SetLongObj(resultPtr, (long) Tk_InternAtom(tkwin, string));
- break;
- }
- case WIN_ATOMNAME: {
- CONST char *name;
- long id;
-
- skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
- if (skip < 0) {
- return TCL_ERROR;
- }
- if (objc - skip != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? id");
- return TCL_ERROR;
- }
- objv += skip;
- if (Tcl_GetLongFromObj(interp, objv[2], &id) != TCL_OK) {
- return TCL_ERROR;
- }
- name = Tk_GetAtomName(tkwin, (Atom) id);
- if (strcmp(name, "?bad atom?") == 0) {
- string = Tcl_GetStringFromObj(objv[2], NULL);
- Tcl_AppendStringsToObj(resultPtr,
- "no atom exists with id \"", string, "\"", NULL);
- return TCL_ERROR;
- }
- Tcl_SetStringObj(resultPtr, name, -1);
- break;
- }
- case WIN_CONTAINING: {
- skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
- if (skip < 0) {
- return TCL_ERROR;
- }
- if (objc - skip != 4) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-displayof window? rootX rootY");
- return TCL_ERROR;
- }
- objv += skip;
- string = Tcl_GetStringFromObj(objv[2], NULL);
- if (Tk_GetPixels(interp, tkwin, string, &x) != TCL_OK) {
- return TCL_ERROR;
- }
- string = Tcl_GetStringFromObj(objv[3], NULL);
- if (Tk_GetPixels(interp, tkwin, string, &y) != TCL_OK) {
- return TCL_ERROR;
- }
- tkwin = Tk_CoordsToWindow(x, y, tkwin);
- if (tkwin != NULL) {
- Tcl_SetStringObj(resultPtr, Tk_PathName(tkwin), -1);
- }
- break;
- }
- case WIN_INTERPS: {
- int result;
-
- skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
- if (skip < 0) {
- return TCL_ERROR;
- }
- if (objc - skip != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
- return TCL_ERROR;
- }
- result = TkGetInterpNames(interp, tkwin);
- return result;
- }
- case WIN_PATHNAME: {
- Window id;
- skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
- if (skip < 0) {
- return TCL_ERROR;
- }
- if (objc - skip != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? id");
- return TCL_ERROR;
- }
- string = Tcl_GetStringFromObj(objv[2 + skip], NULL);
- if (TkpScanWindowId(interp, string, &id) != TCL_OK) {
- return TCL_ERROR;
- }
- winPtr = (TkWindow *)Tk_IdToWindow(Tk_Display(tkwin), id);
- if ((winPtr == NULL) ||
- (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr)) {
- Tcl_AppendStringsToObj(resultPtr, "window id \"", string,
- "\" doesn't exist in this application", (char *) NULL);
- return TCL_ERROR;
- }
-
- /*
- * If the window is a utility window with no associated path
- * (such as a wrapper window or send communication window), just
- * return an empty string.
- */
-
- tkwin = (Tk_Window) winPtr;
- if (Tk_PathName(tkwin) != NULL) {
- Tcl_SetStringObj(resultPtr, Tk_PathName(tkwin), -1);
- }
- break;
+ tkwin = (Tk_Window) winPtr;
+ if (Tk_PathName(tkwin) != NULL) {
+ Tcl_SetStringObj(resultPtr, Tk_PathName(tkwin), -1);
}
+ break;
+ }
/*
* objv[3] is window.
*/
- case WIN_EXISTS: {
- int alive;
+ case WIN_EXISTS: {
+ int alive;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "window");
- return TCL_ERROR;
- }
- string = Tcl_GetStringFromObj(objv[2], NULL);
- winPtr = (TkWindow *) Tk_NameToWindow(interp, string, tkwin);
- Tcl_ResetResult(interp);
- resultPtr = Tcl_GetObjResult(interp);
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window");
+ return TCL_ERROR;
+ }
+ string = Tcl_GetString(objv[2]);
+ 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_SetBooleanObj(resultPtr, alive);
- break;
+ alive = 1;
+ if ((winPtr == NULL) || (winPtr->flags & TK_ALREADY_DEAD)) {
+ alive = 0;
}
- case WIN_FPIXELS: {
- double mm, pixels;
+ Tcl_SetBooleanObj(resultPtr, alive);
+ break;
+ }
+ case WIN_FPIXELS: {
+ double mm, pixels;
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "window number");
- return TCL_ERROR;
- }
- string = Tcl_GetStringFromObj(objv[2], NULL);
- tkwin = Tk_NameToWindow(interp, string, tkwin);
- if (tkwin == NULL) {
- return TCL_ERROR;
- }
- string = Tcl_GetStringFromObj(objv[3], NULL);
- if (Tk_GetScreenMM(interp, tkwin, string, &mm) != TCL_OK) {
- return TCL_ERROR;
- }
- pixels = mm * WidthOfScreen(Tk_Screen(tkwin))
- / WidthMMOfScreen(Tk_Screen(tkwin));
- Tcl_SetDoubleObj(resultPtr, pixels);
- break;
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window number");
+ return TCL_ERROR;
}
- case WIN_PIXELS: {
- int pixels;
-
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "window number");
- return TCL_ERROR;
- }
- string = Tcl_GetStringFromObj(objv[2], NULL);
- tkwin = Tk_NameToWindow(interp, string, tkwin);
- if (tkwin == NULL) {
- return TCL_ERROR;
- }
- string = Tcl_GetStringFromObj(objv[3], NULL);
- if (Tk_GetPixels(interp, tkwin, string, &pixels) != TCL_OK) {
- return TCL_ERROR;
- }
- Tcl_SetIntObj(resultPtr, pixels);
- break;
+ string = Tcl_GetString(objv[2]);
+ tkwin = Tk_NameToWindow(interp, string, tkwin);
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+ string = Tcl_GetString(objv[3]);
+ if (Tk_GetScreenMM(interp, tkwin, string, &mm) != TCL_OK) {
+ return TCL_ERROR;
}
- case WIN_RGB: {
- XColor *colorPtr;
- char buf[TCL_INTEGER_SPACE * 3];
+ pixels = mm * WidthOfScreen(Tk_Screen(tkwin))
+ / WidthMMOfScreen(Tk_Screen(tkwin));
+ Tcl_SetDoubleObj(resultPtr, pixels);
+ break;
+ }
+ case WIN_PIXELS: {
+ int pixels;
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "window colorName");
- return TCL_ERROR;
- }
- string = Tcl_GetStringFromObj(objv[2], NULL);
- tkwin = Tk_NameToWindow(interp, string, tkwin);
- if (tkwin == NULL) {
- return TCL_ERROR;
- }
- string = Tcl_GetStringFromObj(objv[3], NULL);
- colorPtr = Tk_GetColor(interp, tkwin, string);
- if (colorPtr == NULL) {
- return TCL_ERROR;
- }
- sprintf(buf, "%d %d %d", colorPtr->red, colorPtr->green,
- colorPtr->blue);
- Tk_FreeColor(colorPtr);
- Tcl_SetStringObj(resultPtr, buf, -1);
- break;
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window number");
+ return TCL_ERROR;
}
- case WIN_VISUALSAVAILABLE: {
- XVisualInfo template, *visInfoPtr;
- int count, i;
- int includeVisualId;
- Tcl_Obj *strPtr;
- char buf[16 + TCL_INTEGER_SPACE];
- char visualIdString[TCL_INTEGER_SPACE];
-
- if (objc == 3) {
- includeVisualId = 0;
- } else if ((objc == 4)
- && (strcmp(Tcl_GetStringFromObj(objv[3], NULL),
- "includeids") == 0)) {
- includeVisualId = 1;
- } else {
- Tcl_WrongNumArgs(interp, 2, objv, "window ?includeids?");
- return TCL_ERROR;
- }
+ string = Tcl_GetString(objv[2]);
+ tkwin = Tk_NameToWindow(interp, string, tkwin);
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+ string = Tcl_GetString(objv[3]);
+ if (Tk_GetPixels(interp, tkwin, string, &pixels) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ Tcl_SetIntObj(resultPtr, pixels);
+ break;
+ }
+ case WIN_RGB: {
+ XColor *colorPtr;
+ char buf[TCL_INTEGER_SPACE * 3];
- string = Tcl_GetStringFromObj(objv[2], NULL);
- tkwin = Tk_NameToWindow(interp, string, tkwin);
- if (tkwin == NULL) {
- return TCL_ERROR;
- }
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window colorName");
+ return TCL_ERROR;
+ }
+ string = Tcl_GetString(objv[2]);
+ tkwin = Tk_NameToWindow(interp, string, tkwin);
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+ string = Tcl_GetString(objv[3]);
+ colorPtr = Tk_GetColor(interp, tkwin, string);
+ if (colorPtr == NULL) {
+ return TCL_ERROR;
+ }
+ sprintf(buf, "%d %d %d", colorPtr->red, colorPtr->green,
+ colorPtr->blue);
+ Tk_FreeColor(colorPtr);
+ Tcl_SetStringObj(resultPtr, buf, -1);
+ break;
+ }
+ case WIN_VISUALSAVAILABLE: {
+ XVisualInfo template, *visInfoPtr;
+ int count, i;
+ int includeVisualId;
+ Tcl_Obj *strPtr;
+ char buf[16 + TCL_INTEGER_SPACE];
+ char visualIdString[TCL_INTEGER_SPACE];
+
+ if (objc == 3) {
+ includeVisualId = 0;
+ } else if ((objc == 4)
+ && (strcmp(Tcl_GetString(objv[3]), "includeids") == 0)) {
+ includeVisualId = 1;
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?includeids?");
+ return TCL_ERROR;
+ }
- template.screen = Tk_ScreenNumber(tkwin);
- visInfoPtr = XGetVisualInfo(Tk_Display(tkwin), VisualScreenMask,
- &template, &count);
- if (visInfoPtr == NULL) {
- Tcl_SetStringObj(resultPtr,
- "can't find any visuals for screen", -1);
- return TCL_ERROR;
+ string = Tcl_GetString(objv[2]);
+ tkwin = Tk_NameToWindow(interp, string, tkwin);
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+
+ template.screen = Tk_ScreenNumber(tkwin);
+ visInfoPtr = XGetVisualInfo(Tk_Display(tkwin), VisualScreenMask,
+ &template, &count);
+ if (visInfoPtr == NULL) {
+ Tcl_SetStringObj(resultPtr,
+ "can't find any visuals for screen", -1);
+ return TCL_ERROR;
+ }
+ for (i = 0; i < count; i++) {
+ string = TkFindStateString(visualMap, visInfoPtr[i].class);
+ if (string == NULL) {
+ strcpy(buf, "unknown");
+ } else {
+ sprintf(buf, "%s %d", string, visInfoPtr[i].depth);
}
- for (i = 0; i < count; i++) {
- string = TkFindStateString(visualMap, visInfoPtr[i].class);
- if (string == NULL) {
- strcpy(buf, "unknown");
- } else {
- sprintf(buf, "%s %d", string, visInfoPtr[i].depth);
- }
- if (includeVisualId) {
- sprintf(visualIdString, " 0x%x",
- (unsigned int) visInfoPtr[i].visualid);
- strcat(buf, visualIdString);
- }
- strPtr = Tcl_NewStringObj(buf, -1);
- Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
+ if (includeVisualId) {
+ sprintf(visualIdString, " 0x%x",
+ (unsigned int) visInfoPtr[i].visualid);
+ strcat(buf, visualIdString);
}
- XFree((char *) visInfoPtr);
- break;
+ strPtr = Tcl_NewStringObj(buf, -1);
+ Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
}
+ XFree((char *) visInfoPtr);
+ break;
+ }
}
return TCL_OK;
}
@@ -1696,8 +1700,8 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv)
*
* Tk_WmObjCmd --
*
- * This procedure is invoked to process the "wm" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "wm" Tcl command. See the user
+ * documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -1710,24 +1714,23 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv)
/* ARGSUSED */
int
-Tk_WmObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_WmObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
Tk_Window tkwin;
TkWindow *winPtr;
- static CONST char *optionStrings[] = {
+ static const char *optionStrings[] = {
"aspect", "client", "command", "deiconify",
"focusmodel", "frame", "geometry", "grid",
"group", "iconbitmap", "iconify", "iconmask",
"iconname", "iconposition", "iconwindow", "maxsize",
"minsize", "overrideredirect", "positionfrom", "protocol",
"resizable", "sizefrom", "state", "title",
- "tracing", "transient", "withdraw", (char *) NULL
+ "tracing", "transient", "withdraw", NULL
};
enum options {
TKWM_ASPECT, TKWM_CLIENT, TKWM_COMMAND, TKWM_DEICONIFY,
@@ -1786,127 +1789,119 @@ Tk_WmObjCmd(clientData, interp, objc, objv)
}
if (!(winPtr->flags & TK_TOP_LEVEL)) {
Tcl_AppendResult(interp, "window \"", winPtr->pathName,
- "\" isn't a top-level window", (char *) NULL);
+ "\" isn't a top-level window", NULL);
return TCL_ERROR;
}
switch ((enum options) index) {
- case TKWM_ASPECT: {
- TkpWmAspectCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_CLIENT: {
- TkpWmClientCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_COMMAND: {
- TkpWmCommandCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_DEICONIFY: {
- TkpWmDeiconifyCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_FOCUSMOD: {
- TkpWmFocusmodCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_FRAME: {
- TkpWmFrameCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_GEOMETRY: {
- TkpWmGeometryCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_GRID: {
- TkpWmGridCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_GROUP: {
- TkpWmGroupCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_ICONBMP: {
- TkpWmIconbitmapCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_ICONIFY: {
- TkpWmIconifyCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_ICONMASK: {
- TkpWmIconmaskCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_ICONNAME: {
- /* slight Unix variation */
- TkpWmIconnameCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_ICONPOS: {
- /* nearly same - 1 line more on Unix */
- TkpWmIconpositionCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_ICONWIN: {
- TkpWmIconwindowCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_MAXSIZE: {
- /* nearly same, win diffs */
- TkpWmMaxsizeCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_MINSIZE: {
- /* nearly same, win diffs */
- TkpWmMinsizeCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_OVERRIDE: {
- /* almost same */
- TkpWmOverrideCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_POSFROM: {
- /* Equal across platforms */
- TkpWmPositionfromCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_PROTOCOL: {
- /* Equal across platforms */
- TkpWmProtocolCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_RESIZABLE: {
- /* almost same */
- TkpWmResizableCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_SIZEFROM: {
- /* Equal across platforms */
- TkpWmSizefromCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_STATE: {
- TkpWmStateCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_TITLE: {
- TkpWmTitleCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_TRANSIENT: {
- TkpWmTransientCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
- case TKWM_WITHDRAW: {
- TkpWmWithdrawCmd(interp, tkwin, winPtr, objc, objv);
- break;
- }
+ case TKWM_ASPECT:
+ TkpWmAspectCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_CLIENT:
+ TkpWmClientCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_COMMAND:
+ TkpWmCommandCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_DEICONIFY:
+ TkpWmDeiconifyCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_FOCUSMOD:
+ TkpWmFocusmodCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_FRAME:
+ TkpWmFrameCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_GEOMETRY:
+ TkpWmGeometryCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_GRID:
+ TkpWmGridCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_GROUP:
+ TkpWmGroupCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_ICONBMP:
+ TkpWmIconbitmapCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_ICONIFY:
+ TkpWmIconifyCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_ICONMASK:
+ TkpWmIconmaskCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_ICONNAME:
+ /*
+ * Slight Unix variation.
+ */
+ TkpWmIconnameCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_ICONPOS:
+ /*
+ * nearly same - 1 line more on Unix.
+ */
+ TkpWmIconpositionCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_ICONWIN:
+ TkpWmIconwindowCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_MAXSIZE:
+ /*
+ * Nearly same, win diffs.
+ */
+ TkpWmMaxsizeCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_MINSIZE:
+ /*
+ * Nearly same, win diffs
+ */
+ TkpWmMinsizeCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_OVERRIDE:
+ /*
+ * Almost same.
+ */
+ TkpWmOverrideCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_POSFROM:
+ /*
+ * Equal across platforms
+ */
+ TkpWmPositionfromCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_PROTOCOL:
+ /*
+ * Equal across platforms
+ */
+ TkpWmProtocolCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_RESIZABLE:
+ /*
+ * Almost same
+ */
+ TkpWmResizableCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_SIZEFROM:
+ /*
+ * Equal across platforms
+ */
+ TkpWmSizefromCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_STATE:
+ TkpWmStateCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_TITLE:
+ TkpWmTitleCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_TRANSIENT:
+ TkpWmTransientCmd(interp, tkwin, winPtr, objc, objv);
+ break;
+ case TKWM_WITHDRAW:
+ TkpWmWithdrawCmd(interp, tkwin, winPtr, objc, objv);
+ break;
}
- updateGeom:
+ updateGeom:
if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
wmPtr->flags |= WM_UPDATE_PENDING;
@@ -1920,21 +1915,20 @@ Tk_WmObjCmd(clientData, interp, objc, objv)
*
* TkGetDisplayOf --
*
- * Parses a "-displayof window" option for various commands. If
- * present, the literal "-displayof" should be in objv[0] and the
- * window name in objv[1].
+ * Parses a "-displayof window" option for various commands. If present,
+ * the literal "-displayof" should be in objv[0] and the window name in
+ * objv[1].
*
* Results:
- * The return value is 0 if the argument strings did not contain
- * the "-displayof" option. The return value is 2 if the
- * argument strings contained both the "-displayof" option and
- * a valid window name. Otherwise, the return value is -1 if
- * the window name was missing or did not specify a valid window.
+ * The return value is 0 if the argument strings did not contain the
+ * "-displayof" option. The return value is 2 if the argument strings
+ * contained both the "-displayof" option and a valid window name.
+ * Otherwise, the return value is -1 if the window name was missing or
+ * did not specify a valid window.
*
- * If the return value was 2, *tkwinPtr is filled with the
- * token for the window specified on the command line. If the
- * return value was -1, an error message is left in interp's
- * result object.
+ * If the return value was 2, *tkwinPtr is filled with the token for the
+ * window specified on the command line. If the return value was -1, an
+ * error message is left in interp's result object.
*
* Side effects:
* None.
@@ -1943,14 +1937,14 @@ Tk_WmObjCmd(clientData, interp, objc, objv)
*/
int
-TkGetDisplayOf(interp, objc, objv, tkwinPtr)
- Tcl_Interp *interp; /* Interpreter for error reporting. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. If it is present,
+TkGetDisplayOf(
+ Tcl_Interp *interp, /* Interpreter for error reporting. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[], /* Argument objects. If it is present,
* "-displayof" should be in objv[0] and
* objv[1] the name of a window. */
- Tk_Window *tkwinPtr; /* On input, contains main window of
- * application associated with interp. On
+ Tk_Window *tkwinPtr) /* On input, contains main window of
+ * application associated with interp. On
* output, filled with window specified as
* option to "-displayof" argument, or
* unmodified if "-displayof" argument was not
@@ -1958,7 +1952,7 @@ TkGetDisplayOf(interp, objc, objv, tkwinPtr)
{
char *string;
int length;
-
+
if (objc < 1) {
return 0;
}
@@ -1970,8 +1964,7 @@ TkGetDisplayOf(interp, objc, objv, tkwinPtr)
"value for \"-displayof\" missing", -1);
return -1;
}
- string = Tcl_GetStringFromObj(objv[1], NULL);
- *tkwinPtr = Tk_NameToWindow(interp, string, *tkwinPtr);
+ *tkwinPtr = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), *tkwinPtr);
if (*tkwinPtr == NULL) {
return -1;
}
@@ -1986,11 +1979,11 @@ TkGetDisplayOf(interp, objc, objv, tkwinPtr)
* TkDeadAppCmd --
*
* If an application has been deleted then all Tk commands will be
- * re-bound to this procedure.
+ * re-bound to this function.
*
* Results:
- * A standard Tcl error is reported to let the user know that
- * the application is dead.
+ * A standard Tcl error is reported to let the user know that the
+ * application is dead.
*
* Side effects:
* See the user documentation.
@@ -2000,28 +1993,28 @@ TkGetDisplayOf(interp, objc, objv, tkwinPtr)
/* ARGSUSED */
int
-TkDeadAppCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Dummy. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+TkDeadAppCmd(
+ ClientData clientData, /* Dummy. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ const char **argv) /* Argument strings. */
{
Tcl_AppendResult(interp, "can't invoke \"", argv[0],
- "\" command: application has been destroyed", (char *) NULL);
+ "\" command: application has been destroyed", NULL);
return TCL_ERROR;
}
/*
*----------------------------------------------------------------------
*
- * GetToplevel --
+ * GetTopHierarchy --
*
- * Retrieves the toplevel window which is the nearest ancestor of
- * of the specified window.
+ * Retrieves the top-of-hierarchy window which is the nearest ancestor of
+ * the specified window.
*
* Results:
- * Returns the toplevel window or NULL if the window has no
- * ancestor which is a toplevel.
+ * Returns the top-of-hierarchy window, or NULL if the window has no
+ * ancestor which is at the top of a physical window hierarchy.
*
* Side effects:
* None.
@@ -2030,17 +2023,22 @@ TkDeadAppCmd(clientData, interp, argc, argv)
*/
static TkWindow *
-GetToplevel(tkwin)
- Tk_Window tkwin; /* Window for which the toplevel should be
- * deterined. */
+GetTopHierarchy(
+ Tk_Window tkwin) /* Window for which the top-of-hierarchy
+ * ancestor should be deterined. */
{
- TkWindow *winPtr = (TkWindow *) tkwin;
-
- while (!(winPtr->flags & TK_TOP_LEVEL)) {
- winPtr = winPtr->parentPtr;
- if (winPtr == NULL) {
- return NULL;
- }
- }
- return winPtr;
+ TkWindow *winPtr = (TkWindow *) tkwin;
+
+ while ((winPtr != NULL) && !(winPtr->flags & TK_TOP_HIERARCHY)) {
+ winPtr = winPtr->parentPtr;
+ }
+ return winPtr;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkColor.c b/generic/tkColor.c
index 848e9ab..76d0baa 100755..100644
--- a/generic/tkColor.c
+++ b/generic/tkColor.c
@@ -40,11 +40,10 @@ static Tcl_ThreadDataKey dataKey;
* Forward declarations for functions defined in this file:
*/
-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));
+static void ColorInit(TkDisplay *dispPtr);
+static void DupColorObjProc(Tcl_Obj *srcObjPtr,Tcl_Obj *dupObjPtr);
+static void FreeColorObjProc(Tcl_Obj *objPtr);
+static void InitColorObj(Tcl_Obj *objPtr);
/*
* The following structure defines the implementation of the "color" Tcl
@@ -85,11 +84,11 @@ Tcl_ObjType tkColorObjType = {
*/
XColor *
-Tk_AllocColorFromObj(interp, tkwin, objPtr)
- Tcl_Interp *interp; /* Used only for error reporting. If NULL,
+Tk_AllocColorFromObj(
+ 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
+ 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".*/
{
@@ -128,8 +127,8 @@ Tk_AllocColorFromObj(interp, tkwin, objPtr)
*/
if (tkColPtr != NULL) {
- TkColor *firstColorPtr =
- (TkColor *) Tcl_GetHashValue(tkColPtr->hashPtr);
+ TkColor *firstColorPtr = Tcl_GetHashValue(tkColPtr->hashPtr);
+
FreeColorObjProc(objPtr);
for (tkColPtr = firstColorPtr; tkColPtr != NULL;
tkColPtr = tkColPtr->nextPtr) {
@@ -137,7 +136,7 @@ Tk_AllocColorFromObj(interp, tkwin, objPtr)
&& (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
tkColPtr->resourceRefCount++;
tkColPtr->objRefCount++;
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr;
return (XColor *) tkColPtr;
}
}
@@ -148,7 +147,7 @@ Tk_AllocColorFromObj(interp, tkwin, objPtr)
*/
tkColPtr = (TkColor *) Tk_GetColor(interp, tkwin, Tcl_GetString(objPtr));
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr;
if (tkColPtr != NULL) {
tkColPtr->objRefCount++;
}
@@ -180,11 +179,11 @@ Tk_AllocColorFromObj(interp, tkwin, objPtr)
*/
XColor *
-Tk_GetColor(interp, tkwin, name)
- Tcl_Interp *interp; /* Place to leave error message if color can't
+Tk_GetColor(
+ 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 be allocated (in form
+ Tk_Window tkwin, /* Window in which color will be used. */
+ Tk_Uid name) /* Name of color to be allocated (in form
* suitable for passing to XParseColor). */
{
Tcl_HashEntry *nameHashPtr;
@@ -203,7 +202,7 @@ Tk_GetColor(interp, tkwin, name)
nameHashPtr = Tcl_CreateHashEntry(&dispPtr->colorNameTable, name, &isNew);
if (!isNew) {
- existingColPtr = (TkColor *) Tcl_GetHashValue(nameHashPtr);
+ existingColPtr = Tcl_GetHashValue(nameHashPtr);
for (tkColPtr = existingColPtr; tkColPtr != NULL;
tkColPtr = tkColPtr->nextPtr) {
if ((tkColPtr->screen == Tk_Screen(tkwin))
@@ -234,7 +233,7 @@ Tk_GetColor(interp, tkwin, name)
if (isNew) {
Tcl_DeleteHashEntry(nameHashPtr);
}
- return (XColor *) NULL;
+ return NULL;
}
/*
@@ -281,9 +280,9 @@ Tk_GetColor(interp, tkwin, name)
*/
XColor *
-Tk_GetColorByValue(tkwin, colorPtr)
- Tk_Window tkwin; /* Window where color will be used. */
- XColor *colorPtr; /* Red, green, and blue fields indicate
+Tk_GetColorByValue(
+ Tk_Window tkwin, /* Window where color will be used. */
+ XColor *colorPtr) /* Red, green, and blue fields indicate
* desired color. */
{
ValueKey valueKey;
@@ -312,7 +311,7 @@ Tk_GetColorByValue(tkwin, colorPtr)
valueHashPtr = Tcl_CreateHashEntry(&dispPtr->colorValueTable,
(char *) &valueKey, &isNew);
if (!isNew) {
- tkColPtr = (TkColor *) Tcl_GetHashValue(valueHashPtr);
+ tkColPtr = Tcl_GetHashValue(valueHashPtr);
tkColPtr->resourceRefCount++;
return &tkColPtr->color;
}
@@ -358,13 +357,12 @@ Tk_GetColorByValue(tkwin, colorPtr)
*/
CONST char *
-Tk_NameOfColor(colorPtr)
- XColor *colorPtr; /* Color whose name is desired. */
+Tk_NameOfColor(
+ XColor *colorPtr) /* Color whose name is desired. */
{
register TkColor *tkColPtr = (TkColor *) colorPtr;
- if ((tkColPtr->magic == COLOR_MAGIC) &&
- (tkColPtr->type == TK_COLOR_BY_NAME)) {
+ if (tkColPtr->magic==COLOR_MAGIC && tkColPtr->type==TK_COLOR_BY_NAME) {
return tkColPtr->hashPtr->key.string;
} else {
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
@@ -397,10 +395,10 @@ Tk_NameOfColor(colorPtr)
*/
GC
-Tk_GCForColor(colorPtr, drawable)
- XColor *colorPtr; /* Color for which a GC is desired. Must have
+Tk_GCForColor(
+ XColor *colorPtr, /* Color for which a GC is desired. Must have
* been allocated by Tk_GetColor. */
- Drawable drawable; /* Drawable in which the color will be used
+ Drawable drawable) /* Drawable in which the color will be used
* (must have same screen and depth as the one
* for which the color was allocated). */
{
@@ -442,8 +440,8 @@ Tk_GCForColor(colorPtr, drawable)
*/
void
-Tk_FreeColor(colorPtr)
- XColor *colorPtr; /* Color to be released. Must have been
+Tk_FreeColor(
+ XColor *colorPtr) /* Color to be released. Must have been
* allocated by Tk_GetColor or
* Tk_GetColorByValue. */
{
@@ -477,7 +475,7 @@ Tk_FreeColor(colorPtr)
}
TkpFreeColor(tkColPtr);
- prevPtr = (TkColor *) Tcl_GetHashValue(tkColPtr->hashPtr);
+ prevPtr = Tcl_GetHashValue(tkColPtr->hashPtr);
if (prevPtr == tkColPtr) {
if (tkColPtr->nextPtr == NULL) {
Tcl_DeleteHashEntry(tkColPtr->hashPtr);
@@ -524,10 +522,10 @@ Tk_FreeColor(colorPtr)
*/
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_FreeColorFromObj(
+ 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(objPtr);
@@ -553,8 +551,8 @@ Tk_FreeColorFromObj(tkwin, objPtr)
*/
static void
-FreeColorObjProc(objPtr)
- Tcl_Obj *objPtr; /* The object we are releasing. */
+FreeColorObjProc(
+ Tcl_Obj *objPtr) /* The object we are releasing. */
{
TkColor *tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;
@@ -564,7 +562,7 @@ FreeColorObjProc(objPtr)
&& (tkColPtr->resourceRefCount == 0)) {
ckfree((char *) tkColPtr);
}
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
+ objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}
}
@@ -587,14 +585,14 @@ FreeColorObjProc(objPtr)
*/
static void
-DupColorObjProc(srcObjPtr, dupObjPtr)
- Tcl_Obj *srcObjPtr; /* The object we are copying from. */
- Tcl_Obj *dupObjPtr; /* The object we are copying to. */
+DupColorObjProc(
+ 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;
+ dupObjPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr;
if (tkColPtr != NULL) {
tkColPtr->objRefCount++;
@@ -621,10 +619,10 @@ DupColorObjProc(srcObjPtr, dupObjPtr)
*/
XColor *
-Tk_GetColorFromObj(tkwin, objPtr)
- Tk_Window tkwin; /* The window in which the color will be
+Tk_GetColorFromObj(
+ Tk_Window tkwin, /* The window in which the color will be
* used. */
- Tcl_Obj *objPtr; /* String value contains the name of the
+ Tcl_Obj *objPtr) /* String value contains the name of the
* desired color. */
{
TkColor *tkColPtr;
@@ -667,12 +665,12 @@ Tk_GetColorFromObj(tkwin, objPtr)
if (hashPtr == NULL) {
goto error;
}
- for (tkColPtr = (TkColor *) Tcl_GetHashValue(hashPtr);
+ for (tkColPtr = Tcl_GetHashValue(hashPtr);
(tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) {
if ((Tk_Screen(tkwin) == tkColPtr->screen)
&& (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
FreeColorObjProc(objPtr);
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr;
tkColPtr->objRefCount++;
return (XColor *) tkColPtr;
}
@@ -705,10 +703,10 @@ Tk_GetColorFromObj(tkwin, objPtr)
*/
static void
-InitColorObj(objPtr)
- Tcl_Obj *objPtr; /* The object to convert. */
+InitColorObj(
+ Tcl_Obj *objPtr) /* The object to convert. */
{
- Tcl_ObjType *typePtr;
+ const Tcl_ObjType *typePtr;
/*
* Free the old internalRep before setting the new one.
@@ -720,7 +718,7 @@ InitColorObj(objPtr)
(*typePtr->freeIntRepProc)(objPtr);
}
objPtr->typePtr = &tkColorObjType;
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
+ objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}
/*
@@ -740,8 +738,8 @@ InitColorObj(objPtr)
*/
static void
-ColorInit(dispPtr)
- TkDisplay *dispPtr;
+ColorInit(
+ TkDisplay *dispPtr)
{
if (!dispPtr->colorInit) {
dispPtr->colorInit = 1;
@@ -771,10 +769,10 @@ ColorInit(dispPtr)
*/
Tcl_Obj *
-TkDebugColor(tkwin, name)
- Tk_Window tkwin; /* The window in which the color will be used
+TkDebugColor(
+ Tk_Window tkwin, /* The window in which the color will be used
* (not currently used). */
- char *name; /* Name of the desired color. */
+ char *name) /* Name of the desired color. */
{
Tcl_HashEntry *hashPtr;
Tcl_Obj *resultPtr;
@@ -783,7 +781,7 @@ TkDebugColor(tkwin, name)
resultPtr = Tcl_NewObj();
hashPtr = Tcl_FindHashEntry(&dispPtr->colorNameTable, name);
if (hashPtr != NULL) {
- TkColor *tkColPtr = (TkColor *) Tcl_GetHashValue(hashPtr);
+ TkColor *tkColPtr = Tcl_GetHashValue(hashPtr);
if (tkColPtr == NULL) {
Tcl_Panic("TkDebugColor found empty hash table entry");
@@ -832,11 +830,11 @@ CONST char *CONST tkWebColors[20] = {
};
Status
-TkParseColor(display, map, name, color)
- Display * display; /* The display */
- Colormap map; /* Color map */
- CONST char* name; /* String to be parsed */
- XColor * color;
+TkParseColor(
+ Display *display, /* The display */
+ Colormap map, /* Color map */
+ const char *name, /* String to be parsed */
+ XColor *color)
{
char buf[14];
if (*name == '#') {
diff --git a/generic/tkColor.h b/generic/tkColor.h
index 2a59e05..d4679cf 100644
--- a/generic/tkColor.h
+++ b/generic/tkColor.h
@@ -1,13 +1,12 @@
/*
* tkColor.h --
*
- * Declarations of data types and functions used by the
- * Tk color module.
+ * Declarations of data types and functions used by the Tk color module.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKCOLOR
@@ -16,14 +15,14 @@
#include <tkInt.h>
#ifdef BUILD_tk
-# undef TCL_STORAGE_CLASS
-# define TCL_STORAGE_CLASS DLLEXPORT
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
#endif
/*
- * One of the following data structures is used to keep track of
- * each color that is being used by the application; typically there
- * is a colormap entry allocated for each of these colors.
+ * One of the following data structures is used to keep track of each color
+ * that is being used by the application; typically there is a colormap entry
+ * allocated for each of these colors.
*/
#define TK_COLOR_BY_NAME 1
@@ -34,39 +33,38 @@
typedef struct TkColor {
XColor color; /* Information about this color. */
unsigned int magic; /* Used for quick integrity check on this
- * structure. Must always have the
- * value COLOR_MAGIC. */
+ * structure. Must always have the value
+ * COLOR_MAGIC. */
GC gc; /* Simple gc with this color as foreground
- * color and all other fields defaulted.
- * May be None. */
- Screen *screen; /* Screen where this color is valid. Used
- * to delete it, and to find its display. */
+ * color and all other fields defaulted. May
+ * be None. */
+ Screen *screen; /* Screen where this color is valid. Used to
+ * delete it, and to find its display. */
Colormap colormap; /* Colormap from which this entry was
* allocated. */
- Visual *visual; /* Visual associated with colormap. */
+ Visual *visual; /* Visual associated with colormap. */
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
+ * 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. */
+ * 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. */
- int type; /* TK_COLOR_BY_NAME or TK_COLOR_BY_VALUE */
+ int type; /* TK_COLOR_BY_NAME or TK_COLOR_BY_VALUE. */
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. */
+ * 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;
/*
@@ -74,14 +72,12 @@ typedef struct TkColor {
*/
#ifndef TkpFreeColor
-EXTERN void TkpFreeColor _ANSI_ARGS_((TkColor *tkColPtr));
+MODULE_SCOPE void TkpFreeColor(TkColor *tkColPtr);
#endif
-EXTERN TkColor * TkpGetColor _ANSI_ARGS_((Tk_Window tkwin,
- Tk_Uid name));
-EXTERN TkColor * TkpGetColorByValue _ANSI_ARGS_((Tk_Window tkwin,
- XColor *colorPtr));
+MODULE_SCOPE TkColor * TkpGetColor(Tk_Window tkwin, Tk_Uid name);
+MODULE_SCOPE TkColor * TkpGetColorByValue(Tk_Window tkwin, XColor *colorPtr);
-# undef TCL_STORAGE_CLASS
-# define TCL_STORAGE_CLASS DLLIMPORT
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLIMPORT
#endif /* _TKCOLOR */
diff --git a/generic/tkConfig.c b/generic/tkConfig.c
index 1e66af0..f2eaa33 100644
--- a/generic/tkConfig.c
+++ b/generic/tkConfig.c
@@ -1,13 +1,13 @@
-/*
+/*
* tkConfig.c --
*
- * This file contains procedures that manage configuration options
- * for widgets and other things.
+ * This file contains functions that manage configuration options for
+ * widgets and other things.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
/*
@@ -23,129 +23,123 @@
#define __NO_OLD_CONFIG
#endif
-#include "tk.h"
#include "tkInt.h"
-#include "tkPort.h"
#include "tkFont.h"
/*
- * The following definition is an AssocData key used to keep track of
- * all of the option tables that have been created for an interpreter.
+ * The following definition 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_OptionSpec is
- * 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.
+ * The following two structures are used along with Tk_OptionSpec structures
+ * to manage configuration options. Tk_OptionSpec is 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. */
+ 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. */
- struct Tk_ObjCustomOption *custom; /* For TK_OPTION_CUSTOM. */
+ 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. */
+ struct Tk_ObjCustomOption *custom;
+ /* For TK_OPTION_CUSTOM. */
} extra;
- int flags; /* Miscellaneous flag values; see
- * below for definitions. */
+ int flags; /* Miscellaneous flag values; see below for
+ * definitions. */
} Option;
/*
* Flag bits defined for Option structures:
*
- * OPTION_NEEDS_FREEING - 1 means that FreeResources must be
- * invoke to free resources associated with
- * the option when it is no longer needed.
+ * OPTION_NEEDS_FREEING - 1 means that FreeResources must be invoked to
+ * free resources associated with the option when
+ * it is no longer needed.
*/
#define OPTION_NEEDS_FREEING 1
/*
- * One of the following exists for each Tk_OptionSpec array that has
- * been passed to Tk_CreateOptionTable.
+ * 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. */
+ 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:
+ * Forward declarations for functions defined later in this file:
*/
-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 * GetOption _ANSI_ARGS_((CONST char *name,
- OptionTable *tablePtr));
-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));
+static int DoObjConfig(Tcl_Interp *interp, char *recordPtr,
+ Option *optionPtr, Tcl_Obj *valuePtr,
+ Tk_Window tkwin, Tk_SavedOption *savePtr);
+static void DestroyOptionHashTable(ClientData clientData,
+ Tcl_Interp *interp);
+static void FreeResources(Option *optionPtr, Tcl_Obj *objPtr,
+ char *internalPtr, Tk_Window tkwin);
+static Tcl_Obj * GetConfigList(char *recordPtr,
+ Option *optionPtr, Tk_Window tkwin);
+static Tcl_Obj * GetObjectForOption(char *recordPtr,
+ Option *optionPtr, Tk_Window tkwin);
+static Option * GetOption(const char *name, OptionTable *tablePtr);
+static Option * GetOptionFromObj(Tcl_Interp *interp,
+ Tcl_Obj *objPtr, OptionTable *tablePtr);
+static int ObjectIsEmpty(Tcl_Obj *objPtr);
+static int SetOptionFromAny(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.
+ * 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 tkOptionObjType = {
- "option", /* name */
- (Tcl_FreeInternalRepProc *) NULL, /* freeIntRepProc */
- (Tcl_DupInternalRepProc *) NULL, /* dupIntRepProc */
- (Tcl_UpdateStringProc *) NULL, /* updateStringProc */
- SetOptionFromAny /* setFromAnyProc */
+ "option", /* name */
+ NULL, /* freeIntRepProc */
+ NULL, /* dupIntRepProc */
+ NULL, /* updateStringProc */
+ SetOptionFromAny /* setFromAnyProc */
};
/*
@@ -153,12 +147,12 @@ Tcl_ObjType tkOptionObjType = {
*
* Tk_CreateOptionTable --
*
- * Given a template for configuration options, this procedure
- * creates a table that may be used to look up options efficiently.
+ * Given a template for configuration options, this function creates a
+ * table that may be used to look up options efficiently.
*
* Results:
- * Returns a token to a structure that can be passed to procedures
- * such as Tk_InitOptions, Tk_SetOptions, and Tk_FreeConfigOptions.
+ * Returns a token to a structure that can be passed to functions such as
+ * Tk_InitOptions, Tk_SetOptions, and Tk_FreeConfigOptions.
*
* Side effects:
* Storage is allocated.
@@ -167,29 +161,29 @@ Tcl_ObjType tkOptionObjType = {
*/
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. */
+Tk_CreateOptionTable(
+ 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. */
{
Tcl_HashTable *hashTablePtr;
Tcl_HashEntry *hashEntryPtr;
int newEntry;
OptionTable *tablePtr;
- CONST Tk_OptionSpec *specPtr, *specPtr2;
+ 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.
+ * 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,
@@ -202,8 +196,8 @@ Tk_CreateOptionTable(interp, templatePtr)
}
/*
- * See if a table has already been created for this template. If
- * so, just reuse the existing table.
+ * See if a table has already been created for this template. If so, just
+ * reuse the existing table.
*/
hashEntryPtr = Tcl_CreateHashEntry(hashTablePtr, (char *) templatePtr,
@@ -215,8 +209,8 @@ Tk_CreateOptionTable(interp, templatePtr)
}
/*
- * Count the number of options in the template, then create the
- * table structure.
+ * Count the number of options in the template, then create the table
+ * structure.
*/
numOptions = 0;
@@ -245,14 +239,13 @@ Tk_CreateOptionTable(interp, templatePtr)
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.
+ * 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");
+ Tcl_Panic("Tk_CreateOptionTable couldn't find synonym");
}
if (strcmp(specPtr2->optionName,
(char *) specPtr->clientData) == 0) {
@@ -265,12 +258,10 @@ Tk_CreateOptionTable(interp, templatePtr)
optionPtr->dbNameUID = Tk_GetUid(specPtr->dbName);
}
if (specPtr->dbClass != NULL) {
- optionPtr->dbClassUID =
- Tk_GetUid(specPtr->dbClass);
+ optionPtr->dbClassUID = Tk_GetUid(specPtr->dbClass);
}
if (specPtr->defValue != NULL) {
- optionPtr->defaultPtr =
- Tcl_NewStringObj(specPtr->defValue, -1);
+ optionPtr->defaultPtr = Tcl_NewStringObj(specPtr->defValue,-1);
Tcl_IncrRefCount(optionPtr->defaultPtr);
}
if (((specPtr->type == TK_OPTION_COLOR)
@@ -286,7 +277,7 @@ Tk_CreateOptionTable(interp, templatePtr)
* Get the custom parsing, etc., functions.
*/
optionPtr->extra.custom =
- (Tk_ObjCustomOption *)specPtr->clientData;
+ (Tk_ObjCustomOption *) specPtr->clientData;
}
}
if (((specPtr->type == TK_OPTION_STRING)
@@ -304,9 +295,9 @@ Tk_CreateOptionTable(interp, templatePtr)
Tcl_SetHashValue(hashEntryPtr, tablePtr);
/*
- * 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).
+ * 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).
*/
if (specPtr->clientData != NULL) {
@@ -322,22 +313,22 @@ Tk_CreateOptionTable(interp, templatePtr)
*
* Tk_DeleteOptionTable --
*
- * Called to release resources used by an option table when
- * the table is no longer needed.
+ * 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.
+ * 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. */
+Tk_DeleteOptionTable(
+ Tk_OptionTable optionTable) /* The option table to delete. */
{
OptionTable *tablePtr = (OptionTable *) optionTable;
Option *optionPtr;
@@ -372,25 +363,25 @@ Tk_DeleteOptionTable(optionTable)
*
* 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.
+ * This function is the deletion callback associated with the AssocData
+ * entry created by Tk_CreateOptionTable. It is invoked when an
+ * interpreter is deleted, and deletes all of the option tables
+ * associated with that interpreter.
*
* Results:
* None.
*
* Side effects:
- * The option hash table is destroyed along with all of the
- * OptionTable structures that it refers to.
+ * 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 */
+DestroyOptionHashTable(
+ 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;
@@ -404,13 +395,12 @@ DestroyOptionHashTable(clientData, interp)
/*
* 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).
+ * 1. They ensure that the option table is deleted, even if there are
+ * outstanding references to it.
+ * 2. They ensure that Tk_DeleteOptionTable doesn't delete other
+ * tables chained from this one; we'll do it when we come across
+ * the hash table entry for the chained table (in fact, the chained
+ * table may already have been deleted).
*/
tablePtr->refCount = 1;
@@ -426,16 +416,16 @@ DestroyOptionHashTable(clientData, interp)
*
* 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).
+ * This function 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.
+ * The return value is TCL_OK if the function 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.
@@ -444,21 +434,21 @@ DestroyOptionHashTable(clientData, interp)
*/
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. */
+Tk_InitOptions(
+ 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;
@@ -471,8 +461,8 @@ Tk_InitOptions(interp, recordPtr, optionTable, tkwin)
/*
* 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.
+ * 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) {
@@ -489,11 +479,11 @@ Tk_InitOptions(interp, recordPtr, optionTable, tkwin)
for (optionPtr = tablePtr->options, count = tablePtr->numOptions;
count > 0; optionPtr++, count--) {
-
/*
* If we specify TK_OPTION_DONT_SET_DEFAULT, then the user has
* processed and set a default for this already.
*/
+
if ((optionPtr->specPtr->type == TK_OPTION_SYNONYM) ||
(optionPtr->specPtr->flags & TK_OPTION_DONT_SET_DEFAULT)) {
continue;
@@ -502,12 +492,12 @@ Tk_InitOptions(interp, recordPtr, optionTable, tkwin)
/*
* We look in three places for the initial value, using the first
- * non-NULL value that we find. First, check the option database.
+ * non-NULL value that we find. First, check the option database.
*/
valuePtr = NULL;
if (optionPtr->dbNameUID != NULL) {
- value = Tk_GetOption(tkwin, optionPtr->dbNameUID,
+ value = Tk_GetOption(tkwin, optionPtr->dbNameUID,
optionPtr->dbClassUID);
if (value != NULL) {
valuePtr = Tcl_NewStringObj(value, -1);
@@ -518,6 +508,7 @@ Tk_InitOptions(interp, recordPtr, optionTable, tkwin)
/*
* Second, check for a system-specific default value.
*/
+
if ((valuePtr == NULL)
&& (optionPtr->dbNameUID != NULL)) {
valuePtr = TkpGetSystemDefault(tkwin, optionPtr->dbNameUID,
@@ -528,16 +519,16 @@ Tk_InitOptions(interp, recordPtr, optionTable, tkwin)
}
/*
- * 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.
+ * 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)
+ if ((tkwin != NULL)
&& ((optionPtr->specPtr->type == TK_OPTION_COLOR)
|| (optionPtr->specPtr->type == TK_OPTION_BORDER))
- && (Tk_Depth(tkwin) <= 1)
+ && (Tk_Depth(tkwin) <= 1)
&& (optionPtr->extra.monoColorPtr != NULL)) {
valuePtr = optionPtr->extra.monoColorPtr;
} else {
@@ -554,25 +545,26 @@ Tk_InitOptions(interp, recordPtr, optionTable, tkwin)
* referenced here, and will be properly free'd when finished,
* regardless of what DoObjConfig does.
*/
+
Tcl_IncrRefCount(valuePtr);
-
+
if (DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin,
- (Tk_SavedOption *) NULL) != TCL_OK) {
+ NULL) != TCL_OK) {
if (interp != NULL) {
char msg[200];
-
+
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);
+ 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);
}
if (tkwin != NULL) {
sprintf(msg + strlen(msg) - 1, " in widget \"%.50s\")",
@@ -593,40 +585,38 @@ Tk_InitOptions(interp, recordPtr, optionTable, tkwin)
*
* DoObjConfig --
*
- * This procedure applies a new value for a configuration option
- * to the record being configured.
+ * This function applies a new value for a configuration option to the
+ * record being configured.
*
* Results:
- * 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.
+ * The return value is TCL_OK if the function 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:
- * 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.
+ * 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 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
+DoObjConfig(
+ 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
+ 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;
+ * 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
@@ -634,14 +624,15 @@ DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin, savedOptionPtr)
* free the old value). */
{
Tcl_Obj **slotPtrPtr, *oldPtr;
- char *internalPtr; /* Points to location in record where
- * internal representation of value should
- * be stored, or NULL. */
+ 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;
+ Tk_SavedOption internal; /* Used to save the old internal
+ * representation of the value if
+ * savedOptionPtr is NULL. */
+ const Tk_OptionSpec *specPtr;
int nullOK;
/*
@@ -658,8 +649,8 @@ DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin, savedOptionPtr)
}
/*
- * Apply the new value in a type-specific way. Also remember the
- * old object and internal forms, if they exist.
+ * Apply the new value in a type-specific way. Also remember the old
+ * object and internal forms, if they exist.
*/
if (specPtr->internalOffset >= 0) {
@@ -676,296 +667,293 @@ DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin, savedOptionPtr)
}
nullOK = (optionPtr->specPtr->flags & TK_OPTION_NULL_OK);
switch (optionPtr->specPtr->type) {
- case TK_OPTION_BOOLEAN: {
- int new;
+ case TK_OPTION_BOOLEAN: {
+ int newBool;
- if (Tcl_GetBooleanFromObj(interp, valuePtr, &new)
- != TCL_OK) {
- return TCL_ERROR;
- }
- if (internalPtr != NULL) {
- *((int *) oldInternalPtr) = *((int *) internalPtr);
- *((int *) internalPtr) = new;
- }
- break;
+ if (Tcl_GetBooleanFromObj(interp, valuePtr, &newBool) != TCL_OK) {
+ return TCL_ERROR;
}
- 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 (internalPtr != NULL) {
+ *((int *) oldInternalPtr) = *((int *) internalPtr);
+ *((int *) internalPtr) = newBool;
}
- case TK_OPTION_DOUBLE: {
- double new;
-
- if (nullOK && ObjectIsEmpty(valuePtr)) {
- valuePtr = NULL;
- new = 0;
- } else {
- if (Tcl_GetDoubleFromObj(interp, valuePtr, &new) != TCL_OK) {
- return TCL_ERROR;
- }
- }
+ break;
+ }
+ case TK_OPTION_INT: {
+ int newInt;
- if (internalPtr != NULL) {
- *((double *) oldInternalPtr) = *((double *) internalPtr);
- *((double *) internalPtr) = new;
- }
- break;
+ if (Tcl_GetIntFromObj(interp, valuePtr, &newInt) != TCL_OK) {
+ return TCL_ERROR;
}
- 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 (internalPtr != NULL) {
+ *((int *) oldInternalPtr) = *((int *) internalPtr);
+ *((int *) internalPtr) = newInt;
}
- case TK_OPTION_STRING_TABLE: {
- int new;
+ break;
+ }
+ case TK_OPTION_DOUBLE: {
+ double newDbl;
- if (Tcl_GetIndexFromObj(interp, valuePtr,
- (CONST char **) optionPtr->specPtr->clientData,
- optionPtr->specPtr->optionName+1, 0, &new) != TCL_OK) {
+ if (nullOK && ObjectIsEmpty(valuePtr)) {
+ valuePtr = NULL;
+ newDbl = 0;
+ } else {
+ if (Tcl_GetDoubleFromObj(interp, valuePtr, &newDbl) != TCL_OK) {
return TCL_ERROR;
}
- if (internalPtr != NULL) {
- *((int *) oldInternalPtr) = *((int *) internalPtr);
- *((int *) internalPtr) = new;
- }
- break;
}
- 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;
+ if (internalPtr != NULL) {
+ *((double *) oldInternalPtr) = *((double *) internalPtr);
+ *((double *) internalPtr) = newDbl;
}
- case TK_OPTION_FONT: {
- Tk_Font new;
+ break;
+ }
+ case TK_OPTION_STRING: {
+ char *newStr, *value;
+ int length;
- if (nullOK && ObjectIsEmpty(valuePtr)) {
- valuePtr = NULL;
- new = NULL;
+ if (nullOK && ObjectIsEmpty(valuePtr)) {
+ valuePtr = NULL;
+ }
+ if (internalPtr != NULL) {
+ if (valuePtr != NULL) {
+ value = Tcl_GetStringFromObj(valuePtr, &length);
+ newStr = ckalloc((unsigned) (length + 1));
+ strcpy(newStr, value);
} 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;
+ newStr = NULL;
}
- break;
+ *((char **) oldInternalPtr) = *((char **) internalPtr);
+ *((char **) internalPtr) = newStr;
}
- case TK_OPTION_STYLE: {
- Tk_Style new;
+ break;
+ }
+ case TK_OPTION_STRING_TABLE: {
+ int newValue;
- if (nullOK && ObjectIsEmpty(valuePtr)) {
- valuePtr = NULL;
- new = NULL;
- } else {
- new = Tk_AllocStyleFromObj(interp, valuePtr);
- if (new == NULL) {
- return TCL_ERROR;
- }
- }
- if (internalPtr != NULL) {
- *((Tk_Style *) oldInternalPtr) = *((Tk_Style *) internalPtr);
- *((Tk_Style *) internalPtr) = new;
- }
- break;
+ if (Tcl_GetIndexFromObj(interp, valuePtr,
+ (const char **) optionPtr->specPtr->clientData,
+ optionPtr->specPtr->optionName+1, 0, &newValue) != TCL_OK) {
+ return TCL_ERROR;
}
- case TK_OPTION_BITMAP: {
- Pixmap new;
+ if (internalPtr != NULL) {
+ *((int *) oldInternalPtr) = *((int *) internalPtr);
+ *((int *) internalPtr) = newValue;
+ }
+ break;
+ }
+ case TK_OPTION_COLOR: {
+ XColor *newPtr;
- 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;
+ if (nullOK && ObjectIsEmpty(valuePtr)) {
+ valuePtr = NULL;
+ newPtr = NULL;
+ } else {
+ newPtr = Tk_AllocColorFromObj(interp, tkwin, valuePtr);
+ if (newPtr == NULL) {
+ return TCL_ERROR;
}
- break;
}
- case TK_OPTION_BORDER: {
- Tk_3DBorder new;
+ if (internalPtr != NULL) {
+ *((XColor **) oldInternalPtr) = *((XColor **) internalPtr);
+ *((XColor **) internalPtr) = newPtr;
+ }
+ break;
+ }
+ case TK_OPTION_FONT: {
+ Tk_Font newFont;
- 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;
+ if (nullOK && ObjectIsEmpty(valuePtr)) {
+ valuePtr = NULL;
+ newFont = NULL;
+ } else {
+ newFont = Tk_AllocFontFromObj(interp, tkwin, valuePtr);
+ if (newFont == NULL) {
+ return TCL_ERROR;
}
- break;
}
- case TK_OPTION_RELIEF: {
- int new;
+ if (internalPtr != NULL) {
+ *((Tk_Font *) oldInternalPtr) = *((Tk_Font *) internalPtr);
+ *((Tk_Font *) internalPtr) = newFont;
+ }
+ break;
+ }
+ case TK_OPTION_STYLE: {
+ Tk_Style newStyle;
- if (nullOK && ObjectIsEmpty(valuePtr)) {
- valuePtr = NULL;
- new = TK_RELIEF_NULL;
- } else {
- if (Tk_GetReliefFromObj(interp, valuePtr, &new) != TCL_OK) {
- return TCL_ERROR;
- }
- }
- if (internalPtr != NULL) {
- *((int *) oldInternalPtr) = *((int *) internalPtr);
- *((int *) internalPtr) = new;
+ if (nullOK && ObjectIsEmpty(valuePtr)) {
+ valuePtr = NULL;
+ newStyle = NULL;
+ } else {
+ newStyle = Tk_AllocStyleFromObj(interp, valuePtr);
+ if (newStyle == NULL) {
+ return TCL_ERROR;
}
- break;
}
- case TK_OPTION_CURSOR: {
- Tk_Cursor new;
+ if (internalPtr != NULL) {
+ *((Tk_Style *) oldInternalPtr) = *((Tk_Style *) internalPtr);
+ *((Tk_Style *) internalPtr) = newStyle;
+ }
+ break;
+ }
+ case TK_OPTION_BITMAP: {
+ Pixmap newBitmap;
- 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;
+ if (nullOK && ObjectIsEmpty(valuePtr)) {
+ valuePtr = NULL;
+ newBitmap = None;
+ } else {
+ newBitmap = Tk_AllocBitmapFromObj(interp, tkwin, valuePtr);
+ if (newBitmap == None) {
+ return TCL_ERROR;
}
- Tk_DefineCursor(tkwin, new);
- break;
}
- case TK_OPTION_JUSTIFY: {
- Tk_Justify new;
+ if (internalPtr != NULL) {
+ *((Pixmap *) oldInternalPtr) = *((Pixmap *) internalPtr);
+ *((Pixmap *) internalPtr) = newBitmap;
+ }
+ break;
+ }
+ case TK_OPTION_BORDER: {
+ Tk_3DBorder newBorder;
- if (Tk_GetJustifyFromObj(interp, valuePtr, &new) != TCL_OK) {
+ if (nullOK && ObjectIsEmpty(valuePtr)) {
+ valuePtr = NULL;
+ newBorder = NULL;
+ } else {
+ newBorder = Tk_Alloc3DBorderFromObj(interp, tkwin, valuePtr);
+ if (newBorder == NULL) {
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 (internalPtr != NULL) {
+ *((Tk_3DBorder *) oldInternalPtr) = *((Tk_3DBorder *) internalPtr);
+ *((Tk_3DBorder *) internalPtr) = newBorder;
+ }
+ break;
+ }
+ case TK_OPTION_RELIEF: {
+ int newRelief;
- if (Tk_GetAnchorFromObj(interp, valuePtr, &new) != TCL_OK) {
+ if (nullOK && ObjectIsEmpty(valuePtr)) {
+ valuePtr = NULL;
+ newRelief = TK_RELIEF_NULL;
+ } else {
+ if (Tk_GetReliefFromObj(interp, valuePtr, &newRelief) != 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 (internalPtr != NULL) {
+ *((int *) oldInternalPtr) = *((int *) internalPtr);
+ *((int *) internalPtr) = newRelief;
+ }
+ break;
+ }
+ case TK_OPTION_CURSOR: {
+ Tk_Cursor newCursor;
- if (nullOK && ObjectIsEmpty(valuePtr)) {
- valuePtr = NULL;
- new = 0;
- } else {
- if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr,
- &new) != TCL_OK) {
- return TCL_ERROR;
- }
- }
- if (internalPtr != NULL) {
- *((int *) oldInternalPtr) = *((int *) internalPtr);
- *((int *) internalPtr) = new;
+ if (nullOK && ObjectIsEmpty(valuePtr)) {
+ newCursor = None;
+ valuePtr = NULL;
+ } else {
+ newCursor = Tk_AllocCursorFromObj(interp, tkwin, valuePtr);
+ if (newCursor == None) {
+ return TCL_ERROR;
}
- break;
}
- case TK_OPTION_WINDOW: {
- Tk_Window new;
+ if (internalPtr != NULL) {
+ *((Tk_Cursor *) oldInternalPtr) = *((Tk_Cursor *) internalPtr);
+ *((Tk_Cursor *) internalPtr) = newCursor;
+ }
+ Tk_DefineCursor(tkwin, newCursor);
+ break;
+ }
+ case TK_OPTION_JUSTIFY: {
+ Tk_Justify newJustify;
- 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;
+ if (Tk_GetJustifyFromObj(interp, valuePtr, &newJustify) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (internalPtr != NULL) {
+ *((Tk_Justify *) oldInternalPtr) = *((Tk_Justify *) internalPtr);
+ *((Tk_Justify *) internalPtr) = newJustify;
+ }
+ break;
+ }
+ case TK_OPTION_ANCHOR: {
+ Tk_Anchor newAnchor;
+
+ if (Tk_GetAnchorFromObj(interp, valuePtr, &newAnchor) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (internalPtr != NULL) {
+ *((Tk_Anchor *) oldInternalPtr) = *((Tk_Anchor *) internalPtr);
+ *((Tk_Anchor *) internalPtr) = newAnchor;
+ }
+ break;
+ }
+ case TK_OPTION_PIXELS: {
+ int newPixels;
+
+ if (nullOK && ObjectIsEmpty(valuePtr)) {
+ valuePtr = NULL;
+ newPixels = 0;
+ } else {
+ if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr,
+ &newPixels) != TCL_OK) {
+ return TCL_ERROR;
}
- break;
}
- case TK_OPTION_CUSTOM: {
- Tk_ObjCustomOption *custom = optionPtr->extra.custom;
- if (custom->setProc(custom->clientData, interp, tkwin,
- &valuePtr, recordPtr, optionPtr->specPtr->internalOffset,
- (char *)oldInternalPtr,
- optionPtr->specPtr->flags) != TCL_OK) {
+ if (internalPtr != NULL) {
+ *((int *) oldInternalPtr) = *((int *) internalPtr);
+ *((int *) internalPtr) = newPixels;
+ }
+ break;
+ }
+ case TK_OPTION_WINDOW: {
+ Tk_Window newWin;
+
+ if (nullOK && ObjectIsEmpty(valuePtr)) {
+ valuePtr = NULL;
+ newWin = None;
+ } else {
+ if (TkGetWindowFromObj(interp, tkwin, valuePtr,
+ &newWin) != TCL_OK) {
return TCL_ERROR;
}
- break;
}
-
- default: {
- char buf[40+TCL_INTEGER_SPACE];
- sprintf(buf, "bad config table: unknown type %d",
- optionPtr->specPtr->type);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ if (internalPtr != NULL) {
+ *((Tk_Window *) oldInternalPtr) = *((Tk_Window *) internalPtr);
+ *((Tk_Window *) internalPtr) = newWin;
+ }
+ break;
+ }
+ case TK_OPTION_CUSTOM: {
+ Tk_ObjCustomOption *custom = optionPtr->extra.custom;
+
+ if (custom->setProc(custom->clientData, interp, tkwin,
+ &valuePtr, recordPtr, optionPtr->specPtr->internalOffset,
+ (char *)oldInternalPtr, optionPtr->specPtr->flags) != TCL_OK) {
return TCL_ERROR;
}
+ break;
+ }
+
+ {
+ char buf[40+TCL_INTEGER_SPACE];
+
+ default:
+ sprintf(buf, "bad config table: unknown type %d",
+ optionPtr->specPtr->type);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ return TCL_ERROR;
+ }
}
/*
- * 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.
+ * 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.
*/
if (savedOptionPtr == NULL) {
@@ -990,12 +978,11 @@ DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin, savedOptionPtr)
*
* ObjectIsEmpty --
*
- * This procedure tests whether the string value of an object is
- * empty.
+ * This function tests whether the string value of an object is empty.
*
* Results:
- * The return value is 1 if the string value of objPtr has length
- * zero, and 0 otherwise.
+ * The return value is 1 if the string value of objPtr has length zero,
+ * and 0 otherwise.
*
* Side effects:
* None.
@@ -1004,8 +991,8 @@ DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin, savedOptionPtr)
*/
static int
-ObjectIsEmpty(objPtr)
- Tcl_Obj *objPtr; /* Object to test. May be NULL. */
+ObjectIsEmpty(
+ Tcl_Obj *objPtr) /* Object to test. May be NULL. */
{
int length;
@@ -1024,15 +1011,14 @@ ObjectIsEmpty(objPtr)
*
* GetOption --
*
- * This procedure searches through a chained option table to find
- * the entry for a particular option name.
+ * This function 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.
- * 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.
+ * The return value is a pointer to the matching entry, or NULL if no
+ * matching entry could be found. Note: if the matching entry is a
+ * synonym then this function returns a pointer to the synonym entry,
+ * *not* the "real" entry that the synonym refers to.
*
* Side effects:
* None.
@@ -1041,25 +1027,24 @@ ObjectIsEmpty(objPtr)
*/
static Option *
-GetOption(name, tablePtr)
- CONST char *name; /* String balue to be looked up in the
- * option table. */
- OptionTable *tablePtr; /* Table in which to look up name. */
+GetOption(
+ const char *name, /* String balue to be looked up in the option
+ * table. */
+ OptionTable *tablePtr) /* Table in which to look up name. */
{
Option *bestPtr, *optionPtr;
OptionTable *tablePtr2;
- CONST char *p1, *p2;
+ const char *p1, *p2;
int count;
/*
- * Search through all of the option tables in the chain to find the
- * best match. Some tricky aspects:
+ * 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.
+ * 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;
@@ -1071,40 +1056,38 @@ GetOption(name, tablePtr)
*p1 == *p2; p1++, p2++) {
if (*p1 == 0) {
/*
- * This is an exact match. We're done.
+ * This is an exact match. We're done.
*/
- bestPtr = optionPtr;
- goto done;
+ return optionPtr;
}
}
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.
+ * 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 (bestPtr == NULL) {
bestPtr = optionPtr;
- } else {
- if (strcmp(bestPtr->specPtr->optionName,
- optionPtr->specPtr->optionName) != 0) {
- goto error;
- }
+ } else if (strcmp(bestPtr->specPtr->optionName,
+ optionPtr->specPtr->optionName) != 0) {
+ return NULL;
}
}
}
}
- done:
- return bestPtr;
+ /*
+ * Return whatever we have found, which could be NULL if nothing
+ * matched. The multiple-matching case is handled above.
+ */
- error:
- return NULL;
+ return bestPtr;
}
/*
@@ -1112,32 +1095,30 @@ GetOption(name, tablePtr)
*
* GetOptionFromObj --
*
- * This procedure searches through a chained option table to find
- * the entry for a particular option name.
+ * This function 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.
+ * 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 function 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.
+ * Information about the matching entry is cached in the object
+ * containing the name, so that future lookups can proceed more quickly.
*
*----------------------------------------------------------------------
*/
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. */
+GetOptionFromObj(
+ 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;
char *name;
@@ -1147,16 +1128,16 @@ GetOptionFromObj(interp, objPtr, tablePtr)
*/
if (objPtr->typePtr == &tkOptionObjType) {
- if (objPtr->internalRep.twoPtrValue.ptr1 == (VOID *) tablePtr) {
- return (Option *) objPtr->internalRep.twoPtrValue.ptr2;
- }
+ if (objPtr->internalRep.twoPtrValue.ptr1 == (void *) tablePtr) {
+ return (Option *) objPtr->internalRep.twoPtrValue.ptr2;
+ }
}
/*
* The answer isn't cached.
*/
- name = Tcl_GetStringFromObj(objPtr, NULL);
+ name = Tcl_GetString(objPtr);
bestPtr = GetOption(name, tablePtr);
if (bestPtr == NULL) {
goto error;
@@ -1166,15 +1147,14 @@ GetOptionFromObj(interp, objPtr, tablePtr)
&& (objPtr->typePtr->freeIntRepProc != NULL)) {
objPtr->typePtr->freeIntRepProc(objPtr);
}
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tablePtr;
- objPtr->internalRep.twoPtrValue.ptr2 = (VOID *) bestPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) tablePtr;
+ objPtr->internalRep.twoPtrValue.ptr2 = (void *) bestPtr;
objPtr->typePtr = &tkOptionObjType;
return bestPtr;
- error:
+ error:
if (interp != NULL) {
- Tcl_AppendResult(interp, "unknown option \"", name,
- "\"", (char *) NULL);
+ Tcl_AppendResult(interp, "unknown option \"", name, "\"", NULL);
}
return NULL;
}
@@ -1184,29 +1164,28 @@ GetOptionFromObj(interp, objPtr, tablePtr)
*
* TkGetOptionSpec --
*
- * This procedure searches through a chained option table to find
- * the option spec for a particular option name.
+ * This function searches through a chained option table to find the
+ * option spec for a particular option name.
*
* Results:
- * The return value is a pointer to the option spec of the matching
- * entry, or NULL if no matching entry could be found.
- * Note: if the matching entry is a synonym then this procedure
- * returns a pointer to the option spec of the synonym entry, *not*
- * the "real" entry that the synonym refers to.
- * Note: this call is primarily used by the style management code
- * (tkStyle.c) to look up an element's option spec into a widget's
- * option table.
+ * The return value is a pointer to the option spec of the matching
+ * entry, or NULL if no matching entry could be found. Note: if the
+ * matching entry is a synonym then this function returns a pointer to
+ * the option spec of the synonym entry, *not* the "real" entry that the
+ * synonym refers to. Note: this call is primarily used by the style
+ * management code (tkStyle.c) to look up an element's option spec into a
+ * widget's option table.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
-CONST Tk_OptionSpec *
-TkGetOptionSpec(name, optionTable)
- CONST char *name; /* String value to be looked up. */
- Tk_OptionTable optionTable; /* Table in which to look up name. */
+const Tk_OptionSpec *
+TkGetOptionSpec(
+ const char *name, /* String value to be looked up. */
+ Tk_OptionTable optionTable) /* Table in which to look up name. */
{
Option *optionPtr;
@@ -1222,14 +1201,14 @@ TkGetOptionSpec(name, optionTable)
*
* 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.
+ * This function is called to convert a Tcl object to option internal
+ * form. However, this doesn't make sense (need to have a table of
+ * options in order to do the conversion) so the function always
+ * generates an error.
*
* Results:
- * The return value is always TCL_ERROR, and an error message is
- * left in interp's result if interp isn't NULL.
+ * 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.
@@ -1238,9 +1217,9 @@ TkGetOptionSpec(name, optionTable)
*/
static int
-SetOptionFromAny(interp, objPtr)
- Tcl_Interp *interp; /* Used for error reporting if not NULL. */
- register Tcl_Obj *objPtr; /* The object to convert. */
+SetOptionFromAny(
+ 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",
@@ -1253,53 +1232,47 @@ SetOptionFromAny(interp, objPtr)
*
* Tk_SetOptions --
*
- * Process one or more name-value pairs for configuration options
- * and fill in fields of a record with new values.
+ * 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
+ * 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.
+ * 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. */
+Tk_SetOptions(
+ 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;
@@ -1315,8 +1288,8 @@ Tk_SetOptions(interp, recordPtr, optionTable, objc, objv, tkwin, savePtr,
lastSavePtr = savePtr;
/*
- * Scan through all of the arguments, processing those
- * that match entries in the option table.
+ * Scan through all of the arguments, processing those that match entries
+ * in the option table.
*/
mask = 0;
@@ -1333,19 +1306,18 @@ Tk_SetOptions(interp, recordPtr, optionTable, objc, objv, tkwin, savePtr,
if (interp != NULL) {
Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
"value for \"", Tcl_GetStringFromObj(*objv, NULL),
- "\" missing", (char *) NULL);
+ "\" missing", NULL);
goto error;
}
}
if ((savePtr != NULL)
&& (lastSavePtr->numItems >= TK_NUM_SAVED_OPTIONS)) {
/*
- * We've run out of space for saving old option values. Allocate
+ * We've run out of space for saving old option values. Allocate
* more space.
*/
- newSavePtr = (Tk_SavedOptions *) ckalloc(sizeof(
- Tk_SavedOptions));
+ newSavePtr = (Tk_SavedOptions *) ckalloc(sizeof(Tk_SavedOptions));
newSavePtr->recordPtr = recordPtr;
newSavePtr->tkwin = tkwin;
newSavePtr->numItems = 0;
@@ -1355,7 +1327,7 @@ Tk_SetOptions(interp, recordPtr, optionTable, objc, objv, tkwin, savePtr,
}
if (DoObjConfig(interp, recordPtr, optionPtr, objv[1], tkwin,
(savePtr != NULL) ? &lastSavePtr->items[lastSavePtr->numItems]
- : (Tk_SavedOption *) NULL) != TCL_OK) {
+ : NULL) != TCL_OK) {
char msg[100];
sprintf(msg, "\n (processing \"%.40s\" option)",
@@ -1373,7 +1345,7 @@ Tk_SetOptions(interp, recordPtr, optionTable, objc, objv, tkwin, savePtr,
}
return TCL_OK;
- error:
+ error:
if (savePtr != NULL) {
Tk_RestoreSavedOptions(savePtr);
}
@@ -1385,38 +1357,38 @@ Tk_SetOptions(interp, recordPtr, optionTable, objc, objv, tkwin, savePtr,
*
* 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.
+ * This function 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.
+ * 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. */
+Tk_RestoreSavedOptions(
+ 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. */
+ * replace with old value and free. Taken from
+ * record. */
char *internalPtr; /* Points to internal value of option in
* record. */
- CONST Tk_OptionSpec *specPtr;
+ 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.
+ * 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) {
@@ -1429,8 +1401,8 @@ Tk_RestoreSavedOptions(savePtr)
specPtr = optionPtr->specPtr;
/*
- * First free the new value of the option, which is currently
- * in the record.
+ * First free the new value of the option, which is currently in the
+ * record.
*/
if (specPtr->objOffset >= 0) {
@@ -1459,101 +1431,69 @@ Tk_RestoreSavedOptions(savePtr)
= savePtr->items[i].valuePtr;
}
if (specPtr->internalOffset >= 0) {
+ register char *ptr = (char *) &savePtr->items[i].internalForm;
+
switch (specPtr->type) {
- case TK_OPTION_BOOLEAN: {
- *((int *) internalPtr)
- = *((int *) &savePtr->items[i].internalForm);
- break;
- }
- case TK_OPTION_INT: {
- *((int *) internalPtr)
- = *((int *) &savePtr->items[i].internalForm);
- break;
- }
- case TK_OPTION_DOUBLE: {
- *((double *) internalPtr)
- = *((double *) &savePtr->items[i].internalForm);
- break;
- }
- case TK_OPTION_STRING: {
- *((char **) internalPtr)
- = *((char **) &savePtr->items[i].internalForm);
- break;
- }
- case TK_OPTION_STRING_TABLE: {
- *((int *) internalPtr)
- = *((int *) &savePtr->items[i].internalForm);
- break;
- }
- case TK_OPTION_COLOR: {
- *((XColor **) internalPtr)
- = *((XColor **) &savePtr->items[i].internalForm);
- break;
- }
- case TK_OPTION_FONT: {
- *((Tk_Font *) internalPtr)
- = *((Tk_Font *) &savePtr->items[i].internalForm);
- break;
- }
- case TK_OPTION_STYLE: {
- *((Tk_Style *) internalPtr)
- = *((Tk_Style *) &savePtr->items[i].internalForm);
- break;
- }
- case TK_OPTION_BITMAP: {
- *((Pixmap *) internalPtr)
- = *((Pixmap *) &savePtr->items[i].internalForm);
- break;
- }
- case TK_OPTION_BORDER: {
- *((Tk_3DBorder *) internalPtr)
- = *((Tk_3DBorder *) &savePtr->items[i].internalForm);
- break;
- }
- case TK_OPTION_RELIEF: {
- *((int *) internalPtr)
- = *((int *) &savePtr->items[i].internalForm);
- break;
- }
- case TK_OPTION_CURSOR: {
- *((Tk_Cursor *) internalPtr)
- = *((Tk_Cursor *) &savePtr->items[i].internalForm);
- Tk_DefineCursor(savePtr->tkwin,
- *((Tk_Cursor *) internalPtr));
- break;
- }
- case TK_OPTION_JUSTIFY: {
- *((Tk_Justify *) internalPtr)
- = *((Tk_Justify *) &savePtr->items[i].internalForm);
- break;
- }
- case TK_OPTION_ANCHOR: {
- *((Tk_Anchor *) internalPtr)
- = *((Tk_Anchor *) &savePtr->items[i].internalForm);
- break;
- }
- 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;
- }
- case TK_OPTION_CUSTOM: {
- Tk_ObjCustomOption *custom = optionPtr->extra.custom;
- if (custom->restoreProc != NULL) {
- custom->restoreProc(custom->clientData, savePtr->tkwin,
- internalPtr,
- (char *)&savePtr->items[i].internalForm);
- }
- break;
- }
- default: {
- panic("bad option type in Tk_RestoreSavedOptions");
+ case TK_OPTION_BOOLEAN:
+ *((int *) internalPtr) = *((int *) ptr);
+ break;
+ case TK_OPTION_INT:
+ *((int *) internalPtr) = *((int *) ptr);
+ break;
+ case TK_OPTION_DOUBLE:
+ *((double *) internalPtr) = *((double *) ptr);
+ break;
+ case TK_OPTION_STRING:
+ *((char **) internalPtr) = *((char **) ptr);
+ break;
+ case TK_OPTION_STRING_TABLE:
+ *((int *) internalPtr) = *((int *) ptr);
+ break;
+ case TK_OPTION_COLOR:
+ *((XColor **) internalPtr) = *((XColor **) ptr);
+ break;
+ case TK_OPTION_FONT:
+ *((Tk_Font *) internalPtr) = *((Tk_Font *) ptr);
+ break;
+ case TK_OPTION_STYLE:
+ *((Tk_Style *) internalPtr) = *((Tk_Style *) ptr);
+ break;
+ case TK_OPTION_BITMAP:
+ *((Pixmap *) internalPtr) = *((Pixmap *) ptr);
+ break;
+ case TK_OPTION_BORDER:
+ *((Tk_3DBorder *) internalPtr) = *((Tk_3DBorder *) ptr);
+ break;
+ case TK_OPTION_RELIEF:
+ *((int *) internalPtr) = *((int *) ptr);
+ break;
+ case TK_OPTION_CURSOR:
+ *((Tk_Cursor *) internalPtr) = *((Tk_Cursor *) ptr);
+ Tk_DefineCursor(savePtr->tkwin, *((Tk_Cursor *) internalPtr));
+ break;
+ case TK_OPTION_JUSTIFY:
+ *((Tk_Justify *) internalPtr) = *((Tk_Justify *) ptr);
+ break;
+ case TK_OPTION_ANCHOR:
+ *((Tk_Anchor *) internalPtr) = *((Tk_Anchor *) ptr);
+ break;
+ case TK_OPTION_PIXELS:
+ *((int *) internalPtr) = *((int *) ptr);
+ break;
+ case TK_OPTION_WINDOW:
+ *((Tk_Window *) internalPtr) = *((Tk_Window *) ptr);
+ break;
+ case TK_OPTION_CUSTOM: {
+ Tk_ObjCustomOption *custom = optionPtr->extra.custom;
+
+ if (custom->restoreProc != NULL) {
+ custom->restoreProc(custom->clientData, savePtr->tkwin,
+ internalPtr, ptr);
}
+ break;
+ }
+ default:
+ Tcl_Panic("bad option type in Tk_RestoreSavedOptions");
}
}
}
@@ -1565,8 +1505,8 @@ Tk_RestoreSavedOptions(savePtr)
*
* Tk_FreeSavedOptions --
*
- * Free all of the saved configuration option values from a
- * previous call to Tk_SetOptions.
+ * Free all of the saved configuration option values from a previous call
+ * to Tk_SetOptions.
*
* Results:
* None.
@@ -1578,9 +1518,9 @@ Tk_RestoreSavedOptions(savePtr)
*/
void
-Tk_FreeSavedOptions(savePtr)
- Tk_SavedOptions *savePtr; /* Contains options saved in a previous
- * call to Tk_SetOptions. */
+Tk_FreeSavedOptions(
+ Tk_SavedOptions *savePtr) /* Contains options saved in a previous call
+ * to Tk_SetOptions. */
{
int count;
Tk_SavedOption *savedOptionPtr;
@@ -1613,27 +1553,27 @@ Tk_FreeSavedOptions(savePtr)
* None.
*
* Side effects:
- * All of the Tcl_Obj's in recordPtr that are controlled by
- * configuration options in optionTable are freed.
+ * 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
+Tk_FreeConfigOptions(
+ 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;
+ Tcl_Obj **oldPtrPtr, *oldPtr;
char *oldInternalPtr;
- CONST Tk_OptionSpec *specPtr;
+ const Tk_OptionSpec *specPtr;
for (tablePtr = (OptionTable *) optionTable; tablePtr != NULL;
tablePtr = tablePtr->nextPtr) {
@@ -1670,114 +1610,113 @@ Tk_FreeConfigOptions(recordPtr, optionTable, tkwin)
*
* FreeResources --
*
- * Free system resources associated with a configuration option,
- * such as colors or fonts.
+ * 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,
+ * 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
+FreeResources(
+ 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
+ char *internalPtr, /* A pointer to an internal representation for
* the option's value, such as an int or
- * (XColor *). Only valid if
+ * (XColor *). Only valid if
* optionPtr->specPtr->internalOffset >= 0. */
- Tk_Window tkwin; /* The window in which this option is used. */
+ 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.
+ * 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;
- }
- }
- break;
- case TK_OPTION_COLOR:
- if (internalFormExists) {
- if (*((XColor **) internalPtr) != NULL) {
- Tk_FreeColor(*((XColor **) internalPtr));
- *((XColor **) internalPtr) = NULL;
- }
- } else if (objPtr != NULL) {
- Tk_FreeColorFromObj(tkwin, objPtr);
- }
- 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_STYLE:
- if (internalFormExists) {
- Tk_FreeStyle(*((Tk_Style *) internalPtr));
- *((Tk_Style *) internalPtr) = NULL;
- } else if (objPtr != NULL) {
- Tk_FreeStyleFromObj(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;
- case TK_OPTION_CUSTOM: {
- Tk_ObjCustomOption *custom = optionPtr->extra.custom;
- if (internalFormExists && custom->freeProc != NULL) {
- custom->freeProc(custom->clientData, tkwin, internalPtr);
- }
- break;
- }
- default:
- break;
+ case TK_OPTION_STRING:
+ if (internalFormExists) {
+ if (*((char **) internalPtr) != NULL) {
+ ckfree(*((char **) internalPtr));
+ *((char **) internalPtr) = NULL;
+ }
+ }
+ break;
+ case TK_OPTION_COLOR:
+ if (internalFormExists) {
+ if (*((XColor **) internalPtr) != NULL) {
+ Tk_FreeColor(*((XColor **) internalPtr));
+ *((XColor **) internalPtr) = NULL;
+ }
+ } else if (objPtr != NULL) {
+ Tk_FreeColorFromObj(tkwin, objPtr);
+ }
+ 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_STYLE:
+ if (internalFormExists) {
+ Tk_FreeStyle(*((Tk_Style *) internalPtr));
+ *((Tk_Style *) internalPtr) = NULL;
+ } else if (objPtr != NULL) {
+ Tk_FreeStyleFromObj(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;
+ case TK_OPTION_CUSTOM: {
+ Tk_ObjCustomOption *custom = optionPtr->extra.custom;
+ if (internalFormExists && custom->freeProc != NULL) {
+ custom->freeProc(custom->clientData, tkwin, internalPtr);
+ }
+ break;
+ }
+ default:
+ break;
}
}
@@ -1786,23 +1725,21 @@ FreeResources(optionPtr, objPtr, internalPtr, tkwin)
*
* Tk_GetOptionInfo --
*
- * Returns a list object containing complete information about
- * either a single option or all the configuration options in a
- * table.
+ * Returns a list object containing complete information about either a
+ * single option or all the configuration options in a table.
*
* Results:
- * 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.
+
+ * This function 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.
@@ -1811,18 +1748,18 @@ FreeResources(optionPtr, objPtr, internalPtr, tkwin)
*/
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. */
- 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
+Tk_GetOptionInfo(
+ 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. */
+ 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. */
{
Tcl_Obj *resultPtr;
@@ -1831,14 +1768,14 @@ Tk_GetOptionInfo(interp, recordPtr, optionTable, namePtr, tkwin)
int count;
/*
- * If information is only wanted for a single configuration
- * spec, then handle that one spec specially.
+ * If information is only wanted for a single configuration spec, then
+ * handle that one spec specially.
*/
if (namePtr != NULL) {
optionPtr = GetOptionFromObj(interp, namePtr, tablePtr);
if (optionPtr == NULL) {
- return (Tcl_Obj *) NULL;
+ return NULL;
}
if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) {
optionPtr = optionPtr->extra.synonymPtr;
@@ -1847,11 +1784,11 @@ Tk_GetOptionInfo(interp, recordPtr, optionTable, namePtr, tkwin)
}
/*
- * Loop through all the specs, creating a big list with all
- * their information.
+ * Loop through all the specs, creating a big list with all their
+ * information.
*/
- resultPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
+ resultPtr = Tcl_NewListObj(0, NULL);
for (; tablePtr != NULL; tablePtr = tablePtr->nextPtr) {
for (optionPtr = tablePtr->options, count = tablePtr->numOptions;
count > 0; optionPtr++, count--) {
@@ -1867,12 +1804,12 @@ Tk_GetOptionInfo(interp, recordPtr, optionTable, namePtr, tkwin)
*
* GetConfigList --
*
- * Create a valid Tcl list holding the configuration information
- * for a single configuration option.
+ * 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.
+ * A Tcl list, dynamically allocated. The caller is expected to arrange
+ * for this list to be freed eventually.
*
* Side effects:
* Memory is allocated.
@@ -1881,37 +1818,37 @@ Tk_GetOptionInfo(interp, recordPtr, optionTable, namePtr, tkwin)
*/
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
+GetConfigList(
+ 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. */
+ Tk_Window tkwin) /* Window corresponding to recordPtr. */
{
Tcl_Obj *listPtr, *elementPtr;
- listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
- Tcl_ListObjAppendElement((Tcl_Interp *) NULL, listPtr,
+ listPtr = Tcl_NewListObj(0, NULL);
+ Tcl_ListObjAppendElement(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);
+ Tcl_ListObjAppendElement(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);
+ Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);
if (optionPtr->dbClassUID == NULL) {
elementPtr = Tcl_NewObj();
} else {
elementPtr = Tcl_NewStringObj(optionPtr->dbClassUID, -1);
}
- Tcl_ListObjAppendElement((Tcl_Interp *) NULL, listPtr, elementPtr);
+ Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);
if ((tkwin != NULL) && ((optionPtr->specPtr->type == TK_OPTION_COLOR)
|| (optionPtr->specPtr->type == TK_OPTION_BORDER))
@@ -1923,7 +1860,7 @@ GetConfigList(recordPtr, optionPtr, tkwin)
} else {
elementPtr = Tcl_NewObj();
}
- Tcl_ListObjAppendElement((Tcl_Interp *) NULL, listPtr, elementPtr);
+ Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);
if (optionPtr->specPtr->objOffset >= 0) {
elementPtr = *((Tcl_Obj **) (recordPtr
@@ -1934,7 +1871,7 @@ GetConfigList(recordPtr, optionPtr, tkwin)
} else {
elementPtr = GetObjectForOption(recordPtr, optionPtr, tkwin);
}
- Tcl_ListObjAppendElement((Tcl_Interp *) NULL, listPtr, elementPtr);
+ Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);
}
return listPtr;
}
@@ -1944,14 +1881,13 @@ GetConfigList(recordPtr, optionPtr, tkwin)
*
* GetObjectForOption --
*
- * 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.
+ * This function 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 a pointer to a Tcl object. The caller
- * must call Tcl_IncrRefCount on this object to preserve it.
+ * 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.
@@ -1960,13 +1896,13 @@ GetConfigList(recordPtr, optionPtr, tkwin)
*/
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. */
+GetObjectForOption(
+ 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. */
{
Tcl_Obj *objPtr;
char *internalPtr; /* Points to internal value of option in
@@ -1975,107 +1911,103 @@ GetObjectForOption(recordPtr, optionPtr, tkwin)
internalPtr = recordPtr + optionPtr->specPtr->internalOffset;
objPtr = NULL;
switch (optionPtr->specPtr->type) {
- case TK_OPTION_BOOLEAN: {
- objPtr = Tcl_NewIntObj(*((int *) internalPtr));
- break;
- }
- case TK_OPTION_INT: {
- objPtr = Tcl_NewIntObj(*((int *) internalPtr));
- break;
- }
- case TK_OPTION_DOUBLE: {
- objPtr = Tcl_NewDoubleObj(*((double *) internalPtr));
- break;
+ case TK_OPTION_BOOLEAN:
+ objPtr = Tcl_NewIntObj(*((int *) internalPtr));
+ break;
+ case TK_OPTION_INT:
+ objPtr = Tcl_NewIntObj(*((int *) internalPtr));
+ break;
+ case TK_OPTION_DOUBLE:
+ objPtr = Tcl_NewDoubleObj(*((double *) internalPtr));
+ break;
+ case TK_OPTION_STRING:
+ objPtr = Tcl_NewStringObj(*((char **) internalPtr), -1);
+ break;
+ case TK_OPTION_STRING_TABLE:
+ objPtr = Tcl_NewStringObj(((char **) optionPtr->specPtr->clientData)[
+ *((int *) internalPtr)], -1);
+ break;
+ case TK_OPTION_COLOR: {
+ XColor *colorPtr = *((XColor **) internalPtr);
+
+ if (colorPtr != NULL) {
+ objPtr = Tcl_NewStringObj(Tk_NameOfColor(colorPtr), -1);
+ }
+ break;
+ }
+ case TK_OPTION_FONT: {
+ Tk_Font tkfont = *((Tk_Font *) internalPtr);
+
+ if (tkfont != NULL) {
+ objPtr = Tcl_NewStringObj(Tk_NameOfFont(tkfont), -1);
}
- case TK_OPTION_STRING: {
- objPtr = Tcl_NewStringObj(*((char **) internalPtr), -1);
- break;
+ break;
+ }
+ case TK_OPTION_STYLE: {
+ Tk_Style style = *((Tk_Style *) internalPtr);
+
+ if (style != NULL) {
+ objPtr = Tcl_NewStringObj(Tk_NameOfStyle(style), -1);
}
- case TK_OPTION_STRING_TABLE: {
+ break;
+ }
+ case TK_OPTION_BITMAP: {
+ Pixmap pixmap = *((Pixmap *) internalPtr);
+
+ if (pixmap != None) {
objPtr = Tcl_NewStringObj(
- ((char **) optionPtr->specPtr->clientData)[
- *((int *) internalPtr)], -1);
- break;
- }
- case TK_OPTION_COLOR: {
- XColor *colorPtr = *((XColor **) internalPtr);
- if (colorPtr != NULL) {
- objPtr = Tcl_NewStringObj(Tk_NameOfColor(colorPtr), -1);
- }
- break;
- }
- case TK_OPTION_FONT: {
- Tk_Font tkfont = *((Tk_Font *) internalPtr);
- if (tkfont != NULL) {
- objPtr = Tcl_NewStringObj(Tk_NameOfFont(tkfont), -1);
- }
- break;
- }
- case TK_OPTION_STYLE: {
- Tk_Style style = *((Tk_Style *) internalPtr);
- if (style != NULL) {
- objPtr = Tcl_NewStringObj(Tk_NameOfStyle(style), -1);
- }
- break;
- }
- case TK_OPTION_BITMAP: {
- Pixmap pixmap = *((Pixmap *) internalPtr);
- if (pixmap != None) {
- objPtr = Tcl_NewStringObj(Tk_NameOfBitmap(Tk_Display(tkwin),
- pixmap), -1);
- }
- break;
- }
- case TK_OPTION_BORDER: {
- Tk_3DBorder border = *((Tk_3DBorder *) internalPtr);
- if (border != NULL) {
- objPtr = Tcl_NewStringObj(Tk_NameOf3DBorder(border), -1);
- }
- break;
- }
- case TK_OPTION_RELIEF: {
- objPtr = Tcl_NewStringObj(Tk_NameOfRelief(
- *((int *) internalPtr)), -1);
- break;
- }
- case TK_OPTION_CURSOR: {
- Tk_Cursor cursor = *((Tk_Cursor *) internalPtr);
- if (cursor != None) {
- objPtr = Tcl_NewStringObj(
- Tk_NameOfCursor(Tk_Display(tkwin), cursor), -1);
- }
- break;
+ Tk_NameOfBitmap(Tk_Display(tkwin), pixmap), -1);
}
- case TK_OPTION_JUSTIFY: {
- objPtr = Tcl_NewStringObj(Tk_NameOfJustify(
- *((Tk_Justify *) internalPtr)), -1);
- break;
- }
- case TK_OPTION_ANCHOR: {
- objPtr = Tcl_NewStringObj(Tk_NameOfAnchor(
- *((Tk_Anchor *) internalPtr)), -1);
- break;
- }
- case TK_OPTION_PIXELS: {
- objPtr = Tcl_NewIntObj(*((int *) internalPtr));
- break;
- }
- case TK_OPTION_WINDOW: {
- Tk_Window tkwin = *((Tk_Window *) internalPtr);
- if (tkwin != NULL) {
- objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1);
- }
- break;
- }
- case TK_OPTION_CUSTOM: {
- Tk_ObjCustomOption *custom = optionPtr->extra.custom;
- objPtr = custom->getProc(custom->clientData, tkwin, recordPtr,
- optionPtr->specPtr->internalOffset);
- break;
+ break;
+ }
+ case TK_OPTION_BORDER: {
+ Tk_3DBorder border = *((Tk_3DBorder *) internalPtr);
+
+ if (border != NULL) {
+ objPtr = Tcl_NewStringObj(Tk_NameOf3DBorder(border), -1);
}
- default: {
- panic("bad option type in GetObjectForOption");
+ break;
+ }
+ case TK_OPTION_RELIEF:
+ objPtr = Tcl_NewStringObj(Tk_NameOfRelief(*((int *) internalPtr)), -1);
+ break;
+ case TK_OPTION_CURSOR: {
+ Tk_Cursor cursor = *((Tk_Cursor *) internalPtr);
+
+ if (cursor != None) {
+ objPtr = Tcl_NewStringObj(
+ Tk_NameOfCursor(Tk_Display(tkwin), cursor), -1);
}
+ break;
+ }
+ case TK_OPTION_JUSTIFY:
+ objPtr = Tcl_NewStringObj(Tk_NameOfJustify(
+ *((Tk_Justify *) internalPtr)), -1);
+ break;
+ case TK_OPTION_ANCHOR:
+ objPtr = Tcl_NewStringObj(Tk_NameOfAnchor(
+ *((Tk_Anchor *) internalPtr)), -1);
+ break;
+ case TK_OPTION_PIXELS:
+ objPtr = Tcl_NewIntObj(*((int *) internalPtr));
+ break;
+ case TK_OPTION_WINDOW: {
+ Tk_Window tkwin = *((Tk_Window *) internalPtr);
+
+ if (tkwin != NULL) {
+ objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1);
+ }
+ break;
+ }
+ case TK_OPTION_CUSTOM: {
+ Tk_ObjCustomOption *custom = optionPtr->extra.custom;
+
+ objPtr = custom->getProc(custom->clientData, tkwin, recordPtr,
+ optionPtr->specPtr->internalOffset);
+ break;
+ }
+ default:
+ Tcl_Panic("bad option type in GetObjectForOption");
}
if (objPtr == NULL) {
objPtr = Tcl_NewObj();
@@ -2088,14 +2020,13 @@ GetObjectForOption(recordPtr, optionPtr, tkwin)
*
* Tk_GetOptionValue --
*
- * This procedure returns the current value of a configuration
- * option.
+ * This function returns the current value of a configuration option.
*
* Results:
- * 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).
+ * 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.
@@ -2104,16 +2035,16 @@ GetObjectForOption(recordPtr, optionPtr, tkwin)
*/
Tcl_Obj *
-Tk_GetOptionValue(interp, recordPtr, optionTable, namePtr, tkwin)
- Tcl_Interp *interp; /* Interpreter for error reporting. If
- * NULL then no messages are provided for
+Tk_GetOptionValue(
+ 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. */
- Tk_OptionTable optionTable; /* Describes legal options. */
- Tcl_Obj *namePtr; /* Gives the command-line name for the
- * option whose value is to be returned. */
- Tk_Window tkwin; /* Window corresponding to recordPtr. */
+ char *recordPtr, /* Record whose fields contain current values
+ * for options. */
+ Tk_OptionTable optionTable, /* Describes legal options. */
+ Tcl_Obj *namePtr, /* Gives the command-line name for the option
+ * whose value is to be returned. */
+ Tk_Window tkwin) /* Window corresponding to recordPtr. */
{
OptionTable *tablePtr = (OptionTable *) optionTable;
Option *optionPtr;
@@ -2127,16 +2058,16 @@ Tk_GetOptionValue(interp, recordPtr, optionTable, namePtr, tkwin)
optionPtr = optionPtr->extra.synonymPtr;
}
if (optionPtr->specPtr->objOffset >= 0) {
- resultPtr = *((Tcl_Obj **) (recordPtr + optionPtr->specPtr->objOffset));
+ 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.
+ * 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);
}
@@ -2148,19 +2079,17 @@ Tk_GetOptionValue(interp, recordPtr, optionTable, namePtr, tkwin)
*
* TkDebugConfig --
*
- * This is a debugging procedure that returns information about
- * one of the configuration tables that currently exists for an
- * interpreter.
+ * This is a debugging function that returns information about one of the
+ * configuration tables that currently exists for an interpreter.
*
* Results:
- * 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.
+ * 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:
* None.
@@ -2169,12 +2098,12 @@ Tk_GetOptionValue(interp, recordPtr, optionTable, namePtr, tkwin)
*/
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. */
+TkDebugConfig(
+ 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. */
{
OptionTable *tablePtr = (OptionTable *) table;
Tcl_HashTable *hashTablePtr;
@@ -2190,8 +2119,8 @@ TkDebugConfig(interp, table)
}
/*
- * Scan all the tables for this interpreter to make sure that the
- * one we want still is valid.
+ * Scan all the tables for this interpreter to make sure that the one we
+ * want still is valid.
*/
for (hashEntryPtr = Tcl_FirstHashEntry(hashTablePtr, &search);
@@ -2199,17 +2128,23 @@ TkDebugConfig(interp, table)
hashEntryPtr = Tcl_NextHashEntry(&search)) {
if (tablePtr == (OptionTable *) Tcl_GetHashValue(hashEntryPtr)) {
for ( ; tablePtr != NULL; tablePtr = tablePtr->nextPtr) {
- Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
+ Tcl_ListObjAppendElement(NULL, objPtr,
Tcl_NewIntObj(tablePtr->refCount));
- Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
+ Tcl_ListObjAppendElement(NULL, objPtr,
Tcl_NewIntObj(tablePtr->numOptions));
- Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
- Tcl_NewStringObj(
- tablePtr->options[0].specPtr->optionName,
- -1));
+ Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(
+ tablePtr->options[0].specPtr->optionName, -1));
}
break;
}
}
return objPtr;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkConsole.c b/generic/tkConsole.c
index e93c0fc..f894638 100644
--- a/generic/tkConsole.c
+++ b/generic/tkConsole.c
@@ -1,15 +1,14 @@
-/*
+/*
* tkConsole.c --
*
- * This file implements a Tcl console for systems that may not
- * otherwise have access to a console. It uses the Text widget
- * and provides special access via a console command.
+ * This file implements a Tcl console for systems that may not otherwise
+ * have access to a console. It uses the Text widget and provides special
+ * access via a console command.
*
* Copyright (c) 1995-1996 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tk.h"
@@ -23,8 +22,8 @@
*/
typedef struct ConsoleInfo {
- Tcl_Interp *consoleInterp; /* Interpreter displaying the console. */
- Tcl_Interp *interp; /* Interpreter controlled by console. */
+ Tcl_Interp *consoleInterp; /* Interpreter displaying the console. */
+ Tcl_Interp *interp; /* Interpreter controlled by console. */
int refCount;
} ConsoleInfo;
@@ -40,30 +39,26 @@ typedef struct ChannelData {
int type; /* TCL_STDOUT or TCL_STDERR */
} ChannelData;
-/*
+/*
* Prototypes for local procedures defined in this file:
*/
-static int ConsoleClose _ANSI_ARGS_((ClientData instanceData,
- Tcl_Interp *interp));
-static void ConsoleDeleteProc _ANSI_ARGS_((ClientData clientData));
-static void ConsoleEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static int ConsoleHandle _ANSI_ARGS_((ClientData instandeData,
- int direction, ClientData *handlePtr));
-static int ConsoleInput _ANSI_ARGS_((ClientData instanceData,
- char *buf, int toRead, int *errorCode));
-static int ConsoleObjCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
-static int ConsoleOutput _ANSI_ARGS_((ClientData instanceData,
- CONST char *buf, int toWrite, int *errorCode));
-static void ConsoleWatch _ANSI_ARGS_((ClientData instanceData,
- int mask));
-static void DeleteConsoleInterp _ANSI_ARGS_((ClientData clientData));
-static void InterpDeleteProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp));
-static int InterpreterObjCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
+static int ConsoleClose(ClientData instanceData, Tcl_Interp *interp);
+static void ConsoleDeleteProc(ClientData clientData);
+static void ConsoleEventProc(ClientData clientData, XEvent *eventPtr);
+static int ConsoleHandle(ClientData instanceData,
+ int direction, ClientData *handlePtr);
+static int ConsoleInput(ClientData instanceData,
+ char *buf, int toRead, int *errorCode);
+static int ConsoleObjCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int ConsoleOutput(ClientData instanceData,
+ CONST char *buf, int toWrite, int *errorCode);
+static void ConsoleWatch(ClientData instanceData, int mask);
+static void DeleteConsoleInterp(ClientData clientData);
+static void InterpDeleteProc(ClientData clientData, Tcl_Interp *interp);
+static int InterpreterObjCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
/*
* This structure describes the channel type structure for file based IO:
@@ -84,13 +79,12 @@ static Tcl_ChannelType consoleChannelType = {
NULL, /* Always non-blocking.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
- NULL, /* wide seek proc */
- NULL, /* thread action proc */
+ NULL, /* wide seek proc */
+ NULL, /* thread action proc */
+ NULL
};
-
#ifdef __WIN32__
-
#include <windows.h>
/*
@@ -98,20 +92,21 @@ static Tcl_ChannelType consoleChannelType = {
*
* ShouldUseConsoleChannel
*
- * Check to see if console window should be used for a given
- * standard channel
+ * Check to see if console window should be used for a given standard
+ * channel.
*
* Results:
* None.
*
* Side effects:
- * Creates the console channel and installs it as the standard
- * channels.
+ * Creates the console channel and installs it as the standard channels.
*
*----------------------------------------------------------------------
*/
-static int ShouldUseConsoleChannel(type)
- int type;
+
+static int
+ShouldUseConsoleChannel(
+ int type)
{
DWORD handleId; /* Standard handle to retrieve. */
DCB dcb;
@@ -120,18 +115,18 @@ static int ShouldUseConsoleChannel(type)
HANDLE handle;
switch (type) {
- case TCL_STDIN:
- handleId = STD_INPUT_HANDLE;
- break;
- case TCL_STDOUT:
- handleId = STD_OUTPUT_HANDLE;
- break;
- case TCL_STDERR:
- handleId = STD_ERROR_HANDLE;
- break;
- default:
- return 0;
- break;
+ case TCL_STDIN:
+ handleId = STD_INPUT_HANDLE;
+ break;
+ case TCL_STDOUT:
+ handleId = STD_OUTPUT_HANDLE;
+ break;
+ case TCL_STDERR:
+ handleId = STD_ERROR_HANDLE;
+ break;
+ default:
+ return 0;
+ break;
}
handle = GetStdHandle(handleId);
@@ -139,7 +134,7 @@ static int ShouldUseConsoleChannel(type)
/*
* Note that we need to check for 0 because Windows will return 0 if this
* is not a console mode application, even though this is not a valid
- * handle.
+ * handle.
*/
if ((handle == INVALID_HANDLE_VALUE) || (handle == 0)) {
@@ -147,27 +142,27 @@ static int ShouldUseConsoleChannel(type)
}
/*
- * Win2K BUG: GetStdHandle(STD_OUTPUT_HANDLE) can return what appears
- * to be a valid handle. See TclpGetDefaultStdChannel() for this change
- * implemented. We didn't change it here because GetFileType() [below]
- * will catch this with FILE_TYPE_UNKNOWN and appropriately return a
- * value of 1, anyways.
+ * Win2K BUG: GetStdHandle(STD_OUTPUT_HANDLE) can return what appears to
+ * be a valid handle. See TclpGetDefaultStdChannel() for this change
+ * implemented. We didn't change it here because GetFileType() [below]
+ * will catch this with FILE_TYPE_UNKNOWN and appropriately return a value
+ * of 1, anyways.
*
* char dummyBuff[1];
* DWORD dummyWritten;
*
* if ((type == TCL_STDOUT)
- * && !WriteFile(handle, dummyBuff, 0, &dummyWritten, NULL)) {
- * return 1;
+ * && !WriteFile(handle, dummyBuff, 0, &dummyWritten, NULL)) {
+ * return 1;
* }
*/
fileType = GetFileType(handle);
/*
- * If the file is a character device, we need to try to figure out
- * whether it is a serial port, a console, or something else. We
- * test for the console case first because this is more common.
+ * If the file is a character device, we need to try to figure out whether
+ * it is a serial port, a console, or something else. We test for the
+ * console case first because this is more common.
*/
if (fileType == FILE_TYPE_CHAR) {
@@ -175,10 +170,10 @@ static int ShouldUseConsoleChannel(type)
if (!GetConsoleMode(handle, &consoleParams) &&
!GetCommState(handle, &dcb)) {
/*
- * Don't use a CHAR type channel for stdio, otherwise Tk
- * runs into trouble with the MS DevStudio debugger.
+ * Don't use a CHAR type channel for stdio, otherwise Tk runs into
+ * trouble with the MS DevStudio debugger.
*/
-
+
return 1;
}
} else if (fileType == FILE_TYPE_UNKNOWN) {
@@ -202,23 +197,22 @@ static int ShouldUseConsoleChannel(type)
*
* Tk_InitConsoleChannels --
*
- * Create the console channels and install them as the standard
- * channels. All I/O will be discarded until Tk_CreateConsoleWindow
- * is called to attach the console to a text widget.
+ * Create the console channels and install them as the standard channels.
+ * All I/O will be discarded until Tk_CreateConsoleWindow is called to
+ * attach the console to a text widget.
*
* Results:
* None.
*
* Side effects:
- * Creates the console channel and installs it as the standard
- * channels.
+ * Creates the console channel and installs it as the standard channels.
*
*----------------------------------------------------------------------
*/
void
-Tk_InitConsoleChannels(interp)
- Tcl_Interp *interp;
+Tk_InitConsoleChannels(
+ Tcl_Interp *interp)
{
static Tcl_ThreadDataKey consoleInitKey;
int *consoleInitPtr, doIn, doOut, doErr;
@@ -226,11 +220,11 @@ Tk_InitConsoleChannels(interp)
Tcl_Channel consoleChannel;
/*
- * Ensure that we are getting the matching version of Tcl. This is
- * really only an issue when Tk is loaded dynamically.
+ * Ensure that we are getting a compatible version of Tcl. This is really
+ * only an issue when Tk is loaded dynamically.
*/
- if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
+ if (Tcl_InitStubs(interp, "8.5.0", 0) == NULL) {
return;
}
@@ -326,9 +320,9 @@ Tk_InitConsoleChannels(interp)
*
* Tk_CreateConsoleWindow --
*
- * Initialize the console. This code actually creates a new
- * application and associated interpreter. This effectivly hides
- * the implementation from the main application.
+ * Initialize the console. This code actually creates a new application
+ * and associated interpreter. This effectivly hides the implementation
+ * from the main application.
*
* Results:
* None.
@@ -339,9 +333,9 @@ Tk_InitConsoleChannels(interp)
*----------------------------------------------------------------------
*/
-int
-Tk_CreateConsoleWindow(interp)
- Tcl_Interp *interp; /* Interpreter to use for prompting. */
+int
+Tk_CreateConsoleWindow(
+ Tcl_Interp *interp) /* Interpreter to use for prompting. */
{
Tcl_Channel chan;
ConsoleInfo *info;
@@ -350,28 +344,26 @@ Tk_CreateConsoleWindow(interp)
int result = TCL_OK;
int haveConsoleChannel = 1;
- static CONST char *initCmd = "source $tk_library/console.tcl";
-
/* Init an interp with Tcl and Tk */
Tcl_Interp *consoleInterp = Tcl_CreateInterp();
if (Tcl_Init(consoleInterp) != TCL_OK) {
- goto error;
+ goto error;
}
if (Tk_Init(consoleInterp) != TCL_OK) {
goto error;
}
-
+
/*
* Fetch the instance data from whatever std channel is a
* console channel. If none, create fresh instance data.
*/
if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDIN))
- == &consoleChannelType) {
+ == &consoleChannelType) {
} else if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDOUT))
- == &consoleChannelType) {
+ == &consoleChannelType) {
} else if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDERR))
- == &consoleChannelType) {
+ == &consoleChannelType) {
} else {
haveConsoleChannel = 0;
}
@@ -418,14 +410,14 @@ Tk_CreateConsoleWindow(interp)
Tcl_CallWhenDeleted(consoleInterp, InterpDeleteProc, (ClientData) info);
info->refCount++;
Tcl_CreateThreadExitHandler(DeleteConsoleInterp,
- (ClientData) consoleInterp);
-
- /*
- * Add console commands to the interp
+ (ClientData) consoleInterp);
+
+ /*
+ * Add console commands to the interp
*/
token = Tcl_CreateObjCommand(interp, "console", ConsoleObjCmd,
- (ClientData) info, ConsoleDeleteProc);
+ (ClientData) info, ConsoleDeleteProc);
info->refCount++;
/*
@@ -444,22 +436,11 @@ Tk_CreateConsoleWindow(interp)
}
Tcl_Preserve((ClientData) consoleInterp);
- result = Tcl_EvalEx(consoleInterp, initCmd, -1, TCL_EVAL_GLOBAL);
+ result = Tcl_EvalEx(consoleInterp, "source $tk_library/console.tcl",
+ -1, TCL_EVAL_GLOBAL);
if (result == TCL_ERROR) {
- Tcl_Obj *objPtr = Tcl_GetVar2Ex(consoleInterp, "errorCode", NULL,
- TCL_GLOBAL_ONLY);
- Tcl_ResetResult(interp);
- if (objPtr) {
- Tcl_SetObjErrorCode(interp, objPtr);
- }
-
- objPtr = Tcl_GetVar2Ex(consoleInterp, "errorInfo", NULL,
- TCL_GLOBAL_ONLY);
- if (objPtr) {
- int numBytes;
- CONST char *message = Tcl_GetStringFromObj(objPtr, &numBytes);
- Tcl_AddObjErrorInfo(interp, message, numBytes);
- }
+ Tcl_SetReturnOptions(interp,
+ Tcl_GetReturnOptions(consoleInterp, result));
Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp));
}
Tcl_Release((ClientData) consoleInterp);
@@ -476,7 +457,7 @@ Tk_CreateConsoleWindow(interp)
goto error;
}
return TCL_OK;
-
+
error:
Tcl_AddErrorInfo(interp, "\n (creating console window)");
if (!Tcl_InterpDeleted(consoleInterp)) {
@@ -490,12 +471,12 @@ Tk_CreateConsoleWindow(interp)
*
* ConsoleOutput--
*
- * Writes the given output on the IO channel. Returns count of how
- * many characters were actually written, and an error indication.
+ * Writes the given output on the IO channel. Returns count of how many
+ * characters were actually written, and an error indication.
*
* Results:
- * A count of how many characters were written is returned and an
- * error indication is returned in an output argument.
+ * A count of how many characters were written is returned and an error
+ * indication is returned in an output argument.
*
* Side effects:
* Writes output on the actual channel.
@@ -504,11 +485,11 @@ Tk_CreateConsoleWindow(interp)
*/
static int
-ConsoleOutput(instanceData, buf, toWrite, errorCode)
- ClientData instanceData; /* Indicates which device to use. */
- CONST char *buf; /* The data buffer. */
- int toWrite; /* How many bytes to write? */
- int *errorCode; /* Where to store error code. */
+ConsoleOutput(
+ ClientData instanceData, /* Indicates which device to use. */
+ CONST char *buf, /* The data buffer. */
+ int toWrite, /* How many bytes to write? */
+ int *errorCode) /* Where to store error code. */
{
ChannelData *data = (ChannelData *)instanceData;
ConsoleInfo *info = data->info;
@@ -560,7 +541,7 @@ ConsoleOutput(instanceData, buf, toWrite, errorCode)
*
* ConsoleInput --
*
- * Read input from the console. Not currently implemented.
+ * Read input from the console. Not currently implemented.
*
* Results:
* Always returns EOF.
@@ -573,12 +554,12 @@ ConsoleOutput(instanceData, buf, toWrite, errorCode)
/* ARGSUSED */
static int
-ConsoleInput(instanceData, buf, bufSize, errorCode)
- ClientData instanceData; /* Unused. */
- char *buf; /* Where to store data read. */
- int bufSize; /* How much space is available
- * in the buffer? */
- int *errorCode; /* Where to store error code. */
+ConsoleInput(
+ ClientData instanceData, /* Unused. */
+ char *buf, /* Where to store data read. */
+ int bufSize, /* How much space is available in the
+ * buffer? */
+ int *errorCode) /* Where to store error code. */
{
return 0; /* Always return EOF. */
}
@@ -601,9 +582,9 @@ ConsoleInput(instanceData, buf, bufSize, errorCode)
/* ARGSUSED */
static int
-ConsoleClose(instanceData, interp)
- ClientData instanceData; /* Unused. */
- Tcl_Interp *interp; /* Unused. */
+ConsoleClose(
+ ClientData instanceData, /* Unused. */
+ Tcl_Interp *interp) /* Unused. */
{
ChannelData *data = (ChannelData *)instanceData;
ConsoleInfo *info = data->info;
@@ -623,9 +604,9 @@ ConsoleClose(instanceData, interp)
*
* ConsoleWatch --
*
- * Called by the notifier to set up the console device so that
- * events will be noticed. Since there are no events on the
- * console, this routine just returns without doing anything.
+ * Called by the notifier to set up the console device so that events
+ * will be noticed. Since there are no events on the console, this
+ * routine just returns without doing anything.
*
* Results:
* None.
@@ -638,12 +619,11 @@ ConsoleClose(instanceData, interp)
/* ARGSUSED */
static void
-ConsoleWatch(instanceData, mask)
- ClientData instanceData; /* Device ID for the channel. */
- int mask; /* OR-ed combination of
- * TCL_READABLE, TCL_WRITABLE and
- * TCL_EXCEPTION, for the events
- * we are interested in. */
+ConsoleWatch(
+ ClientData instanceData, /* Device ID for the channel. */
+ int mask) /* OR-ed combination of TCL_READABLE,
+ * TCL_WRITABLE and TCL_EXCEPTION, for the
+ * events we are interested in. */
{
}
@@ -653,8 +633,7 @@ ConsoleWatch(instanceData, mask)
* ConsoleHandle --
*
* Invoked by the generic IO layer to get a handle from a channel.
- * Because console channels are not devices, this function always
- * fails.
+ * Because console channels are not devices, this function always fails.
*
* Results:
* Always returns TCL_ERROR.
@@ -667,12 +646,12 @@ ConsoleWatch(instanceData, mask)
/* ARGSUSED */
static int
-ConsoleHandle(instanceData, direction, handlePtr)
- ClientData instanceData; /* Device ID for the channel. */
- int direction; /* TCL_READABLE or TCL_WRITABLE to indicate
+ConsoleHandle(
+ ClientData instanceData, /* Device ID for the channel. */
+ int direction, /* TCL_READABLE or TCL_WRITABLE to indicate
* which direction of the channel is being
* requested. */
- ClientData *handlePtr; /* Where to store handle */
+ ClientData *handlePtr) /* Where to store handle */
{
return TCL_ERROR;
}
@@ -695,11 +674,11 @@ ConsoleHandle(instanceData, direction, handlePtr)
*/
static int
-ConsoleObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Access to the console interp */
- Tcl_Interp *interp; /* Current interpreter */
- int objc; /* Number of arguments */
- Tcl_Obj *CONST objv[]; /* Argument objects */
+ConsoleObjCmd(
+ ClientData clientData, /* Access to the console interp */
+ Tcl_Interp *interp, /* Current interpreter */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[]) /* Argument objects */
{
int index, result;
static CONST char *options[] = {"eval", "hide", "show", "title", NULL};
@@ -755,22 +734,8 @@ ConsoleObjCmd(clientData, interp, objc, objv)
if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) {
Tcl_Preserve((ClientData) consoleInterp);
result = Tcl_EvalObjEx(consoleInterp, cmd, TCL_EVAL_GLOBAL);
- if (result == TCL_ERROR) {
- Tcl_Obj *objPtr = Tcl_GetVar2Ex(consoleInterp, "errorCode",
- NULL, TCL_GLOBAL_ONLY);
- Tcl_ResetResult(interp);
- if (objPtr) {
- Tcl_SetObjErrorCode(interp, objPtr);
- }
-
- objPtr = Tcl_GetVar2Ex(consoleInterp, "errorInfo",
- NULL, TCL_GLOBAL_ONLY);
- if (objPtr) {
- int numBytes;
- CONST char *message = Tcl_GetStringFromObj(objPtr, &numBytes);
- Tcl_AddObjErrorInfo(interp, message, numBytes);
- }
- }
+ Tcl_SetReturnOptions(interp,
+ Tcl_GetReturnOptions(consoleInterp, result));
Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp));
Tcl_Release((ClientData) consoleInterp);
} else {
@@ -786,8 +751,8 @@ ConsoleObjCmd(clientData, interp, objc, objv)
*
* InterpreterObjCmd --
*
- * This command allows the console interp to communicate with the
- * main interpreter.
+ * This command allows the console interp to communicate with the main
+ * interpreter.
*
* Results:
* A standard Tcl result.
@@ -796,11 +761,11 @@ ConsoleObjCmd(clientData, interp, objc, objv)
*/
static int
-InterpreterObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Not used */
- Tcl_Interp *interp; /* Current interpreter */
- int objc; /* Number of arguments */
- Tcl_Obj *CONST objv[]; /* Argument objects */
+InterpreterObjCmd(
+ ClientData clientData, /* */
+ Tcl_Interp *interp, /* Current interpreter */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[]) /* Argument objects */
{
int index, result = TCL_OK;
static CONST char *options[] = {"eval", "record", NULL};
@@ -813,7 +778,7 @@ InterpreterObjCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, &index)
- != TCL_OK) {
+ != TCL_OK) {
return TCL_ERROR;
}
@@ -830,30 +795,16 @@ InterpreterObjCmd(clientData, interp, objc, objv)
Tcl_Preserve((ClientData) otherInterp);
switch ((enum option) index) {
case OTHER_EVAL:
- result = Tcl_EvalObjEx(otherInterp, objv[2], TCL_EVAL_GLOBAL);
+ result = Tcl_EvalObjEx(otherInterp, objv[2], TCL_EVAL_GLOBAL);
/*
* TODO: Should exceptions be filtered here?
*/
- if (result == TCL_ERROR) {
- Tcl_Obj *objPtr = Tcl_GetVar2Ex(otherInterp, "errorCode",
- NULL, TCL_GLOBAL_ONLY);
- Tcl_ResetResult(interp);
- if (objPtr) {
- Tcl_SetObjErrorCode(interp, objPtr);
- }
-
- objPtr = Tcl_GetVar2Ex(otherInterp, "errorInfo",
- NULL, TCL_GLOBAL_ONLY);
- if (objPtr) {
- int numBytes;
- CONST char *message = Tcl_GetStringFromObj(objPtr, &numBytes);
- Tcl_AddObjErrorInfo(interp, message, numBytes);
- }
- }
+ Tcl_SetReturnOptions(interp,
+ Tcl_GetReturnOptions(otherInterp, result));
Tcl_SetObjResult(interp, Tcl_GetObjResult(otherInterp));
break;
case OTHER_RECORD:
- Tcl_RecordAndEvalObj(otherInterp, objv[2], TCL_EVAL_GLOBAL);
+ Tcl_RecordAndEvalObj(otherInterp, objv[2], TCL_EVAL_GLOBAL);
/*
* By not setting result, we discard any exceptions or errors here
* and always return TCL_OK. All the caller wants is the
@@ -878,8 +829,8 @@ InterpreterObjCmd(clientData, interp, objc, objv)
*/
static void
-DeleteConsoleInterp(clientData)
- ClientData clientData;
+DeleteConsoleInterp(
+ ClientData clientData)
{
Tcl_Interp *interp = (Tcl_Interp *)clientData;
Tcl_DeleteInterp(interp);
@@ -890,23 +841,28 @@ DeleteConsoleInterp(clientData)
*
* InterpDeleteProc --
*
- * React when the interp in which the console is displayed is deleted
- * for any reason.
+ * React when the interp in which the console is displayed is deleted
+ * for any reason.
*
* Results:
* None.
+ *
+ * Side effects:
+ * A new console it created.
+ *
+ *----------------------------------------------------------------------
*/
static void
-InterpDeleteProc(clientData, interp)
- ClientData clientData;
- Tcl_Interp *interp;
+InterpDeleteProc(
+ ClientData clientData,
+ Tcl_Interp *interp)
{
ConsoleInfo *info = (ConsoleInfo *) clientData;
- if(info->consoleInterp == interp) {
+ if (info->consoleInterp == interp) {
Tcl_DeleteThreadExitHandler(DeleteConsoleInterp,
- (ClientData) info-> consoleInterp);
+ (ClientData) info->consoleInterp);
info->consoleInterp = NULL;
}
if (--info->refCount <= 0) {
@@ -920,20 +876,20 @@ InterpDeleteProc(clientData, interp)
* ConsoleDeleteProc --
*
* If the console command is deleted we destroy the console window and
- * all associated data structures.
-
+ * all associated data structures.
+ *
* Results:
* None.
*
* Side effects:
- * A new console is created.
+ * A new console it created.
*
*----------------------------------------------------------------------
*/
static void
-ConsoleDeleteProc(clientData)
- ClientData clientData;
+ConsoleDeleteProc(
+ ClientData clientData)
{
ConsoleInfo *info = (ConsoleInfo *) clientData;
@@ -950,10 +906,11 @@ ConsoleDeleteProc(clientData)
*
* ConsoleEventProc --
*
- * This event function is registered on the main window of the slave
- * interpreter. If the user or a running script causes the main window to
- * be destroyed, then we need to inform the console interpreter by
+ * This event function is registered on the main window of the slave
+ * interpreter. If the user or a running script causes the main window to
+ * be destroyed, then we need to inform the console interpreter by
* invoking "::tk::ConsoleExit".
+ *
* Results:
* None.
*
@@ -964,9 +921,9 @@ ConsoleDeleteProc(clientData)
*/
static void
-ConsoleEventProc(clientData, eventPtr)
- ClientData clientData;
- XEvent *eventPtr;
+ConsoleEventProc(
+ ClientData clientData,
+ XEvent *eventPtr)
{
if (eventPtr->type == DestroyNotify) {
ConsoleInfo *info = (ConsoleInfo *) clientData;
@@ -981,3 +938,11 @@ ConsoleEventProc(clientData, eventPtr)
}
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkCursor.c b/generic/tkCursor.c
index f599083..410aea9 100644
--- a/generic/tkCursor.c
+++ b/generic/tkCursor.c
@@ -1,52 +1,50 @@
-/*
+/*
* tkCursor.c --
*
* This file maintains a database of read-only cursors for the Tk
- * toolkit. This allows cursors to be shared between widgets and
- * also avoids round-trips to the X server.
+ * toolkit. This allows cursors to be shared between widgets and also
+ * avoids round-trips to the X server.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
/*
- * 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 cursorIdTable, and the other is either
- * cursorNameTable or cursorDataTable, each of which are stored in the
- * TkDisplay structure for the current thread.
+ * 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 cursorIdTable, and the other is either cursorNameTable or
+ * cursorDataTable, each of which are stored in the TkDisplay structure for
+ * the current thread.
*/
typedef struct {
CONST char *source; /* Cursor bits. */
CONST char *mask; /* Mask bits. */
- int width, height; /* Dimensions of cursor (and data
- * and mask). */
+ int width, height; /* Dimensions of cursor (and data and
+ * mask). */
int xHot, yHot; /* Location of cursor hot-spot. */
Tk_Uid fg, bg; /* Colors for cursor. */
Display *display; /* Display on which cursor will be used. */
} DataKey;
/*
- * Forward declarations for procedures defined in this file:
+ * Forward declarations for functions defined in this file:
*/
-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 * TkcGetCursor _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *name));
-static TkCursor * GetCursorFromObj _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Obj *objPtr));
-static void InitCursorObj _ANSI_ARGS_((Tcl_Obj *objPtr));
+static void CursorInit(TkDisplay *dispPtr);
+static void DupCursorObjProc(Tcl_Obj *srcObjPtr,
+ Tcl_Obj *dupObjPtr);
+static void FreeCursor(TkCursor *cursorPtr);
+static void FreeCursorObjProc(Tcl_Obj *objPtr);
+static TkCursor * TkcGetCursor(Tcl_Interp *interp,
+ Tk_Window tkwin, CONST char *name);
+static TkCursor * GetCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
+static void InitCursorObj(Tcl_Obj *objPtr);
/*
* The following structure defines the implementation of the "cursor" Tcl
@@ -69,33 +67,32 @@ Tcl_ObjType tkCursorObjType = {
*
* Tk_AllocCursorFromObj --
*
- * Given a Tcl_Obj *, map the value to a corresponding
- * Tk_Cursor structure based on the tkwin given.
+ * 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.
+ * 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.
+ * For each call to this function, there should eventually be a call to
+ * Tk_FreeCursorFromObj, so that the database can be cleaned up when
+ * cursors aren't needed anymore.
*
*----------------------------------------------------------------------
*/
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. */
+Tk_AllocCursorFromObj(
+ 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;
@@ -105,16 +102,17 @@ Tk_AllocCursorFromObj(interp, tkwin, 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 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.
+ * 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) {
@@ -124,38 +122,37 @@ Tk_AllocCursorFromObj(interp, tkwin, objPtr)
}
/*
- * 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.
+ * 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);
+ 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;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) cursorPtr;
return cursorPtr->cursor;
}
}
}
/*
- * Still no luck. Call TkcGetCursor to allocate a new TkCursor object.
+ * Still no luck. Call TkcGetCursor to allocate a new TkCursor object.
*/
cursorPtr = TkcGetCursor(interp, tkwin, Tcl_GetString(objPtr));
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) cursorPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) cursorPtr;
if (cursorPtr == NULL) {
return None;
- } else {
- cursorPtr->objRefCount++;
- return cursorPtr->cursor;
}
+ cursorPtr->objRefCount++;
+ return cursorPtr->cursor;
}
/*
@@ -163,32 +160,31 @@ Tk_AllocCursorFromObj(interp, tkwin, objPtr)
*
* Tk_GetCursor --
*
- * Given a string describing a cursor, locate (or create if necessary)
- * a cursor that fits the description.
+ * Given a string describing a cursor, locate (or create if necessary) a
+ * cursor that fits the description.
*
* 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 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.
+ * 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 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
+ * For each call to this function, there should eventually be a call to
+ * Tk_FreeCursor, so that the database can be cleaned up when cursors
* aren't needed anymore.
*
*----------------------------------------------------------------------
*/
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
- * for details on legal syntax. */
+Tk_GetCursor(
+ 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 for
+ * details on legal syntax. */
{
TkCursor *cursorPtr = TkcGetCursor(interp, tkwin, string);
if (cursorPtr == NULL) {
@@ -202,48 +198,47 @@ Tk_GetCursor(interp, tkwin, string)
*
* TkcGetCursor --
*
- * 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.
+ * 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.
+ * 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
+ * For each call to this function, 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 *
-TkcGetCursor(interp, tkwin, string)
- Tcl_Interp *interp; /* Interpreter to use for error reporting. */
- Tk_Window tkwin; /* Window in which cursor will be used. */
- CONST char *string; /* Description of cursor. See manual entry
- * for details on legal syntax. */
+TkcGetCursor(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ Tk_Window tkwin, /* Window in which cursor will be used. */
+ CONST char *string) /* Description of cursor. See manual entry for
+ * details on legal syntax. */
{
Tcl_HashEntry *nameHashPtr;
register TkCursor *cursorPtr;
TkCursor *existingCursorPtr = NULL;
- int new;
+ int isNew;
TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
if (!dispPtr->cursorInit) {
CursorInit(dispPtr);
}
- nameHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorNameTable,
- string, &new);
- if (!new) {
+ nameHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorNameTable,
+ string, &isNew);
+ if (!isNew) {
existingCursorPtr = (TkCursor *) Tcl_GetHashValue(nameHashPtr);
for (cursorPtr = existingCursorPtr; cursorPtr != NULL;
cursorPtr = cursorPtr->nextPtr) {
@@ -259,7 +254,7 @@ TkcGetCursor(interp, tkwin, string)
cursorPtr = TkGetCursorByName(interp, tkwin, string);
if (cursorPtr == NULL) {
- if (new) {
+ if (isNew) {
Tcl_DeleteHashEntry(nameHashPtr);
}
return NULL;
@@ -275,10 +270,10 @@ TkcGetCursor(interp, tkwin, string)
cursorPtr->otherTable = &dispPtr->cursorNameTable;
cursorPtr->hashPtr = nameHashPtr;
cursorPtr->nextPtr = existingCursorPtr;
- cursorPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorIdTable,
- (char *) cursorPtr->cursor, &new);
- if (!new) {
- panic("cursor already registered in Tk_GetCursor");
+ cursorPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorIdTable,
+ (char *) cursorPtr->cursor, &isNew);
+ if (!isNew) {
+ Tcl_Panic("cursor already registered in Tk_GetCursor");
}
Tcl_SetHashValue(nameHashPtr, cursorPtr);
Tcl_SetHashValue(cursorPtr->idHashPtr, cursorPtr);
@@ -291,46 +286,43 @@ TkcGetCursor(interp, tkwin, string)
*
* Tk_GetCursorFromData --
*
- * Given a description of the bits and colors for a cursor,
- * make a cursor that has the given properties.
+ * Given a description of the bits and colors for a cursor, make a cursor
+ * that has the given properties.
*
* 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 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.
+ * 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 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
+ * For each call to this function, there should eventually be a call to
+ * Tk_FreeCursor, so that the database can be cleaned up when cursors
* aren't needed anymore.
*
*----------------------------------------------------------------------
*/
Tk_Cursor
-Tk_GetCursorFromData(interp, tkwin, source, mask, width, height,
- xHot, yHot, fg, bg)
- Tcl_Interp *interp; /* Interpreter to use for error reporting. */
- Tk_Window tkwin; /* Window in which cursor will be used. */
- CONST char *source; /* Bitmap data for cursor shape. */
- CONST char *mask; /* Bitmap data for cursor mask. */
- int width, height; /* Dimensions of cursor. */
- int xHot, yHot; /* Location of hot-spot in cursor. */
- Tk_Uid fg; /* Foreground color for cursor. */
- Tk_Uid bg; /* Background color for cursor. */
+Tk_GetCursorFromData(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ Tk_Window tkwin, /* Window in which cursor will be used. */
+ CONST char *source, /* Bitmap data for cursor shape. */
+ CONST char *mask, /* Bitmap data for cursor mask. */
+ int width, int height, /* Dimensions of cursor. */
+ int xHot, int yHot, /* Location of hot-spot in cursor. */
+ Tk_Uid fg, /* Foreground color for cursor. */
+ Tk_Uid bg) /* Background color for cursor. */
{
DataKey dataKey;
Tcl_HashEntry *dataHashPtr;
register TkCursor *cursorPtr;
- int new;
+ int isNew;
XColor fgColor, bgColor;
TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
-
if (!dispPtr->cursorInit) {
CursorInit(dispPtr);
}
@@ -344,27 +336,25 @@ Tk_GetCursorFromData(interp, tkwin, source, mask, width, height,
dataKey.fg = fg;
dataKey.bg = bg;
dataKey.display = Tk_Display(tkwin);
- dataHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorDataTable,
- (char *) &dataKey, &new);
- if (!new) {
+ dataHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorDataTable,
+ (char *) &dataKey, &isNew);
+ if (!isNew) {
cursorPtr = (TkCursor *) Tcl_GetHashValue(dataHashPtr);
cursorPtr->resourceRefCount++;
return cursorPtr->cursor;
}
/*
- * No suitable cursor exists yet. Make one using the data
- * available and add it to the database.
+ * No suitable cursor exists yet. Make one using the data available and
+ * add it to the database.
*/
if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), fg, &fgColor) == 0) {
- Tcl_AppendResult(interp, "invalid color name \"", fg, "\"",
- (char *) NULL);
+ Tcl_AppendResult(interp, "invalid color name \"", fg, "\"", NULL);
goto error;
}
if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), bg, &bgColor) == 0) {
- Tcl_AppendResult(interp, "invalid color name \"", bg, "\"",
- (char *) NULL);
+ Tcl_AppendResult(interp, "invalid color name \"", bg, "\"", NULL);
goto error;
}
@@ -379,18 +369,18 @@ Tk_GetCursorFromData(interp, tkwin, source, mask, width, height,
cursorPtr->otherTable = &dispPtr->cursorDataTable;
cursorPtr->hashPtr = dataHashPtr;
cursorPtr->objRefCount = 0;
- cursorPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorIdTable,
- (char *) cursorPtr->cursor, &new);
+ cursorPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorIdTable,
+ (char *) cursorPtr->cursor, &isNew);
cursorPtr->nextPtr = NULL;
- if (!new) {
- panic("cursor already registered in Tk_GetCursorFromData");
+ if (!isNew) {
+ Tcl_Panic("cursor already registered in Tk_GetCursorFromData");
}
Tcl_SetHashValue(dataHashPtr, cursorPtr);
Tcl_SetHashValue(cursorPtr->idHashPtr, cursorPtr);
return cursorPtr->cursor;
- error:
+ error:
Tcl_DeleteHashEntry(dataHashPtr);
return None;
}
@@ -403,12 +393,11 @@ Tk_GetCursorFromData(interp, tkwin, source, mask, width, height,
* Given a cursor, return a textual string identifying it.
*
* Results:
- * If cursor was created by Tk_GetCursor, then the return
- * value is the "string" that was used to create it.
- * Otherwise the return value is a string giving the X
- * identifier for the cursor. The storage for the returned
- * string is only guaranteed to persist up until the next
- * call to this procedure.
+ * If cursor was created by Tk_GetCursor, then the return value is the
+ * "string" that was used to create it. Otherwise the return value is a
+ * string giving the X identifier for the cursor. The storage for the
+ * returned string is only guaranteed to persist up until the next call
+ * to this function.
*
* Side effects:
* None.
@@ -417,9 +406,9 @@ Tk_GetCursorFromData(interp, tkwin, source, mask, width, height,
*/
CONST char *
-Tk_NameOfCursor(display, cursor)
- Display *display; /* Display for which cursor was allocated. */
- Tk_Cursor cursor; /* Identifier for cursor whose name is
+Tk_NameOfCursor(
+ Display *display, /* Display for which cursor was allocated. */
+ Tk_Cursor cursor) /* Identifier for cursor whose name is
* wanted. */
{
Tcl_HashEntry *idHashPtr;
@@ -429,9 +418,8 @@ Tk_NameOfCursor(display, cursor)
dispPtr = TkGetDisplay(display);
if (!dispPtr->cursorInit) {
- printid:
- sprintf(dispPtr->cursorString, "cursor id 0x%x",
- (unsigned int) cursor);
+ printid:
+ sprintf(dispPtr->cursorString, "cursor id %p", cursor);
return dispPtr->cursorString;
}
idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, (char *) cursor);
@@ -450,23 +438,22 @@ Tk_NameOfCursor(display, cursor)
*
* FreeCursor --
*
- * This procedure is invoked by both Tk_FreeCursor and
- * Tk_FreeCursorFromObj; it does all the real work of deallocating
- * a cursor.
+ * This function is invoked by both Tk_FreeCursorFromObj and
+ * Tk_FreeCursor; 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.
+ * 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. */
+FreeCursor(
+ TkCursor *cursorPtr) /* Cursor to be released. */
{
TkCursor *prevPtr;
@@ -500,34 +487,34 @@ FreeCursor(cursorPtr)
*
* Tk_FreeCursor --
*
- * This procedure is called to release a cursor allocated by
- * Tk_GetCursor or TkGetCursorFromData.
+ * This function is called to release a cursor allocated by Tk_GetCursor
+ * or TkGetCursorFromData.
*
* Results:
* None.
*
* Side effects:
- * The reference count associated with cursor is decremented, and
- * it is officially deallocated if no-one is using it anymore.
+ * The reference count associated with cursor is decremented, and it is
+ * officially deallocated if no-one is using it anymore.
*
*----------------------------------------------------------------------
*/
void
-Tk_FreeCursor(display, cursor)
- Display *display; /* Display for which cursor was allocated. */
- Tk_Cursor cursor; /* Identifier for cursor to be released. */
+Tk_FreeCursor(
+ Display *display, /* Display for which cursor was allocated. */
+ Tk_Cursor cursor) /* Identifier for cursor to be released. */
{
Tcl_HashEntry *idHashPtr;
TkDisplay *dispPtr = TkGetDisplay(display);
if (!dispPtr->cursorInit) {
- panic("Tk_FreeCursor called before Tk_GetCursor");
+ Tcl_Panic("Tk_FreeCursor called before Tk_GetCursor");
}
idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, (char *) cursor);
if (idHashPtr == NULL) {
- panic("Tk_FreeCursor received unknown cursor argument");
+ Tcl_Panic("Tk_FreeCursor received unknown cursor argument");
}
FreeCursor((TkCursor *) Tcl_GetHashValue(idHashPtr));
}
@@ -537,27 +524,27 @@ Tk_FreeCursor(display, cursor)
*
* 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.
+ * This function 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.
+ * 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. */
+Tk_FreeCursorFromObj(
+ 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));
FreeCursorObjProc(objPtr);
@@ -566,66 +553,65 @@ Tk_FreeCursorFromObj(tkwin, objPtr)
/*
*---------------------------------------------------------------------------
*
- * FreeCursorFromObjProc --
+ * 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.
+ * 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.
+ * 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. */
+FreeCursorObjProc(
+ Tcl_Obj *objPtr) /* The object we are releasing. */
{
TkCursor *cursorPtr = (TkCursor *) objPtr->internalRep.twoPtrValue.ptr1;
if (cursorPtr != NULL) {
cursorPtr->objRefCount--;
- if ((cursorPtr->objRefCount == 0)
+ if ((cursorPtr->objRefCount == 0)
&& (cursorPtr->resourceRefCount == 0)) {
ckfree((char *) cursorPtr);
}
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
+ objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}
}
/*
*---------------------------------------------------------------------------
*
- * DupCursorObjProc --
+ * DupCursorObjProc --
*
- * When a cached cursor object is duplicated, this is called to
- * update the internal reps.
+ * 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.
+ * 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. */
+DupCursorObjProc(
+ 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;
+ dupObjPtr->internalRep.twoPtrValue.ptr1 = (void *) cursorPtr;
if (cursorPtr != NULL) {
cursorPtr->objRefCount++;
@@ -638,27 +624,31 @@ DupCursorObjProc(srcObjPtr, dupObjPtr)
* 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
+ * 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.
+ * 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.
+ * 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. */
+Tk_GetCursorFromObj(
+ Tk_Window tkwin,
+ Tcl_Obj *objPtr) /* The object from which to get pixels. */
{
TkCursor *cursorPtr = GetCursorFromObj(tkwin, objPtr);
- /* GetCursorFromObj should never return NULL */
+
+ /*
+ * GetCursorFromObj should never return NULL
+ */
+
return cursorPtr->cursor;
}
@@ -667,25 +657,25 @@ Tk_GetCursorFromObj(tkwin, objPtr)
*
* 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.
+ * 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.
+ * 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.
+ * 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
+GetCursorFromObj(
+ Tk_Window tkwin, /* Window in which the cursor will be used. */
+ Tcl_Obj *objPtr) /* The object that describes the desired
* cursor. */
{
TkCursor *cursorPtr;
@@ -697,11 +687,12 @@ GetCursorFromObj(tkwin, objPtr)
}
/*
- * The internal representation is a cache of the last cursor used
- * with the given name. But there can be lots different cursors
- * for each cursor name; one cursor for each display. Check to
- * see if the cursor we have cached is the one that is needed.
+ * The internal representation is a cache of the last cursor used with the
+ * given name. But there can be lots different cursors for each cursor
+ * name; one cursor for each display. Check to see if the cursor we have
+ * cached is the one that is needed.
*/
+
cursorPtr = (TkCursor *) objPtr->internalRep.twoPtrValue.ptr1;
if ((cursorPtr != NULL) && (Tk_Display(tkwin) == cursorPtr->display)) {
return cursorPtr;
@@ -721,14 +712,14 @@ GetCursorFromObj(tkwin, objPtr)
cursorPtr != NULL; cursorPtr = cursorPtr->nextPtr) {
if (Tk_Display(tkwin) == cursorPtr->display) {
FreeCursorObjProc(objPtr);
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) cursorPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) cursorPtr;
cursorPtr->objRefCount++;
return cursorPtr;
}
}
- error:
- panic("GetCursorFromObj called with non-existent cursor!");
+ error:
+ Tcl_Panic("GetCursorFromObj called with non-existent cursor!");
/*
* The following code isn't reached; it's just there to please compilers.
*/
@@ -740,27 +731,27 @@ GetCursorFromObj(tkwin, objPtr)
*
* InitCursorObj --
*
- * Bookeeping procedure to change an objPtr to a cursor type.
+ * Bookeeping function 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.
+ * 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. */
+InitCursorObj(
+ Tcl_Obj *objPtr) /* The object to convert. */
{
- Tcl_ObjType *typePtr;
+ const Tcl_ObjType *typePtr;
/*
- * Free the old internalRep before setting the new one.
+ * Free the old internalRep before setting the new one.
*/
Tcl_GetString(objPtr);
@@ -769,7 +760,7 @@ InitCursorObj(objPtr)
(*typePtr->freeIntRepProc)(objPtr);
}
objPtr->typePtr = &tkCursorObjType;
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
+ objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}
/*
@@ -789,26 +780,26 @@ InitCursorObj(objPtr)
*/
static void
-CursorInit(dispPtr)
- TkDisplay *dispPtr; /* Display used to store thread-specific data. */
+CursorInit(
+ TkDisplay *dispPtr) /* Display used to store thread-specific
+ * data. */
{
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
- * gets padded with extra unpredictable bytes on some 64-bit
- * machines.
+ * The call below is tricky: can't use sizeof(IdKey) because it gets
+ * padded with extra unpredictable bytes on some 64-bit machines.
*/
- /*
- * Old code....
- * Tcl_InitHashTable(&dispPtr->cursorIdTable, sizeof(Display *)
+ /*
+ * 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:
+ * 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);
@@ -821,13 +812,13 @@ CursorInit(dispPtr)
*
* TkDebugCursor --
*
- * This procedure returns debugging information about a cursor.
+ * This function 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.
+ * corresponding to "name". Each sublist has two elements that contain
+ * the resourceRefCount and objRefCount fields from the TkCursor
+ * structure.
*
* Side effects:
* None.
@@ -836,10 +827,10 @@ CursorInit(dispPtr)
*/
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. */
+TkDebugCursor(
+ 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;
@@ -854,16 +845,24 @@ TkDebugCursor(tkwin, name)
if (hashPtr != NULL) {
cursorPtr = (TkCursor *) Tcl_GetHashValue(hashPtr);
if (cursorPtr == NULL) {
- panic("TkDebugCursor found empty hash table entry");
+ Tcl_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_NewIntObj(cursorPtr->objRefCount));
Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
}
}
return resultPtr;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkDecls.h b/generic/tkDecls.h
index 81871a2..d06df4b 100644
--- a/generic/tkDecls.h
+++ b/generic/tkDecls.h
@@ -29,882 +29,1651 @@
* Exported function declarations:
*/
+#ifndef Tk_MainLoop_TCL_DECLARED
+#define Tk_MainLoop_TCL_DECLARED
/* 0 */
-EXTERN void Tk_MainLoop _ANSI_ARGS_((void));
+EXTERN void Tk_MainLoop(void);
+#endif
+#ifndef Tk_3DBorderColor_TCL_DECLARED
+#define Tk_3DBorderColor_TCL_DECLARED
/* 1 */
-EXTERN XColor * Tk_3DBorderColor _ANSI_ARGS_((Tk_3DBorder border));
+EXTERN XColor * Tk_3DBorderColor(Tk_3DBorder border);
+#endif
+#ifndef Tk_3DBorderGC_TCL_DECLARED
+#define Tk_3DBorderGC_TCL_DECLARED
/* 2 */
-EXTERN GC Tk_3DBorderGC _ANSI_ARGS_((Tk_Window tkwin,
- Tk_3DBorder border, int which));
+EXTERN GC Tk_3DBorderGC(Tk_Window tkwin, Tk_3DBorder border,
+ int which);
+#endif
+#ifndef Tk_3DHorizontalBevel_TCL_DECLARED
+#define Tk_3DHorizontalBevel_TCL_DECLARED
/* 3 */
-EXTERN void Tk_3DHorizontalBevel _ANSI_ARGS_((Tk_Window tkwin,
+EXTERN void Tk_3DHorizontalBevel(Tk_Window tkwin,
Drawable drawable, Tk_3DBorder border, int x,
int y, int width, int height, int leftIn,
- int rightIn, int topBevel, int relief));
+ int rightIn, int topBevel, int relief);
+#endif
+#ifndef Tk_3DVerticalBevel_TCL_DECLARED
+#define Tk_3DVerticalBevel_TCL_DECLARED
/* 4 */
-EXTERN void Tk_3DVerticalBevel _ANSI_ARGS_((Tk_Window tkwin,
+EXTERN void Tk_3DVerticalBevel(Tk_Window tkwin,
Drawable drawable, Tk_3DBorder border, int x,
int y, int width, int height, int leftBevel,
- int relief));
+ int relief);
+#endif
+#ifndef Tk_AddOption_TCL_DECLARED
+#define Tk_AddOption_TCL_DECLARED
/* 5 */
-EXTERN void Tk_AddOption _ANSI_ARGS_((Tk_Window tkwin,
- CONST char *name, CONST char *value,
- int priority));
+EXTERN void Tk_AddOption(Tk_Window tkwin, CONST char *name,
+ CONST char *value, int priority);
+#endif
+#ifndef Tk_BindEvent_TCL_DECLARED
+#define Tk_BindEvent_TCL_DECLARED
/* 6 */
-EXTERN void Tk_BindEvent _ANSI_ARGS_((
- Tk_BindingTable bindingTable,
+EXTERN void Tk_BindEvent(Tk_BindingTable bindingTable,
XEvent *eventPtr, Tk_Window tkwin,
- int numObjects, ClientData *objectPtr));
+ int numObjects, ClientData *objectPtr);
+#endif
+#ifndef Tk_CanvasDrawableCoords_TCL_DECLARED
+#define Tk_CanvasDrawableCoords_TCL_DECLARED
/* 7 */
-EXTERN void Tk_CanvasDrawableCoords _ANSI_ARGS_((
- Tk_Canvas canvas, double x, double y,
- short *drawableXPtr, short *drawableYPtr));
+EXTERN void Tk_CanvasDrawableCoords(Tk_Canvas canvas, double x,
+ double y, short *drawableXPtr,
+ short *drawableYPtr);
+#endif
+#ifndef Tk_CanvasEventuallyRedraw_TCL_DECLARED
+#define Tk_CanvasEventuallyRedraw_TCL_DECLARED
/* 8 */
-EXTERN void Tk_CanvasEventuallyRedraw _ANSI_ARGS_((
- Tk_Canvas canvas, int x1, int y1, int x2,
- int y2));
+EXTERN void Tk_CanvasEventuallyRedraw(Tk_Canvas canvas, int x1,
+ int y1, int x2, int y2);
+#endif
+#ifndef Tk_CanvasGetCoord_TCL_DECLARED
+#define Tk_CanvasGetCoord_TCL_DECLARED
/* 9 */
-EXTERN int Tk_CanvasGetCoord _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN int Tk_CanvasGetCoord(Tcl_Interp *interp,
Tk_Canvas canvas, CONST char *str,
- double *doublePtr));
+ double *doublePtr);
+#endif
+#ifndef Tk_CanvasGetTextInfo_TCL_DECLARED
+#define Tk_CanvasGetTextInfo_TCL_DECLARED
/* 10 */
-EXTERN Tk_CanvasTextInfo * Tk_CanvasGetTextInfo _ANSI_ARGS_((
- Tk_Canvas canvas));
+EXTERN Tk_CanvasTextInfo * Tk_CanvasGetTextInfo(Tk_Canvas canvas);
+#endif
+#ifndef Tk_CanvasPsBitmap_TCL_DECLARED
+#define Tk_CanvasPsBitmap_TCL_DECLARED
/* 11 */
-EXTERN int Tk_CanvasPsBitmap _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN int Tk_CanvasPsBitmap(Tcl_Interp *interp,
Tk_Canvas canvas, Pixmap bitmap, int x,
- int y, int width, int height));
+ int y, int width, int height);
+#endif
+#ifndef Tk_CanvasPsColor_TCL_DECLARED
+#define Tk_CanvasPsColor_TCL_DECLARED
/* 12 */
-EXTERN int Tk_CanvasPsColor _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, XColor *colorPtr));
+EXTERN int Tk_CanvasPsColor(Tcl_Interp *interp,
+ Tk_Canvas canvas, XColor *colorPtr);
+#endif
+#ifndef Tk_CanvasPsFont_TCL_DECLARED
+#define Tk_CanvasPsFont_TCL_DECLARED
/* 13 */
-EXTERN int Tk_CanvasPsFont _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, Tk_Font font));
+EXTERN int Tk_CanvasPsFont(Tcl_Interp *interp, Tk_Canvas canvas,
+ Tk_Font font);
+#endif
+#ifndef Tk_CanvasPsPath_TCL_DECLARED
+#define Tk_CanvasPsPath_TCL_DECLARED
/* 14 */
-EXTERN void Tk_CanvasPsPath _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, double *coordPtr,
- int numPoints));
+EXTERN void Tk_CanvasPsPath(Tcl_Interp *interp, Tk_Canvas canvas,
+ double *coordPtr, int numPoints);
+#endif
+#ifndef Tk_CanvasPsStipple_TCL_DECLARED
+#define Tk_CanvasPsStipple_TCL_DECLARED
/* 15 */
-EXTERN int Tk_CanvasPsStipple _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, Pixmap bitmap));
+EXTERN int Tk_CanvasPsStipple(Tcl_Interp *interp,
+ Tk_Canvas canvas, Pixmap bitmap);
+#endif
+#ifndef Tk_CanvasPsY_TCL_DECLARED
+#define Tk_CanvasPsY_TCL_DECLARED
/* 16 */
-EXTERN double Tk_CanvasPsY _ANSI_ARGS_((Tk_Canvas canvas, double y));
+EXTERN double Tk_CanvasPsY(Tk_Canvas canvas, double y);
+#endif
+#ifndef Tk_CanvasSetStippleOrigin_TCL_DECLARED
+#define Tk_CanvasSetStippleOrigin_TCL_DECLARED
/* 17 */
-EXTERN void Tk_CanvasSetStippleOrigin _ANSI_ARGS_((
- Tk_Canvas canvas, GC gc));
+EXTERN void Tk_CanvasSetStippleOrigin(Tk_Canvas canvas, GC gc);
+#endif
+#ifndef Tk_CanvasTagsParseProc_TCL_DECLARED
+#define Tk_CanvasTagsParseProc_TCL_DECLARED
/* 18 */
-EXTERN int Tk_CanvasTagsParseProc _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *value,
- char *widgRec, int offset));
+EXTERN int Tk_CanvasTagsParseProc(ClientData clientData,
+ Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *value, char *widgRec, int offset);
+#endif
+#ifndef Tk_CanvasTagsPrintProc_TCL_DECLARED
+#define Tk_CanvasTagsPrintProc_TCL_DECLARED
/* 19 */
-EXTERN char * Tk_CanvasTagsPrintProc _ANSI_ARGS_((
- ClientData clientData, Tk_Window tkwin,
- char *widgRec, int offset,
- Tcl_FreeProc **freeProcPtr));
+EXTERN char * Tk_CanvasTagsPrintProc(ClientData clientData,
+ Tk_Window tkwin, char *widgRec, int offset,
+ Tcl_FreeProc **freeProcPtr);
+#endif
+#ifndef Tk_CanvasTkwin_TCL_DECLARED
+#define Tk_CanvasTkwin_TCL_DECLARED
/* 20 */
-EXTERN Tk_Window Tk_CanvasTkwin _ANSI_ARGS_((Tk_Canvas canvas));
+EXTERN Tk_Window Tk_CanvasTkwin(Tk_Canvas canvas);
+#endif
+#ifndef Tk_CanvasWindowCoords_TCL_DECLARED
+#define Tk_CanvasWindowCoords_TCL_DECLARED
/* 21 */
-EXTERN void Tk_CanvasWindowCoords _ANSI_ARGS_((Tk_Canvas canvas,
- double x, double y, short *screenXPtr,
- short *screenYPtr));
+EXTERN void Tk_CanvasWindowCoords(Tk_Canvas canvas, double x,
+ double y, short *screenXPtr,
+ short *screenYPtr);
+#endif
+#ifndef Tk_ChangeWindowAttributes_TCL_DECLARED
+#define Tk_ChangeWindowAttributes_TCL_DECLARED
/* 22 */
-EXTERN void Tk_ChangeWindowAttributes _ANSI_ARGS_((
- Tk_Window tkwin, unsigned long valueMask,
- XSetWindowAttributes *attsPtr));
+EXTERN void Tk_ChangeWindowAttributes(Tk_Window tkwin,
+ unsigned long valueMask,
+ XSetWindowAttributes *attsPtr);
+#endif
+#ifndef Tk_CharBbox_TCL_DECLARED
+#define Tk_CharBbox_TCL_DECLARED
/* 23 */
-EXTERN int Tk_CharBbox _ANSI_ARGS_((Tk_TextLayout layout,
- int index, int *xPtr, int *yPtr,
- int *widthPtr, int *heightPtr));
+EXTERN int Tk_CharBbox(Tk_TextLayout layout, int index,
+ int *xPtr, int *yPtr, int *widthPtr,
+ int *heightPtr);
+#endif
+#ifndef Tk_ClearSelection_TCL_DECLARED
+#define Tk_ClearSelection_TCL_DECLARED
/* 24 */
-EXTERN void Tk_ClearSelection _ANSI_ARGS_((Tk_Window tkwin,
- Atom selection));
+EXTERN void Tk_ClearSelection(Tk_Window tkwin, Atom selection);
+#endif
+#ifndef Tk_ClipboardAppend_TCL_DECLARED
+#define Tk_ClipboardAppend_TCL_DECLARED
/* 25 */
-EXTERN int Tk_ClipboardAppend _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN int Tk_ClipboardAppend(Tcl_Interp *interp,
Tk_Window tkwin, Atom target, Atom format,
- char *buffer));
+ char *buffer);
+#endif
+#ifndef Tk_ClipboardClear_TCL_DECLARED
+#define Tk_ClipboardClear_TCL_DECLARED
/* 26 */
-EXTERN int Tk_ClipboardClear _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin));
+EXTERN int Tk_ClipboardClear(Tcl_Interp *interp,
+ Tk_Window tkwin);
+#endif
+#ifndef Tk_ConfigureInfo_TCL_DECLARED
+#define Tk_ConfigureInfo_TCL_DECLARED
/* 27 */
-EXTERN int Tk_ConfigureInfo _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, Tk_ConfigSpec *specs,
- char *widgRec, CONST char *argvName,
- int flags));
+EXTERN int Tk_ConfigureInfo(Tcl_Interp *interp, Tk_Window tkwin,
+ Tk_ConfigSpec *specs, char *widgRec,
+ CONST char *argvName, int flags);
+#endif
+#ifndef Tk_ConfigureValue_TCL_DECLARED
+#define Tk_ConfigureValue_TCL_DECLARED
/* 28 */
-EXTERN int Tk_ConfigureValue _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN int Tk_ConfigureValue(Tcl_Interp *interp,
Tk_Window tkwin, Tk_ConfigSpec *specs,
char *widgRec, CONST char *argvName,
- int flags));
+ int flags);
+#endif
+#ifndef Tk_ConfigureWidget_TCL_DECLARED
+#define Tk_ConfigureWidget_TCL_DECLARED
/* 29 */
-EXTERN int Tk_ConfigureWidget _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN int Tk_ConfigureWidget(Tcl_Interp *interp,
Tk_Window tkwin, Tk_ConfigSpec *specs,
int argc, CONST84 char **argv, char *widgRec,
- int flags));
+ int flags);
+#endif
+#ifndef Tk_ConfigureWindow_TCL_DECLARED
+#define Tk_ConfigureWindow_TCL_DECLARED
/* 30 */
-EXTERN void Tk_ConfigureWindow _ANSI_ARGS_((Tk_Window tkwin,
+EXTERN void Tk_ConfigureWindow(Tk_Window tkwin,
unsigned int valueMask,
- XWindowChanges *valuePtr));
+ XWindowChanges *valuePtr);
+#endif
+#ifndef Tk_ComputeTextLayout_TCL_DECLARED
+#define Tk_ComputeTextLayout_TCL_DECLARED
/* 31 */
-EXTERN 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));
+EXTERN Tk_TextLayout Tk_ComputeTextLayout(Tk_Font font, CONST char *str,
+ int numChars, int wrapLength,
+ Tk_Justify justify, int flags, int *widthPtr,
+ int *heightPtr);
+#endif
+#ifndef Tk_CoordsToWindow_TCL_DECLARED
+#define Tk_CoordsToWindow_TCL_DECLARED
/* 32 */
-EXTERN Tk_Window Tk_CoordsToWindow _ANSI_ARGS_((int rootX, int rootY,
- Tk_Window tkwin));
+EXTERN Tk_Window Tk_CoordsToWindow(int rootX, int rootY,
+ Tk_Window tkwin);
+#endif
+#ifndef Tk_CreateBinding_TCL_DECLARED
+#define Tk_CreateBinding_TCL_DECLARED
/* 33 */
-EXTERN unsigned long Tk_CreateBinding _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN unsigned long Tk_CreateBinding(Tcl_Interp *interp,
Tk_BindingTable bindingTable,
ClientData object, CONST char *eventStr,
- CONST char *script, int append));
+ CONST char *command, int append);
+#endif
+#ifndef Tk_CreateBindingTable_TCL_DECLARED
+#define Tk_CreateBindingTable_TCL_DECLARED
/* 34 */
-EXTERN Tk_BindingTable Tk_CreateBindingTable _ANSI_ARGS_((
- Tcl_Interp *interp));
+EXTERN Tk_BindingTable Tk_CreateBindingTable(Tcl_Interp *interp);
+#endif
+#ifndef Tk_CreateErrorHandler_TCL_DECLARED
+#define Tk_CreateErrorHandler_TCL_DECLARED
/* 35 */
-EXTERN Tk_ErrorHandler Tk_CreateErrorHandler _ANSI_ARGS_((Display *display,
- int errNum, int request, int minorCode,
+EXTERN Tk_ErrorHandler Tk_CreateErrorHandler(Display *display, int errNum,
+ int request, int minorCode,
Tk_ErrorProc *errorProc,
- ClientData clientData));
+ ClientData clientData);
+#endif
+#ifndef Tk_CreateEventHandler_TCL_DECLARED
+#define Tk_CreateEventHandler_TCL_DECLARED
/* 36 */
-EXTERN void Tk_CreateEventHandler _ANSI_ARGS_((Tk_Window token,
+EXTERN void Tk_CreateEventHandler(Tk_Window token,
unsigned long mask, Tk_EventProc *proc,
- ClientData clientData));
+ ClientData clientData);
+#endif
+#ifndef Tk_CreateGenericHandler_TCL_DECLARED
+#define Tk_CreateGenericHandler_TCL_DECLARED
/* 37 */
-EXTERN void Tk_CreateGenericHandler _ANSI_ARGS_((
- Tk_GenericProc *proc, ClientData clientData));
+EXTERN void Tk_CreateGenericHandler(Tk_GenericProc *proc,
+ ClientData clientData);
+#endif
+#ifndef Tk_CreateImageType_TCL_DECLARED
+#define Tk_CreateImageType_TCL_DECLARED
/* 38 */
-EXTERN void Tk_CreateImageType _ANSI_ARGS_((
- Tk_ImageType *typePtr));
+EXTERN void Tk_CreateImageType(Tk_ImageType *typePtr);
+#endif
+#ifndef Tk_CreateItemType_TCL_DECLARED
+#define Tk_CreateItemType_TCL_DECLARED
/* 39 */
-EXTERN void Tk_CreateItemType _ANSI_ARGS_((Tk_ItemType *typePtr));
+EXTERN void Tk_CreateItemType(Tk_ItemType *typePtr);
+#endif
+#ifndef Tk_CreatePhotoImageFormat_TCL_DECLARED
+#define Tk_CreatePhotoImageFormat_TCL_DECLARED
/* 40 */
-EXTERN void Tk_CreatePhotoImageFormat _ANSI_ARGS_((
- Tk_PhotoImageFormat *formatPtr));
+EXTERN void Tk_CreatePhotoImageFormat(
+ Tk_PhotoImageFormat *formatPtr);
+#endif
+#ifndef Tk_CreateSelHandler_TCL_DECLARED
+#define Tk_CreateSelHandler_TCL_DECLARED
/* 41 */
-EXTERN void Tk_CreateSelHandler _ANSI_ARGS_((Tk_Window tkwin,
- Atom selection, Atom target,
- Tk_SelectionProc *proc,
- ClientData clientData, Atom format));
+EXTERN void Tk_CreateSelHandler(Tk_Window tkwin, Atom selection,
+ Atom target, Tk_SelectionProc *proc,
+ ClientData clientData, Atom format);
+#endif
+#ifndef Tk_CreateWindow_TCL_DECLARED
+#define Tk_CreateWindow_TCL_DECLARED
/* 42 */
-EXTERN Tk_Window Tk_CreateWindow _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window parent, CONST char *name,
- CONST char *screenName));
+EXTERN Tk_Window Tk_CreateWindow(Tcl_Interp *interp, Tk_Window parent,
+ CONST char *name, CONST char *screenName);
+#endif
+#ifndef Tk_CreateWindowFromPath_TCL_DECLARED
+#define Tk_CreateWindowFromPath_TCL_DECLARED
/* 43 */
-EXTERN Tk_Window Tk_CreateWindowFromPath _ANSI_ARGS_((
- Tcl_Interp *interp, Tk_Window tkwin,
- CONST char *pathName, CONST char *screenName));
+EXTERN Tk_Window Tk_CreateWindowFromPath(Tcl_Interp *interp,
+ Tk_Window tkwin, CONST char *pathName,
+ CONST char *screenName);
+#endif
+#ifndef Tk_DefineBitmap_TCL_DECLARED
+#define Tk_DefineBitmap_TCL_DECLARED
/* 44 */
-EXTERN int Tk_DefineBitmap _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *name, CONST char *source,
- int width, int height));
+EXTERN int Tk_DefineBitmap(Tcl_Interp *interp, CONST char *name,
+ CONST char *source, int width, int height);
+#endif
+#ifndef Tk_DefineCursor_TCL_DECLARED
+#define Tk_DefineCursor_TCL_DECLARED
/* 45 */
-EXTERN void Tk_DefineCursor _ANSI_ARGS_((Tk_Window window,
- Tk_Cursor cursor));
+EXTERN void Tk_DefineCursor(Tk_Window window, Tk_Cursor cursor);
+#endif
+#ifndef Tk_DeleteAllBindings_TCL_DECLARED
+#define Tk_DeleteAllBindings_TCL_DECLARED
/* 46 */
-EXTERN void Tk_DeleteAllBindings _ANSI_ARGS_((
- Tk_BindingTable bindingTable,
- ClientData object));
+EXTERN void Tk_DeleteAllBindings(Tk_BindingTable bindingTable,
+ ClientData object);
+#endif
+#ifndef Tk_DeleteBinding_TCL_DECLARED
+#define Tk_DeleteBinding_TCL_DECLARED
/* 47 */
-EXTERN int Tk_DeleteBinding _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN int Tk_DeleteBinding(Tcl_Interp *interp,
Tk_BindingTable bindingTable,
- ClientData object, CONST char *eventStr));
+ ClientData object, CONST char *eventStr);
+#endif
+#ifndef Tk_DeleteBindingTable_TCL_DECLARED
+#define Tk_DeleteBindingTable_TCL_DECLARED
/* 48 */
-EXTERN void Tk_DeleteBindingTable _ANSI_ARGS_((
- Tk_BindingTable bindingTable));
+EXTERN void Tk_DeleteBindingTable(Tk_BindingTable bindingTable);
+#endif
+#ifndef Tk_DeleteErrorHandler_TCL_DECLARED
+#define Tk_DeleteErrorHandler_TCL_DECLARED
/* 49 */
-EXTERN void Tk_DeleteErrorHandler _ANSI_ARGS_((
- Tk_ErrorHandler handler));
+EXTERN void Tk_DeleteErrorHandler(Tk_ErrorHandler handler);
+#endif
+#ifndef Tk_DeleteEventHandler_TCL_DECLARED
+#define Tk_DeleteEventHandler_TCL_DECLARED
/* 50 */
-EXTERN void Tk_DeleteEventHandler _ANSI_ARGS_((Tk_Window token,
+EXTERN void Tk_DeleteEventHandler(Tk_Window token,
unsigned long mask, Tk_EventProc *proc,
- ClientData clientData));
+ ClientData clientData);
+#endif
+#ifndef Tk_DeleteGenericHandler_TCL_DECLARED
+#define Tk_DeleteGenericHandler_TCL_DECLARED
/* 51 */
-EXTERN void Tk_DeleteGenericHandler _ANSI_ARGS_((
- Tk_GenericProc *proc, ClientData clientData));
+EXTERN void Tk_DeleteGenericHandler(Tk_GenericProc *proc,
+ ClientData clientData);
+#endif
+#ifndef Tk_DeleteImage_TCL_DECLARED
+#define Tk_DeleteImage_TCL_DECLARED
/* 52 */
-EXTERN void Tk_DeleteImage _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *name));
+EXTERN void Tk_DeleteImage(Tcl_Interp *interp, CONST char *name);
+#endif
+#ifndef Tk_DeleteSelHandler_TCL_DECLARED
+#define Tk_DeleteSelHandler_TCL_DECLARED
/* 53 */
-EXTERN void Tk_DeleteSelHandler _ANSI_ARGS_((Tk_Window tkwin,
- Atom selection, Atom target));
+EXTERN void Tk_DeleteSelHandler(Tk_Window tkwin, Atom selection,
+ Atom target);
+#endif
+#ifndef Tk_DestroyWindow_TCL_DECLARED
+#define Tk_DestroyWindow_TCL_DECLARED
/* 54 */
-EXTERN void Tk_DestroyWindow _ANSI_ARGS_((Tk_Window tkwin));
+EXTERN void Tk_DestroyWindow(Tk_Window tkwin);
+#endif
+#ifndef Tk_DisplayName_TCL_DECLARED
+#define Tk_DisplayName_TCL_DECLARED
/* 55 */
-EXTERN CONST84_RETURN char * Tk_DisplayName _ANSI_ARGS_((Tk_Window tkwin));
+EXTERN CONST84_RETURN char * Tk_DisplayName(Tk_Window tkwin);
+#endif
+#ifndef Tk_DistanceToTextLayout_TCL_DECLARED
+#define Tk_DistanceToTextLayout_TCL_DECLARED
/* 56 */
-EXTERN int Tk_DistanceToTextLayout _ANSI_ARGS_((
- Tk_TextLayout layout, int x, int y));
+EXTERN int Tk_DistanceToTextLayout(Tk_TextLayout layout, int x,
+ int y);
+#endif
+#ifndef Tk_Draw3DPolygon_TCL_DECLARED
+#define Tk_Draw3DPolygon_TCL_DECLARED
/* 57 */
-EXTERN void Tk_Draw3DPolygon _ANSI_ARGS_((Tk_Window tkwin,
- Drawable drawable, Tk_3DBorder border,
- XPoint *pointPtr, int numPoints,
- int borderWidth, int leftRelief));
+EXTERN void Tk_Draw3DPolygon(Tk_Window tkwin, Drawable drawable,
+ Tk_3DBorder border, XPoint *pointPtr,
+ int numPoints, int borderWidth,
+ int leftRelief);
+#endif
+#ifndef Tk_Draw3DRectangle_TCL_DECLARED
+#define Tk_Draw3DRectangle_TCL_DECLARED
/* 58 */
-EXTERN void Tk_Draw3DRectangle _ANSI_ARGS_((Tk_Window tkwin,
+EXTERN void Tk_Draw3DRectangle(Tk_Window tkwin,
Drawable drawable, Tk_3DBorder border, int x,
int y, int width, int height,
- int borderWidth, int relief));
+ int borderWidth, int relief);
+#endif
+#ifndef Tk_DrawChars_TCL_DECLARED
+#define Tk_DrawChars_TCL_DECLARED
/* 59 */
-EXTERN void Tk_DrawChars _ANSI_ARGS_((Display *display,
- Drawable drawable, GC gc, Tk_Font tkfont,
- CONST char *source, int numBytes, int x,
- int y));
+EXTERN void Tk_DrawChars(Display *display, Drawable drawable,
+ GC gc, Tk_Font tkfont, CONST char *source,
+ int numBytes, int x, int y);
+#endif
+#ifndef Tk_DrawFocusHighlight_TCL_DECLARED
+#define Tk_DrawFocusHighlight_TCL_DECLARED
/* 60 */
-EXTERN void Tk_DrawFocusHighlight _ANSI_ARGS_((Tk_Window tkwin,
- GC gc, int width, Drawable drawable));
+EXTERN void Tk_DrawFocusHighlight(Tk_Window tkwin, GC gc,
+ int width, Drawable drawable);
+#endif
+#ifndef Tk_DrawTextLayout_TCL_DECLARED
+#define Tk_DrawTextLayout_TCL_DECLARED
/* 61 */
-EXTERN void Tk_DrawTextLayout _ANSI_ARGS_((Display *display,
+EXTERN void Tk_DrawTextLayout(Display *display,
Drawable drawable, GC gc,
Tk_TextLayout layout, int x, int y,
- int firstChar, int lastChar));
+ int firstChar, int lastChar);
+#endif
+#ifndef Tk_Fill3DPolygon_TCL_DECLARED
+#define Tk_Fill3DPolygon_TCL_DECLARED
/* 62 */
-EXTERN void Tk_Fill3DPolygon _ANSI_ARGS_((Tk_Window tkwin,
- Drawable drawable, Tk_3DBorder border,
- XPoint *pointPtr, int numPoints,
- int borderWidth, int leftRelief));
+EXTERN void Tk_Fill3DPolygon(Tk_Window tkwin, Drawable drawable,
+ Tk_3DBorder border, XPoint *pointPtr,
+ int numPoints, int borderWidth,
+ int leftRelief);
+#endif
+#ifndef Tk_Fill3DRectangle_TCL_DECLARED
+#define Tk_Fill3DRectangle_TCL_DECLARED
/* 63 */
-EXTERN void Tk_Fill3DRectangle _ANSI_ARGS_((Tk_Window tkwin,
+EXTERN void Tk_Fill3DRectangle(Tk_Window tkwin,
Drawable drawable, Tk_3DBorder border, int x,
int y, int width, int height,
- int borderWidth, int relief));
+ int borderWidth, int relief);
+#endif
+#ifndef Tk_FindPhoto_TCL_DECLARED
+#define Tk_FindPhoto_TCL_DECLARED
/* 64 */
-EXTERN Tk_PhotoHandle Tk_FindPhoto _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *imageName));
+EXTERN Tk_PhotoHandle Tk_FindPhoto(Tcl_Interp *interp,
+ CONST char *imageName);
+#endif
+#ifndef Tk_FontId_TCL_DECLARED
+#define Tk_FontId_TCL_DECLARED
/* 65 */
-EXTERN Font Tk_FontId _ANSI_ARGS_((Tk_Font font));
+EXTERN Font Tk_FontId(Tk_Font font);
+#endif
+#ifndef Tk_Free3DBorder_TCL_DECLARED
+#define Tk_Free3DBorder_TCL_DECLARED
/* 66 */
-EXTERN void Tk_Free3DBorder _ANSI_ARGS_((Tk_3DBorder border));
+EXTERN void Tk_Free3DBorder(Tk_3DBorder border);
+#endif
+#ifndef Tk_FreeBitmap_TCL_DECLARED
+#define Tk_FreeBitmap_TCL_DECLARED
/* 67 */
-EXTERN void Tk_FreeBitmap _ANSI_ARGS_((Display *display,
- Pixmap bitmap));
+EXTERN void Tk_FreeBitmap(Display *display, Pixmap bitmap);
+#endif
+#ifndef Tk_FreeColor_TCL_DECLARED
+#define Tk_FreeColor_TCL_DECLARED
/* 68 */
-EXTERN void Tk_FreeColor _ANSI_ARGS_((XColor *colorPtr));
+EXTERN void Tk_FreeColor(XColor *colorPtr);
+#endif
+#ifndef Tk_FreeColormap_TCL_DECLARED
+#define Tk_FreeColormap_TCL_DECLARED
/* 69 */
-EXTERN void Tk_FreeColormap _ANSI_ARGS_((Display *display,
- Colormap colormap));
+EXTERN void Tk_FreeColormap(Display *display, Colormap colormap);
+#endif
+#ifndef Tk_FreeCursor_TCL_DECLARED
+#define Tk_FreeCursor_TCL_DECLARED
/* 70 */
-EXTERN void Tk_FreeCursor _ANSI_ARGS_((Display *display,
- Tk_Cursor cursor));
+EXTERN void Tk_FreeCursor(Display *display, Tk_Cursor cursor);
+#endif
+#ifndef Tk_FreeFont_TCL_DECLARED
+#define Tk_FreeFont_TCL_DECLARED
/* 71 */
-EXTERN void Tk_FreeFont _ANSI_ARGS_((Tk_Font f));
+EXTERN void Tk_FreeFont(Tk_Font f);
+#endif
+#ifndef Tk_FreeGC_TCL_DECLARED
+#define Tk_FreeGC_TCL_DECLARED
/* 72 */
-EXTERN void Tk_FreeGC _ANSI_ARGS_((Display *display, GC gc));
+EXTERN void Tk_FreeGC(Display *display, GC gc);
+#endif
+#ifndef Tk_FreeImage_TCL_DECLARED
+#define Tk_FreeImage_TCL_DECLARED
/* 73 */
-EXTERN void Tk_FreeImage _ANSI_ARGS_((Tk_Image image));
+EXTERN void Tk_FreeImage(Tk_Image image);
+#endif
+#ifndef Tk_FreeOptions_TCL_DECLARED
+#define Tk_FreeOptions_TCL_DECLARED
/* 74 */
-EXTERN void Tk_FreeOptions _ANSI_ARGS_((Tk_ConfigSpec *specs,
- char *widgRec, Display *display,
- int needFlags));
+EXTERN void Tk_FreeOptions(Tk_ConfigSpec *specs, char *widgRec,
+ Display *display, int needFlags);
+#endif
+#ifndef Tk_FreePixmap_TCL_DECLARED
+#define Tk_FreePixmap_TCL_DECLARED
/* 75 */
-EXTERN void Tk_FreePixmap _ANSI_ARGS_((Display *display,
- Pixmap pixmap));
+EXTERN void Tk_FreePixmap(Display *display, Pixmap pixmap);
+#endif
+#ifndef Tk_FreeTextLayout_TCL_DECLARED
+#define Tk_FreeTextLayout_TCL_DECLARED
/* 76 */
-EXTERN void Tk_FreeTextLayout _ANSI_ARGS_((
- Tk_TextLayout textLayout));
+EXTERN void Tk_FreeTextLayout(Tk_TextLayout textLayout);
+#endif
+#ifndef Tk_FreeXId_TCL_DECLARED
+#define Tk_FreeXId_TCL_DECLARED
/* 77 */
-EXTERN void Tk_FreeXId _ANSI_ARGS_((Display *display, XID xid));
+EXTERN void Tk_FreeXId(Display *display, XID xid);
+#endif
+#ifndef Tk_GCForColor_TCL_DECLARED
+#define Tk_GCForColor_TCL_DECLARED
/* 78 */
-EXTERN GC Tk_GCForColor _ANSI_ARGS_((XColor *colorPtr,
- Drawable drawable));
+EXTERN GC Tk_GCForColor(XColor *colorPtr, Drawable drawable);
+#endif
+#ifndef Tk_GeometryRequest_TCL_DECLARED
+#define Tk_GeometryRequest_TCL_DECLARED
/* 79 */
-EXTERN void Tk_GeometryRequest _ANSI_ARGS_((Tk_Window tkwin,
- int reqWidth, int reqHeight));
+EXTERN void Tk_GeometryRequest(Tk_Window tkwin, int reqWidth,
+ int reqHeight);
+#endif
+#ifndef Tk_Get3DBorder_TCL_DECLARED
+#define Tk_Get3DBorder_TCL_DECLARED
/* 80 */
-EXTERN Tk_3DBorder Tk_Get3DBorder _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, Tk_Uid colorName));
+EXTERN Tk_3DBorder Tk_Get3DBorder(Tcl_Interp *interp, Tk_Window tkwin,
+ Tk_Uid colorName);
+#endif
+#ifndef Tk_GetAllBindings_TCL_DECLARED
+#define Tk_GetAllBindings_TCL_DECLARED
/* 81 */
-EXTERN void Tk_GetAllBindings _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN void Tk_GetAllBindings(Tcl_Interp *interp,
Tk_BindingTable bindingTable,
- ClientData object));
+ ClientData object);
+#endif
+#ifndef Tk_GetAnchor_TCL_DECLARED
+#define Tk_GetAnchor_TCL_DECLARED
/* 82 */
-EXTERN int Tk_GetAnchor _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *str, Tk_Anchor *anchorPtr));
+EXTERN int Tk_GetAnchor(Tcl_Interp *interp, CONST char *str,
+ Tk_Anchor *anchorPtr);
+#endif
+#ifndef Tk_GetAtomName_TCL_DECLARED
+#define Tk_GetAtomName_TCL_DECLARED
/* 83 */
-EXTERN CONST84_RETURN char * Tk_GetAtomName _ANSI_ARGS_((Tk_Window tkwin,
- Atom atom));
+EXTERN CONST84_RETURN char * Tk_GetAtomName(Tk_Window tkwin, Atom atom);
+#endif
+#ifndef Tk_GetBinding_TCL_DECLARED
+#define Tk_GetBinding_TCL_DECLARED
/* 84 */
-EXTERN CONST84_RETURN char * Tk_GetBinding _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN CONST84_RETURN char * Tk_GetBinding(Tcl_Interp *interp,
Tk_BindingTable bindingTable,
- ClientData object, CONST char *eventStr));
+ ClientData object, CONST char *eventStr);
+#endif
+#ifndef Tk_GetBitmap_TCL_DECLARED
+#define Tk_GetBitmap_TCL_DECLARED
/* 85 */
-EXTERN Pixmap Tk_GetBitmap _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *str));
+EXTERN Pixmap Tk_GetBitmap(Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *str);
+#endif
+#ifndef Tk_GetBitmapFromData_TCL_DECLARED
+#define Tk_GetBitmapFromData_TCL_DECLARED
/* 86 */
-EXTERN Pixmap Tk_GetBitmapFromData _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN Pixmap Tk_GetBitmapFromData(Tcl_Interp *interp,
Tk_Window tkwin, CONST char *source,
- int width, int height));
+ int width, int height);
+#endif
+#ifndef Tk_GetCapStyle_TCL_DECLARED
+#define Tk_GetCapStyle_TCL_DECLARED
/* 87 */
-EXTERN int Tk_GetCapStyle _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *str, int *capPtr));
+EXTERN int Tk_GetCapStyle(Tcl_Interp *interp, CONST char *str,
+ int *capPtr);
+#endif
+#ifndef Tk_GetColor_TCL_DECLARED
+#define Tk_GetColor_TCL_DECLARED
/* 88 */
-EXTERN XColor * Tk_GetColor _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, Tk_Uid name));
+EXTERN XColor * Tk_GetColor(Tcl_Interp *interp, Tk_Window tkwin,
+ Tk_Uid name);
+#endif
+#ifndef Tk_GetColorByValue_TCL_DECLARED
+#define Tk_GetColorByValue_TCL_DECLARED
/* 89 */
-EXTERN XColor * Tk_GetColorByValue _ANSI_ARGS_((Tk_Window tkwin,
- XColor *colorPtr));
+EXTERN XColor * Tk_GetColorByValue(Tk_Window tkwin, XColor *colorPtr);
+#endif
+#ifndef Tk_GetColormap_TCL_DECLARED
+#define Tk_GetColormap_TCL_DECLARED
/* 90 */
-EXTERN Colormap Tk_GetColormap _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *str));
+EXTERN Colormap Tk_GetColormap(Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *str);
+#endif
+#ifndef Tk_GetCursor_TCL_DECLARED
+#define Tk_GetCursor_TCL_DECLARED
/* 91 */
-EXTERN Tk_Cursor Tk_GetCursor _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, Tk_Uid str));
+EXTERN Tk_Cursor Tk_GetCursor(Tcl_Interp *interp, Tk_Window tkwin,
+ Tk_Uid str);
+#endif
+#ifndef Tk_GetCursorFromData_TCL_DECLARED
+#define Tk_GetCursorFromData_TCL_DECLARED
/* 92 */
-EXTERN Tk_Cursor Tk_GetCursorFromData _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN Tk_Cursor Tk_GetCursorFromData(Tcl_Interp *interp,
Tk_Window tkwin, CONST char *source,
CONST char *mask, int width, int height,
- int xHot, int yHot, Tk_Uid fg, Tk_Uid bg));
+ int xHot, int yHot, Tk_Uid fg, Tk_Uid bg);
+#endif
+#ifndef Tk_GetFont_TCL_DECLARED
+#define Tk_GetFont_TCL_DECLARED
/* 93 */
-EXTERN Tk_Font Tk_GetFont _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *str));
+EXTERN Tk_Font Tk_GetFont(Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *str);
+#endif
+#ifndef Tk_GetFontFromObj_TCL_DECLARED
+#define Tk_GetFontFromObj_TCL_DECLARED
/* 94 */
-EXTERN Tk_Font Tk_GetFontFromObj _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Obj *objPtr));
+EXTERN Tk_Font Tk_GetFontFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_GetFontMetrics_TCL_DECLARED
+#define Tk_GetFontMetrics_TCL_DECLARED
/* 95 */
-EXTERN void Tk_GetFontMetrics _ANSI_ARGS_((Tk_Font font,
- Tk_FontMetrics *fmPtr));
+EXTERN void Tk_GetFontMetrics(Tk_Font font,
+ Tk_FontMetrics *fmPtr);
+#endif
+#ifndef Tk_GetGC_TCL_DECLARED
+#define Tk_GetGC_TCL_DECLARED
/* 96 */
-EXTERN GC Tk_GetGC _ANSI_ARGS_((Tk_Window tkwin,
- unsigned long valueMask, XGCValues *valuePtr));
+EXTERN GC Tk_GetGC(Tk_Window tkwin, unsigned long valueMask,
+ XGCValues *valuePtr);
+#endif
+#ifndef Tk_GetImage_TCL_DECLARED
+#define Tk_GetImage_TCL_DECLARED
/* 97 */
-EXTERN Tk_Image Tk_GetImage _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *name,
+EXTERN Tk_Image Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *name,
Tk_ImageChangedProc *changeProc,
- ClientData clientData));
+ ClientData clientData);
+#endif
+#ifndef Tk_GetImageMasterData_TCL_DECLARED
+#define Tk_GetImageMasterData_TCL_DECLARED
/* 98 */
-EXTERN ClientData Tk_GetImageMasterData _ANSI_ARGS_((
- Tcl_Interp *interp, CONST char *name,
- Tk_ImageType **typePtrPtr));
+EXTERN ClientData Tk_GetImageMasterData(Tcl_Interp *interp,
+ CONST char *name, Tk_ImageType **typePtrPtr);
+#endif
+#ifndef Tk_GetItemTypes_TCL_DECLARED
+#define Tk_GetItemTypes_TCL_DECLARED
/* 99 */
-EXTERN Tk_ItemType * Tk_GetItemTypes _ANSI_ARGS_((void));
+EXTERN Tk_ItemType * Tk_GetItemTypes(void);
+#endif
+#ifndef Tk_GetJoinStyle_TCL_DECLARED
+#define Tk_GetJoinStyle_TCL_DECLARED
/* 100 */
-EXTERN int Tk_GetJoinStyle _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *str, int *joinPtr));
+EXTERN int Tk_GetJoinStyle(Tcl_Interp *interp, CONST char *str,
+ int *joinPtr);
+#endif
+#ifndef Tk_GetJustify_TCL_DECLARED
+#define Tk_GetJustify_TCL_DECLARED
/* 101 */
-EXTERN int Tk_GetJustify _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *str, Tk_Justify *justifyPtr));
+EXTERN int Tk_GetJustify(Tcl_Interp *interp, CONST char *str,
+ Tk_Justify *justifyPtr);
+#endif
+#ifndef Tk_GetNumMainWindows_TCL_DECLARED
+#define Tk_GetNumMainWindows_TCL_DECLARED
/* 102 */
-EXTERN int Tk_GetNumMainWindows _ANSI_ARGS_((void));
+EXTERN int Tk_GetNumMainWindows(void);
+#endif
+#ifndef Tk_GetOption_TCL_DECLARED
+#define Tk_GetOption_TCL_DECLARED
/* 103 */
-EXTERN Tk_Uid Tk_GetOption _ANSI_ARGS_((Tk_Window tkwin,
- CONST char *name, CONST char *className));
+EXTERN Tk_Uid Tk_GetOption(Tk_Window tkwin, CONST char *name,
+ CONST char *className);
+#endif
+#ifndef Tk_GetPixels_TCL_DECLARED
+#define Tk_GetPixels_TCL_DECLARED
/* 104 */
-EXTERN int Tk_GetPixels _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *str,
- int *intPtr));
+EXTERN int Tk_GetPixels(Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *str, int *intPtr);
+#endif
+#ifndef Tk_GetPixmap_TCL_DECLARED
+#define Tk_GetPixmap_TCL_DECLARED
/* 105 */
-EXTERN Pixmap Tk_GetPixmap _ANSI_ARGS_((Display *display,
- Drawable d, int width, int height, int depth));
+EXTERN Pixmap Tk_GetPixmap(Display *display, Drawable d, int width,
+ int height, int depth);
+#endif
+#ifndef Tk_GetRelief_TCL_DECLARED
+#define Tk_GetRelief_TCL_DECLARED
/* 106 */
-EXTERN int Tk_GetRelief _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *name, int *reliefPtr));
+EXTERN int Tk_GetRelief(Tcl_Interp *interp, CONST char *name,
+ int *reliefPtr);
+#endif
+#ifndef Tk_GetRootCoords_TCL_DECLARED
+#define Tk_GetRootCoords_TCL_DECLARED
/* 107 */
-EXTERN void Tk_GetRootCoords _ANSI_ARGS_((Tk_Window tkwin,
- int *xPtr, int *yPtr));
+EXTERN void Tk_GetRootCoords(Tk_Window tkwin, int *xPtr,
+ int *yPtr);
+#endif
+#ifndef Tk_GetScrollInfo_TCL_DECLARED
+#define Tk_GetScrollInfo_TCL_DECLARED
/* 108 */
-EXTERN int Tk_GetScrollInfo _ANSI_ARGS_((Tcl_Interp *interp,
- int argc, CONST84 char **argv,
- double *dblPtr, int *intPtr));
+EXTERN int Tk_GetScrollInfo(Tcl_Interp *interp, int argc,
+ CONST84 char **argv, double *dblPtr,
+ int *intPtr);
+#endif
+#ifndef Tk_GetScreenMM_TCL_DECLARED
+#define Tk_GetScreenMM_TCL_DECLARED
/* 109 */
-EXTERN int Tk_GetScreenMM _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *str,
- double *doublePtr));
+EXTERN int Tk_GetScreenMM(Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *str, double *doublePtr);
+#endif
+#ifndef Tk_GetSelection_TCL_DECLARED
+#define Tk_GetSelection_TCL_DECLARED
/* 110 */
-EXTERN int Tk_GetSelection _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, Atom selection, Atom target,
- Tk_GetSelProc *proc, ClientData clientData));
+EXTERN int Tk_GetSelection(Tcl_Interp *interp, Tk_Window tkwin,
+ Atom selection, Atom target,
+ Tk_GetSelProc *proc, ClientData clientData);
+#endif
+#ifndef Tk_GetUid_TCL_DECLARED
+#define Tk_GetUid_TCL_DECLARED
/* 111 */
-EXTERN Tk_Uid Tk_GetUid _ANSI_ARGS_((CONST char *str));
+EXTERN Tk_Uid Tk_GetUid(CONST char *str);
+#endif
+#ifndef Tk_GetVisual_TCL_DECLARED
+#define Tk_GetVisual_TCL_DECLARED
/* 112 */
-EXTERN Visual * Tk_GetVisual _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *str,
- int *depthPtr, Colormap *colormapPtr));
+EXTERN Visual * Tk_GetVisual(Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *str, int *depthPtr,
+ Colormap *colormapPtr);
+#endif
+#ifndef Tk_GetVRootGeometry_TCL_DECLARED
+#define Tk_GetVRootGeometry_TCL_DECLARED
/* 113 */
-EXTERN void Tk_GetVRootGeometry _ANSI_ARGS_((Tk_Window tkwin,
- int *xPtr, int *yPtr, int *widthPtr,
- int *heightPtr));
+EXTERN void Tk_GetVRootGeometry(Tk_Window tkwin, int *xPtr,
+ int *yPtr, int *widthPtr, int *heightPtr);
+#endif
+#ifndef Tk_Grab_TCL_DECLARED
+#define Tk_Grab_TCL_DECLARED
/* 114 */
-EXTERN int Tk_Grab _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, int grabGlobal));
+EXTERN int Tk_Grab(Tcl_Interp *interp, Tk_Window tkwin,
+ int grabGlobal);
+#endif
+#ifndef Tk_HandleEvent_TCL_DECLARED
+#define Tk_HandleEvent_TCL_DECLARED
/* 115 */
-EXTERN void Tk_HandleEvent _ANSI_ARGS_((XEvent *eventPtr));
+EXTERN void Tk_HandleEvent(XEvent *eventPtr);
+#endif
+#ifndef Tk_IdToWindow_TCL_DECLARED
+#define Tk_IdToWindow_TCL_DECLARED
/* 116 */
-EXTERN Tk_Window Tk_IdToWindow _ANSI_ARGS_((Display *display,
- Window window));
+EXTERN Tk_Window Tk_IdToWindow(Display *display, Window window);
+#endif
+#ifndef Tk_ImageChanged_TCL_DECLARED
+#define Tk_ImageChanged_TCL_DECLARED
/* 117 */
-EXTERN void Tk_ImageChanged _ANSI_ARGS_((Tk_ImageMaster master,
- int x, int y, int width, int height,
- int imageWidth, int imageHeight));
+EXTERN void Tk_ImageChanged(Tk_ImageMaster master, int x, int y,
+ int width, int height, int imageWidth,
+ int imageHeight);
+#endif
+#ifndef Tk_Init_TCL_DECLARED
+#define Tk_Init_TCL_DECLARED
/* 118 */
-EXTERN int Tk_Init _ANSI_ARGS_((Tcl_Interp *interp));
+EXTERN int Tk_Init(Tcl_Interp *interp);
+#endif
+#ifndef Tk_InternAtom_TCL_DECLARED
+#define Tk_InternAtom_TCL_DECLARED
/* 119 */
-EXTERN Atom Tk_InternAtom _ANSI_ARGS_((Tk_Window tkwin,
- CONST char *name));
+EXTERN Atom Tk_InternAtom(Tk_Window tkwin, CONST char *name);
+#endif
+#ifndef Tk_IntersectTextLayout_TCL_DECLARED
+#define Tk_IntersectTextLayout_TCL_DECLARED
/* 120 */
-EXTERN int Tk_IntersectTextLayout _ANSI_ARGS_((
- Tk_TextLayout layout, int x, int y,
- int width, int height));
+EXTERN int Tk_IntersectTextLayout(Tk_TextLayout layout, int x,
+ int y, int width, int height);
+#endif
+#ifndef Tk_MaintainGeometry_TCL_DECLARED
+#define Tk_MaintainGeometry_TCL_DECLARED
/* 121 */
-EXTERN void Tk_MaintainGeometry _ANSI_ARGS_((Tk_Window slave,
+EXTERN void Tk_MaintainGeometry(Tk_Window slave,
Tk_Window master, int x, int y, int width,
- int height));
+ int height);
+#endif
+#ifndef Tk_MainWindow_TCL_DECLARED
+#define Tk_MainWindow_TCL_DECLARED
/* 122 */
-EXTERN Tk_Window Tk_MainWindow _ANSI_ARGS_((Tcl_Interp *interp));
+EXTERN Tk_Window Tk_MainWindow(Tcl_Interp *interp);
+#endif
+#ifndef Tk_MakeWindowExist_TCL_DECLARED
+#define Tk_MakeWindowExist_TCL_DECLARED
/* 123 */
-EXTERN void Tk_MakeWindowExist _ANSI_ARGS_((Tk_Window tkwin));
+EXTERN void Tk_MakeWindowExist(Tk_Window tkwin);
+#endif
+#ifndef Tk_ManageGeometry_TCL_DECLARED
+#define Tk_ManageGeometry_TCL_DECLARED
/* 124 */
-EXTERN void Tk_ManageGeometry _ANSI_ARGS_((Tk_Window tkwin,
- Tk_GeomMgr *mgrPtr, ClientData clientData));
+EXTERN void Tk_ManageGeometry(Tk_Window tkwin,
+ CONST Tk_GeomMgr *mgrPtr,
+ ClientData clientData);
+#endif
+#ifndef Tk_MapWindow_TCL_DECLARED
+#define Tk_MapWindow_TCL_DECLARED
/* 125 */
-EXTERN void Tk_MapWindow _ANSI_ARGS_((Tk_Window tkwin));
+EXTERN void Tk_MapWindow(Tk_Window tkwin);
+#endif
+#ifndef Tk_MeasureChars_TCL_DECLARED
+#define Tk_MeasureChars_TCL_DECLARED
/* 126 */
-EXTERN int Tk_MeasureChars _ANSI_ARGS_((Tk_Font tkfont,
- CONST char *source, int numBytes,
- int maxPixels, int flags, int *lengthPtr));
+EXTERN int Tk_MeasureChars(Tk_Font tkfont, CONST char *source,
+ int numBytes, int maxPixels, int flags,
+ int *lengthPtr);
+#endif
+#ifndef Tk_MoveResizeWindow_TCL_DECLARED
+#define Tk_MoveResizeWindow_TCL_DECLARED
/* 127 */
-EXTERN void Tk_MoveResizeWindow _ANSI_ARGS_((Tk_Window tkwin,
- int x, int y, int width, int height));
+EXTERN void Tk_MoveResizeWindow(Tk_Window tkwin, int x, int y,
+ int width, int height);
+#endif
+#ifndef Tk_MoveWindow_TCL_DECLARED
+#define Tk_MoveWindow_TCL_DECLARED
/* 128 */
-EXTERN void Tk_MoveWindow _ANSI_ARGS_((Tk_Window tkwin, int x,
- int y));
+EXTERN void Tk_MoveWindow(Tk_Window tkwin, int x, int y);
+#endif
+#ifndef Tk_MoveToplevelWindow_TCL_DECLARED
+#define Tk_MoveToplevelWindow_TCL_DECLARED
/* 129 */
-EXTERN void Tk_MoveToplevelWindow _ANSI_ARGS_((Tk_Window tkwin,
- int x, int y));
+EXTERN void Tk_MoveToplevelWindow(Tk_Window tkwin, int x, int y);
+#endif
+#ifndef Tk_NameOf3DBorder_TCL_DECLARED
+#define Tk_NameOf3DBorder_TCL_DECLARED
/* 130 */
-EXTERN CONST84_RETURN char * Tk_NameOf3DBorder _ANSI_ARGS_((
- Tk_3DBorder border));
+EXTERN CONST84_RETURN char * Tk_NameOf3DBorder(Tk_3DBorder border);
+#endif
+#ifndef Tk_NameOfAnchor_TCL_DECLARED
+#define Tk_NameOfAnchor_TCL_DECLARED
/* 131 */
-EXTERN CONST84_RETURN char * Tk_NameOfAnchor _ANSI_ARGS_((Tk_Anchor anchor));
+EXTERN CONST84_RETURN char * Tk_NameOfAnchor(Tk_Anchor anchor);
+#endif
+#ifndef Tk_NameOfBitmap_TCL_DECLARED
+#define Tk_NameOfBitmap_TCL_DECLARED
/* 132 */
-EXTERN CONST84_RETURN char * Tk_NameOfBitmap _ANSI_ARGS_((Display *display,
- Pixmap bitmap));
+EXTERN CONST84_RETURN char * Tk_NameOfBitmap(Display *display, Pixmap bitmap);
+#endif
+#ifndef Tk_NameOfCapStyle_TCL_DECLARED
+#define Tk_NameOfCapStyle_TCL_DECLARED
/* 133 */
-EXTERN CONST84_RETURN char * Tk_NameOfCapStyle _ANSI_ARGS_((int cap));
+EXTERN CONST84_RETURN char * Tk_NameOfCapStyle(int cap);
+#endif
+#ifndef Tk_NameOfColor_TCL_DECLARED
+#define Tk_NameOfColor_TCL_DECLARED
/* 134 */
-EXTERN CONST84_RETURN char * Tk_NameOfColor _ANSI_ARGS_((XColor *colorPtr));
+EXTERN CONST84_RETURN char * Tk_NameOfColor(XColor *colorPtr);
+#endif
+#ifndef Tk_NameOfCursor_TCL_DECLARED
+#define Tk_NameOfCursor_TCL_DECLARED
/* 135 */
-EXTERN CONST84_RETURN char * Tk_NameOfCursor _ANSI_ARGS_((Display *display,
- Tk_Cursor cursor));
+EXTERN CONST84_RETURN char * Tk_NameOfCursor(Display *display,
+ Tk_Cursor cursor);
+#endif
+#ifndef Tk_NameOfFont_TCL_DECLARED
+#define Tk_NameOfFont_TCL_DECLARED
/* 136 */
-EXTERN CONST84_RETURN char * Tk_NameOfFont _ANSI_ARGS_((Tk_Font font));
+EXTERN CONST84_RETURN char * Tk_NameOfFont(Tk_Font font);
+#endif
+#ifndef Tk_NameOfImage_TCL_DECLARED
+#define Tk_NameOfImage_TCL_DECLARED
/* 137 */
-EXTERN CONST84_RETURN char * Tk_NameOfImage _ANSI_ARGS_((
- Tk_ImageMaster imageMaster));
+EXTERN CONST84_RETURN char * Tk_NameOfImage(Tk_ImageMaster imageMaster);
+#endif
+#ifndef Tk_NameOfJoinStyle_TCL_DECLARED
+#define Tk_NameOfJoinStyle_TCL_DECLARED
/* 138 */
-EXTERN CONST84_RETURN char * Tk_NameOfJoinStyle _ANSI_ARGS_((int join));
+EXTERN CONST84_RETURN char * Tk_NameOfJoinStyle(int join);
+#endif
+#ifndef Tk_NameOfJustify_TCL_DECLARED
+#define Tk_NameOfJustify_TCL_DECLARED
/* 139 */
-EXTERN CONST84_RETURN char * Tk_NameOfJustify _ANSI_ARGS_((
- Tk_Justify justify));
+EXTERN CONST84_RETURN char * Tk_NameOfJustify(Tk_Justify justify);
+#endif
+#ifndef Tk_NameOfRelief_TCL_DECLARED
+#define Tk_NameOfRelief_TCL_DECLARED
/* 140 */
-EXTERN CONST84_RETURN char * Tk_NameOfRelief _ANSI_ARGS_((int relief));
+EXTERN CONST84_RETURN char * Tk_NameOfRelief(int relief);
+#endif
+#ifndef Tk_NameToWindow_TCL_DECLARED
+#define Tk_NameToWindow_TCL_DECLARED
/* 141 */
-EXTERN Tk_Window Tk_NameToWindow _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *pathName, Tk_Window tkwin));
+EXTERN Tk_Window Tk_NameToWindow(Tcl_Interp *interp,
+ CONST char *pathName, Tk_Window tkwin);
+#endif
+#ifndef Tk_OwnSelection_TCL_DECLARED
+#define Tk_OwnSelection_TCL_DECLARED
/* 142 */
-EXTERN void Tk_OwnSelection _ANSI_ARGS_((Tk_Window tkwin,
- Atom selection, Tk_LostSelProc *proc,
- ClientData clientData));
+EXTERN void Tk_OwnSelection(Tk_Window tkwin, Atom selection,
+ Tk_LostSelProc *proc, ClientData clientData);
+#endif
+#ifndef Tk_ParseArgv_TCL_DECLARED
+#define Tk_ParseArgv_TCL_DECLARED
/* 143 */
-EXTERN int Tk_ParseArgv _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, int *argcPtr,
- CONST84 char **argv, Tk_ArgvInfo *argTable,
- int flags));
+EXTERN int Tk_ParseArgv(Tcl_Interp *interp, Tk_Window tkwin,
+ int *argcPtr, CONST84 char **argv,
+ Tk_ArgvInfo *argTable, int flags);
+#endif
+#ifndef Tk_PhotoPutBlock_NoComposite_TCL_DECLARED
+#define Tk_PhotoPutBlock_NoComposite_TCL_DECLARED
/* 144 */
-EXTERN void Tk_PhotoPutBlock_NoComposite _ANSI_ARGS_((
- Tk_PhotoHandle handle,
+EXTERN void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr, int x, int y,
- int width, int height));
+ int width, int height);
+#endif
+#ifndef Tk_PhotoPutZoomedBlock_NoComposite_TCL_DECLARED
+#define Tk_PhotoPutZoomedBlock_NoComposite_TCL_DECLARED
/* 145 */
-EXTERN void Tk_PhotoPutZoomedBlock_NoComposite _ANSI_ARGS_((
+EXTERN void Tk_PhotoPutZoomedBlock_NoComposite(
Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr, int x, int y,
int width, int height, int zoomX, int zoomY,
- int subsampleX, int subsampleY));
+ int subsampleX, int subsampleY);
+#endif
+#ifndef Tk_PhotoGetImage_TCL_DECLARED
+#define Tk_PhotoGetImage_TCL_DECLARED
/* 146 */
-EXTERN int Tk_PhotoGetImage _ANSI_ARGS_((Tk_PhotoHandle handle,
- Tk_PhotoImageBlock *blockPtr));
+EXTERN int Tk_PhotoGetImage(Tk_PhotoHandle handle,
+ Tk_PhotoImageBlock *blockPtr);
+#endif
+#ifndef Tk_PhotoBlank_TCL_DECLARED
+#define Tk_PhotoBlank_TCL_DECLARED
/* 147 */
-EXTERN void Tk_PhotoBlank _ANSI_ARGS_((Tk_PhotoHandle handle));
+EXTERN void Tk_PhotoBlank(Tk_PhotoHandle handle);
+#endif
+#ifndef Tk_PhotoExpand_Panic_TCL_DECLARED
+#define Tk_PhotoExpand_Panic_TCL_DECLARED
/* 148 */
-EXTERN void Tk_PhotoExpand _ANSI_ARGS_((Tk_PhotoHandle handle,
- int width, int height));
+EXTERN void Tk_PhotoExpand_Panic(Tk_PhotoHandle handle,
+ int width, int height);
+#endif
+#ifndef Tk_PhotoGetSize_TCL_DECLARED
+#define Tk_PhotoGetSize_TCL_DECLARED
/* 149 */
-EXTERN void Tk_PhotoGetSize _ANSI_ARGS_((Tk_PhotoHandle handle,
- int *widthPtr, int *heightPtr));
+EXTERN void Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr,
+ int *heightPtr);
+#endif
+#ifndef Tk_PhotoSetSize_Panic_TCL_DECLARED
+#define Tk_PhotoSetSize_Panic_TCL_DECLARED
/* 150 */
-EXTERN void Tk_PhotoSetSize _ANSI_ARGS_((Tk_PhotoHandle handle,
- int width, int height));
+EXTERN void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle,
+ int width, int height);
+#endif
+#ifndef Tk_PointToChar_TCL_DECLARED
+#define Tk_PointToChar_TCL_DECLARED
/* 151 */
-EXTERN int Tk_PointToChar _ANSI_ARGS_((Tk_TextLayout layout,
- int x, int y));
+EXTERN int Tk_PointToChar(Tk_TextLayout layout, int x, int y);
+#endif
+#ifndef Tk_PostscriptFontName_TCL_DECLARED
+#define Tk_PostscriptFontName_TCL_DECLARED
/* 152 */
-EXTERN int Tk_PostscriptFontName _ANSI_ARGS_((Tk_Font tkfont,
- Tcl_DString *dsPtr));
+EXTERN int Tk_PostscriptFontName(Tk_Font tkfont,
+ Tcl_DString *dsPtr);
+#endif
+#ifndef Tk_PreserveColormap_TCL_DECLARED
+#define Tk_PreserveColormap_TCL_DECLARED
/* 153 */
-EXTERN void Tk_PreserveColormap _ANSI_ARGS_((Display *display,
- Colormap colormap));
+EXTERN void Tk_PreserveColormap(Display *display,
+ Colormap colormap);
+#endif
+#ifndef Tk_QueueWindowEvent_TCL_DECLARED
+#define Tk_QueueWindowEvent_TCL_DECLARED
/* 154 */
-EXTERN void Tk_QueueWindowEvent _ANSI_ARGS_((XEvent *eventPtr,
- Tcl_QueuePosition position));
+EXTERN void Tk_QueueWindowEvent(XEvent *eventPtr,
+ Tcl_QueuePosition position);
+#endif
+#ifndef Tk_RedrawImage_TCL_DECLARED
+#define Tk_RedrawImage_TCL_DECLARED
/* 155 */
-EXTERN void Tk_RedrawImage _ANSI_ARGS_((Tk_Image image,
- int imageX, int imageY, int width,
- int height, Drawable drawable, int drawableX,
- int drawableY));
+EXTERN void Tk_RedrawImage(Tk_Image image, int imageX,
+ int imageY, int width, int height,
+ Drawable drawable, int drawableX,
+ int drawableY);
+#endif
+#ifndef Tk_ResizeWindow_TCL_DECLARED
+#define Tk_ResizeWindow_TCL_DECLARED
/* 156 */
-EXTERN void Tk_ResizeWindow _ANSI_ARGS_((Tk_Window tkwin,
- int width, int height));
+EXTERN void Tk_ResizeWindow(Tk_Window tkwin, int width,
+ int height);
+#endif
+#ifndef Tk_RestackWindow_TCL_DECLARED
+#define Tk_RestackWindow_TCL_DECLARED
/* 157 */
-EXTERN int Tk_RestackWindow _ANSI_ARGS_((Tk_Window tkwin,
- int aboveBelow, Tk_Window other));
+EXTERN int Tk_RestackWindow(Tk_Window tkwin, int aboveBelow,
+ Tk_Window other);
+#endif
+#ifndef Tk_RestrictEvents_TCL_DECLARED
+#define Tk_RestrictEvents_TCL_DECLARED
/* 158 */
-EXTERN Tk_RestrictProc * Tk_RestrictEvents _ANSI_ARGS_((
- Tk_RestrictProc *proc, ClientData arg,
- ClientData *prevArgPtr));
+EXTERN Tk_RestrictProc * Tk_RestrictEvents(Tk_RestrictProc *proc,
+ ClientData arg, ClientData *prevArgPtr);
+#endif
+#ifndef Tk_SafeInit_TCL_DECLARED
+#define Tk_SafeInit_TCL_DECLARED
/* 159 */
-EXTERN int Tk_SafeInit _ANSI_ARGS_((Tcl_Interp *interp));
+EXTERN int Tk_SafeInit(Tcl_Interp *interp);
+#endif
+#ifndef Tk_SetAppName_TCL_DECLARED
+#define Tk_SetAppName_TCL_DECLARED
/* 160 */
-EXTERN CONST char * Tk_SetAppName _ANSI_ARGS_((Tk_Window tkwin,
- CONST char *name));
+EXTERN CONST char * Tk_SetAppName(Tk_Window tkwin, CONST char *name);
+#endif
+#ifndef Tk_SetBackgroundFromBorder_TCL_DECLARED
+#define Tk_SetBackgroundFromBorder_TCL_DECLARED
/* 161 */
-EXTERN void Tk_SetBackgroundFromBorder _ANSI_ARGS_((
- Tk_Window tkwin, Tk_3DBorder border));
+EXTERN void Tk_SetBackgroundFromBorder(Tk_Window tkwin,
+ Tk_3DBorder border);
+#endif
+#ifndef Tk_SetClass_TCL_DECLARED
+#define Tk_SetClass_TCL_DECLARED
/* 162 */
-EXTERN void Tk_SetClass _ANSI_ARGS_((Tk_Window tkwin,
- CONST char *className));
+EXTERN void Tk_SetClass(Tk_Window tkwin, CONST char *className);
+#endif
+#ifndef Tk_SetGrid_TCL_DECLARED
+#define Tk_SetGrid_TCL_DECLARED
/* 163 */
-EXTERN void Tk_SetGrid _ANSI_ARGS_((Tk_Window tkwin,
- int reqWidth, int reqHeight, int gridWidth,
- int gridHeight));
+EXTERN void Tk_SetGrid(Tk_Window tkwin, int reqWidth,
+ int reqHeight, int gridWidth, int gridHeight);
+#endif
+#ifndef Tk_SetInternalBorder_TCL_DECLARED
+#define Tk_SetInternalBorder_TCL_DECLARED
/* 164 */
-EXTERN void Tk_SetInternalBorder _ANSI_ARGS_((Tk_Window tkwin,
- int width));
+EXTERN void Tk_SetInternalBorder(Tk_Window tkwin, int width);
+#endif
+#ifndef Tk_SetWindowBackground_TCL_DECLARED
+#define Tk_SetWindowBackground_TCL_DECLARED
/* 165 */
-EXTERN void Tk_SetWindowBackground _ANSI_ARGS_((Tk_Window tkwin,
- unsigned long pixel));
+EXTERN void Tk_SetWindowBackground(Tk_Window tkwin,
+ unsigned long pixel);
+#endif
+#ifndef Tk_SetWindowBackgroundPixmap_TCL_DECLARED
+#define Tk_SetWindowBackgroundPixmap_TCL_DECLARED
/* 166 */
-EXTERN void Tk_SetWindowBackgroundPixmap _ANSI_ARGS_((
- Tk_Window tkwin, Pixmap pixmap));
+EXTERN void Tk_SetWindowBackgroundPixmap(Tk_Window tkwin,
+ Pixmap pixmap);
+#endif
+#ifndef Tk_SetWindowBorder_TCL_DECLARED
+#define Tk_SetWindowBorder_TCL_DECLARED
/* 167 */
-EXTERN void Tk_SetWindowBorder _ANSI_ARGS_((Tk_Window tkwin,
- unsigned long pixel));
+EXTERN void Tk_SetWindowBorder(Tk_Window tkwin,
+ unsigned long pixel);
+#endif
+#ifndef Tk_SetWindowBorderWidth_TCL_DECLARED
+#define Tk_SetWindowBorderWidth_TCL_DECLARED
/* 168 */
-EXTERN void Tk_SetWindowBorderWidth _ANSI_ARGS_((Tk_Window tkwin,
- int width));
+EXTERN void Tk_SetWindowBorderWidth(Tk_Window tkwin, int width);
+#endif
+#ifndef Tk_SetWindowBorderPixmap_TCL_DECLARED
+#define Tk_SetWindowBorderPixmap_TCL_DECLARED
/* 169 */
-EXTERN void Tk_SetWindowBorderPixmap _ANSI_ARGS_((
- Tk_Window tkwin, Pixmap pixmap));
+EXTERN void Tk_SetWindowBorderPixmap(Tk_Window tkwin,
+ Pixmap pixmap);
+#endif
+#ifndef Tk_SetWindowColormap_TCL_DECLARED
+#define Tk_SetWindowColormap_TCL_DECLARED
/* 170 */
-EXTERN void Tk_SetWindowColormap _ANSI_ARGS_((Tk_Window tkwin,
- Colormap colormap));
+EXTERN void Tk_SetWindowColormap(Tk_Window tkwin,
+ Colormap colormap);
+#endif
+#ifndef Tk_SetWindowVisual_TCL_DECLARED
+#define Tk_SetWindowVisual_TCL_DECLARED
/* 171 */
-EXTERN int Tk_SetWindowVisual _ANSI_ARGS_((Tk_Window tkwin,
- Visual *visual, int depth, Colormap colormap));
+EXTERN int Tk_SetWindowVisual(Tk_Window tkwin, Visual *visual,
+ int depth, Colormap colormap);
+#endif
+#ifndef Tk_SizeOfBitmap_TCL_DECLARED
+#define Tk_SizeOfBitmap_TCL_DECLARED
/* 172 */
-EXTERN void Tk_SizeOfBitmap _ANSI_ARGS_((Display *display,
- Pixmap bitmap, int *widthPtr, int *heightPtr));
+EXTERN void Tk_SizeOfBitmap(Display *display, Pixmap bitmap,
+ int *widthPtr, int *heightPtr);
+#endif
+#ifndef Tk_SizeOfImage_TCL_DECLARED
+#define Tk_SizeOfImage_TCL_DECLARED
/* 173 */
-EXTERN void Tk_SizeOfImage _ANSI_ARGS_((Tk_Image image,
- int *widthPtr, int *heightPtr));
+EXTERN void Tk_SizeOfImage(Tk_Image image, int *widthPtr,
+ int *heightPtr);
+#endif
+#ifndef Tk_StrictMotif_TCL_DECLARED
+#define Tk_StrictMotif_TCL_DECLARED
/* 174 */
-EXTERN int Tk_StrictMotif _ANSI_ARGS_((Tk_Window tkwin));
+EXTERN int Tk_StrictMotif(Tk_Window tkwin);
+#endif
+#ifndef Tk_TextLayoutToPostscript_TCL_DECLARED
+#define Tk_TextLayoutToPostscript_TCL_DECLARED
/* 175 */
-EXTERN void Tk_TextLayoutToPostscript _ANSI_ARGS_((
- Tcl_Interp *interp, Tk_TextLayout layout));
+EXTERN void Tk_TextLayoutToPostscript(Tcl_Interp *interp,
+ Tk_TextLayout layout);
+#endif
+#ifndef Tk_TextWidth_TCL_DECLARED
+#define Tk_TextWidth_TCL_DECLARED
/* 176 */
-EXTERN int Tk_TextWidth _ANSI_ARGS_((Tk_Font font,
- CONST char *str, int numBytes));
+EXTERN int Tk_TextWidth(Tk_Font font, CONST char *str,
+ int numBytes);
+#endif
+#ifndef Tk_UndefineCursor_TCL_DECLARED
+#define Tk_UndefineCursor_TCL_DECLARED
/* 177 */
-EXTERN void Tk_UndefineCursor _ANSI_ARGS_((Tk_Window window));
+EXTERN void Tk_UndefineCursor(Tk_Window window);
+#endif
+#ifndef Tk_UnderlineChars_TCL_DECLARED
+#define Tk_UnderlineChars_TCL_DECLARED
/* 178 */
-EXTERN void Tk_UnderlineChars _ANSI_ARGS_((Display *display,
+EXTERN void Tk_UnderlineChars(Display *display,
Drawable drawable, GC gc, Tk_Font tkfont,
CONST char *source, int x, int y,
- int firstByte, int lastByte));
+ int firstByte, int lastByte);
+#endif
+#ifndef Tk_UnderlineTextLayout_TCL_DECLARED
+#define Tk_UnderlineTextLayout_TCL_DECLARED
/* 179 */
-EXTERN void Tk_UnderlineTextLayout _ANSI_ARGS_((Display *display,
+EXTERN void Tk_UnderlineTextLayout(Display *display,
Drawable drawable, GC gc,
Tk_TextLayout layout, int x, int y,
- int underline));
+ int underline);
+#endif
+#ifndef Tk_Ungrab_TCL_DECLARED
+#define Tk_Ungrab_TCL_DECLARED
/* 180 */
-EXTERN void Tk_Ungrab _ANSI_ARGS_((Tk_Window tkwin));
+EXTERN void Tk_Ungrab(Tk_Window tkwin);
+#endif
+#ifndef Tk_UnmaintainGeometry_TCL_DECLARED
+#define Tk_UnmaintainGeometry_TCL_DECLARED
/* 181 */
-EXTERN void Tk_UnmaintainGeometry _ANSI_ARGS_((Tk_Window slave,
- Tk_Window master));
+EXTERN void Tk_UnmaintainGeometry(Tk_Window slave,
+ Tk_Window master);
+#endif
+#ifndef Tk_UnmapWindow_TCL_DECLARED
+#define Tk_UnmapWindow_TCL_DECLARED
/* 182 */
-EXTERN void Tk_UnmapWindow _ANSI_ARGS_((Tk_Window tkwin));
+EXTERN void Tk_UnmapWindow(Tk_Window tkwin);
+#endif
+#ifndef Tk_UnsetGrid_TCL_DECLARED
+#define Tk_UnsetGrid_TCL_DECLARED
/* 183 */
-EXTERN void Tk_UnsetGrid _ANSI_ARGS_((Tk_Window tkwin));
+EXTERN void Tk_UnsetGrid(Tk_Window tkwin);
+#endif
+#ifndef Tk_UpdatePointer_TCL_DECLARED
+#define Tk_UpdatePointer_TCL_DECLARED
/* 184 */
-EXTERN void Tk_UpdatePointer _ANSI_ARGS_((Tk_Window tkwin, int x,
- int y, int state));
+EXTERN void Tk_UpdatePointer(Tk_Window tkwin, int x, int y,
+ int state);
+#endif
+#ifndef Tk_AllocBitmapFromObj_TCL_DECLARED
+#define Tk_AllocBitmapFromObj_TCL_DECLARED
/* 185 */
-EXTERN Pixmap Tk_AllocBitmapFromObj _ANSI_ARGS_((
- Tcl_Interp *interp, Tk_Window tkwin,
- Tcl_Obj *objPtr));
+EXTERN Pixmap Tk_AllocBitmapFromObj(Tcl_Interp *interp,
+ Tk_Window tkwin, Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_Alloc3DBorderFromObj_TCL_DECLARED
+#define Tk_Alloc3DBorderFromObj_TCL_DECLARED
/* 186 */
-EXTERN Tk_3DBorder Tk_Alloc3DBorderFromObj _ANSI_ARGS_((
- Tcl_Interp *interp, Tk_Window tkwin,
- Tcl_Obj *objPtr));
+EXTERN Tk_3DBorder Tk_Alloc3DBorderFromObj(Tcl_Interp *interp,
+ Tk_Window tkwin, Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_AllocColorFromObj_TCL_DECLARED
+#define Tk_AllocColorFromObj_TCL_DECLARED
/* 187 */
-EXTERN XColor * Tk_AllocColorFromObj _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, Tcl_Obj *objPtr));
+EXTERN XColor * Tk_AllocColorFromObj(Tcl_Interp *interp,
+ Tk_Window tkwin, Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_AllocCursorFromObj_TCL_DECLARED
+#define Tk_AllocCursorFromObj_TCL_DECLARED
/* 188 */
-EXTERN Tk_Cursor Tk_AllocCursorFromObj _ANSI_ARGS_((
- Tcl_Interp *interp, Tk_Window tkwin,
- Tcl_Obj *objPtr));
+EXTERN Tk_Cursor Tk_AllocCursorFromObj(Tcl_Interp *interp,
+ Tk_Window tkwin, Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_AllocFontFromObj_TCL_DECLARED
+#define Tk_AllocFontFromObj_TCL_DECLARED
/* 189 */
-EXTERN Tk_Font Tk_AllocFontFromObj _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, Tcl_Obj *objPtr));
+EXTERN Tk_Font Tk_AllocFontFromObj(Tcl_Interp *interp,
+ Tk_Window tkwin, Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_CreateOptionTable_TCL_DECLARED
+#define Tk_CreateOptionTable_TCL_DECLARED
/* 190 */
-EXTERN Tk_OptionTable Tk_CreateOptionTable _ANSI_ARGS_((Tcl_Interp *interp,
- CONST Tk_OptionSpec *templatePtr));
+EXTERN Tk_OptionTable Tk_CreateOptionTable(Tcl_Interp *interp,
+ CONST Tk_OptionSpec *templatePtr);
+#endif
+#ifndef Tk_DeleteOptionTable_TCL_DECLARED
+#define Tk_DeleteOptionTable_TCL_DECLARED
/* 191 */
-EXTERN void Tk_DeleteOptionTable _ANSI_ARGS_((
- Tk_OptionTable optionTable));
+EXTERN void Tk_DeleteOptionTable(Tk_OptionTable optionTable);
+#endif
+#ifndef Tk_Free3DBorderFromObj_TCL_DECLARED
+#define Tk_Free3DBorderFromObj_TCL_DECLARED
/* 192 */
-EXTERN void Tk_Free3DBorderFromObj _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Obj *objPtr));
+EXTERN void Tk_Free3DBorderFromObj(Tk_Window tkwin,
+ Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_FreeBitmapFromObj_TCL_DECLARED
+#define Tk_FreeBitmapFromObj_TCL_DECLARED
/* 193 */
-EXTERN void Tk_FreeBitmapFromObj _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Obj *objPtr));
+EXTERN void Tk_FreeBitmapFromObj(Tk_Window tkwin,
+ Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_FreeColorFromObj_TCL_DECLARED
+#define Tk_FreeColorFromObj_TCL_DECLARED
/* 194 */
-EXTERN void Tk_FreeColorFromObj _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Obj *objPtr));
+EXTERN void Tk_FreeColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_FreeConfigOptions_TCL_DECLARED
+#define Tk_FreeConfigOptions_TCL_DECLARED
/* 195 */
-EXTERN void Tk_FreeConfigOptions _ANSI_ARGS_((char *recordPtr,
- Tk_OptionTable optionToken, Tk_Window tkwin));
+EXTERN void Tk_FreeConfigOptions(char *recordPtr,
+ Tk_OptionTable optionToken, Tk_Window tkwin);
+#endif
+#ifndef Tk_FreeSavedOptions_TCL_DECLARED
+#define Tk_FreeSavedOptions_TCL_DECLARED
/* 196 */
-EXTERN void Tk_FreeSavedOptions _ANSI_ARGS_((
- Tk_SavedOptions *savePtr));
+EXTERN void Tk_FreeSavedOptions(Tk_SavedOptions *savePtr);
+#endif
+#ifndef Tk_FreeCursorFromObj_TCL_DECLARED
+#define Tk_FreeCursorFromObj_TCL_DECLARED
/* 197 */
-EXTERN void Tk_FreeCursorFromObj _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Obj *objPtr));
+EXTERN void Tk_FreeCursorFromObj(Tk_Window tkwin,
+ Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_FreeFontFromObj_TCL_DECLARED
+#define Tk_FreeFontFromObj_TCL_DECLARED
/* 198 */
-EXTERN void Tk_FreeFontFromObj _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Obj *objPtr));
+EXTERN void Tk_FreeFontFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_Get3DBorderFromObj_TCL_DECLARED
+#define Tk_Get3DBorderFromObj_TCL_DECLARED
/* 199 */
-EXTERN Tk_3DBorder Tk_Get3DBorderFromObj _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Obj *objPtr));
+EXTERN Tk_3DBorder Tk_Get3DBorderFromObj(Tk_Window tkwin,
+ Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_GetAnchorFromObj_TCL_DECLARED
+#define Tk_GetAnchorFromObj_TCL_DECLARED
/* 200 */
-EXTERN int Tk_GetAnchorFromObj _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Obj *objPtr, Tk_Anchor *anchorPtr));
+EXTERN int Tk_GetAnchorFromObj(Tcl_Interp *interp,
+ Tcl_Obj *objPtr, Tk_Anchor *anchorPtr);
+#endif
+#ifndef Tk_GetBitmapFromObj_TCL_DECLARED
+#define Tk_GetBitmapFromObj_TCL_DECLARED
/* 201 */
-EXTERN Pixmap Tk_GetBitmapFromObj _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Obj *objPtr));
+EXTERN Pixmap Tk_GetBitmapFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_GetColorFromObj_TCL_DECLARED
+#define Tk_GetColorFromObj_TCL_DECLARED
/* 202 */
-EXTERN XColor * Tk_GetColorFromObj _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Obj *objPtr));
+EXTERN XColor * Tk_GetColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_GetCursorFromObj_TCL_DECLARED
+#define Tk_GetCursorFromObj_TCL_DECLARED
/* 203 */
-EXTERN Tk_Cursor Tk_GetCursorFromObj _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Obj *objPtr));
+EXTERN Tk_Cursor Tk_GetCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_GetOptionInfo_TCL_DECLARED
+#define Tk_GetOptionInfo_TCL_DECLARED
/* 204 */
-EXTERN Tcl_Obj * Tk_GetOptionInfo _ANSI_ARGS_((Tcl_Interp *interp,
- char *recordPtr, Tk_OptionTable optionTable,
- Tcl_Obj *namePtr, Tk_Window tkwin));
+EXTERN Tcl_Obj * Tk_GetOptionInfo(Tcl_Interp *interp, char *recordPtr,
+ Tk_OptionTable optionTable, Tcl_Obj *namePtr,
+ Tk_Window tkwin);
+#endif
+#ifndef Tk_GetOptionValue_TCL_DECLARED
+#define Tk_GetOptionValue_TCL_DECLARED
/* 205 */
-EXTERN Tcl_Obj * Tk_GetOptionValue _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN Tcl_Obj * Tk_GetOptionValue(Tcl_Interp *interp,
char *recordPtr, Tk_OptionTable optionTable,
- Tcl_Obj *namePtr, Tk_Window tkwin));
+ Tcl_Obj *namePtr, Tk_Window tkwin);
+#endif
+#ifndef Tk_GetJustifyFromObj_TCL_DECLARED
+#define Tk_GetJustifyFromObj_TCL_DECLARED
/* 206 */
-EXTERN int Tk_GetJustifyFromObj _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Obj *objPtr, Tk_Justify *justifyPtr));
+EXTERN int Tk_GetJustifyFromObj(Tcl_Interp *interp,
+ Tcl_Obj *objPtr, Tk_Justify *justifyPtr);
+#endif
+#ifndef Tk_GetMMFromObj_TCL_DECLARED
+#define Tk_GetMMFromObj_TCL_DECLARED
/* 207 */
-EXTERN int Tk_GetMMFromObj _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, Tcl_Obj *objPtr,
- double *doublePtr));
+EXTERN int Tk_GetMMFromObj(Tcl_Interp *interp, Tk_Window tkwin,
+ Tcl_Obj *objPtr, double *doublePtr);
+#endif
+#ifndef Tk_GetPixelsFromObj_TCL_DECLARED
+#define Tk_GetPixelsFromObj_TCL_DECLARED
/* 208 */
-EXTERN int Tk_GetPixelsFromObj _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN int Tk_GetPixelsFromObj(Tcl_Interp *interp,
Tk_Window tkwin, Tcl_Obj *objPtr,
- int *intPtr));
+ int *intPtr);
+#endif
+#ifndef Tk_GetReliefFromObj_TCL_DECLARED
+#define Tk_GetReliefFromObj_TCL_DECLARED
/* 209 */
-EXTERN int Tk_GetReliefFromObj _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Obj *objPtr, int *resultPtr));
+EXTERN int Tk_GetReliefFromObj(Tcl_Interp *interp,
+ Tcl_Obj *objPtr, int *resultPtr);
+#endif
+#ifndef Tk_GetScrollInfoObj_TCL_DECLARED
+#define Tk_GetScrollInfoObj_TCL_DECLARED
/* 210 */
-EXTERN int Tk_GetScrollInfoObj _ANSI_ARGS_((Tcl_Interp *interp,
- int objc, Tcl_Obj *CONST objv[],
- double *dblPtr, int *intPtr));
+EXTERN int Tk_GetScrollInfoObj(Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[], double *dblPtr,
+ int *intPtr);
+#endif
+#ifndef Tk_InitOptions_TCL_DECLARED
+#define Tk_InitOptions_TCL_DECLARED
/* 211 */
-EXTERN int Tk_InitOptions _ANSI_ARGS_((Tcl_Interp *interp,
- char *recordPtr, Tk_OptionTable optionToken,
- Tk_Window tkwin));
+EXTERN int Tk_InitOptions(Tcl_Interp *interp, char *recordPtr,
+ Tk_OptionTable optionToken, Tk_Window tkwin);
+#endif
+#ifndef Tk_MainEx_TCL_DECLARED
+#define Tk_MainEx_TCL_DECLARED
/* 212 */
-EXTERN void Tk_MainEx _ANSI_ARGS_((int argc, char **argv,
+EXTERN void Tk_MainEx(int argc, char **argv,
Tcl_AppInitProc *appInitProc,
- Tcl_Interp *interp));
+ Tcl_Interp *interp);
+#endif
+#ifndef Tk_RestoreSavedOptions_TCL_DECLARED
+#define Tk_RestoreSavedOptions_TCL_DECLARED
/* 213 */
-EXTERN void Tk_RestoreSavedOptions _ANSI_ARGS_((
- Tk_SavedOptions *savePtr));
+EXTERN void Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr);
+#endif
+#ifndef Tk_SetOptions_TCL_DECLARED
+#define Tk_SetOptions_TCL_DECLARED
/* 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));
+EXTERN 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);
+#endif
+#ifndef Tk_InitConsoleChannels_TCL_DECLARED
+#define Tk_InitConsoleChannels_TCL_DECLARED
/* 215 */
-EXTERN void Tk_InitConsoleChannels _ANSI_ARGS_((
- Tcl_Interp *interp));
+EXTERN void Tk_InitConsoleChannels(Tcl_Interp *interp);
+#endif
+#ifndef Tk_CreateConsoleWindow_TCL_DECLARED
+#define Tk_CreateConsoleWindow_TCL_DECLARED
/* 216 */
-EXTERN int Tk_CreateConsoleWindow _ANSI_ARGS_((
- Tcl_Interp *interp));
+EXTERN int Tk_CreateConsoleWindow(Tcl_Interp *interp);
+#endif
+#ifndef Tk_CreateSmoothMethod_TCL_DECLARED
+#define Tk_CreateSmoothMethod_TCL_DECLARED
/* 217 */
-EXTERN void Tk_CreateSmoothMethod _ANSI_ARGS_((
- Tcl_Interp *interp, Tk_SmoothMethod *method));
+EXTERN void Tk_CreateSmoothMethod(Tcl_Interp *interp,
+ Tk_SmoothMethod *method);
+#endif
/* Slot 218 is reserved */
/* Slot 219 is reserved */
+#ifndef Tk_GetDash_TCL_DECLARED
+#define Tk_GetDash_TCL_DECLARED
/* 220 */
-EXTERN int Tk_GetDash _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *value, Tk_Dash *dash));
+EXTERN int Tk_GetDash(Tcl_Interp *interp, CONST char *value,
+ Tk_Dash *dash);
+#endif
+#ifndef Tk_CreateOutline_TCL_DECLARED
+#define Tk_CreateOutline_TCL_DECLARED
/* 221 */
-EXTERN void Tk_CreateOutline _ANSI_ARGS_((Tk_Outline *outline));
+EXTERN void Tk_CreateOutline(Tk_Outline *outline);
+#endif
+#ifndef Tk_DeleteOutline_TCL_DECLARED
+#define Tk_DeleteOutline_TCL_DECLARED
/* 222 */
-EXTERN void Tk_DeleteOutline _ANSI_ARGS_((Display *display,
- Tk_Outline *outline));
+EXTERN void Tk_DeleteOutline(Display *display,
+ Tk_Outline *outline);
+#endif
+#ifndef Tk_ConfigOutlineGC_TCL_DECLARED
+#define Tk_ConfigOutlineGC_TCL_DECLARED
/* 223 */
-EXTERN int Tk_ConfigOutlineGC _ANSI_ARGS_((XGCValues *gcValues,
+EXTERN int Tk_ConfigOutlineGC(XGCValues *gcValues,
Tk_Canvas canvas, Tk_Item *item,
- Tk_Outline *outline));
+ Tk_Outline *outline);
+#endif
+#ifndef Tk_ChangeOutlineGC_TCL_DECLARED
+#define Tk_ChangeOutlineGC_TCL_DECLARED
/* 224 */
-EXTERN int Tk_ChangeOutlineGC _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *item, Tk_Outline *outline));
+EXTERN int Tk_ChangeOutlineGC(Tk_Canvas canvas, Tk_Item *item,
+ Tk_Outline *outline);
+#endif
+#ifndef Tk_ResetOutlineGC_TCL_DECLARED
+#define Tk_ResetOutlineGC_TCL_DECLARED
/* 225 */
-EXTERN int Tk_ResetOutlineGC _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *item, Tk_Outline *outline));
+EXTERN int Tk_ResetOutlineGC(Tk_Canvas canvas, Tk_Item *item,
+ Tk_Outline *outline);
+#endif
+#ifndef Tk_CanvasPsOutline_TCL_DECLARED
+#define Tk_CanvasPsOutline_TCL_DECLARED
/* 226 */
-EXTERN int Tk_CanvasPsOutline _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *item, Tk_Outline *outline));
+EXTERN int Tk_CanvasPsOutline(Tk_Canvas canvas, Tk_Item *item,
+ Tk_Outline *outline);
+#endif
+#ifndef Tk_SetTSOrigin_TCL_DECLARED
+#define Tk_SetTSOrigin_TCL_DECLARED
/* 227 */
-EXTERN void Tk_SetTSOrigin _ANSI_ARGS_((Tk_Window tkwin, GC gc,
- int x, int y));
+EXTERN void Tk_SetTSOrigin(Tk_Window tkwin, GC gc, int x, int y);
+#endif
+#ifndef Tk_CanvasGetCoordFromObj_TCL_DECLARED
+#define Tk_CanvasGetCoordFromObj_TCL_DECLARED
/* 228 */
-EXTERN int Tk_CanvasGetCoordFromObj _ANSI_ARGS_((
- Tcl_Interp *interp, Tk_Canvas canvas,
- Tcl_Obj *obj, double *doublePtr));
+EXTERN int Tk_CanvasGetCoordFromObj(Tcl_Interp *interp,
+ Tk_Canvas canvas, Tcl_Obj *obj,
+ double *doublePtr);
+#endif
+#ifndef Tk_CanvasSetOffset_TCL_DECLARED
+#define Tk_CanvasSetOffset_TCL_DECLARED
/* 229 */
-EXTERN void Tk_CanvasSetOffset _ANSI_ARGS_((Tk_Canvas canvas,
- GC gc, Tk_TSOffset *offset));
+EXTERN void Tk_CanvasSetOffset(Tk_Canvas canvas, GC gc,
+ Tk_TSOffset *offset);
+#endif
+#ifndef Tk_DitherPhoto_TCL_DECLARED
+#define Tk_DitherPhoto_TCL_DECLARED
/* 230 */
-EXTERN void Tk_DitherPhoto _ANSI_ARGS_((Tk_PhotoHandle handle,
- int x, int y, int width, int height));
+EXTERN void Tk_DitherPhoto(Tk_PhotoHandle handle, int x, int y,
+ int width, int height);
+#endif
+#ifndef Tk_PostscriptBitmap_TCL_DECLARED
+#define Tk_PostscriptBitmap_TCL_DECLARED
/* 231 */
-EXTERN int Tk_PostscriptBitmap _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN int Tk_PostscriptBitmap(Tcl_Interp *interp,
Tk_Window tkwin, Tk_PostscriptInfo psInfo,
Pixmap bitmap, int startX, int startY,
- int width, int height));
+ int width, int height);
+#endif
+#ifndef Tk_PostscriptColor_TCL_DECLARED
+#define Tk_PostscriptColor_TCL_DECLARED
/* 232 */
-EXTERN int Tk_PostscriptColor _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_PostscriptInfo psInfo, XColor *colorPtr));
+EXTERN int Tk_PostscriptColor(Tcl_Interp *interp,
+ Tk_PostscriptInfo psInfo, XColor *colorPtr);
+#endif
+#ifndef Tk_PostscriptFont_TCL_DECLARED
+#define Tk_PostscriptFont_TCL_DECLARED
/* 233 */
-EXTERN int Tk_PostscriptFont _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_PostscriptInfo psInfo, Tk_Font font));
+EXTERN int Tk_PostscriptFont(Tcl_Interp *interp,
+ Tk_PostscriptInfo psInfo, Tk_Font font);
+#endif
+#ifndef Tk_PostscriptImage_TCL_DECLARED
+#define Tk_PostscriptImage_TCL_DECLARED
/* 234 */
-EXTERN int Tk_PostscriptImage _ANSI_ARGS_((Tk_Image image,
+EXTERN int Tk_PostscriptImage(Tk_Image image,
Tcl_Interp *interp, Tk_Window tkwin,
Tk_PostscriptInfo psinfo, int x, int y,
- int width, int height, int prepass));
+ int width, int height, int prepass);
+#endif
+#ifndef Tk_PostscriptPath_TCL_DECLARED
+#define Tk_PostscriptPath_TCL_DECLARED
/* 235 */
-EXTERN void Tk_PostscriptPath _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN void Tk_PostscriptPath(Tcl_Interp *interp,
Tk_PostscriptInfo psInfo, double *coordPtr,
- int numPoints));
+ int numPoints);
+#endif
+#ifndef Tk_PostscriptStipple_TCL_DECLARED
+#define Tk_PostscriptStipple_TCL_DECLARED
/* 236 */
-EXTERN int Tk_PostscriptStipple _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN int Tk_PostscriptStipple(Tcl_Interp *interp,
Tk_Window tkwin, Tk_PostscriptInfo psInfo,
- Pixmap bitmap));
+ Pixmap bitmap);
+#endif
+#ifndef Tk_PostscriptY_TCL_DECLARED
+#define Tk_PostscriptY_TCL_DECLARED
/* 237 */
-EXTERN double Tk_PostscriptY _ANSI_ARGS_((double y,
- Tk_PostscriptInfo psInfo));
+EXTERN double Tk_PostscriptY(double y, Tk_PostscriptInfo psInfo);
+#endif
+#ifndef Tk_PostscriptPhoto_TCL_DECLARED
+#define Tk_PostscriptPhoto_TCL_DECLARED
/* 238 */
-EXTERN int Tk_PostscriptPhoto _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN int Tk_PostscriptPhoto(Tcl_Interp *interp,
Tk_PhotoImageBlock *blockPtr,
Tk_PostscriptInfo psInfo, int width,
- int height));
+ int height);
+#endif
+#ifndef Tk_CreateClientMessageHandler_TCL_DECLARED
+#define Tk_CreateClientMessageHandler_TCL_DECLARED
/* 239 */
-EXTERN void Tk_CreateClientMessageHandler _ANSI_ARGS_((
- Tk_ClientMessageProc *proc));
+EXTERN void Tk_CreateClientMessageHandler(
+ Tk_ClientMessageProc *proc);
+#endif
+#ifndef Tk_DeleteClientMessageHandler_TCL_DECLARED
+#define Tk_DeleteClientMessageHandler_TCL_DECLARED
/* 240 */
-EXTERN void Tk_DeleteClientMessageHandler _ANSI_ARGS_((
- Tk_ClientMessageProc *proc));
+EXTERN void Tk_DeleteClientMessageHandler(
+ Tk_ClientMessageProc *proc);
+#endif
+#ifndef Tk_CreateAnonymousWindow_TCL_DECLARED
+#define Tk_CreateAnonymousWindow_TCL_DECLARED
/* 241 */
-EXTERN Tk_Window Tk_CreateAnonymousWindow _ANSI_ARGS_((
- Tcl_Interp *interp, Tk_Window parent,
- CONST char *screenName));
+EXTERN Tk_Window Tk_CreateAnonymousWindow(Tcl_Interp *interp,
+ Tk_Window parent, CONST char *screenName);
+#endif
+#ifndef Tk_SetClassProcs_TCL_DECLARED
+#define Tk_SetClassProcs_TCL_DECLARED
/* 242 */
-EXTERN void Tk_SetClassProcs _ANSI_ARGS_((Tk_Window tkwin,
+EXTERN void Tk_SetClassProcs(Tk_Window tkwin,
Tk_ClassProcs *procs,
- ClientData instanceData));
+ ClientData instanceData);
+#endif
+#ifndef Tk_SetInternalBorderEx_TCL_DECLARED
+#define Tk_SetInternalBorderEx_TCL_DECLARED
/* 243 */
-EXTERN void Tk_SetInternalBorderEx _ANSI_ARGS_((Tk_Window tkwin,
- int left, int right, int top, int bottom));
+EXTERN void Tk_SetInternalBorderEx(Tk_Window tkwin, int left,
+ int right, int top, int bottom);
+#endif
+#ifndef Tk_SetMinimumRequestSize_TCL_DECLARED
+#define Tk_SetMinimumRequestSize_TCL_DECLARED
/* 244 */
-EXTERN void Tk_SetMinimumRequestSize _ANSI_ARGS_((
- Tk_Window tkwin, int minWidth, int minHeight));
+EXTERN void Tk_SetMinimumRequestSize(Tk_Window tkwin,
+ int minWidth, int minHeight);
+#endif
+#ifndef Tk_SetCaretPos_TCL_DECLARED
+#define Tk_SetCaretPos_TCL_DECLARED
/* 245 */
-EXTERN void Tk_SetCaretPos _ANSI_ARGS_((Tk_Window tkwin, int x,
- int y, int height));
+EXTERN void Tk_SetCaretPos(Tk_Window tkwin, int x, int y,
+ int height);
+#endif
+#ifndef Tk_PhotoPutBlock_Panic_TCL_DECLARED
+#define Tk_PhotoPutBlock_Panic_TCL_DECLARED
/* 246 */
-EXTERN void Tk_PhotoPutBlock _ANSI_ARGS_((Tk_PhotoHandle handle,
+EXTERN void Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr, int x, int y,
- int width, int height, int compRule));
+ int width, int height, int compRule);
+#endif
+#ifndef Tk_PhotoPutZoomedBlock_Panic_TCL_DECLARED
+#define Tk_PhotoPutZoomedBlock_Panic_TCL_DECLARED
/* 247 */
-EXTERN void Tk_PhotoPutZoomedBlock _ANSI_ARGS_((
- Tk_PhotoHandle handle,
+EXTERN void Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr, int x, int y,
int width, int height, int zoomX, int zoomY,
- int subsampleX, int subsampleY, int compRule));
+ int subsampleX, int subsampleY, int compRule);
+#endif
+#ifndef Tk_CollapseMotionEvents_TCL_DECLARED
+#define Tk_CollapseMotionEvents_TCL_DECLARED
/* 248 */
-EXTERN int Tk_CollapseMotionEvents _ANSI_ARGS_((
- Display *display, int collapse));
+EXTERN int Tk_CollapseMotionEvents(Display *display,
+ int collapse);
+#endif
+#ifndef Tk_RegisterStyleEngine_TCL_DECLARED
+#define Tk_RegisterStyleEngine_TCL_DECLARED
/* 249 */
-EXTERN Tk_StyleEngine Tk_RegisterStyleEngine _ANSI_ARGS_((CONST char *name,
- Tk_StyleEngine parent));
+EXTERN Tk_StyleEngine Tk_RegisterStyleEngine(CONST char *name,
+ Tk_StyleEngine parent);
+#endif
+#ifndef Tk_GetStyleEngine_TCL_DECLARED
+#define Tk_GetStyleEngine_TCL_DECLARED
/* 250 */
-EXTERN Tk_StyleEngine Tk_GetStyleEngine _ANSI_ARGS_((CONST char *name));
+EXTERN Tk_StyleEngine Tk_GetStyleEngine(CONST char *name);
+#endif
+#ifndef Tk_RegisterStyledElement_TCL_DECLARED
+#define Tk_RegisterStyledElement_TCL_DECLARED
/* 251 */
-EXTERN int Tk_RegisterStyledElement _ANSI_ARGS_((
- Tk_StyleEngine engine,
- Tk_ElementSpec *templatePtr));
+EXTERN int Tk_RegisterStyledElement(Tk_StyleEngine engine,
+ Tk_ElementSpec *templatePtr);
+#endif
+#ifndef Tk_GetElementId_TCL_DECLARED
+#define Tk_GetElementId_TCL_DECLARED
/* 252 */
-EXTERN int Tk_GetElementId _ANSI_ARGS_((CONST char *name));
+EXTERN int Tk_GetElementId(CONST char *name);
+#endif
+#ifndef Tk_CreateStyle_TCL_DECLARED
+#define Tk_CreateStyle_TCL_DECLARED
/* 253 */
-EXTERN Tk_Style Tk_CreateStyle _ANSI_ARGS_((CONST char *name,
- Tk_StyleEngine engine, ClientData clientData));
+EXTERN Tk_Style Tk_CreateStyle(CONST char *name,
+ Tk_StyleEngine engine, ClientData clientData);
+#endif
+#ifndef Tk_GetStyle_TCL_DECLARED
+#define Tk_GetStyle_TCL_DECLARED
/* 254 */
-EXTERN Tk_Style Tk_GetStyle _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *name));
+EXTERN Tk_Style Tk_GetStyle(Tcl_Interp *interp, CONST char *name);
+#endif
+#ifndef Tk_FreeStyle_TCL_DECLARED
+#define Tk_FreeStyle_TCL_DECLARED
/* 255 */
-EXTERN void Tk_FreeStyle _ANSI_ARGS_((Tk_Style style));
+EXTERN void Tk_FreeStyle(Tk_Style style);
+#endif
+#ifndef Tk_NameOfStyle_TCL_DECLARED
+#define Tk_NameOfStyle_TCL_DECLARED
/* 256 */
-EXTERN CONST char * Tk_NameOfStyle _ANSI_ARGS_((Tk_Style style));
+EXTERN CONST char * Tk_NameOfStyle(Tk_Style style);
+#endif
+#ifndef Tk_AllocStyleFromObj_TCL_DECLARED
+#define Tk_AllocStyleFromObj_TCL_DECLARED
/* 257 */
-EXTERN Tk_Style Tk_AllocStyleFromObj _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Obj *objPtr));
+EXTERN Tk_Style Tk_AllocStyleFromObj(Tcl_Interp *interp,
+ Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_GetStyleFromObj_TCL_DECLARED
+#define Tk_GetStyleFromObj_TCL_DECLARED
/* 258 */
-EXTERN Tk_Style Tk_GetStyleFromObj _ANSI_ARGS_((Tcl_Obj *objPtr));
+EXTERN Tk_Style Tk_GetStyleFromObj(Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_FreeStyleFromObj_TCL_DECLARED
+#define Tk_FreeStyleFromObj_TCL_DECLARED
/* 259 */
-EXTERN void Tk_FreeStyleFromObj _ANSI_ARGS_((Tcl_Obj *objPtr));
+EXTERN void Tk_FreeStyleFromObj(Tcl_Obj *objPtr);
+#endif
+#ifndef Tk_GetStyledElement_TCL_DECLARED
+#define Tk_GetStyledElement_TCL_DECLARED
/* 260 */
-EXTERN Tk_StyledElement Tk_GetStyledElement _ANSI_ARGS_((Tk_Style style,
- int elementId, Tk_OptionTable optionTable));
+EXTERN Tk_StyledElement Tk_GetStyledElement(Tk_Style style, int elementId,
+ Tk_OptionTable optionTable);
+#endif
+#ifndef Tk_GetElementSize_TCL_DECLARED
+#define Tk_GetElementSize_TCL_DECLARED
/* 261 */
-EXTERN void Tk_GetElementSize _ANSI_ARGS_((Tk_Style style,
+EXTERN void Tk_GetElementSize(Tk_Style style,
Tk_StyledElement element, char *recordPtr,
Tk_Window tkwin, int width, int height,
- int inner, int *widthPtr, int *heightPtr));
+ int inner, int *widthPtr, int *heightPtr);
+#endif
+#ifndef Tk_GetElementBox_TCL_DECLARED
+#define Tk_GetElementBox_TCL_DECLARED
/* 262 */
-EXTERN void Tk_GetElementBox _ANSI_ARGS_((Tk_Style style,
+EXTERN void Tk_GetElementBox(Tk_Style style,
Tk_StyledElement element, char *recordPtr,
Tk_Window tkwin, int x, int y, int width,
int height, int inner, int *xPtr, int *yPtr,
- int *widthPtr, int *heightPtr));
+ int *widthPtr, int *heightPtr);
+#endif
+#ifndef Tk_GetElementBorderWidth_TCL_DECLARED
+#define Tk_GetElementBorderWidth_TCL_DECLARED
/* 263 */
-EXTERN int Tk_GetElementBorderWidth _ANSI_ARGS_((Tk_Style style,
+EXTERN int Tk_GetElementBorderWidth(Tk_Style style,
Tk_StyledElement element, char *recordPtr,
- Tk_Window tkwin));
+ Tk_Window tkwin);
+#endif
+#ifndef Tk_DrawElement_TCL_DECLARED
+#define Tk_DrawElement_TCL_DECLARED
/* 264 */
-EXTERN void Tk_DrawElement _ANSI_ARGS_((Tk_Style style,
+EXTERN void Tk_DrawElement(Tk_Style style,
Tk_StyledElement element, char *recordPtr,
Tk_Window tkwin, Drawable d, int x, int y,
- int width, int height, int state));
+ int width, int height, int state);
+#endif
+#ifndef Tk_PhotoExpand_TCL_DECLARED
+#define Tk_PhotoExpand_TCL_DECLARED
+/* 265 */
+EXTERN int Tk_PhotoExpand(Tcl_Interp *interp,
+ Tk_PhotoHandle handle, int width, int height);
+#endif
+#ifndef Tk_PhotoPutBlock_TCL_DECLARED
+#define Tk_PhotoPutBlock_TCL_DECLARED
+/* 266 */
+EXTERN int Tk_PhotoPutBlock(Tcl_Interp *interp,
+ Tk_PhotoHandle handle,
+ Tk_PhotoImageBlock *blockPtr, int x, int y,
+ int width, int height, int compRule);
+#endif
+#ifndef Tk_PhotoPutZoomedBlock_TCL_DECLARED
+#define Tk_PhotoPutZoomedBlock_TCL_DECLARED
+/* 267 */
+EXTERN int Tk_PhotoPutZoomedBlock(Tcl_Interp *interp,
+ Tk_PhotoHandle handle,
+ Tk_PhotoImageBlock *blockPtr, int x, int y,
+ int width, int height, int zoomX, int zoomY,
+ int subsampleX, int subsampleY, int compRule);
+#endif
+#ifndef Tk_PhotoSetSize_TCL_DECLARED
+#define Tk_PhotoSetSize_TCL_DECLARED
+/* 268 */
+EXTERN int Tk_PhotoSetSize(Tcl_Interp *interp,
+ Tk_PhotoHandle handle, int width, int height);
+#endif
+#ifndef Tk_GetUserInactiveTime_TCL_DECLARED
+#define Tk_GetUserInactiveTime_TCL_DECLARED
+/* 269 */
+EXTERN long Tk_GetUserInactiveTime(Display *dpy);
+#endif
+#ifndef Tk_ResetUserInactiveTime_TCL_DECLARED
+#define Tk_ResetUserInactiveTime_TCL_DECLARED
+/* 270 */
+EXTERN void Tk_ResetUserInactiveTime(Display *dpy);
+#endif
+#ifndef Tk_Interp_TCL_DECLARED
+#define Tk_Interp_TCL_DECLARED
+/* 271 */
+EXTERN Tcl_Interp * Tk_Interp(Tk_Window tkwin);
+#endif
+#ifndef Tk_CreateOldImageType_TCL_DECLARED
+#define Tk_CreateOldImageType_TCL_DECLARED
+/* 272 */
+EXTERN void Tk_CreateOldImageType(Tk_ImageType *typePtr);
+#endif
+#ifndef Tk_CreateOldPhotoImageFormat_TCL_DECLARED
+#define Tk_CreateOldPhotoImageFormat_TCL_DECLARED
+/* 273 */
+EXTERN void Tk_CreateOldPhotoImageFormat(
+ Tk_PhotoImageFormat *formatPtr);
+#endif
typedef struct TkStubHooks {
struct TkPlatStubs *tkPlatStubs;
@@ -917,271 +1686,280 @@ typedef struct TkStubs {
int magic;
struct TkStubHooks *hooks;
- void (*tk_MainLoop) _ANSI_ARGS_((void)); /* 0 */
- XColor * (*tk_3DBorderColor) _ANSI_ARGS_((Tk_3DBorder border)); /* 1 */
- GC (*tk_3DBorderGC) _ANSI_ARGS_((Tk_Window tkwin, Tk_3DBorder border, int which)); /* 2 */
- void (*tk_3DHorizontalBevel) _ANSI_ARGS_((Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int leftIn, int rightIn, int topBevel, int relief)); /* 3 */
- void (*tk_3DVerticalBevel) _ANSI_ARGS_((Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int leftBevel, int relief)); /* 4 */
- void (*tk_AddOption) _ANSI_ARGS_((Tk_Window tkwin, CONST char *name, CONST char *value, int priority)); /* 5 */
- 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, CONST 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 */
- int (*tk_CanvasPsFont) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, Tk_Font font)); /* 13 */
- void (*tk_CanvasPsPath) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr, int numPoints)); /* 14 */
- int (*tk_CanvasPsStipple) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, Pixmap bitmap)); /* 15 */
- double (*tk_CanvasPsY) _ANSI_ARGS_((Tk_Canvas canvas, double y)); /* 16 */
- void (*tk_CanvasSetStippleOrigin) _ANSI_ARGS_((Tk_Canvas canvas, GC gc)); /* 17 */
- int (*tk_CanvasTagsParseProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset)); /* 18 */
- char * (*tk_CanvasTagsPrintProc) _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); /* 19 */
- Tk_Window (*tk_CanvasTkwin) _ANSI_ARGS_((Tk_Canvas canvas)); /* 20 */
- void (*tk_CanvasWindowCoords) _ANSI_ARGS_((Tk_Canvas canvas, double x, double y, short *screenXPtr, short *screenYPtr)); /* 21 */
- void (*tk_ChangeWindowAttributes) _ANSI_ARGS_((Tk_Window tkwin, unsigned long valueMask, XSetWindowAttributes *attsPtr)); /* 22 */
- int (*tk_CharBbox) _ANSI_ARGS_((Tk_TextLayout layout, int index, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr)); /* 23 */
- void (*tk_ClearSelection) _ANSI_ARGS_((Tk_Window tkwin, Atom selection)); /* 24 */
- int (*tk_ClipboardAppend) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, Atom target, Atom format, char *buffer)); /* 25 */
- int (*tk_ClipboardClear) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin)); /* 26 */
- int (*tk_ConfigureInfo) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, Tk_ConfigSpec *specs, char *widgRec, CONST char *argvName, int flags)); /* 27 */
- int (*tk_ConfigureValue) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, Tk_ConfigSpec *specs, char *widgRec, CONST char *argvName, int flags)); /* 28 */
- int (*tk_ConfigureWidget) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, Tk_ConfigSpec *specs, int argc, CONST84 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 *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, CONST char *eventStr, CONST char *script, 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 */
- void (*tk_CreateGenericHandler) _ANSI_ARGS_((Tk_GenericProc *proc, ClientData clientData)); /* 37 */
- void (*tk_CreateImageType) _ANSI_ARGS_((Tk_ImageType *typePtr)); /* 38 */
- void (*tk_CreateItemType) _ANSI_ARGS_((Tk_ItemType *typePtr)); /* 39 */
- void (*tk_CreatePhotoImageFormat) _ANSI_ARGS_((Tk_PhotoImageFormat *formatPtr)); /* 40 */
- 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, CONST char *name, CONST char *screenName)); /* 42 */
- Tk_Window (*tk_CreateWindowFromPath) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, CONST char *pathName, CONST char *screenName)); /* 43 */
- int (*tk_DefineBitmap) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *name, CONST 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, CONST 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 */
- void (*tk_DeleteGenericHandler) _ANSI_ARGS_((Tk_GenericProc *proc, ClientData clientData)); /* 51 */
- void (*tk_DeleteImage) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *name)); /* 52 */
- void (*tk_DeleteSelHandler) _ANSI_ARGS_((Tk_Window tkwin, Atom selection, Atom target)); /* 53 */
- void (*tk_DestroyWindow) _ANSI_ARGS_((Tk_Window tkwin)); /* 54 */
- CONST84_RETURN char * (*tk_DisplayName) _ANSI_ARGS_((Tk_Window tkwin)); /* 55 */
- 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 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 */
- void (*tk_Fill3DRectangle) _ANSI_ARGS_((Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief)); /* 63 */
- Tk_PhotoHandle (*tk_FindPhoto) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *imageName)); /* 64 */
- Font (*tk_FontId) _ANSI_ARGS_((Tk_Font font)); /* 65 */
- void (*tk_Free3DBorder) _ANSI_ARGS_((Tk_3DBorder border)); /* 66 */
- void (*tk_FreeBitmap) _ANSI_ARGS_((Display *display, Pixmap bitmap)); /* 67 */
- void (*tk_FreeColor) _ANSI_ARGS_((XColor *colorPtr)); /* 68 */
- void (*tk_FreeColormap) _ANSI_ARGS_((Display *display, Colormap colormap)); /* 69 */
- void (*tk_FreeCursor) _ANSI_ARGS_((Display *display, Tk_Cursor cursor)); /* 70 */
- void (*tk_FreeFont) _ANSI_ARGS_((Tk_Font f)); /* 71 */
- void (*tk_FreeGC) _ANSI_ARGS_((Display *display, GC gc)); /* 72 */
- void (*tk_FreeImage) _ANSI_ARGS_((Tk_Image image)); /* 73 */
- void (*tk_FreeOptions) _ANSI_ARGS_((Tk_ConfigSpec *specs, char *widgRec, Display *display, int needFlags)); /* 74 */
- void (*tk_FreePixmap) _ANSI_ARGS_((Display *display, Pixmap pixmap)); /* 75 */
- void (*tk_FreeTextLayout) _ANSI_ARGS_((Tk_TextLayout textLayout)); /* 76 */
- void (*tk_FreeXId) _ANSI_ARGS_((Display *display, XID xid)); /* 77 */
- GC (*tk_GCForColor) _ANSI_ARGS_((XColor *colorPtr, Drawable drawable)); /* 78 */
- 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, CONST char *str, Tk_Anchor *anchorPtr)); /* 82 */
- CONST84_RETURN char * (*tk_GetAtomName) _ANSI_ARGS_((Tk_Window tkwin, Atom atom)); /* 83 */
- CONST84_RETURN char * (*tk_GetBinding) _ANSI_ARGS_((Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, CONST 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, CONST char *source, int width, int height)); /* 86 */
- int (*tk_GetCapStyle) _ANSI_ARGS_((Tcl_Interp *interp, CONST 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, CONST 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, CONST char *source, CONST 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 *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, CONST char *name, Tk_ImageChangedProc *changeProc, ClientData clientData)); /* 97 */
- ClientData (*tk_GetImageMasterData) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *name, Tk_ImageType **typePtrPtr)); /* 98 */
- Tk_ItemType * (*tk_GetItemTypes) _ANSI_ARGS_((void)); /* 99 */
- int (*tk_GetJoinStyle) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *str, int *joinPtr)); /* 100 */
- int (*tk_GetJustify) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *str, Tk_Justify *justifyPtr)); /* 101 */
- int (*tk_GetNumMainWindows) _ANSI_ARGS_((void)); /* 102 */
- Tk_Uid (*tk_GetOption) _ANSI_ARGS_((Tk_Window tkwin, CONST char *name, CONST char *className)); /* 103 */
- int (*tk_GetPixels) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, CONST 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, CONST 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, CONST84 char **argv, double *dblPtr, int *intPtr)); /* 108 */
- int (*tk_GetScreenMM) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, CONST 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 *str)); /* 111 */
- Visual * (*tk_GetVisual) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, CONST 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 */
- Tk_Window (*tk_IdToWindow) _ANSI_ARGS_((Display *display, Window window)); /* 116 */
- void (*tk_ImageChanged) _ANSI_ARGS_((Tk_ImageMaster master, int x, int y, int width, int height, int imageWidth, int imageHeight)); /* 117 */
- int (*tk_Init) _ANSI_ARGS_((Tcl_Interp *interp)); /* 118 */
- Atom (*tk_InternAtom) _ANSI_ARGS_((Tk_Window tkwin, CONST char *name)); /* 119 */
- int (*tk_IntersectTextLayout) _ANSI_ARGS_((Tk_TextLayout layout, int x, int y, int width, int height)); /* 120 */
- void (*tk_MaintainGeometry) _ANSI_ARGS_((Tk_Window slave, Tk_Window master, int x, int y, int width, int height)); /* 121 */
- Tk_Window (*tk_MainWindow) _ANSI_ARGS_((Tcl_Interp *interp)); /* 122 */
- 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 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 */
- CONST84_RETURN char * (*tk_NameOf3DBorder) _ANSI_ARGS_((Tk_3DBorder border)); /* 130 */
- CONST84_RETURN char * (*tk_NameOfAnchor) _ANSI_ARGS_((Tk_Anchor anchor)); /* 131 */
- CONST84_RETURN char * (*tk_NameOfBitmap) _ANSI_ARGS_((Display *display, Pixmap bitmap)); /* 132 */
- CONST84_RETURN char * (*tk_NameOfCapStyle) _ANSI_ARGS_((int cap)); /* 133 */
- CONST84_RETURN char * (*tk_NameOfColor) _ANSI_ARGS_((XColor *colorPtr)); /* 134 */
- CONST84_RETURN char * (*tk_NameOfCursor) _ANSI_ARGS_((Display *display, Tk_Cursor cursor)); /* 135 */
- CONST84_RETURN char * (*tk_NameOfFont) _ANSI_ARGS_((Tk_Font font)); /* 136 */
- CONST84_RETURN char * (*tk_NameOfImage) _ANSI_ARGS_((Tk_ImageMaster imageMaster)); /* 137 */
- CONST84_RETURN char * (*tk_NameOfJoinStyle) _ANSI_ARGS_((int join)); /* 138 */
- CONST84_RETURN char * (*tk_NameOfJustify) _ANSI_ARGS_((Tk_Justify justify)); /* 139 */
- CONST84_RETURN char * (*tk_NameOfRelief) _ANSI_ARGS_((int relief)); /* 140 */
- Tk_Window (*tk_NameToWindow) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *pathName, Tk_Window tkwin)); /* 141 */
- void (*tk_OwnSelection) _ANSI_ARGS_((Tk_Window tkwin, Atom selection, Tk_LostSelProc *proc, ClientData clientData)); /* 142 */
- int (*tk_ParseArgv) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, CONST84 char **argv, Tk_ArgvInfo *argTable, int flags)); /* 143 */
- void (*tk_PhotoPutBlock_NoComposite) _ANSI_ARGS_((Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height)); /* 144 */
- void (*tk_PhotoPutZoomedBlock_NoComposite) _ANSI_ARGS_((Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY)); /* 145 */
- int (*tk_PhotoGetImage) _ANSI_ARGS_((Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr)); /* 146 */
- void (*tk_PhotoBlank) _ANSI_ARGS_((Tk_PhotoHandle handle)); /* 147 */
- void (*tk_PhotoExpand) _ANSI_ARGS_((Tk_PhotoHandle handle, int width, int height)); /* 148 */
- void (*tk_PhotoGetSize) _ANSI_ARGS_((Tk_PhotoHandle handle, int *widthPtr, int *heightPtr)); /* 149 */
- void (*tk_PhotoSetSize) _ANSI_ARGS_((Tk_PhotoHandle handle, int width, int height)); /* 150 */
- int (*tk_PointToChar) _ANSI_ARGS_((Tk_TextLayout layout, int x, int y)); /* 151 */
- int (*tk_PostscriptFontName) _ANSI_ARGS_((Tk_Font tkfont, Tcl_DString *dsPtr)); /* 152 */
- void (*tk_PreserveColormap) _ANSI_ARGS_((Display *display, Colormap colormap)); /* 153 */
- void (*tk_QueueWindowEvent) _ANSI_ARGS_((XEvent *eventPtr, Tcl_QueuePosition position)); /* 154 */
- void (*tk_RedrawImage) _ANSI_ARGS_((Tk_Image image, int imageX, int imageY, int width, int height, Drawable drawable, int drawableX, int drawableY)); /* 155 */
- void (*tk_ResizeWindow) _ANSI_ARGS_((Tk_Window tkwin, int width, int height)); /* 156 */
- int (*tk_RestackWindow) _ANSI_ARGS_((Tk_Window tkwin, int aboveBelow, Tk_Window other)); /* 157 */
- Tk_RestrictProc * (*tk_RestrictEvents) _ANSI_ARGS_((Tk_RestrictProc *proc, ClientData arg, ClientData *prevArgPtr)); /* 158 */
- int (*tk_SafeInit) _ANSI_ARGS_((Tcl_Interp *interp)); /* 159 */
- CONST char * (*tk_SetAppName) _ANSI_ARGS_((Tk_Window tkwin, CONST char *name)); /* 160 */
- void (*tk_SetBackgroundFromBorder) _ANSI_ARGS_((Tk_Window tkwin, Tk_3DBorder border)); /* 161 */
- void (*tk_SetClass) _ANSI_ARGS_((Tk_Window tkwin, CONST char *className)); /* 162 */
- void (*tk_SetGrid) _ANSI_ARGS_((Tk_Window tkwin, int reqWidth, int reqHeight, int gridWidth, int gridHeight)); /* 163 */
- void (*tk_SetInternalBorder) _ANSI_ARGS_((Tk_Window tkwin, int width)); /* 164 */
- void (*tk_SetWindowBackground) _ANSI_ARGS_((Tk_Window tkwin, unsigned long pixel)); /* 165 */
- void (*tk_SetWindowBackgroundPixmap) _ANSI_ARGS_((Tk_Window tkwin, Pixmap pixmap)); /* 166 */
- void (*tk_SetWindowBorder) _ANSI_ARGS_((Tk_Window tkwin, unsigned long pixel)); /* 167 */
- void (*tk_SetWindowBorderWidth) _ANSI_ARGS_((Tk_Window tkwin, int width)); /* 168 */
- void (*tk_SetWindowBorderPixmap) _ANSI_ARGS_((Tk_Window tkwin, Pixmap pixmap)); /* 169 */
- void (*tk_SetWindowColormap) _ANSI_ARGS_((Tk_Window tkwin, Colormap colormap)); /* 170 */
- int (*tk_SetWindowVisual) _ANSI_ARGS_((Tk_Window tkwin, Visual *visual, int depth, Colormap colormap)); /* 171 */
- void (*tk_SizeOfBitmap) _ANSI_ARGS_((Display *display, Pixmap bitmap, int *widthPtr, int *heightPtr)); /* 172 */
- 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 *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 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 */
- void (*tk_InitConsoleChannels) _ANSI_ARGS_((Tcl_Interp *interp)); /* 215 */
- int (*tk_CreateConsoleWindow) _ANSI_ARGS_((Tcl_Interp *interp)); /* 216 */
- void (*tk_CreateSmoothMethod) _ANSI_ARGS_((Tcl_Interp *interp, Tk_SmoothMethod *method)); /* 217 */
+ void (*tk_MainLoop) (void); /* 0 */
+ XColor * (*tk_3DBorderColor) (Tk_3DBorder border); /* 1 */
+ GC (*tk_3DBorderGC) (Tk_Window tkwin, Tk_3DBorder border, int which); /* 2 */
+ void (*tk_3DHorizontalBevel) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int leftIn, int rightIn, int topBevel, int relief); /* 3 */
+ void (*tk_3DVerticalBevel) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int leftBevel, int relief); /* 4 */
+ void (*tk_AddOption) (Tk_Window tkwin, CONST char *name, CONST char *value, int priority); /* 5 */
+ void (*tk_BindEvent) (Tk_BindingTable bindingTable, XEvent *eventPtr, Tk_Window tkwin, int numObjects, ClientData *objectPtr); /* 6 */
+ void (*tk_CanvasDrawableCoords) (Tk_Canvas canvas, double x, double y, short *drawableXPtr, short *drawableYPtr); /* 7 */
+ void (*tk_CanvasEventuallyRedraw) (Tk_Canvas canvas, int x1, int y1, int x2, int y2); /* 8 */
+ int (*tk_CanvasGetCoord) (Tcl_Interp *interp, Tk_Canvas canvas, CONST char *str, double *doublePtr); /* 9 */
+ Tk_CanvasTextInfo * (*tk_CanvasGetTextInfo) (Tk_Canvas canvas); /* 10 */
+ int (*tk_CanvasPsBitmap) (Tcl_Interp *interp, Tk_Canvas canvas, Pixmap bitmap, int x, int y, int width, int height); /* 11 */
+ int (*tk_CanvasPsColor) (Tcl_Interp *interp, Tk_Canvas canvas, XColor *colorPtr); /* 12 */
+ int (*tk_CanvasPsFont) (Tcl_Interp *interp, Tk_Canvas canvas, Tk_Font font); /* 13 */
+ void (*tk_CanvasPsPath) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr, int numPoints); /* 14 */
+ int (*tk_CanvasPsStipple) (Tcl_Interp *interp, Tk_Canvas canvas, Pixmap bitmap); /* 15 */
+ double (*tk_CanvasPsY) (Tk_Canvas canvas, double y); /* 16 */
+ void (*tk_CanvasSetStippleOrigin) (Tk_Canvas canvas, GC gc); /* 17 */
+ int (*tk_CanvasTagsParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset); /* 18 */
+ char * (*tk_CanvasTagsPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 19 */
+ Tk_Window (*tk_CanvasTkwin) (Tk_Canvas canvas); /* 20 */
+ void (*tk_CanvasWindowCoords) (Tk_Canvas canvas, double x, double y, short *screenXPtr, short *screenYPtr); /* 21 */
+ void (*tk_ChangeWindowAttributes) (Tk_Window tkwin, unsigned long valueMask, XSetWindowAttributes *attsPtr); /* 22 */
+ int (*tk_CharBbox) (Tk_TextLayout layout, int index, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 23 */
+ void (*tk_ClearSelection) (Tk_Window tkwin, Atom selection); /* 24 */
+ int (*tk_ClipboardAppend) (Tcl_Interp *interp, Tk_Window tkwin, Atom target, Atom format, char *buffer); /* 25 */
+ int (*tk_ClipboardClear) (Tcl_Interp *interp, Tk_Window tkwin); /* 26 */
+ int (*tk_ConfigureInfo) (Tcl_Interp *interp, Tk_Window tkwin, Tk_ConfigSpec *specs, char *widgRec, CONST char *argvName, int flags); /* 27 */
+ int (*tk_ConfigureValue) (Tcl_Interp *interp, Tk_Window tkwin, Tk_ConfigSpec *specs, char *widgRec, CONST char *argvName, int flags); /* 28 */
+ int (*tk_ConfigureWidget) (Tcl_Interp *interp, Tk_Window tkwin, Tk_ConfigSpec *specs, int argc, CONST84 char **argv, char *widgRec, int flags); /* 29 */
+ void (*tk_ConfigureWindow) (Tk_Window tkwin, unsigned int valueMask, XWindowChanges *valuePtr); /* 30 */
+ Tk_TextLayout (*tk_ComputeTextLayout) (Tk_Font font, CONST char *str, int numChars, int wrapLength, Tk_Justify justify, int flags, int *widthPtr, int *heightPtr); /* 31 */
+ Tk_Window (*tk_CoordsToWindow) (int rootX, int rootY, Tk_Window tkwin); /* 32 */
+ unsigned long (*tk_CreateBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, CONST char *eventStr, CONST char *command, int append); /* 33 */
+ Tk_BindingTable (*tk_CreateBindingTable) (Tcl_Interp *interp); /* 34 */
+ Tk_ErrorHandler (*tk_CreateErrorHandler) (Display *display, int errNum, int request, int minorCode, Tk_ErrorProc *errorProc, ClientData clientData); /* 35 */
+ void (*tk_CreateEventHandler) (Tk_Window token, unsigned long mask, Tk_EventProc *proc, ClientData clientData); /* 36 */
+ void (*tk_CreateGenericHandler) (Tk_GenericProc *proc, ClientData clientData); /* 37 */
+ void (*tk_CreateImageType) (Tk_ImageType *typePtr); /* 38 */
+ void (*tk_CreateItemType) (Tk_ItemType *typePtr); /* 39 */
+ void (*tk_CreatePhotoImageFormat) (Tk_PhotoImageFormat *formatPtr); /* 40 */
+ void (*tk_CreateSelHandler) (Tk_Window tkwin, Atom selection, Atom target, Tk_SelectionProc *proc, ClientData clientData, Atom format); /* 41 */
+ Tk_Window (*tk_CreateWindow) (Tcl_Interp *interp, Tk_Window parent, CONST char *name, CONST char *screenName); /* 42 */
+ Tk_Window (*tk_CreateWindowFromPath) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *pathName, CONST char *screenName); /* 43 */
+ int (*tk_DefineBitmap) (Tcl_Interp *interp, CONST char *name, CONST char *source, int width, int height); /* 44 */
+ void (*tk_DefineCursor) (Tk_Window window, Tk_Cursor cursor); /* 45 */
+ void (*tk_DeleteAllBindings) (Tk_BindingTable bindingTable, ClientData object); /* 46 */
+ int (*tk_DeleteBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, CONST char *eventStr); /* 47 */
+ void (*tk_DeleteBindingTable) (Tk_BindingTable bindingTable); /* 48 */
+ void (*tk_DeleteErrorHandler) (Tk_ErrorHandler handler); /* 49 */
+ void (*tk_DeleteEventHandler) (Tk_Window token, unsigned long mask, Tk_EventProc *proc, ClientData clientData); /* 50 */
+ void (*tk_DeleteGenericHandler) (Tk_GenericProc *proc, ClientData clientData); /* 51 */
+ void (*tk_DeleteImage) (Tcl_Interp *interp, CONST char *name); /* 52 */
+ void (*tk_DeleteSelHandler) (Tk_Window tkwin, Atom selection, Atom target); /* 53 */
+ void (*tk_DestroyWindow) (Tk_Window tkwin); /* 54 */
+ CONST84_RETURN char * (*tk_DisplayName) (Tk_Window tkwin); /* 55 */
+ int (*tk_DistanceToTextLayout) (Tk_TextLayout layout, int x, int y); /* 56 */
+ void (*tk_Draw3DPolygon) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint *pointPtr, int numPoints, int borderWidth, int leftRelief); /* 57 */
+ void (*tk_Draw3DRectangle) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); /* 58 */
+ void (*tk_DrawChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, CONST char *source, int numBytes, int x, int y); /* 59 */
+ void (*tk_DrawFocusHighlight) (Tk_Window tkwin, GC gc, int width, Drawable drawable); /* 60 */
+ void (*tk_DrawTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int firstChar, int lastChar); /* 61 */
+ void (*tk_Fill3DPolygon) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint *pointPtr, int numPoints, int borderWidth, int leftRelief); /* 62 */
+ void (*tk_Fill3DRectangle) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); /* 63 */
+ Tk_PhotoHandle (*tk_FindPhoto) (Tcl_Interp *interp, CONST char *imageName); /* 64 */
+ Font (*tk_FontId) (Tk_Font font); /* 65 */
+ void (*tk_Free3DBorder) (Tk_3DBorder border); /* 66 */
+ void (*tk_FreeBitmap) (Display *display, Pixmap bitmap); /* 67 */
+ void (*tk_FreeColor) (XColor *colorPtr); /* 68 */
+ void (*tk_FreeColormap) (Display *display, Colormap colormap); /* 69 */
+ void (*tk_FreeCursor) (Display *display, Tk_Cursor cursor); /* 70 */
+ void (*tk_FreeFont) (Tk_Font f); /* 71 */
+ void (*tk_FreeGC) (Display *display, GC gc); /* 72 */
+ void (*tk_FreeImage) (Tk_Image image); /* 73 */
+ void (*tk_FreeOptions) (Tk_ConfigSpec *specs, char *widgRec, Display *display, int needFlags); /* 74 */
+ void (*tk_FreePixmap) (Display *display, Pixmap pixmap); /* 75 */
+ void (*tk_FreeTextLayout) (Tk_TextLayout textLayout); /* 76 */
+ void (*tk_FreeXId) (Display *display, XID xid); /* 77 */
+ GC (*tk_GCForColor) (XColor *colorPtr, Drawable drawable); /* 78 */
+ void (*tk_GeometryRequest) (Tk_Window tkwin, int reqWidth, int reqHeight); /* 79 */
+ Tk_3DBorder (*tk_Get3DBorder) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid colorName); /* 80 */
+ void (*tk_GetAllBindings) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object); /* 81 */
+ int (*tk_GetAnchor) (Tcl_Interp *interp, CONST char *str, Tk_Anchor *anchorPtr); /* 82 */
+ CONST84_RETURN char * (*tk_GetAtomName) (Tk_Window tkwin, Atom atom); /* 83 */
+ CONST84_RETURN char * (*tk_GetBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, CONST char *eventStr); /* 84 */
+ Pixmap (*tk_GetBitmap) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *str); /* 85 */
+ Pixmap (*tk_GetBitmapFromData) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *source, int width, int height); /* 86 */
+ int (*tk_GetCapStyle) (Tcl_Interp *interp, CONST char *str, int *capPtr); /* 87 */
+ XColor * (*tk_GetColor) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid name); /* 88 */
+ XColor * (*tk_GetColorByValue) (Tk_Window tkwin, XColor *colorPtr); /* 89 */
+ Colormap (*tk_GetColormap) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *str); /* 90 */
+ Tk_Cursor (*tk_GetCursor) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid str); /* 91 */
+ Tk_Cursor (*tk_GetCursorFromData) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *source, CONST char *mask, int width, int height, int xHot, int yHot, Tk_Uid fg, Tk_Uid bg); /* 92 */
+ Tk_Font (*tk_GetFont) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *str); /* 93 */
+ Tk_Font (*tk_GetFontFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 94 */
+ void (*tk_GetFontMetrics) (Tk_Font font, Tk_FontMetrics *fmPtr); /* 95 */
+ GC (*tk_GetGC) (Tk_Window tkwin, unsigned long valueMask, XGCValues *valuePtr); /* 96 */
+ Tk_Image (*tk_GetImage) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *name, Tk_ImageChangedProc *changeProc, ClientData clientData); /* 97 */
+ ClientData (*tk_GetImageMasterData) (Tcl_Interp *interp, CONST char *name, Tk_ImageType **typePtrPtr); /* 98 */
+ Tk_ItemType * (*tk_GetItemTypes) (void); /* 99 */
+ int (*tk_GetJoinStyle) (Tcl_Interp *interp, CONST char *str, int *joinPtr); /* 100 */
+ int (*tk_GetJustify) (Tcl_Interp *interp, CONST char *str, Tk_Justify *justifyPtr); /* 101 */
+ int (*tk_GetNumMainWindows) (void); /* 102 */
+ Tk_Uid (*tk_GetOption) (Tk_Window tkwin, CONST char *name, CONST char *className); /* 103 */
+ int (*tk_GetPixels) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *str, int *intPtr); /* 104 */
+ Pixmap (*tk_GetPixmap) (Display *display, Drawable d, int width, int height, int depth); /* 105 */
+ int (*tk_GetRelief) (Tcl_Interp *interp, CONST char *name, int *reliefPtr); /* 106 */
+ void (*tk_GetRootCoords) (Tk_Window tkwin, int *xPtr, int *yPtr); /* 107 */
+ int (*tk_GetScrollInfo) (Tcl_Interp *interp, int argc, CONST84 char **argv, double *dblPtr, int *intPtr); /* 108 */
+ int (*tk_GetScreenMM) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *str, double *doublePtr); /* 109 */
+ int (*tk_GetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); /* 110 */
+ Tk_Uid (*tk_GetUid) (CONST char *str); /* 111 */
+ Visual * (*tk_GetVisual) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *str, int *depthPtr, Colormap *colormapPtr); /* 112 */
+ void (*tk_GetVRootGeometry) (Tk_Window tkwin, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 113 */
+ int (*tk_Grab) (Tcl_Interp *interp, Tk_Window tkwin, int grabGlobal); /* 114 */
+ void (*tk_HandleEvent) (XEvent *eventPtr); /* 115 */
+ Tk_Window (*tk_IdToWindow) (Display *display, Window window); /* 116 */
+ void (*tk_ImageChanged) (Tk_ImageMaster master, int x, int y, int width, int height, int imageWidth, int imageHeight); /* 117 */
+ int (*tk_Init) (Tcl_Interp *interp); /* 118 */
+ Atom (*tk_InternAtom) (Tk_Window tkwin, CONST char *name); /* 119 */
+ int (*tk_IntersectTextLayout) (Tk_TextLayout layout, int x, int y, int width, int height); /* 120 */
+ void (*tk_MaintainGeometry) (Tk_Window slave, Tk_Window master, int x, int y, int width, int height); /* 121 */
+ Tk_Window (*tk_MainWindow) (Tcl_Interp *interp); /* 122 */
+ void (*tk_MakeWindowExist) (Tk_Window tkwin); /* 123 */
+ void (*tk_ManageGeometry) (Tk_Window tkwin, CONST Tk_GeomMgr *mgrPtr, ClientData clientData); /* 124 */
+ void (*tk_MapWindow) (Tk_Window tkwin); /* 125 */
+ int (*tk_MeasureChars) (Tk_Font tkfont, CONST char *source, int numBytes, int maxPixels, int flags, int *lengthPtr); /* 126 */
+ void (*tk_MoveResizeWindow) (Tk_Window tkwin, int x, int y, int width, int height); /* 127 */
+ void (*tk_MoveWindow) (Tk_Window tkwin, int x, int y); /* 128 */
+ void (*tk_MoveToplevelWindow) (Tk_Window tkwin, int x, int y); /* 129 */
+ CONST84_RETURN char * (*tk_NameOf3DBorder) (Tk_3DBorder border); /* 130 */
+ CONST84_RETURN char * (*tk_NameOfAnchor) (Tk_Anchor anchor); /* 131 */
+ CONST84_RETURN char * (*tk_NameOfBitmap) (Display *display, Pixmap bitmap); /* 132 */
+ CONST84_RETURN char * (*tk_NameOfCapStyle) (int cap); /* 133 */
+ CONST84_RETURN char * (*tk_NameOfColor) (XColor *colorPtr); /* 134 */
+ CONST84_RETURN char * (*tk_NameOfCursor) (Display *display, Tk_Cursor cursor); /* 135 */
+ CONST84_RETURN char * (*tk_NameOfFont) (Tk_Font font); /* 136 */
+ CONST84_RETURN char * (*tk_NameOfImage) (Tk_ImageMaster imageMaster); /* 137 */
+ CONST84_RETURN char * (*tk_NameOfJoinStyle) (int join); /* 138 */
+ CONST84_RETURN char * (*tk_NameOfJustify) (Tk_Justify justify); /* 139 */
+ CONST84_RETURN char * (*tk_NameOfRelief) (int relief); /* 140 */
+ Tk_Window (*tk_NameToWindow) (Tcl_Interp *interp, CONST char *pathName, Tk_Window tkwin); /* 141 */
+ void (*tk_OwnSelection) (Tk_Window tkwin, Atom selection, Tk_LostSelProc *proc, ClientData clientData); /* 142 */
+ int (*tk_ParseArgv) (Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, CONST84 char **argv, Tk_ArgvInfo *argTable, int flags); /* 143 */
+ void (*tk_PhotoPutBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); /* 144 */
+ void (*tk_PhotoPutZoomedBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY); /* 145 */
+ int (*tk_PhotoGetImage) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr); /* 146 */
+ void (*tk_PhotoBlank) (Tk_PhotoHandle handle); /* 147 */
+ void (*tk_PhotoExpand_Panic) (Tk_PhotoHandle handle, int width, int height); /* 148 */
+ void (*tk_PhotoGetSize) (Tk_PhotoHandle handle, int *widthPtr, int *heightPtr); /* 149 */
+ void (*tk_PhotoSetSize_Panic) (Tk_PhotoHandle handle, int width, int height); /* 150 */
+ int (*tk_PointToChar) (Tk_TextLayout layout, int x, int y); /* 151 */
+ int (*tk_PostscriptFontName) (Tk_Font tkfont, Tcl_DString *dsPtr); /* 152 */
+ void (*tk_PreserveColormap) (Display *display, Colormap colormap); /* 153 */
+ void (*tk_QueueWindowEvent) (XEvent *eventPtr, Tcl_QueuePosition position); /* 154 */
+ void (*tk_RedrawImage) (Tk_Image image, int imageX, int imageY, int width, int height, Drawable drawable, int drawableX, int drawableY); /* 155 */
+ void (*tk_ResizeWindow) (Tk_Window tkwin, int width, int height); /* 156 */
+ int (*tk_RestackWindow) (Tk_Window tkwin, int aboveBelow, Tk_Window other); /* 157 */
+ Tk_RestrictProc * (*tk_RestrictEvents) (Tk_RestrictProc *proc, ClientData arg, ClientData *prevArgPtr); /* 158 */
+ int (*tk_SafeInit) (Tcl_Interp *interp); /* 159 */
+ CONST char * (*tk_SetAppName) (Tk_Window tkwin, CONST char *name); /* 160 */
+ void (*tk_SetBackgroundFromBorder) (Tk_Window tkwin, Tk_3DBorder border); /* 161 */
+ void (*tk_SetClass) (Tk_Window tkwin, CONST char *className); /* 162 */
+ void (*tk_SetGrid) (Tk_Window tkwin, int reqWidth, int reqHeight, int gridWidth, int gridHeight); /* 163 */
+ void (*tk_SetInternalBorder) (Tk_Window tkwin, int width); /* 164 */
+ void (*tk_SetWindowBackground) (Tk_Window tkwin, unsigned long pixel); /* 165 */
+ void (*tk_SetWindowBackgroundPixmap) (Tk_Window tkwin, Pixmap pixmap); /* 166 */
+ void (*tk_SetWindowBorder) (Tk_Window tkwin, unsigned long pixel); /* 167 */
+ void (*tk_SetWindowBorderWidth) (Tk_Window tkwin, int width); /* 168 */
+ void (*tk_SetWindowBorderPixmap) (Tk_Window tkwin, Pixmap pixmap); /* 169 */
+ void (*tk_SetWindowColormap) (Tk_Window tkwin, Colormap colormap); /* 170 */
+ int (*tk_SetWindowVisual) (Tk_Window tkwin, Visual *visual, int depth, Colormap colormap); /* 171 */
+ void (*tk_SizeOfBitmap) (Display *display, Pixmap bitmap, int *widthPtr, int *heightPtr); /* 172 */
+ void (*tk_SizeOfImage) (Tk_Image image, int *widthPtr, int *heightPtr); /* 173 */
+ int (*tk_StrictMotif) (Tk_Window tkwin); /* 174 */
+ void (*tk_TextLayoutToPostscript) (Tcl_Interp *interp, Tk_TextLayout layout); /* 175 */
+ int (*tk_TextWidth) (Tk_Font font, CONST char *str, int numBytes); /* 176 */
+ void (*tk_UndefineCursor) (Tk_Window window); /* 177 */
+ void (*tk_UnderlineChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, CONST char *source, int x, int y, int firstByte, int lastByte); /* 178 */
+ void (*tk_UnderlineTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int underline); /* 179 */
+ void (*tk_Ungrab) (Tk_Window tkwin); /* 180 */
+ void (*tk_UnmaintainGeometry) (Tk_Window slave, Tk_Window master); /* 181 */
+ void (*tk_UnmapWindow) (Tk_Window tkwin); /* 182 */
+ void (*tk_UnsetGrid) (Tk_Window tkwin); /* 183 */
+ void (*tk_UpdatePointer) (Tk_Window tkwin, int x, int y, int state); /* 184 */
+ Pixmap (*tk_AllocBitmapFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 185 */
+ Tk_3DBorder (*tk_Alloc3DBorderFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 186 */
+ XColor * (*tk_AllocColorFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 187 */
+ Tk_Cursor (*tk_AllocCursorFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 188 */
+ Tk_Font (*tk_AllocFontFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 189 */
+ Tk_OptionTable (*tk_CreateOptionTable) (Tcl_Interp *interp, CONST Tk_OptionSpec *templatePtr); /* 190 */
+ void (*tk_DeleteOptionTable) (Tk_OptionTable optionTable); /* 191 */
+ void (*tk_Free3DBorderFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 192 */
+ void (*tk_FreeBitmapFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 193 */
+ void (*tk_FreeColorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 194 */
+ void (*tk_FreeConfigOptions) (char *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 195 */
+ void (*tk_FreeSavedOptions) (Tk_SavedOptions *savePtr); /* 196 */
+ void (*tk_FreeCursorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 197 */
+ void (*tk_FreeFontFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 198 */
+ Tk_3DBorder (*tk_Get3DBorderFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 199 */
+ int (*tk_GetAnchorFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Anchor *anchorPtr); /* 200 */
+ Pixmap (*tk_GetBitmapFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 201 */
+ XColor * (*tk_GetColorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 202 */
+ Tk_Cursor (*tk_GetCursorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 203 */
+ Tcl_Obj * (*tk_GetOptionInfo) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 204 */
+ Tcl_Obj * (*tk_GetOptionValue) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 205 */
+ int (*tk_GetJustifyFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Justify *justifyPtr); /* 206 */
+ int (*tk_GetMMFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); /* 207 */
+ int (*tk_GetPixelsFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *intPtr); /* 208 */
+ int (*tk_GetReliefFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr); /* 209 */
+ int (*tk_GetScrollInfoObj) (Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], double *dblPtr, int *intPtr); /* 210 */
+ int (*tk_InitOptions) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 211 */
+ void (*tk_MainEx) (int argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); /* 212 */
+ void (*tk_RestoreSavedOptions) (Tk_SavedOptions *savePtr); /* 213 */
+ 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); /* 214 */
+ void (*tk_InitConsoleChannels) (Tcl_Interp *interp); /* 215 */
+ int (*tk_CreateConsoleWindow) (Tcl_Interp *interp); /* 216 */
+ void (*tk_CreateSmoothMethod) (Tcl_Interp *interp, Tk_SmoothMethod *method); /* 217 */
VOID *reserved218;
VOID *reserved219;
- int (*tk_GetDash) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *value, Tk_Dash *dash)); /* 220 */
- void (*tk_CreateOutline) _ANSI_ARGS_((Tk_Outline *outline)); /* 221 */
- void (*tk_DeleteOutline) _ANSI_ARGS_((Display *display, Tk_Outline *outline)); /* 222 */
- int (*tk_ConfigOutlineGC) _ANSI_ARGS_((XGCValues *gcValues, Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline)); /* 223 */
- int (*tk_ChangeOutlineGC) _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline)); /* 224 */
- int (*tk_ResetOutlineGC) _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline)); /* 225 */
- int (*tk_CanvasPsOutline) _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline)); /* 226 */
- void (*tk_SetTSOrigin) _ANSI_ARGS_((Tk_Window tkwin, GC gc, int x, int y)); /* 227 */
- int (*tk_CanvasGetCoordFromObj) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, Tcl_Obj *obj, double *doublePtr)); /* 228 */
- void (*tk_CanvasSetOffset) _ANSI_ARGS_((Tk_Canvas canvas, GC gc, Tk_TSOffset *offset)); /* 229 */
- void (*tk_DitherPhoto) _ANSI_ARGS_((Tk_PhotoHandle handle, int x, int y, int width, int height)); /* 230 */
- int (*tk_PostscriptBitmap) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psInfo, Pixmap bitmap, int startX, int startY, int width, int height)); /* 231 */
- int (*tk_PostscriptColor) _ANSI_ARGS_((Tcl_Interp *interp, Tk_PostscriptInfo psInfo, XColor *colorPtr)); /* 232 */
- int (*tk_PostscriptFont) _ANSI_ARGS_((Tcl_Interp *interp, Tk_PostscriptInfo psInfo, Tk_Font font)); /* 233 */
- int (*tk_PostscriptImage) _ANSI_ARGS_((Tk_Image image, Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psinfo, int x, int y, int width, int height, int prepass)); /* 234 */
- void (*tk_PostscriptPath) _ANSI_ARGS_((Tcl_Interp *interp, Tk_PostscriptInfo psInfo, double *coordPtr, int numPoints)); /* 235 */
- int (*tk_PostscriptStipple) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psInfo, Pixmap bitmap)); /* 236 */
- double (*tk_PostscriptY) _ANSI_ARGS_((double y, Tk_PostscriptInfo psInfo)); /* 237 */
- int (*tk_PostscriptPhoto) _ANSI_ARGS_((Tcl_Interp *interp, Tk_PhotoImageBlock *blockPtr, Tk_PostscriptInfo psInfo, int width, int height)); /* 238 */
- void (*tk_CreateClientMessageHandler) _ANSI_ARGS_((Tk_ClientMessageProc *proc)); /* 239 */
- void (*tk_DeleteClientMessageHandler) _ANSI_ARGS_((Tk_ClientMessageProc *proc)); /* 240 */
- Tk_Window (*tk_CreateAnonymousWindow) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window parent, CONST char *screenName)); /* 241 */
- void (*tk_SetClassProcs) _ANSI_ARGS_((Tk_Window tkwin, Tk_ClassProcs *procs, ClientData instanceData)); /* 242 */
- void (*tk_SetInternalBorderEx) _ANSI_ARGS_((Tk_Window tkwin, int left, int right, int top, int bottom)); /* 243 */
- void (*tk_SetMinimumRequestSize) _ANSI_ARGS_((Tk_Window tkwin, int minWidth, int minHeight)); /* 244 */
- void (*tk_SetCaretPos) _ANSI_ARGS_((Tk_Window tkwin, int x, int y, int height)); /* 245 */
- void (*tk_PhotoPutBlock) _ANSI_ARGS_((Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule)); /* 246 */
- void (*tk_PhotoPutZoomedBlock) _ANSI_ARGS_((Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule)); /* 247 */
- int (*tk_CollapseMotionEvents) _ANSI_ARGS_((Display *display, int collapse)); /* 248 */
- Tk_StyleEngine (*tk_RegisterStyleEngine) _ANSI_ARGS_((CONST char *name, Tk_StyleEngine parent)); /* 249 */
- Tk_StyleEngine (*tk_GetStyleEngine) _ANSI_ARGS_((CONST char *name)); /* 250 */
- int (*tk_RegisterStyledElement) _ANSI_ARGS_((Tk_StyleEngine engine, Tk_ElementSpec *templatePtr)); /* 251 */
- int (*tk_GetElementId) _ANSI_ARGS_((CONST char *name)); /* 252 */
- Tk_Style (*tk_CreateStyle) _ANSI_ARGS_((CONST char *name, Tk_StyleEngine engine, ClientData clientData)); /* 253 */
- Tk_Style (*tk_GetStyle) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *name)); /* 254 */
- void (*tk_FreeStyle) _ANSI_ARGS_((Tk_Style style)); /* 255 */
- CONST char * (*tk_NameOfStyle) _ANSI_ARGS_((Tk_Style style)); /* 256 */
- Tk_Style (*tk_AllocStyleFromObj) _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr)); /* 257 */
- Tk_Style (*tk_GetStyleFromObj) _ANSI_ARGS_((Tcl_Obj *objPtr)); /* 258 */
- void (*tk_FreeStyleFromObj) _ANSI_ARGS_((Tcl_Obj *objPtr)); /* 259 */
- Tk_StyledElement (*tk_GetStyledElement) _ANSI_ARGS_((Tk_Style style, int elementId, Tk_OptionTable optionTable)); /* 260 */
- void (*tk_GetElementSize) _ANSI_ARGS_((Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, int width, int height, int inner, int *widthPtr, int *heightPtr)); /* 261 */
- void (*tk_GetElementBox) _ANSI_ARGS_((Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, int x, int y, int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr)); /* 262 */
- int (*tk_GetElementBorderWidth) _ANSI_ARGS_((Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin)); /* 263 */
- void (*tk_DrawElement) _ANSI_ARGS_((Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, Drawable d, int x, int y, int width, int height, int state)); /* 264 */
+ int (*tk_GetDash) (Tcl_Interp *interp, CONST char *value, Tk_Dash *dash); /* 220 */
+ void (*tk_CreateOutline) (Tk_Outline *outline); /* 221 */
+ void (*tk_DeleteOutline) (Display *display, Tk_Outline *outline); /* 222 */
+ int (*tk_ConfigOutlineGC) (XGCValues *gcValues, Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); /* 223 */
+ int (*tk_ChangeOutlineGC) (Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); /* 224 */
+ int (*tk_ResetOutlineGC) (Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); /* 225 */
+ int (*tk_CanvasPsOutline) (Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); /* 226 */
+ void (*tk_SetTSOrigin) (Tk_Window tkwin, GC gc, int x, int y); /* 227 */
+ int (*tk_CanvasGetCoordFromObj) (Tcl_Interp *interp, Tk_Canvas canvas, Tcl_Obj *obj, double *doublePtr); /* 228 */
+ void (*tk_CanvasSetOffset) (Tk_Canvas canvas, GC gc, Tk_TSOffset *offset); /* 229 */
+ void (*tk_DitherPhoto) (Tk_PhotoHandle handle, int x, int y, int width, int height); /* 230 */
+ int (*tk_PostscriptBitmap) (Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psInfo, Pixmap bitmap, int startX, int startY, int width, int height); /* 231 */
+ int (*tk_PostscriptColor) (Tcl_Interp *interp, Tk_PostscriptInfo psInfo, XColor *colorPtr); /* 232 */
+ int (*tk_PostscriptFont) (Tcl_Interp *interp, Tk_PostscriptInfo psInfo, Tk_Font font); /* 233 */
+ int (*tk_PostscriptImage) (Tk_Image image, Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psinfo, int x, int y, int width, int height, int prepass); /* 234 */
+ void (*tk_PostscriptPath) (Tcl_Interp *interp, Tk_PostscriptInfo psInfo, double *coordPtr, int numPoints); /* 235 */
+ int (*tk_PostscriptStipple) (Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psInfo, Pixmap bitmap); /* 236 */
+ double (*tk_PostscriptY) (double y, Tk_PostscriptInfo psInfo); /* 237 */
+ int (*tk_PostscriptPhoto) (Tcl_Interp *interp, Tk_PhotoImageBlock *blockPtr, Tk_PostscriptInfo psInfo, int width, int height); /* 238 */
+ void (*tk_CreateClientMessageHandler) (Tk_ClientMessageProc *proc); /* 239 */
+ void (*tk_DeleteClientMessageHandler) (Tk_ClientMessageProc *proc); /* 240 */
+ Tk_Window (*tk_CreateAnonymousWindow) (Tcl_Interp *interp, Tk_Window parent, CONST char *screenName); /* 241 */
+ void (*tk_SetClassProcs) (Tk_Window tkwin, Tk_ClassProcs *procs, ClientData instanceData); /* 242 */
+ void (*tk_SetInternalBorderEx) (Tk_Window tkwin, int left, int right, int top, int bottom); /* 243 */
+ void (*tk_SetMinimumRequestSize) (Tk_Window tkwin, int minWidth, int minHeight); /* 244 */
+ void (*tk_SetCaretPos) (Tk_Window tkwin, int x, int y, int height); /* 245 */
+ void (*tk_PhotoPutBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 246 */
+ void (*tk_PhotoPutZoomedBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 247 */
+ int (*tk_CollapseMotionEvents) (Display *display, int collapse); /* 248 */
+ Tk_StyleEngine (*tk_RegisterStyleEngine) (CONST char *name, Tk_StyleEngine parent); /* 249 */
+ Tk_StyleEngine (*tk_GetStyleEngine) (CONST char *name); /* 250 */
+ int (*tk_RegisterStyledElement) (Tk_StyleEngine engine, Tk_ElementSpec *templatePtr); /* 251 */
+ int (*tk_GetElementId) (CONST char *name); /* 252 */
+ Tk_Style (*tk_CreateStyle) (CONST char *name, Tk_StyleEngine engine, ClientData clientData); /* 253 */
+ Tk_Style (*tk_GetStyle) (Tcl_Interp *interp, CONST char *name); /* 254 */
+ void (*tk_FreeStyle) (Tk_Style style); /* 255 */
+ CONST char * (*tk_NameOfStyle) (Tk_Style style); /* 256 */
+ Tk_Style (*tk_AllocStyleFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 257 */
+ Tk_Style (*tk_GetStyleFromObj) (Tcl_Obj *objPtr); /* 258 */
+ void (*tk_FreeStyleFromObj) (Tcl_Obj *objPtr); /* 259 */
+ Tk_StyledElement (*tk_GetStyledElement) (Tk_Style style, int elementId, Tk_OptionTable optionTable); /* 260 */
+ void (*tk_GetElementSize) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, int width, int height, int inner, int *widthPtr, int *heightPtr); /* 261 */
+ void (*tk_GetElementBox) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, int x, int y, int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 262 */
+ int (*tk_GetElementBorderWidth) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin); /* 263 */
+ void (*tk_DrawElement) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, Drawable d, int x, int y, int width, int height, int state); /* 264 */
+ int (*tk_PhotoExpand) (Tcl_Interp *interp, Tk_PhotoHandle handle, int width, int height); /* 265 */
+ int (*tk_PhotoPutBlock) (Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 266 */
+ int (*tk_PhotoPutZoomedBlock) (Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 267 */
+ int (*tk_PhotoSetSize) (Tcl_Interp *interp, Tk_PhotoHandle handle, int width, int height); /* 268 */
+ long (*tk_GetUserInactiveTime) (Display *dpy); /* 269 */
+ void (*tk_ResetUserInactiveTime) (Display *dpy); /* 270 */
+ Tcl_Interp * (*tk_Interp) (Tk_Window tkwin); /* 271 */
+ void (*tk_CreateOldImageType) (Tk_ImageType *typePtr); /* 272 */
+ void (*tk_CreateOldPhotoImageFormat) (Tk_PhotoImageFormat *formatPtr); /* 273 */
} TkStubs;
#ifdef __cplusplus
@@ -1790,17 +2568,17 @@ extern TkStubs *tkStubsPtr;
#define Tk_PhotoBlank \
(tkStubsPtr->tk_PhotoBlank) /* 147 */
#endif
-#ifndef Tk_PhotoExpand
-#define Tk_PhotoExpand \
- (tkStubsPtr->tk_PhotoExpand) /* 148 */
+#ifndef Tk_PhotoExpand_Panic
+#define Tk_PhotoExpand_Panic \
+ (tkStubsPtr->tk_PhotoExpand_Panic) /* 148 */
#endif
#ifndef Tk_PhotoGetSize
#define Tk_PhotoGetSize \
(tkStubsPtr->tk_PhotoGetSize) /* 149 */
#endif
-#ifndef Tk_PhotoSetSize
-#define Tk_PhotoSetSize \
- (tkStubsPtr->tk_PhotoSetSize) /* 150 */
+#ifndef Tk_PhotoSetSize_Panic
+#define Tk_PhotoSetSize_Panic \
+ (tkStubsPtr->tk_PhotoSetSize_Panic) /* 150 */
#endif
#ifndef Tk_PointToChar
#define Tk_PointToChar \
@@ -2176,13 +2954,13 @@ extern TkStubs *tkStubsPtr;
#define Tk_SetCaretPos \
(tkStubsPtr->tk_SetCaretPos) /* 245 */
#endif
-#ifndef Tk_PhotoPutBlock
-#define Tk_PhotoPutBlock \
- (tkStubsPtr->tk_PhotoPutBlock) /* 246 */
+#ifndef Tk_PhotoPutBlock_Panic
+#define Tk_PhotoPutBlock_Panic \
+ (tkStubsPtr->tk_PhotoPutBlock_Panic) /* 246 */
#endif
-#ifndef Tk_PhotoPutZoomedBlock
-#define Tk_PhotoPutZoomedBlock \
- (tkStubsPtr->tk_PhotoPutZoomedBlock) /* 247 */
+#ifndef Tk_PhotoPutZoomedBlock_Panic
+#define Tk_PhotoPutZoomedBlock_Panic \
+ (tkStubsPtr->tk_PhotoPutZoomedBlock_Panic) /* 247 */
#endif
#ifndef Tk_CollapseMotionEvents
#define Tk_CollapseMotionEvents \
@@ -2252,6 +3030,42 @@ extern TkStubs *tkStubsPtr;
#define Tk_DrawElement \
(tkStubsPtr->tk_DrawElement) /* 264 */
#endif
+#ifndef Tk_PhotoExpand
+#define Tk_PhotoExpand \
+ (tkStubsPtr->tk_PhotoExpand) /* 265 */
+#endif
+#ifndef Tk_PhotoPutBlock
+#define Tk_PhotoPutBlock \
+ (tkStubsPtr->tk_PhotoPutBlock) /* 266 */
+#endif
+#ifndef Tk_PhotoPutZoomedBlock
+#define Tk_PhotoPutZoomedBlock \
+ (tkStubsPtr->tk_PhotoPutZoomedBlock) /* 267 */
+#endif
+#ifndef Tk_PhotoSetSize
+#define Tk_PhotoSetSize \
+ (tkStubsPtr->tk_PhotoSetSize) /* 268 */
+#endif
+#ifndef Tk_GetUserInactiveTime
+#define Tk_GetUserInactiveTime \
+ (tkStubsPtr->tk_GetUserInactiveTime) /* 269 */
+#endif
+#ifndef Tk_ResetUserInactiveTime
+#define Tk_ResetUserInactiveTime \
+ (tkStubsPtr->tk_ResetUserInactiveTime) /* 270 */
+#endif
+#ifndef Tk_Interp
+#define Tk_Interp \
+ (tkStubsPtr->tk_Interp) /* 271 */
+#endif
+#ifndef Tk_CreateOldImageType
+#define Tk_CreateOldImageType \
+ (tkStubsPtr->tk_CreateOldImageType) /* 272 */
+#endif
+#ifndef Tk_CreateOldPhotoImageFormat
+#define Tk_CreateOldPhotoImageFormat \
+ (tkStubsPtr->tk_CreateOldPhotoImageFormat) /* 273 */
+#endif
#endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */
diff --git a/generic/tkEntry.c b/generic/tkEntry.c
index 996af63..26311a3 100644
--- a/generic/tkEntry.c
+++ b/generic/tkEntry.c
@@ -1,9 +1,9 @@
-/*
- * Entry.c --
+/*
+ * tkEntry.c --
*
* This module implements entry and spinbox widgets for the Tk toolkit.
- * An entry displays a string and allows the string to be edited.
- * A spinbox expands on the entry by adding up/down buttons that control
+ * An entry displays a string and allows the string to be edited. A
+ * spinbox expands on the entry by adding up/down buttons that control
* the value of the entry widget.
*
* Copyright (c) 1990-1994 The Regents of the University of California.
@@ -11,40 +11,40 @@
* Copyright (c) 2000 Ajuba Solutions.
* Copyright (c) 2002 ActiveState Corporation.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
#include "default.h"
#include "tkEntry.h"
-
/*
- * The following macro defines how many extra pixels to leave on each
- * side of the text in the entry.
+ * The following macro defines how many extra pixels to leave on each side of
+ * the text in the entry.
*/
#define XPAD 1
#define YPAD 1
/*
- * A comparison function for double values. For Spinboxes.
+ * A comparison function for double values. For Spinboxes.
*/
+
#define MIN_DBL_VAL 1E-9
#define DOUBLES_EQ(d1, d2) (fabs((d1) - (d2)) < MIN_DBL_VAL)
-static CONST char *CONST stateStrings[] = {
- "disabled", "normal", "readonly", (char *) NULL
+static const char *const stateStrings[] = {
+ "disabled", "normal", "readonly", NULL
};
/*
* Definitions for -validate option values:
*/
-static CONST char *CONST validateStrings[] = {
- "all", "key", "focus", "focusin", "focusout", "none", (char *) NULL
+static const char *const validateStrings[] = {
+ "all", "key", "focus", "focusin", "focusout", "none", NULL
};
enum validateType {
VALIDATE_ALL, VALIDATE_KEY, VALIDATE_FOCUS,
@@ -61,115 +61,104 @@ enum validateType {
* Information used for Entry objv parsing.
*/
-static CONST Tk_OptionSpec entryOptSpec[] = {
+static const Tk_OptionSpec entryOptSpec[] = {
{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_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ 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},
+ 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_BORDER, "-disabledbackground", "disabledBackground",
- "DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, -1,
- Tk_Offset(Entry, disabledBorder), TK_OPTION_NULL_OK,
- (ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0},
+ "DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, -1,
+ Tk_Offset(Entry, disabledBorder), TK_OPTION_NULL_OK,
+ (ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0},
{TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
- "DisabledForeground", DEF_ENTRY_DISABLED_FG, -1,
- Tk_Offset(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
+ "DisabledForeground", DEF_ENTRY_DISABLED_FG, -1,
+ Tk_Offset(Entry, dfgColorPtr), 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},
+ "ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1,
+ Tk_Offset(Entry, exportSelection), 0, 0, 0},
+ {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
+ 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},
+ DEF_ENTRY_FG, -1, Tk_Offset(Entry, fgColorPtr), 0, 0, 0},
{TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
"HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG,
- -1, Tk_Offset(Entry, highlightBgColorPtr),
- 0, 0, 0},
+ -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},
+ DEF_ENTRY_HIGHLIGHT, -1, Tk_Offset(Entry, highlightColorPtr), 0, 0, 0},
{TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
- "HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1,
+ "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},
+ 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},
+ 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},
+ 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},
+ DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth), 0, 0, 0},
{TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
DEF_ENTRY_INVALIDCMD, -1, Tk_Offset(Entry, invalidCmd),
TK_OPTION_NULL_OK, 0, 0},
- {TK_OPTION_SYNONYM, "-invcmd", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-invalidcommand", 0},
+ {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-invalidcommand", 0},
{TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
DEF_ENTRY_JUSTIFY, -1, Tk_Offset(Entry, justify), 0, 0, 0},
{TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
- "ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1,
- Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK,
- (ClientData) DEF_ENTRY_READONLY_BG_MONO, 0},
+ "ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1,
+ Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK,
+ (ClientData) DEF_ENTRY_READONLY_BG_MONO, 0},
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
- DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief),
- 0, 0, 0},
+ 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},
+ 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),
TK_CONFIG_NULL_OK, (ClientData) DEF_ENTRY_SELECT_FG_MONO, 0},
{TK_OPTION_STRING, "-show", "show", "Show",
- DEF_ENTRY_SHOW, -1, Tk_Offset(Entry, showChar),
- TK_OPTION_NULL_OK, 0, 0},
+ 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},
+ 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_OPTION_NULL_OK, 0, 0},
+ DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus),
+ TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
DEF_ENTRY_TEXT_VARIABLE, -1, Tk_Offset(Entry, textVarName),
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
- DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate),
- 0, (ClientData) validateStrings, 0},
- {TK_OPTION_STRING, "-validatecommand", "validateCommand", "ValidateCommand",
- (char *) NULL, -1, Tk_Offset(Entry, validateCmd),
- TK_OPTION_NULL_OK, 0, 0},
- {TK_OPTION_SYNONYM, "-vcmd", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-validatecommand", 0},
+ DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate),
+ 0, (ClientData) validateStrings, 0},
+ {TK_OPTION_STRING, "-validatecommand", "validateCommand","ValidateCommand",
+ NULL, -1, Tk_Offset(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_SYNONYM, "-vcmd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-validatecommand", 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_OPTION_NULL_OK, 0, 0},
- {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, 0, 0}
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};
/*
@@ -189,20 +178,19 @@ static CONST Tk_OptionSpec entryOptSpec[] = {
#define DEF_SPINBOX_VALUES ""
#define DEF_SPINBOX_WRAP "0"
-static CONST Tk_OptionSpec sbOptSpec[] = {
+static const Tk_OptionSpec sbOptSpec[] = {
{TK_OPTION_BORDER, "-activebackground", "activeBackground", "Background",
DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(Spinbox, activeBorder),
0, (ClientData) DEF_BUTTON_ACTIVE_BG_MONO, 0},
{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_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ 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},
+ DEF_ENTRY_BORDER_WIDTH, -1, Tk_Offset(Entry, borderWidth), 0, 0, 0},
{TK_OPTION_BORDER, "-buttonbackground", "Button.background", "Background",
DEF_BUTTON_BG_COLOR, -1, Tk_Offset(Spinbox, buttonBorder),
0, (ClientData) DEF_BUTTON_BG_MONO, 0},
@@ -210,11 +198,9 @@ static CONST Tk_OptionSpec sbOptSpec[] = {
DEF_BUTTON_CURSOR, -1, Tk_Offset(Spinbox, bCursor),
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_RELIEF, "-buttondownrelief", "Button.relief", "Relief",
- DEF_BUTTON_RELIEF, -1, Tk_Offset(Spinbox, bdRelief),
- 0, 0, 0},
+ DEF_BUTTON_RELIEF, -1, Tk_Offset(Spinbox, bdRelief), 0, 0, 0},
{TK_OPTION_RELIEF, "-buttonuprelief", "Button.relief", "Relief",
- DEF_BUTTON_RELIEF, -1, Tk_Offset(Spinbox, buRelief),
- 0, 0, 0},
+ DEF_BUTTON_RELIEF, -1, Tk_Offset(Spinbox, buRelief), 0, 0, 0},
{TK_OPTION_STRING, "-command", "command", "Command",
DEF_SPINBOX_CMD, -1, Tk_Offset(Spinbox, command),
TK_OPTION_NULL_OK, 0, 0},
@@ -222,22 +208,21 @@ static CONST Tk_OptionSpec sbOptSpec[] = {
DEF_ENTRY_CURSOR, -1, Tk_Offset(Entry, cursor),
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_BORDER, "-disabledbackground", "disabledBackground",
- "DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, -1,
- Tk_Offset(Entry, disabledBorder), TK_OPTION_NULL_OK,
- (ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0},
+ "DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, -1,
+ Tk_Offset(Entry, disabledBorder), TK_OPTION_NULL_OK,
+ (ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0},
{TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
- "DisabledForeground", DEF_ENTRY_DISABLED_FG, -1,
- Tk_Offset(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
+ "DisabledForeground", DEF_ENTRY_DISABLED_FG, -1,
+ Tk_Offset(Entry, dfgColorPtr), 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},
+ "ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1,
+ Tk_Offset(Entry, exportSelection), 0, 0, 0},
+ {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
+ 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},
+ DEF_ENTRY_FG, -1, Tk_Offset(Entry, fgColorPtr), 0, 0, 0},
{TK_OPTION_STRING, "-format", "format", "Format",
DEF_SPINBOX_FORMAT, -1, Tk_Offset(Spinbox, reqFormat),
TK_OPTION_NULL_OK, 0, 0},
@@ -245,84 +230,77 @@ static CONST Tk_OptionSpec sbOptSpec[] = {
DEF_SPINBOX_FROM, -1, Tk_Offset(Spinbox, fromValue), 0, 0, 0},
{TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
"HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG,
- -1, Tk_Offset(Entry, highlightBgColorPtr),
- 0, 0, 0},
+ -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},
+ DEF_ENTRY_HIGHLIGHT, -1, Tk_Offset(Entry, highlightColorPtr), 0, 0, 0},
{TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
- "HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1,
+ "HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1,
Tk_Offset(Entry, highlightWidth), 0, 0, 0},
{TK_OPTION_DOUBLE, "-increment", "increment", "Increment",
DEF_SPINBOX_INCREMENT, -1, Tk_Offset(Spinbox, increment), 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},
+ 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},
+ 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},
+ 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},
+ DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth), 0, 0, 0},
{TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
DEF_ENTRY_INVALIDCMD, -1, Tk_Offset(Entry, invalidCmd),
TK_OPTION_NULL_OK, 0, 0},
- {TK_OPTION_SYNONYM, "-invcmd", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-invalidcommand", 0},
+ {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-invalidcommand", 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},
+ DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief), 0, 0, 0},
{TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
- "ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1,
- Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK,
- (ClientData) DEF_ENTRY_READONLY_BG_MONO, 0},
+ "ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1,
+ Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK,
+ (ClientData) DEF_ENTRY_READONLY_BG_MONO, 0},
{TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
- DEF_SPINBOX_REPEAT_DELAY, -1, Tk_Offset(Spinbox, repeatDelay),
- 0, 0, 0},
+ DEF_SPINBOX_REPEAT_DELAY, -1, Tk_Offset(Spinbox, repeatDelay),
+ 0, 0, 0},
{TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
- DEF_SPINBOX_REPEAT_INTERVAL, -1, Tk_Offset(Spinbox, repeatInterval),
- 0, 0, 0},
+ DEF_SPINBOX_REPEAT_INTERVAL, -1, Tk_Offset(Spinbox, repeatInterval),
+ 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},
+ 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),
TK_CONFIG_NULL_OK, (ClientData) DEF_ENTRY_SELECT_FG_MONO, 0},
{TK_OPTION_STRING_TABLE, "-state", "state", "State",
- DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state),
- 0, (ClientData) stateStrings, 0},
+ 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},
+ 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_DOUBLE, "-to", "to", "To",
DEF_SPINBOX_TO, -1, Tk_Offset(Spinbox, toValue), 0, 0, 0},
{TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
- DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate),
- 0, (ClientData) validateStrings, 0},
- {TK_OPTION_STRING, "-validatecommand", "validateCommand", "ValidateCommand",
- (char *) NULL, -1, Tk_Offset(Entry, validateCmd),
- TK_CONFIG_NULL_OK, 0, 0},
+ DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate),
+ 0, (ClientData) validateStrings, 0},
+ {TK_OPTION_STRING, "-validatecommand", "validateCommand","ValidateCommand",
+ NULL, -1, Tk_Offset(Entry, validateCmd), TK_CONFIG_NULL_OK, 0, 0},
{TK_OPTION_STRING, "-values", "values", "Values",
- DEF_SPINBOX_VALUES, -1, Tk_Offset(Spinbox, valueStr),
- TK_OPTION_NULL_OK, 0, 0},
- {TK_OPTION_SYNONYM, "-vcmd", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-validatecommand", 0},
+ DEF_SPINBOX_VALUES, -1, Tk_Offset(Spinbox, valueStr),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_SYNONYM, "-vcmd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-validatecommand", 0},
{TK_OPTION_INT, "-width", "width", "Width",
DEF_ENTRY_WIDTH, -1, Tk_Offset(Entry, prefWidth), 0, 0, 0},
{TK_OPTION_BOOLEAN, "-wrap", "wrap", "Wrap",
@@ -330,29 +308,28 @@ static CONST Tk_OptionSpec sbOptSpec[] = {
{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}
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};
/*
- * 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.
+ * 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 CONST char *entryCmdNames[] = {
- "bbox", "cget", "configure", "delete", "get", "icursor", "index",
- "insert", "scan", "selection", "validate", "xview", (char *) NULL
+static const char *entryCmdNames[] = {
+ "bbox", "cget", "configure", "delete", "get", "icursor", "index",
+ "insert", "scan", "selection", "validate", "xview", NULL
};
enum entryCmd {
- COMMAND_BBOX, COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DELETE,
- COMMAND_GET, COMMAND_ICURSOR, COMMAND_INDEX, COMMAND_INSERT,
+ COMMAND_BBOX, COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DELETE,
+ COMMAND_GET, COMMAND_ICURSOR, COMMAND_INDEX, COMMAND_INSERT,
COMMAND_SCAN, COMMAND_SELECTION, COMMAND_VALIDATE, COMMAND_XVIEW
};
-static CONST char *selCmdNames[] = {
- "adjust", "clear", "from", "present", "range", "to", (char *) NULL
+static const char *selCmdNames[] = {
+ "adjust", "clear", "from", "present", "range", "to", NULL
};
enum selCmd {
@@ -361,31 +338,30 @@ enum selCmd {
};
/*
- * The following tables define the spinbox widget commands (and sub-
- * commands) and map the indexes into the string tables into
- * enumerated types used to dispatch the spinbox widget command.
+ * The following tables define the spinbox widget commands (and sub-commands)
+ * and map the indexes into the string tables into enumerated types used to
+ * dispatch the spinbox widget command.
*/
-static CONST char *sbCmdNames[] = {
+static const char *sbCmdNames[] = {
"bbox", "cget", "configure", "delete", "get", "icursor", "identify",
"index", "insert", "invoke", "scan", "selection", "set",
- "validate", "xview", (char *) NULL
+ "validate", "xview", NULL
};
enum sbCmd {
- SB_CMD_BBOX, SB_CMD_CGET, SB_CMD_CONFIGURE, SB_CMD_DELETE,
+ SB_CMD_BBOX, SB_CMD_CGET, SB_CMD_CONFIGURE, SB_CMD_DELETE,
SB_CMD_GET, SB_CMD_ICURSOR, SB_CMD_IDENTIFY, SB_CMD_INDEX,
SB_CMD_INSERT, SB_CMD_INVOKE, SB_CMD_SCAN, SB_CMD_SELECTION,
SB_CMD_SET, SB_CMD_VALIDATE, SB_CMD_XVIEW
};
-static CONST char *sbSelCmdNames[] = {
- "adjust", "clear", "element", "from", "present", "range", "to",
- (char *) NULL
+static const char *sbSelCmdNames[] = {
+ "adjust", "clear", "element", "from", "present", "range", "to", NULL
};
enum sbselCmd {
- SB_SEL_ADJUST, SB_SEL_CLEAR, SB_SEL_ELEMENT, SB_SEL_FROM,
+ SB_SEL_ADJUST, SB_SEL_CLEAR, SB_SEL_ELEMENT, SB_SEL_FROM,
SB_SEL_PRESENT, SB_SEL_RANGE, SB_SEL_TO
};
@@ -393,91 +369,80 @@ enum sbselCmd {
* Extra for selection of elements
*/
-/*
- * This is the string array corresponding to the enum in selelement.
- * If you modify them, you must modify the strings here.
+/*
+ * This is the string array corresponding to the enum in selelement. If you
+ * modify them, you must modify the strings here.
*/
-
-static CONST char *selElementNames[] = {
- "none", "buttondown", "buttonup", (char *) NULL, "entry"
+
+static const char *selElementNames[] = {
+ "none", "buttondown", "buttonup", NULL, "entry"
};
+
/*
- * Flags for GetEntryIndex procedure:
+ * Flags for GetEntryIndex function:
*/
#define ZERO_OK 1
#define LAST_PLUS_ONE_OK 2
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static int ConfigureEntry _ANSI_ARGS_((Tcl_Interp *interp,
- 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));
-static void DisplayEntry _ANSI_ARGS_((ClientData clientData));
-static void EntryBlinkProc _ANSI_ARGS_((ClientData clientData));
-static void EntryCmdDeletedProc _ANSI_ARGS_((
- ClientData clientData));
-static void EntryComputeGeometry _ANSI_ARGS_((Entry *entryPtr));
-static void EntryEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void EntryFocusProc _ANSI_ARGS_ ((Entry *entryPtr,
- int gotFocus));
-static int EntryFetchSelection _ANSI_ARGS_((ClientData clientData,
- int offset, char *buffer, int maxBytes));
-static void EntryLostSelection _ANSI_ARGS_((
- ClientData clientData));
-static void EventuallyRedraw _ANSI_ARGS_((Entry *entryPtr));
-static void EntryScanTo _ANSI_ARGS_((Entry *entryPtr, int y));
-static void EntrySetValue _ANSI_ARGS_((Entry *entryPtr,
- CONST char *value));
-static void EntrySelectTo _ANSI_ARGS_((
- Entry *entryPtr, int index));
-static char * EntryTextVarProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, CONST char *name1,
- CONST char *name2, int flags));
-static void EntryUpdateScrollbar _ANSI_ARGS_((Entry *entryPtr));
-static int EntryValidate _ANSI_ARGS_((Entry *entryPtr,
- char *cmd));
-static int EntryValidateChange _ANSI_ARGS_((Entry *entryPtr,
- char *change, CONST char *new, int index,
- int type));
-static void ExpandPercents _ANSI_ARGS_((Entry *entryPtr,
- CONST char *before, char *change, CONST char *new,
- int index, int type, Tcl_DString *dsPtr));
-static void EntryValueChanged _ANSI_ARGS_((Entry *entryPtr,
- CONST char *newValue));
-static void EntryVisibleRange _ANSI_ARGS_((Entry *entryPtr,
- double *firstPtr, double *lastPtr));
-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,
- Entry *entryPtr, char *string, int *indexPtr));
-static void InsertChars _ANSI_ARGS_((Entry *entryPtr, int index,
- char *string));
+static int ConfigureEntry(Tcl_Interp *interp, Entry *entryPtr,
+ int objc, Tcl_Obj *const objv[], int flags);
+static void DeleteChars(Entry *entryPtr, int index, int count);
+static void DestroyEntry(char *memPtr);
+static void DisplayEntry(ClientData clientData);
+static void EntryBlinkProc(ClientData clientData);
+static void EntryCmdDeletedProc(ClientData clientData);
+static void EntryComputeGeometry(Entry *entryPtr);
+static void EntryEventProc(ClientData clientData,
+ XEvent *eventPtr);
+static void EntryFocusProc(Entry *entryPtr, int gotFocus);
+static int EntryFetchSelection(ClientData clientData, int offset,
+ char *buffer, int maxBytes);
+static void EntryLostSelection(ClientData clientData);
+static void EventuallyRedraw(Entry *entryPtr);
+static void EntryScanTo(Entry *entryPtr, int y);
+static void EntrySetValue(Entry *entryPtr, const char *value);
+static void EntrySelectTo(Entry *entryPtr, int index);
+static char * EntryTextVarProc(ClientData clientData,
+ Tcl_Interp *interp, const char *name1,
+ const char *name2, int flags);
+static void EntryUpdateScrollbar(Entry *entryPtr);
+static int EntryValidate(Entry *entryPtr, char *cmd);
+static int EntryValidateChange(Entry *entryPtr, char *change,
+ const char *newStr, int index, int type);
+static void ExpandPercents(Entry *entryPtr, const char *before,
+ const char *change, const char *newStr, int index,
+ int type, Tcl_DString *dsPtr);
+static void EntryValueChanged(Entry *entryPtr,
+ const char *newValue);
+static void EntryVisibleRange(Entry *entryPtr,
+ double *firstPtr, double *lastPtr);
+static int EntryWidgetObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+static void EntryWorldChanged(ClientData instanceData);
+static int GetEntryIndex(Tcl_Interp *interp, Entry *entryPtr,
+ char *string, int *indexPtr);
+static void InsertChars(Entry *entryPtr, int index, char *string);
/*
* These forward declarations are the spinbox specific ones:
*/
-static int SpinboxWidgetObjCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int GetSpinboxElement _ANSI_ARGS_((Spinbox *sbPtr,
- int x, int y));
-static int SpinboxInvoke _ANSI_ARGS_((Tcl_Interp *interp,
- Spinbox *sbPtr, int element));
-static int ComputeFormat _ANSI_ARGS_((Spinbox *sbPtr));
+static int SpinboxWidgetObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+static int GetSpinboxElement(Spinbox *sbPtr, int x, int y);
+static int SpinboxInvoke(Tcl_Interp *interp, Spinbox *sbPtr,
+ int element);
+static int ComputeFormat(Spinbox *sbPtr);
/*
- * The structure below defines widget class behavior by means of procedures
+ * The structure below defines widget class behavior by means of functions
* that can be invoked from generic window code.
*/
@@ -492,9 +457,8 @@ static Tk_ClassProcs entryClass = {
*
* Tk_EntryObjCmd --
*
- * This procedure is invoked to process the "entry" Tcl
- * command. See the user documentation for details on what
- * it does.
+ * This function is invoked to process the "entry" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -506,11 +470,11 @@ static Tk_ClassProcs entryClass = {
*/
int
-Tk_EntryObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* NULL. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_EntryObjCmd(
+ ClientData clientData, /* NULL. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
register Entry *entryPtr;
Tk_OptionTable optionTable;
@@ -523,27 +487,27 @@ Tk_EntryObjCmd(clientData, interp, objc, objv)
}
tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
- Tcl_GetString(objv[1]), (char *) NULL);
+ Tcl_GetString(objv[1]), NULL);
if (tkwin == NULL) {
return TCL_ERROR;
}
/*
- * Create the option table for this widget class. If it has already
- * been created, Tk will return the cached value.
+ * Create the option table for this widget class. If it has already been
+ * created, Tk will return the cached value.
*/
optionTable = Tk_CreateOptionTable(interp, entryOptSpec);
/*
- * Initialize the fields of the structure that won't be initialized
- * by ConfigureEntry, or that ConfigureEntry requires to be
- * initialized already (e.g. resource pointers). Only the non-NULL/0
- * data must be initialized as memset covers the rest.
+ * Initialize the fields of the structure that won't be initialized by
+ * ConfigureEntry, or that ConfigureEntry requires to be initialized
+ * already (e.g. resource pointers). Only the non-NULL/0 data must be
+ * initialized as memset covers the rest.
*/
entryPtr = (Entry *) ckalloc(sizeof(Entry));
- memset((VOID *) entryPtr, 0, sizeof(Entry));
+ memset(entryPtr, 0, sizeof(Entry));
entryPtr->tkwin = tkwin;
entryPtr->display = Tk_Display(tkwin);
@@ -573,7 +537,7 @@ Tk_EntryObjCmd(clientData, interp, objc, objv)
entryPtr->validate = VALIDATE_NONE;
/*
- * Keep a hold of the associated tkwin until we destroy the listbox,
+ * Keep a hold of the associated tkwin until we destroy the entry,
* otherwise Tk might free it while we still need it.
*/
@@ -603,9 +567,9 @@ Tk_EntryObjCmd(clientData, interp, objc, objv)
*
* EntryWidgetObjCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to a widget managed by this module.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the Tcl command that corresponds
+ * to a widget managed by this module. See the user documentation for
+ * details on what it does.
*
* Results:
* A standard Tcl result.
@@ -617,11 +581,11 @@ Tk_EntryObjCmd(clientData, interp, objc, objv)
*/
static int
-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. */
+EntryWidgetObjCmd(
+ ClientData clientData, /* Information about entry widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
Entry *entryPtr = (Entry *) clientData;
int cmdIndex, selIndex, result;
@@ -632,9 +596,9 @@ EntryWidgetObjCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
- /*
- * Parse the widget command by looking up the second token in
- * the list of valid command names.
+ /*
+ * Parse the widget command by looking up the second token in the list of
+ * valid command names.
*/
result = Tcl_GetIndexFromObj(interp, objv[1], entryCmdNames,
@@ -645,398 +609,381 @@ EntryWidgetObjCmd(clientData, interp, objc, objv)
Tcl_Preserve((ClientData) entryPtr);
switch ((enum entryCmd) cmdIndex) {
- case COMMAND_BBOX: {
- int index, x, y, width, height;
- char buf[TCL_INTEGER_SPACE * 4];
+ case COMMAND_BBOX: {
+ int index, x, y, width, height;
+ char buf[TCL_INTEGER_SPACE * 4];
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "index");
- goto error;
- }
- if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]),
- &index) != TCL_OK) {
- goto error;
- }
- if ((index == entryPtr->numChars) && (index > 0)) {
- index--;
- }
- 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, 2, objv, "option");
- goto error;
- }
-
- objPtr = Tk_GetOptionValue(interp, (char *) entryPtr,
- entryPtr->optionTable, objv[2], entryPtr->tkwin);
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
+ goto error;
+ }
+ if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]),
+ &index) != TCL_OK) {
+ goto error;
+ }
+ if ((index == entryPtr->numChars) && (index > 0)) {
+ index--;
+ }
+ 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, 2, objv, "option");
+ goto error;
+ }
+
+ objPtr = Tk_GetOptionValue(interp, (char *) entryPtr,
+ entryPtr->optionTable, objv[2], entryPtr->tkwin);
+ if (objPtr == NULL) {
+ goto error;
+ } else {
+ Tcl_SetObjResult(interp, objPtr);
+ }
+ break;
+
+ case COMMAND_CONFIGURE:
+ if (objc <= 3) {
+ objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr,
+ entryPtr->optionTable,
+ (objc == 3) ? objv[2] : NULL,
+ entryPtr->tkwin);
if (objPtr == NULL) {
- goto error;
+ goto error;
} else {
Tcl_SetObjResult(interp, objPtr);
}
- break;
+ } else {
+ result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0);
}
+ break;
- 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;
+ case COMMAND_DELETE: {
+ int first, last;
+
+ if ((objc < 3) || (objc > 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
+ goto error;
+ }
+ 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;
}
+ if ((last >= first) && (entryPtr->state == STATE_NORMAL)) {
+ DeleteChars(entryPtr, first, last - first);
+ }
+ break;
+ }
- case COMMAND_DELETE: {
- int first, last;
+ case COMMAND_GET:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ goto error;
+ }
+ Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1);
+ break;
- if ((objc < 3) || (objc > 4)) {
- Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
- goto error;
- }
- 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;
- }
- }
- if ((last >= first) && (entryPtr->state == STATE_NORMAL)) {
- DeleteChars(entryPtr, first, last - first);
- }
- break;
+ case COMMAND_ICURSOR:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pos");
+ goto error;
}
+ if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]),
+ &entryPtr->insertPos) != TCL_OK) {
+ goto error;
+ }
+ EventuallyRedraw(entryPtr);
+ break;
- case COMMAND_GET: {
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL);
- goto error;
- }
- Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1);
- break;
+ case COMMAND_INDEX: {
+ int index;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "string");
+ goto error;
+ }
+ if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]),
+ &index) != TCL_OK) {
+ goto error;
}
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
+ break;
+ }
- case COMMAND_ICURSOR: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "pos");
+ case COMMAND_INSERT: {
+ int index;
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index text");
+ goto error;
+ }
+ 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, 2, objv, "mark|dragto x");
+ 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",
+ NULL);
+ goto error;
+ }
+ break;
+ }
+
+ case COMMAND_SELECTION: {
+ int index, index2;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
+ goto error;
+ }
+
+ /*
+ * Parse the selection sub-command, using the command table
+ * "selCmdNames" defined above.
+ */
+
+ result = Tcl_GetIndexFromObj(interp, objv[2], selCmdNames,
+ "selection option", 0, &selIndex);
+ if (result != TCL_OK) {
+ goto error;
+ }
+
+ /*
+ * Disabled entries don't allow the selection to be modified, but
+ * 'selection present' must return a boolean.
+ */
+
+ if ((entryPtr->state == STATE_DISABLED)
+ && (selIndex != SELECTION_PRESENT)) {
+ goto done;
+ }
+
+ switch (selIndex) {
+ case SELECTION_ADJUST:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index");
goto error;
}
- if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]),
- &entryPtr->insertPos) != TCL_OK) {
- goto error;
+ if (GetEntryIndex(interp, entryPtr,
+ Tcl_GetString(objv[3]), &index) != TCL_OK) {
+ goto error;
}
- EventuallyRedraw(entryPtr);
+ 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 COMMAND_INDEX: {
- int index;
+ case SELECTION_CLEAR:
if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "string");
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
goto error;
}
- if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]),
- &index) != TCL_OK) {
- goto error;
+ if (entryPtr->selectFirst >= 0) {
+ entryPtr->selectFirst = -1;
+ entryPtr->selectLast = -1;
+ EventuallyRedraw(entryPtr);
}
- Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
- break;
- }
-
- case COMMAND_INSERT: {
- int index;
+ goto done;
+ case SELECTION_FROM:
if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "index text");
+ Tcl_WrongNumArgs(interp, 3, objv, "index");
goto error;
}
- 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]));
+ if (GetEntryIndex(interp, entryPtr,
+ Tcl_GetString(objv[3]), &index) != TCL_OK) {
+ goto error;
}
+ entryPtr->selectAnchor = index;
break;
- }
- case COMMAND_SCAN: {
- int x;
- char *minorCmd;
+ case SELECTION_PRESENT:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
+ goto error;
+ }
+ Tcl_SetObjResult(interp,
+ Tcl_NewBooleanObj((entryPtr->selectFirst >= 0)));
+ goto done;
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x");
+ case SELECTION_RANGE:
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "start end");
goto error;
}
- if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) {
- goto error;
+ if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[3]),
+ &index) != 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);
+ 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 COMMAND_SELECTION: {
- int index, index2;
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
+ case SELECTION_TO:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index");
goto error;
}
-
- /*
- * Parse the selection sub-command, using the command
- * table "selCmdNames" defined above.
- */
-
- result = Tcl_GetIndexFromObj(interp, objv[2], selCmdNames,
- "selection option", 0, &selIndex);
- if (result != TCL_OK) {
+ if (GetEntryIndex(interp, entryPtr,
+ Tcl_GetString(objv[3]), &index) != TCL_OK) {
goto error;
}
+ EntrySelectTo(entryPtr, index);
+ break;
+ }
+ break;
+ }
- /*
- * Disabled entries don't allow the selection to be modified,
- * but 'selection present' must return a boolean.
- */
-
- if ((entryPtr->state == STATE_DISABLED)
- && (selIndex != SELECTION_PRESENT)) {
- goto done;
- }
-
- switch (selIndex) {
- case SELECTION_ADJUST: {
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 3, objv, "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 SELECTION_CLEAR: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL);
- 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, 3, objv, "index");
- goto error;
- }
- if (GetEntryIndex(interp, entryPtr,
- Tcl_GetString(objv[3]), &index) != TCL_OK) {
- goto error;
- }
- entryPtr->selectAnchor = index;
- break;
- }
-
- case SELECTION_PRESENT: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL);
- goto error;
- }
- Tcl_SetObjResult(interp,
- Tcl_NewBooleanObj((entryPtr->selectFirst >= 0)));
- goto done;
- }
+ case COMMAND_VALIDATE: {
+ int code;
- case SELECTION_RANGE: {
- if (objc != 5) {
- Tcl_WrongNumArgs(interp, 3, objv, "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, 3, objv, "index");
- goto error;
- }
- if (GetEntryIndex(interp, entryPtr,
- Tcl_GetString(objv[3]), &index) != TCL_OK) {
- goto error;
- }
- EntrySelectTo(entryPtr, index);
- break;
- }
- }
- break;
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ goto error;
+ }
+ selIndex = entryPtr->validate;
+ entryPtr->validate = VALIDATE_ALL;
+ code = EntryValidateChange(entryPtr, NULL, entryPtr->string,
+ -1, VALIDATE_FORCED);
+ if (entryPtr->validate != VALIDATE_NONE) {
+ entryPtr->validate = selIndex;
}
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj((code == TCL_OK)));
+ break;
+ }
- case COMMAND_VALIDATE: {
- int code;
+ case COMMAND_XVIEW: {
+ int index;
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL);
+ if (objc == 2) {
+ double first, last;
+ char buf[TCL_DOUBLE_SPACE];
+
+ EntryVisibleRange(entryPtr, &first, &last);
+ Tcl_PrintDouble(NULL, first, buf);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ Tcl_PrintDouble(NULL, last, buf);
+ Tcl_AppendResult(interp, " ", buf, NULL);
+ goto done;
+ } else if (objc == 3) {
+ if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]),
+ &index) != TCL_OK) {
goto error;
}
- selIndex = entryPtr->validate;
- entryPtr->validate = VALIDATE_ALL;
- code = EntryValidateChange(entryPtr, (char *) NULL,
- entryPtr->string, -1, VALIDATE_FORCED);
- if (entryPtr->validate != VALIDATE_NONE) {
- entryPtr->validate = selIndex;
- }
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj((code == TCL_OK)));
- break;
- }
+ } else {
+ double fraction;
+ int count;
- 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;
- }
+ 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;
}
- if (index >= entryPtr->numChars) {
- index = entryPtr->numChars - 1;
- }
- if (index < 0) {
- index = 0;
+ case TK_SCROLL_UNITS:
+ index += count;
+ break;
}
- 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);
+ break;
+ }
}
- done:
+ done:
Tcl_Release((ClientData) entryPtr);
return result;
- error:
+ error:
Tcl_Release((ClientData) entryPtr);
return TCL_ERROR;
}
@@ -1046,9 +993,9 @@ EntryWidgetObjCmd(clientData, interp, objc, objv)
*
* DestroyEntry --
*
- * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release
- * to clean up the internal structure of an entry at a safe time
- * (when no-one is using it anymore).
+ * This function is invoked by Tcl_EventuallyFree or Tcl_Release to clean
+ * up the internal structure of an entry at a safe time (when no-one is
+ * using it anymore).
*
* Results:
* None.
@@ -1060,15 +1007,14 @@ EntryWidgetObjCmd(clientData, interp, objc, objv)
*/
static void
-DestroyEntry(memPtr)
- char *memPtr; /* Info about entry widget. */
+DestroyEntry(
+ char *memPtr) /* Info about entry widget. */
{
Entry *entryPtr = (Entry *) memPtr;
/*
- * Free up all the stuff that requires special handling, then
- * let Tk_FreeOptions handle all the standard option-related
- * stuff.
+ * Free up all the stuff that requires special handling, then let
+ * Tk_FreeOptions handle all the standard option-related stuff.
*/
ckfree((char *)entryPtr->string);
@@ -1113,43 +1059,43 @@ DestroyEntry(memPtr)
*
* ConfigureEntry --
*
- * This procedure is called to process an argv/argc list, plus
- * the Tk option database, in order to configure (or reconfigure)
- * an entry widget.
+ * This function is called to process an argv/argc list, plus the Tk
+ * option database, in order to configure (or reconfigure) an entry
+ * widget.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message.
+ * 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 colors, border width,
- * etc. get set for entryPtr; old resources get freed,
- * if there were any.
+ * Configuration information, such as colors, border width, etc. get set
+ * for entryPtr; old resources get freed, if there were any.
*
*----------------------------------------------------------------------
*/
static int
-ConfigureEntry(interp, entryPtr, objc, objv, flags)
- Tcl_Interp *interp; /* Used for error reporting. */
- Entry *entryPtr; /* Information about widget; may or may not
+ConfigureEntry(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ 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. */
+ 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;
Tk_3DBorder border;
Tcl_Obj *errorResult = NULL;
- Spinbox *sbPtr = (Spinbox *) entryPtr; /* Only used when this widget
- * is of type TK_SPINBOX */
- char *oldValues = NULL; /* lint initialization */
- char *oldFormat = NULL; /* lint initialization */
+ Spinbox *sbPtr = (Spinbox *) entryPtr;
+ /* Only used when this widget is of type
+ * TK_SPINBOX */
+ char *oldValues = NULL; /* lint initialization */
+ char *oldFormat = NULL; /* lint initialization */
int error;
- int oldExport = 0; /* lint initialization */
- int valuesChanged = 0; /* lint initialization */
- double oldFrom = 0.0; /* lint initialization */
- double oldTo = 0.0; /* lint initialization */
+ int oldExport = 0; /* lint initialization */
+ int valuesChanged = 0; /* lint initialization */
+ double oldFrom = 0.0; /* lint initialization */
+ double oldTo = 0.0; /* lint initialization */
/*
* Eliminate any existing trace on a variable monitored by the entry.
@@ -1157,16 +1103,17 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags)
if ((entryPtr->textVarName != NULL)
&& (entryPtr->flags & ENTRY_VAR_TRACED)) {
- Tcl_UntraceVar(interp, entryPtr->textVarName,
+ Tcl_UntraceVar(interp, entryPtr->textVarName,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
EntryTextVarProc, (ClientData) entryPtr);
entryPtr->flags &= ~ENTRY_VAR_TRACED;
}
/*
- * Store old values that we need to effect certain behavior if
- * they change value
+ * Store old values that we need to effect certain behavior if they change
+ * value.
*/
+
oldExport = entryPtr->exportSelection;
if (entryPtr->type == TK_SPINBOX) {
oldValues = sbPtr->valueStr;
@@ -1183,7 +1130,7 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags)
if (Tk_SetOptions(interp, (char *) entryPtr,
entryPtr->optionTable, objc, objv,
- entryPtr->tkwin, &savedOptions, (int *) NULL) != TCL_OK) {
+ entryPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
continue;
}
} else {
@@ -1233,6 +1180,7 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags)
* calculate the minimum space we'll need for the values as
* strings.
*/
+
int min, max;
size_t formatLen, formatSpace = TCL_DOUBLE_SPACE;
char fbuf[4], *fmt = sbPtr->reqFormat;
@@ -1241,7 +1189,7 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags)
if ((fmt[0] != '%') || (fmt[formatLen-1] != 'f')) {
badFormatOpt:
Tcl_AppendResult(interp, "bad spinbox format specifier \"",
- sbPtr->reqFormat, "\"", (char *) NULL);
+ sbPtr->reqFormat, "\"", NULL);
continue;
}
if ((sscanf(fmt, "%%%d.%d%[f]", &min, &max, fbuf) == 3)
@@ -1259,16 +1207,19 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags)
formatSpace = TCL_DOUBLE_SPACE;
}
sbPtr->formatBuf = ckrealloc(sbPtr->formatBuf, formatSpace);
+
/*
- * We perturb the value of oldFrom to allow us to go into
- * the branch below that will reformat the displayed value.
+ * We perturb the value of oldFrom to allow us to go into the
+ * branch below that will reformat the displayed value.
*/
+
oldFrom = sbPtr->fromValue - 1;
}
/*
- * See if we have to rearrange our listObj data
+ * See if we have to rearrange our listObj data.
*/
+
if (oldValues != sbPtr->valueStr) {
if (sbPtr->listObj != NULL) {
Tcl_DecrRefCount(sbPtr->listObj);
@@ -1294,13 +1245,14 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags)
}
/*
- * Restart the cursor timing sequence in case the on-time or
- * off-time just changed. Set validate temporarily to none,
- * so the configure doesn't cause it to be triggered.
+ * Restart the cursor timing sequence in case the on-time or off-time
+ * just changed. Set validate temporarily to none, so the configure
+ * doesn't cause it to be triggered.
*/
if (entryPtr->flags & GOT_FOCUS) {
int validate = entryPtr->validate;
+
entryPtr->validate = VALIDATE_NONE;
EntryFocusProc(entryPtr, 1);
entryPtr->validate = validate;
@@ -1311,8 +1263,8 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags)
*/
if (entryPtr->exportSelection && (!oldExport)
- && (entryPtr->selectFirst != -1)
- && !(entryPtr->flags & GOT_SELECTION)) {
+ && (entryPtr->selectFirst != -1)
+ && !(entryPtr->flags & GOT_SELECTION)) {
Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
(ClientData) entryPtr);
entryPtr->flags |= GOT_SELECTION;
@@ -1324,12 +1276,12 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags)
*/
Tk_SetInternalBorder(entryPtr->tkwin,
- entryPtr->borderWidth + entryPtr->highlightWidth);
+ entryPtr->borderWidth + entryPtr->highlightWidth);
if (entryPtr->highlightWidth <= 0) {
entryPtr->highlightWidth = 0;
}
- entryPtr->inset = entryPtr->highlightWidth
- + entryPtr->borderWidth + XPAD;
+ entryPtr->inset = entryPtr->highlightWidth
+ + entryPtr->borderWidth + XPAD;
break;
}
if (!error) {
@@ -1342,7 +1294,7 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags)
*/
if (entryPtr->textVarName != NULL) {
- CONST char *value;
+ const char *value;
value = Tcl_GetVar(interp, entryPtr->textVarName, TCL_GLOBAL_ONLY);
if (value == NULL) {
@@ -1359,9 +1311,10 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags)
Tcl_Obj *objPtr;
/*
- * No check for error return, because there shouldn't be one
- * given the check for valid list above
+ * No check for error return, because there shouldn't be one given
+ * the check for valid list above.
*/
+
Tcl_ListObjIndex(interp, sbPtr->listObj, 0, &objPtr);
EntryValueChanged(entryPtr, Tcl_GetString(objPtr));
} else if ((sbPtr->valueStr == NULL)
@@ -1370,15 +1323,15 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags)
|| !DOUBLES_EQ(sbPtr->toValue, oldTo))) {
/*
* If the valueStr is empty and -from && -to are specified, check
- * to see if the current string is within the range. If not,
- * it will be constrained to the nearest edge. If the current
- * string isn't a double value, we set it to -from.
+ * to see if the current string is within the range. If not, it
+ * will be constrained to the nearest edge. If the current string
+ * isn't a double value, we set it to -from.
*/
- int code;
+
double dvalue;
- code = Tcl_GetDouble(NULL, entryPtr->string, &dvalue);
- if (code != TCL_OK) {
+ if (sscanf(entryPtr->string, "%lf", &dvalue) == 0) {
+ /* Scan failure */
dvalue = sbPtr->fromValue;
} else {
if (dvalue > sbPtr->toValue) {
@@ -1393,8 +1346,8 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags)
}
/*
- * Set up a trace on the variable's value after we've possibly
- * constrained the value according to new -from/-to values.
+ * Set up a trace on the variable's value after we've possibly constrained
+ * the value according to new -from/-to values.
*/
if ((entryPtr->textVarName != NULL)
@@ -1407,11 +1360,11 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags)
EntryWorldChanged((ClientData) entryPtr);
if (error) {
- Tcl_SetObjResult(interp, errorResult);
+ Tcl_SetObjResult(interp, errorResult);
Tcl_DecrRefCount(errorResult);
return TCL_ERROR;
} else {
- return TCL_OK;
+ return TCL_OK;
}
}
@@ -1420,22 +1373,22 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags)
*
* EntryWorldChanged --
*
- * This procedure is called when the world has changed in some
- * way and the widget needs to recompute all its graphics contexts
- * and determine its new geometry.
+ * This function is called when the world has changed in some way and the
+ * widget needs to recompute all its graphics contexts and determine its
+ * new geometry.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Entry will be relayed out and redisplayed.
+ * Entry will be relayed out and redisplayed.
*
*---------------------------------------------------------------------------
*/
-
+
static void
-EntryWorldChanged(instanceData)
- ClientData instanceData; /* Information about widget. */
+EntryWorldChanged(
+ ClientData instanceData) /* Information about widget. */
{
XGCValues gcValues;
GC gc = None;
@@ -1461,27 +1414,27 @@ EntryWorldChanged(instanceData)
}
/*
- * Default background and foreground are from the normal state.
- * In a disabled state, both of those may be overridden; in the readonly
- * state, the background may be overridden.
+ * Default background and foreground are from the normal state. In a
+ * disabled state, both of those may be overridden; in the readonly state,
+ * the background may be overridden.
*/
border = entryPtr->normalBorder;
colorPtr = entryPtr->fgColorPtr;
switch (entryPtr->state) {
- case STATE_DISABLED:
- if (entryPtr->disabledBorder != NULL) {
- border = entryPtr->disabledBorder;
- }
- if (entryPtr->dfgColorPtr != NULL) {
- colorPtr = entryPtr->dfgColorPtr;
- }
- break;
- case STATE_READONLY:
- if (entryPtr->readonlyBorder != NULL) {
- border = entryPtr->readonlyBorder;
- }
- break;
+ case STATE_DISABLED:
+ if (entryPtr->disabledBorder != NULL) {
+ border = entryPtr->disabledBorder;
+ }
+ if (entryPtr->dfgColorPtr != NULL) {
+ colorPtr = entryPtr->dfgColorPtr;
+ }
+ break;
+ case STATE_READONLY:
+ if (entryPtr->readonlyBorder != NULL) {
+ border = entryPtr->readonlyBorder;
+ }
+ break;
}
Tk_SetBackgroundFromBorder(entryPtr->tkwin, border);
@@ -1507,8 +1460,7 @@ EntryWorldChanged(instanceData)
entryPtr->selTextGC = gc;
/*
- * Recompute the window's geometry and arrange for it to be
- * redisplayed.
+ * Recompute the window's geometry and arrange for it to be redisplayed.
*/
EntryComputeGeometry(entryPtr);
@@ -1516,18 +1468,17 @@ EntryWorldChanged(instanceData)
EventuallyRedraw(entryPtr);
}
-#ifndef MAC_OSX_TK
+#ifndef MAC_OSX_TK
/*
*--------------------------------------------------------------
*
* TkpDrawEntryBorderAndFocus --
*
- * This procedure redraws the border of an entry widget.
- * It overrides the generic border drawing code if the
- * entry widget parameters are such that the native widget
- * drawing is a good fit.
- * This version just returns o, so platforms that don't
- * do special native drawing don't have to implement it.
+ * This function redraws the border of an entry widget. It overrides the
+ * generic border drawing code if the entry widget parameters are such
+ * that the native widget drawing is a good fit. This version just
+ * returns 0, so platforms that don't do special native drawing don't
+ * have to implement it.
*
* Results:
* 1 if it has drawn the border, 0 if not.
@@ -1539,26 +1490,24 @@ EntryWorldChanged(instanceData)
*/
int
-TkpDrawEntryBorderAndFocus(entryPtr, pixmap, isSpinbox)
- Entry *entryPtr;
- Drawable pixmap;
- int isSpinbox;
+TkpDrawEntryBorderAndFocus(
+ Entry *entryPtr,
+ Drawable pixmap,
+ int isSpinbox)
{
return 0;
}
-
-
+
/*
*--------------------------------------------------------------
*
* TkpDrawSpinboxButtons --
*
- * This procedure redraws the buttons of an spinbox widget.
- * It overrides the generic button drawing code if the
- * spinbox widget parameters are such that the native widget
- * drawing is a good fit.
- * This version just returns 0, so platforms that don't
- * do special native drawing don't have to implement it.
+ * This function redraws the buttons of an spinbox widget. It overrides
+ * the generic button drawing code if the spinbox widget parameters are
+ * such that the native widget drawing is a good fit. This version just
+ * returns 0, so platforms that don't do special native drawing don't
+ * have to implement it.
*
* Results:
* 1 if it has drawn the border, 0 if not.
@@ -1570,20 +1519,20 @@ TkpDrawEntryBorderAndFocus(entryPtr, pixmap, isSpinbox)
*/
int
-TkpDrawSpinboxButtons(sbPtr, pixmap)
- Spinbox *sbPtr;
- Pixmap pixmap;
+TkpDrawSpinboxButtons(
+ Spinbox *sbPtr,
+ Pixmap pixmap)
{
return 0;
}
#endif /* Not MAC_OSX_TK */
-
+
/*
*--------------------------------------------------------------
*
* DisplayEntry --
*
- * This procedure redraws the contents of an entry window.
+ * This function redraws the contents of an entry window.
*
* Results:
* None.
@@ -1595,8 +1544,8 @@ TkpDrawSpinboxButtons(sbPtr, pixmap)
*/
static void
-DisplayEntry(clientData)
- ClientData clientData; /* Information about window. */
+DisplayEntry(
+ ClientData clientData) /* Information about window. */
{
Entry *entryPtr = (Entry *) clientData;
Tk_Window tkwin = entryPtr->tkwin;
@@ -1620,9 +1569,9 @@ DisplayEntry(clientData)
if (entryPtr->flags & UPDATE_SCROLLBAR) {
entryPtr->flags &= ~UPDATE_SCROLLBAR;
- /*
- * Preserve/Release because updating the scrollbar can have
- * the side-effect of destroying or unmapping the entry widget.
+ /*
+ * Preserve/Release because updating the scrollbar can have the
+ * side-effect of destroying or unmapping the entry widget.
*/
Tcl_Preserve((ClientData) entryPtr);
@@ -1637,10 +1586,10 @@ DisplayEntry(clientData)
#ifndef TK_NO_DOUBLE_BUFFERING
/*
- * In order to avoid screen flashes, this procedure redraws the
- * textual area of the entry into off-screen memory, then copies
- * it back on-screen in a single operation. This means there's
- * no point in time where the on-screen image has been cleared.
+ * In order to avoid screen flashes, this function redraws the textual
+ * area of the entry into off-screen memory, then copies it back on-screen
+ * in a single operation. This means there's no point in time where the
+ * on-screen image has been cleared.
*/
pixmap = Tk_GetPixmap(entryPtr->display, Tk_WindowId(tkwin),
@@ -1650,18 +1599,17 @@ DisplayEntry(clientData)
#endif /* TK_NO_DOUBLE_BUFFERING */
/*
- * Compute x-coordinate of the pixel just after last visible
- * one, plus vertical position of baseline of text.
+ * Compute x-coordinate of the pixel just after last visible one, plus
+ * vertical position of baseline of text.
*/
xBound = Tk_Width(tkwin) - entryPtr->inset - entryPtr->xWidth;
baseY = (Tk_Height(tkwin) + fm.ascent - fm.descent) / 2;
/*
- * On Windows and Mac, we need to hide the selection whenever we
- * don't have the focus.
+ * Hide the selection whenever we don't have the focus, unless we
+ * always want to show selection.
*/
-
if (TkpAlwaysShowSelection(entryPtr->tkwin)) {
showSelection = 1;
} else {
@@ -1669,9 +1617,9 @@ DisplayEntry(clientData)
}
/*
- * Draw the background in three layers. From bottom to top the
- * layers are: normal background, selection background, and
- * insertion cursor background.
+ * Draw the background in three layers. From bottom to top the layers are:
+ * normal background, selection background, and insertion cursor
+ * background.
*/
if ((entryPtr->state == STATE_DISABLED) &&
@@ -1711,16 +1659,16 @@ DisplayEntry(clientData)
MAC_OSX_ENTRY_SELECT_RELIEF
#endif
);
- }
+ }
}
/*
- * Draw a special background for the insertion cursor, overriding
- * even the selection background. As a special hack to keep the
- * cursor visible when the insertion cursor color is the same as
- * the color for selected text (e.g., on mono displays), write
- * background in the cursor area (instead of nothing) when the
- * cursor isn't on. Otherwise the selection would hide the cursor.
+ * Draw a special background for the insertion cursor, overriding even the
+ * selection background. As a special hack to keep the cursor visible when
+ * the insertion cursor color is the same as the color for selected text
+ * (e.g., on mono displays), write background in the cursor area (instead
+ * of nothing) when the cursor isn't on. Otherwise the selection would
+ * hide the cursor.
*/
if ((entryPtr->state == STATE_NORMAL) && (entryPtr->flags & GOT_FOCUS)) {
@@ -1730,25 +1678,22 @@ DisplayEntry(clientData)
cursorX -= (entryPtr->insertWidth)/2;
Tk_SetCaretPos(entryPtr->tkwin, cursorX, baseY - fm.ascent,
fm.ascent + fm.descent);
- if (entryPtr->insertPos >= entryPtr->leftIndex) {
- 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);
- } else if (entryPtr->insertBorder == entryPtr->selBorder) {
- Tk_Fill3DRectangle(tkwin, pixmap, border,
- cursorX, baseY - fm.ascent, entryPtr->insertWidth,
- fm.ascent + fm.descent, 0, TK_RELIEF_FLAT);
- }
+ if (entryPtr->insertPos >= entryPtr->leftIndex && 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);
+ } else if (entryPtr->insertBorder == entryPtr->selBorder) {
+ Tk_Fill3DRectangle(tkwin, pixmap, border, cursorX,
+ baseY - fm.ascent, entryPtr->insertWidth,
+ fm.ascent + fm.descent, 0, TK_RELIEF_FLAT);
}
}
}
/*
- * Draw the text in two pieces: first the unselected portion, then the
+ * Draw the text in two pieces: first the unselected portion, then the
* selected portion on top of it.
*/
@@ -1778,17 +1723,18 @@ DisplayEntry(clientData)
/*
* Draw the spin button controls.
*/
- if (TkpDrawSpinboxButtons(sbPtr, pixmap) == 0) {
- xWidth = entryPtr->xWidth;
- pad = XPAD + 1;
- inset = entryPtr->inset - XPAD;
- startx = Tk_Width(tkwin) - (xWidth + inset);
- height = (Tk_Height(tkwin) - 2*inset)/2;
+
+ if (TkpDrawSpinboxButtons(sbPtr, pixmap) == 0) {
+ xWidth = entryPtr->xWidth;
+ pad = XPAD + 1;
+ inset = entryPtr->inset - XPAD;
+ startx = Tk_Width(tkwin) - (xWidth + inset);
+ height = (Tk_Height(tkwin) - 2*inset)/2;
#if 0
- Tk_Fill3DRectangle(tkwin, pixmap, sbPtr->buttonBorder,
- startx, inset, xWidth, height, 1, sbPtr->buRelief);
- Tk_Fill3DRectangle(tkwin, pixmap, sbPtr->buttonBorder,
- startx, inset+height, xWidth, height, 1, sbPtr->bdRelief);
+ Tk_Fill3DRectangle(tkwin, pixmap, sbPtr->buttonBorder,
+ startx, inset, xWidth, height, 1, sbPtr->buRelief);
+ Tk_Fill3DRectangle(tkwin, pixmap, sbPtr->buttonBorder,
+ startx, inset+height, xWidth, height, 1, sbPtr->bdRelief);
#else
Tk_Fill3DRectangle(tkwin, pixmap, sbPtr->buttonBorder,
startx, inset, xWidth, height, 1,
@@ -1799,90 +1745,97 @@ DisplayEntry(clientData)
(sbPtr->selElement == SEL_BUTTONDOWN) ?
TK_RELIEF_SUNKEN : TK_RELIEF_RAISED);
#endif
-
- xWidth -= 2*pad;
- /*
- * Only draw the triangles if we have enough display space
- */
- if ((xWidth > 1)) {
- XPoint points[3];
- int starty, space, offset;
-
- space = height - 2*pad;
- /*
- * Ensure width of triangle is odd to guarantee a sharp tip
- */
- if (!(xWidth % 2)) {
- xWidth++;
- }
- tHeight = (xWidth + 1) / 2;
- if (tHeight > space) {
- tHeight = space;
- }
- space = (space - tHeight) / 2;
- startx += pad;
- starty = inset + height - pad - space;
- offset = (sbPtr->selElement == SEL_BUTTONUP);
- /*
- * The points are slightly different for the up and down arrows
- * because (for *.x), we need to account for a bug in the way
- * XFillPolygon draws triangles, and we want to shift
- * the arrows differently when allowing for depressed behavior.
- */
- points[0].x = startx + offset;
- points[0].y = starty + (offset ? 0 : -1);
- points[1].x = startx + xWidth/2 + offset;
- points[1].y = starty - tHeight + (offset ? 0 : -1);
- points[2].x = startx + xWidth + offset;
- points[2].y = points[0].y;
- XFillPolygon(entryPtr->display, pixmap, entryPtr->textGC,
- points, 3, Convex, CoordModeOrigin);
-
- starty = inset + height + pad + space;
- offset = (sbPtr->selElement == SEL_BUTTONDOWN);
- points[0].x = startx + 1 + offset;
- points[0].y = starty + (offset ? 1 : 0);
- points[1].x = startx + xWidth/2 + offset;
- points[1].y = starty + tHeight + (offset ? 0 : -1);
- points[2].x = startx - 1 + xWidth + offset;
- points[2].y = points[0].y;
- XFillPolygon(entryPtr->display, pixmap, entryPtr->textGC,
- points, 3, Convex, CoordModeOrigin);
- }
- }
+
+ xWidth -= 2*pad;
+
+ /*
+ * Only draw the triangles if we have enough display space
+ */
+
+ if ((xWidth > 1)) {
+ XPoint points[3];
+ int starty, space, offset;
+
+ space = height - 2*pad;
+
+ /*
+ * Ensure width of triangle is odd to guarantee a sharp tip
+ */
+
+ if (!(xWidth % 2)) {
+ xWidth++;
+ }
+ tHeight = (xWidth + 1) / 2;
+ if (tHeight > space) {
+ tHeight = space;
+ }
+ space = (space - tHeight) / 2;
+ startx += pad;
+ starty = inset + height - pad - space;
+ offset = (sbPtr->selElement == SEL_BUTTONUP);
+
+ /*
+ * The points are slightly different for the up and down
+ * arrows because (for *.x), we need to account for a bug in
+ * the way XFillPolygon draws triangles, and we want to shift
+ * the arrows differently when allowing for depressed
+ * behavior.
+ */
+
+ points[0].x = startx + offset;
+ points[0].y = starty + (offset ? 0 : -1);
+ points[1].x = startx + xWidth/2 + offset;
+ points[1].y = starty - tHeight + (offset ? 0 : -1);
+ points[2].x = startx + xWidth + offset;
+ points[2].y = points[0].y;
+ XFillPolygon(entryPtr->display, pixmap, entryPtr->textGC,
+ points, 3, Convex, CoordModeOrigin);
+
+ starty = inset + height + pad + space;
+ offset = (sbPtr->selElement == SEL_BUTTONDOWN);
+ points[0].x = startx + 1 + offset;
+ points[0].y = starty + (offset ? 1 : 0);
+ points[1].x = startx + xWidth/2 + offset;
+ points[1].y = starty + tHeight + (offset ? 0 : -1);
+ points[2].x = startx - 1 + xWidth + offset;
+ points[2].y = points[0].y;
+ XFillPolygon(entryPtr->display, pixmap, entryPtr->textGC,
+ points, 3, Convex, CoordModeOrigin);
+ }
+ }
}
/*
- * Draw the border and focus highlight last, so they will overwrite
- * any text that extends past the viewable part of the window.
+ * Draw the border and focus highlight last, so they will overwrite any
+ * text that extends past the viewable part of the window.
*/
- if (!TkpDrawEntryBorderAndFocus(entryPtr, pixmap,
- (entryPtr->type == TK_SPINBOX))) {
- xBound = entryPtr->highlightWidth;
- if (entryPtr->relief != TK_RELIEF_FLAT) {
+ if (!TkpDrawEntryBorderAndFocus(entryPtr, pixmap,
+ (entryPtr->type == TK_SPINBOX))) {
+ xBound = entryPtr->highlightWidth;
+ if (entryPtr->relief != TK_RELIEF_FLAT) {
Tk_Draw3DRectangle(tkwin, pixmap, border, xBound, xBound,
- Tk_Width(tkwin) - 2 * xBound,
+ Tk_Width(tkwin) - 2 * xBound,
Tk_Height(tkwin) - 2 * xBound,
entryPtr->borderWidth, entryPtr->relief);
- }
- if (xBound > 0) {
+ }
+ if (xBound > 0) {
GC fgGC, bgGC;
bgGC = Tk_GCForColor(entryPtr->highlightBgColorPtr, pixmap);
if (entryPtr->flags & GOT_FOCUS) {
- fgGC = Tk_GCForColor(entryPtr->highlightColorPtr, pixmap);
- TkpDrawHighlightBorder(tkwin, fgGC, bgGC, xBound, pixmap);
+ fgGC = Tk_GCForColor(entryPtr->highlightColorPtr, pixmap);
+ TkpDrawHighlightBorder(tkwin, fgGC, bgGC, xBound, pixmap);
} else {
- TkpDrawHighlightBorder(tkwin, bgGC, bgGC, xBound, pixmap);
+ TkpDrawHighlightBorder(tkwin, bgGC, bgGC, xBound, pixmap);
}
- }
+ }
}
#ifndef TK_NO_DOUBLE_BUFFERING
/*
- * Everything's been redisplayed; now copy the pixmap onto the screen
- * and free up the pixmap.
+ * Everything's been redisplayed; now copy the pixmap onto the screen and
+ * free up the pixmap.
*/
XCopyArea(entryPtr->display, pixmap, Tk_WindowId(tkwin), entryPtr->textGC,
@@ -1898,24 +1851,24 @@ DisplayEntry(clientData)
*
* EntryComputeGeometry --
*
- * This procedure is invoked to recompute information about where
- * in its window an entry's string will be displayed. It also
- * computes the requested size for the window.
+ * This function is invoked to recompute information about where in its
+ * window an entry's string will be displayed. It also computes the
+ * requested size for the window.
*
* Results:
* None.
*
* Side effects:
- * The leftX and tabOrigin fields are recomputed for entryPtr,
- * and leftIndex may be adjusted. Tk_GeometryRequest is called
- * to register the desired dimensions for the window.
+ * The leftX and tabOrigin fields are recomputed for entryPtr, and
+ * leftIndex may be adjusted. Tk_GeometryRequest is called to register
+ * the desired dimensions for the window.
*
*----------------------------------------------------------------------
*/
static void
-EntryComputeGeometry(entryPtr)
- Entry *entryPtr; /* Widget record for entry. */
+EntryComputeGeometry(
+ Entry *entryPtr) /* Widget record for entry. */
{
int totalLength, overflow, maxOffScreen, rightX;
int height, width, i;
@@ -1929,8 +1882,8 @@ EntryComputeGeometry(entryPtr)
}
/*
- * If we're displaying a special character instead of the value of
- * the entry, recompute the displayString.
+ * If we're displaying a special character instead of the value of the
+ * entry, recompute the displayString.
*/
if (entryPtr->showChar != NULL) {
@@ -1939,10 +1892,10 @@ EntryComputeGeometry(entryPtr)
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.
+ * 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);
@@ -1966,21 +1919,21 @@ EntryComputeGeometry(entryPtr)
entryPtr->layoutY = (Tk_Height(entryPtr->tkwin) - height) / 2;
/*
- * Recompute where the leftmost character on the display will
- * be drawn (entryPtr->leftX) and adjust leftIndex if necessary
- * so that we don't let characters hang off the edge of the
- * window unless the entire window is full.
+ * Recompute where the leftmost character on the display will be drawn
+ * (entryPtr->leftX) and adjust leftIndex if necessary so that we don't
+ * let characters hang off the edge of the window unless the entire window
+ * is full.
*/
overflow = totalLength -
- (Tk_Width(entryPtr->tkwin) - 2*entryPtr->inset - entryPtr->xWidth);
+ (Tk_Width(entryPtr->tkwin) - 2*entryPtr->inset - entryPtr->xWidth);
if (overflow <= 0) {
entryPtr->leftIndex = 0;
if (entryPtr->justify == TK_JUSTIFY_LEFT) {
entryPtr->leftX = entryPtr->inset;
} else if (entryPtr->justify == TK_JUSTIFY_RIGHT) {
entryPtr->leftX = Tk_Width(entryPtr->tkwin) - entryPtr->inset
- - entryPtr->xWidth - totalLength;
+ - entryPtr->xWidth - totalLength;
} else {
entryPtr->leftX = (Tk_Width(entryPtr->tkwin)
- entryPtr->xWidth - totalLength)/2;
@@ -1988,10 +1941,10 @@ EntryComputeGeometry(entryPtr)
entryPtr->layoutX = entryPtr->leftX;
} else {
/*
- * The whole string can't fit in the window. Compute the
- * maximum number of characters that may be off-screen to
- * the left without leaving empty space on the right of the
- * window, then don't let leftIndex be any greater than that.
+ * The whole string can't fit in the window. Compute the maximum
+ * number of characters that may be off-screen to the left without
+ * leaving empty space on the right of the window, then don't let
+ * leftIndex be any greater than that.
*/
maxOffScreen = Tk_PointToChar(entryPtr->textLayout, overflow, 0);
@@ -2040,23 +1993,25 @@ EntryComputeGeometry(entryPtr)
* None.
*
* Side effects:
- * New information gets added to entryPtr; it will be redisplayed
- * soon, but not necessarily immediately.
+ * New information gets added to entryPtr; it will be redisplayed soon,
+ * but not necessarily immediately.
*
*----------------------------------------------------------------------
*/
static void
-InsertChars(entryPtr, index, value)
- Entry *entryPtr; /* Entry that is to get the new elements. */
- int index; /* Add the new elements before this
- * character index. */
- char *value; /* New characters to add (NULL-terminated
+InsertChars(
+ Entry *entryPtr, /* Entry that is to get the new elements. */
+ int index, /* Add the new elements before this character
+ * index. */
+ char *value) /* New characters to add (NULL-terminated
* string). */
{
- int byteIndex, byteCount, oldChars, charsAdded, newByteCount;
- CONST char *string;
- char *new;
+ ptrdiff_t byteIndex;
+ size_t byteCount, newByteCount;
+ int oldChars, charsAdded;
+ const char *string;
+ char *newStr;
string = entryPtr->string;
byteIndex = Tcl_UtfAtIndex(string, index) - string;
@@ -2066,48 +2021,47 @@ InsertChars(entryPtr, index, value)
}
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);
+ newStr = (char *) ckalloc((unsigned) newByteCount);
+ memcpy(newStr, string, byteIndex);
+ strcpy(newStr + byteIndex, value);
+ strcpy(newStr + byteIndex + byteCount, string + byteIndex);
if ((entryPtr->validate == VALIDATE_KEY ||
- entryPtr->validate == VALIDATE_ALL) &&
- EntryValidateChange(entryPtr, value, new, index,
- VALIDATE_INSERT) != TCL_OK) {
- ckfree(new);
+ entryPtr->validate == VALIDATE_ALL) &&
+ EntryValidateChange(entryPtr, value, newStr, index,
+ VALIDATE_INSERT) != TCL_OK) {
+ ckfree(newStr);
return;
}
ckfree((char *)string);
- entryPtr->string = new;
+ entryPtr->string = newStr;
/*
- * 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.
+ * 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);
+ entryPtr->numChars = Tcl_NumUtfChars(newStr, -1);
charsAdded = entryPtr->numChars - oldChars;
entryPtr->numBytes += byteCount;
if (entryPtr->displayString == string) {
- entryPtr->displayString = new;
+ entryPtr->displayString = newStr;
entryPtr->numDisplayBytes = entryPtr->numBytes;
}
/*
- * Inserting characters invalidates all indexes into the string.
- * Touch up the indexes so that they still refer to the same
- * characters (at new positions). When updating the selection
- * end-points, don't include the new text in the selection unless
- * it was completely surrounded by the selection.
+ * Inserting characters invalidates all indexes into the string. Touch up
+ * the indexes so that they still refer to the same characters (at new
+ * positions). When updating the selection end-points, don't include the
+ * new text in the selection unless it was completely surrounded by the
+ * selection.
*/
if (entryPtr->selectFirst >= index) {
@@ -2116,8 +2070,7 @@ InsertChars(entryPtr, index, value)
if (entryPtr->selectLast > index) {
entryPtr->selectLast += charsAdded;
}
- if ((entryPtr->selectAnchor > index)
- || (entryPtr->selectFirst >= index)) {
+ if ((entryPtr->selectAnchor > index) || (entryPtr->selectFirst >= index)) {
entryPtr->selectAnchor += charsAdded;
}
if (entryPtr->leftIndex > index) {
@@ -2147,14 +2100,14 @@ InsertChars(entryPtr, index, value)
*/
static void
-DeleteChars(entryPtr, index, count)
- Entry *entryPtr; /* Entry widget to modify. */
- int index; /* Index of first character to delete. */
- int count; /* How many characters to delete. */
+DeleteChars(
+ Entry *entryPtr, /* Entry widget to modify. */
+ int index, /* Index of first character to delete. */
+ int count) /* How many characters to delete. */
{
int byteIndex, byteCount, newByteCount;
- CONST char *string;
- char *new, *todelete;
+ const char *string;
+ char *newStr, *toDelete;
if ((index + count) > entryPtr->numChars) {
count = entryPtr->numChars - index;
@@ -2165,41 +2118,41 @@ DeleteChars(entryPtr, index, count)
string = entryPtr->string;
byteIndex = Tcl_UtfAtIndex(string, index) - string;
- byteCount = Tcl_UtfAtIndex(string + byteIndex, count) - (string + byteIndex);
+ 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);
+ newStr = (char *) ckalloc((unsigned) newByteCount);
+ memcpy(newStr, string, (size_t) byteIndex);
+ strcpy(newStr + byteIndex, string + byteIndex + byteCount);
- todelete = (char *) ckalloc((unsigned) (byteCount + 1));
- memcpy(todelete, string + byteIndex, (size_t) byteCount);
- todelete[byteCount] = '\0';
+ toDelete = (char *) ckalloc((unsigned) (byteCount + 1));
+ memcpy(toDelete, string + byteIndex, (size_t) byteCount);
+ toDelete[byteCount] = '\0';
if ((entryPtr->validate == VALIDATE_KEY ||
- entryPtr->validate == VALIDATE_ALL) &&
- EntryValidateChange(entryPtr, todelete, new, index,
- VALIDATE_DELETE) != TCL_OK) {
- ckfree(new);
- ckfree(todelete);
+ entryPtr->validate == VALIDATE_ALL) &&
+ EntryValidateChange(entryPtr, toDelete, newStr, index,
+ VALIDATE_DELETE) != TCL_OK) {
+ ckfree(newStr);
+ ckfree(toDelete);
return;
}
- ckfree(todelete);
+ ckfree(toDelete);
ckfree((char *)entryPtr->string);
- entryPtr->string = new;
+ entryPtr->string = newStr;
entryPtr->numChars -= count;
entryPtr->numBytes -= byteCount;
if (entryPtr->displayString == string) {
- entryPtr->displayString = new;
+ entryPtr->displayString = newStr;
entryPtr->numDisplayBytes = entryPtr->numBytes;
}
/*
* Deleting characters results in the remaining characters being
- * renumbered. Update the various indexes into the string to reflect
- * this change.
+ * renumbered. Update the various indexes into the string to reflect this
+ * change.
*/
if (entryPtr->selectFirst >= index) {
@@ -2249,10 +2202,9 @@ DeleteChars(entryPtr, index, count)
*
* EntryValueChanged --
*
- * This procedure is invoked when characters are inserted into
- * an entry or deleted from it. It updates the entry's associated
- * variable, if there is one, and does other bookkeeping such
- * as arranging for redisplay.
+ * This function is invoked when characters are inserted into an entry or
+ * deleted from it. It updates the entry's associated variable, if there
+ * is one, and does other bookkeeping such as arranging for redisplay.
*
* Results:
* None.
@@ -2264,10 +2216,10 @@ DeleteChars(entryPtr, index, count)
*/
static void
-EntryValueChanged(entryPtr, newValue)
- Entry *entryPtr; /* Entry whose value just changed. */
- CONST char *newValue; /* If this value is not NULL, we first
- * force the value of the entry to this */
+EntryValueChanged(
+ Entry *entryPtr, /* Entry whose value just changed. */
+ const char *newValue) /* If this value is not NULL, we first force
+ * the value of the entry to this. */
{
if (newValue != NULL) {
EntrySetValue(entryPtr, newValue);
@@ -2283,10 +2235,10 @@ EntryValueChanged(entryPtr, newValue)
if ((newValue != NULL) && (strcmp(newValue, entryPtr->string) != 0)) {
/*
* The value of the variable is different than what we asked for.
- * This means that a trace on the variable modified it. In this
- * case our trace procedure wasn't invoked since the modification
- * came while a trace was already active on the variable. So,
- * update our value to reflect the variable's latest value.
+ * This means that a trace on the variable modified it. In this case
+ * our trace function wasn't invoked since the modification came while
+ * a trace was already active on the variable. So, update our value to
+ * reflect the variable's latest value.
*/
EntrySetValue(entryPtr, newValue);
@@ -2306,29 +2258,29 @@ EntryValueChanged(entryPtr, newValue)
*
* EntrySetValue --
*
- * Replace the contents of a text entry with a given value. This
- * procedure is invoked when updating the entry from the entry's
- * associated variable.
+ * Replace the contents of a text entry with a given value. This function
+ * is invoked when updating the entry from the entry's associated
+ * variable.
*
* Results:
* None.
*
* Side effects:
- * The string displayed in the entry will change. The selection,
- * insertion point, and view may have to be adjusted to keep them
- * within the bounds of the new string. Note: this procedure does
- * *not* update the entry's associated variable, since that could
- * result in an infinite loop.
+ * The string displayed in the entry will change. The selection,
+ * insertion point, and view may have to be adjusted to keep them within
+ * the bounds of the new string. Note: this function does *not* update
+ * the entry's associated variable, since that could result in an
+ * infinite loop.
*
*----------------------------------------------------------------------
*/
static void
-EntrySetValue(entryPtr, value)
- Entry *entryPtr; /* Entry whose value is to be changed. */
- CONST char *value; /* New text to display in entry. */
+EntrySetValue(
+ Entry *entryPtr, /* Entry whose value is to be changed. */
+ const char *value) /* New text to display in entry. */
{
- CONST char *oldSource;
+ const char *oldSource;
int valueLen, malloced = 0;
if (strcmp(value, entryPtr->string) == 0) {
@@ -2340,23 +2292,27 @@ EntrySetValue(entryPtr, value)
entryPtr->flags |= VALIDATE_ABORT;
} else {
/*
- * If we validate, we create a copy of the value, as it may
- * point to volatile memory, like the value of the -textvar
- * which may get freed during validation
+ * If we validate, we create a copy of the value, as it may point to
+ * volatile memory, like the value of the -textvar which may get freed
+ * during validation
*/
+
char *tmp = (char *) ckalloc((unsigned) (valueLen + 1));
+
strcpy(tmp, value);
value = tmp;
malloced = 1;
entryPtr->flags |= VALIDATE_VAR;
- (void) EntryValidateChange(entryPtr, (char *) NULL, value, -1,
+ (void) EntryValidateChange(entryPtr, NULL, value, -1,
VALIDATE_FORCED);
entryPtr->flags &= ~VALIDATE_VAR;
+
/*
* If VALIDATE_ABORT has been set, then this operation should be
* aborted because the validatecommand did something else instead
*/
+
if (entryPtr->flags & VALIDATE_ABORT) {
entryPtr->flags &= ~VALIDATE_ABORT;
ckfree((char *)value);
@@ -2371,6 +2327,7 @@ EntrySetValue(entryPtr, value)
entryPtr->string = value;
} else {
char *tmp = (char *) ckalloc((unsigned) (valueLen + 1));
+
strcpy(tmp, value);
entryPtr->string = tmp;
}
@@ -2411,23 +2368,23 @@ EntrySetValue(entryPtr, value)
*
* EntryEventProc --
*
- * This procedure is invoked by the Tk dispatcher for various
- * events on entries.
+ * This function is invoked by the Tk dispatcher for various events on
+ * entries.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up.
+ * When it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-EntryEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- XEvent *eventPtr; /* Information about event. */
+EntryEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
Entry *entryPtr = (Entry *) clientData;
@@ -2458,34 +2415,33 @@ EntryEventProc(clientData, eventPtr)
}
switch (eventPtr->type) {
- case Expose:
- EventuallyRedraw(entryPtr);
- entryPtr->flags |= BORDER_NEEDED;
- break;
- case DestroyNotify:
- if (!(entryPtr->flags & ENTRY_DELETED)) {
- entryPtr->flags |= (ENTRY_DELETED | VALIDATE_ABORT);
- Tcl_DeleteCommandFromToken(entryPtr->interp,
- entryPtr->widgetCmd);
- if (entryPtr->flags & REDRAW_PENDING) {
- Tcl_CancelIdleCall(DisplayEntry, clientData);
- }
- Tcl_EventuallyFree(clientData, DestroyEntry);
- }
- break;
- case ConfigureNotify:
- Tcl_Preserve((ClientData) entryPtr);
- entryPtr->flags |= UPDATE_SCROLLBAR;
- EntryComputeGeometry(entryPtr);
- EventuallyRedraw(entryPtr);
- Tcl_Release((ClientData) entryPtr);
- break;
- case FocusIn:
- case FocusOut:
- if (eventPtr->xfocus.detail != NotifyInferior) {
- EntryFocusProc(entryPtr, (eventPtr->type == FocusIn));
+ case Expose:
+ EventuallyRedraw(entryPtr);
+ entryPtr->flags |= BORDER_NEEDED;
+ break;
+ case DestroyNotify:
+ if (!(entryPtr->flags & ENTRY_DELETED)) {
+ entryPtr->flags |= (ENTRY_DELETED | VALIDATE_ABORT);
+ Tcl_DeleteCommandFromToken(entryPtr->interp, entryPtr->widgetCmd);
+ if (entryPtr->flags & REDRAW_PENDING) {
+ Tcl_CancelIdleCall(DisplayEntry, clientData);
}
- break;
+ Tcl_EventuallyFree(clientData, DestroyEntry);
+ }
+ break;
+ case ConfigureNotify:
+ Tcl_Preserve((ClientData) entryPtr);
+ entryPtr->flags |= UPDATE_SCROLLBAR;
+ EntryComputeGeometry(entryPtr);
+ EventuallyRedraw(entryPtr);
+ Tcl_Release((ClientData) entryPtr);
+ break;
+ case FocusIn:
+ case FocusOut:
+ if (eventPtr->xfocus.detail != NotifyInferior) {
+ EntryFocusProc(entryPtr, (eventPtr->type == FocusIn));
+ }
+ break;
}
}
@@ -2494,9 +2450,9 @@ EntryEventProc(clientData, eventPtr)
*
* EntryCmdDeletedProc --
*
- * 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.
+ * This function 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.
@@ -2508,20 +2464,20 @@ EntryEventProc(clientData, eventPtr)
*/
static void
-EntryCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+EntryCmdDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
Entry *entryPtr = (Entry *) clientData;
/*
- * 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.
+ * This function 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 function destroys the
+ * widget.
*/
if (!(entryPtr->flags & ENTRY_DELETED)) {
- Tk_DestroyWindow(entryPtr->tkwin);
+ Tk_DestroyWindow(entryPtr->tkwin);
}
}
@@ -2530,15 +2486,14 @@ EntryCmdDeletedProc(clientData)
*
* GetEntryIndex --
*
- * Parse an index into an entry and return either its value
- * or an error.
+ * Parse an index into an entry and return either its value or an error.
*
* Results:
- * A standard Tcl result. If all went well, then *indexPtr is
- * 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 the interp's result.
+ * A standard Tcl result. If all went well, then *indexPtr is 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 the interp's result.
*
* Side effects:
* None.
@@ -2547,13 +2502,12 @@ EntryCmdDeletedProc(clientData)
*/
static int
-GetEntryIndex(interp, entryPtr, string, indexPtr)
- Tcl_Interp *interp; /* For error messages. */
- Entry *entryPtr; /* Entry for which the index is being
+GetEntryIndex(
+ Tcl_Interp *interp, /* For error messages. */
+ Entry *entryPtr, /* Entry for which the index is being
* specified. */
- char *string; /* Specifies character in entryPtr. */
- int *indexPtr; /* Where to store converted character
- * index. */
+ char *string, /* Specifies character in entryPtr. */
+ int *indexPtr) /* Where to store converted character index */
{
size_t length;
@@ -2563,17 +2517,17 @@ GetEntryIndex(interp, entryPtr, string, indexPtr)
if (strncmp(string, "anchor", length) == 0) {
*indexPtr = entryPtr->selectAnchor;
} else {
- badIndex:
+ badIndex:
/*
* Some of the paths here leave messages in the interp's result,
* so we have to clear it out before storing our own message.
*/
- Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);
+ Tcl_SetResult(interp, NULL, TCL_STATIC);
Tcl_AppendResult(interp, "bad ",
(entryPtr->type == TK_ENTRY) ? "entry" : "spinbox",
- " index \"", string, "\"", (char *) NULL);
+ " index \"", string, "\"", NULL);
return TCL_ERROR;
}
} else if (string[0] == 'e') {
@@ -2590,9 +2544,9 @@ GetEntryIndex(interp, entryPtr, string, indexPtr)
}
} else if (string[0] == 's') {
if (entryPtr->selectFirst < 0) {
- Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);
+ Tcl_SetResult(interp, NULL, TCL_STATIC);
Tcl_AppendResult(interp, "selection isn't in widget ",
- Tk_PathName(entryPtr->tkwin), (char *) NULL);
+ Tk_PathName(entryPtr->tkwin), NULL);
return TCL_ERROR;
}
if (length < 5) {
@@ -2625,10 +2579,10 @@ GetEntryIndex(interp, entryPtr, string, indexPtr)
x - entryPtr->layoutX, 0);
/*
- * Special trick: if the x-position was off-screen to the right,
- * round the index up to refer to the character just after the
- * last visible one on the screen. This is needed to enable the
- * last character to be selected, for example.
+ * Special trick: if the x-position was off-screen to the right, round
+ * the index up to refer to the character just after the last visible
+ * one on the screen. This is needed to enable the last character to
+ * be selected, for example.
*/
if (roundUp && (*indexPtr < entryPtr->numChars)) {
@@ -2642,7 +2596,7 @@ GetEntryIndex(interp, entryPtr, string, indexPtr)
*indexPtr = 0;
} else if (*indexPtr > entryPtr->numChars) {
*indexPtr = entryPtr->numChars;
- }
+ }
}
return TCL_OK;
}
@@ -2652,8 +2606,8 @@ GetEntryIndex(interp, entryPtr, string, indexPtr)
*
* EntryScanTo --
*
- * Given a y-coordinate (presumably of the curent mouse location)
- * drag the view in the window to implement the scan operation.
+ * Given a y-coordinate (presumably of the curent mouse location) drag
+ * the view in the window to implement the scan operation.
*
* Results:
* None.
@@ -2665,21 +2619,21 @@ GetEntryIndex(interp, entryPtr, string, indexPtr)
*/
static void
-EntryScanTo(entryPtr, x)
- Entry *entryPtr; /* Information about widget. */
- int x; /* X-coordinate to use for scan operation. */
+EntryScanTo(
+ Entry *entryPtr, /* Information about widget. */
+ int x) /* X-coordinate to use for scan operation. */
{
int newLeftIndex;
/*
- * Compute new leftIndex for entry by amplifying the difference
- * between the current position and the place where the scan
- * started (the "mark" position). If we run off the left or right
- * side of the entry, then reset the mark point so that the current
- * position continues to correspond to the edge of the window.
- * This means that the picture will start dragging as soon as the
- * mouse reverses direction (without this reset, might have to slide
- * mouse a long ways back before the picture starts moving again).
+ * Compute new leftIndex for entry by amplifying the difference between
+ * the current position and the place where the scan started (the "mark"
+ * position). If we run off the left or right side of the entry, then
+ * reset the mark point so that the current position continues to
+ * correspond to the edge of the window. This means that the picture will
+ * start dragging as soon as the mouse reverses direction (without this
+ * reset, might have to slide mouse a long ways back before the picture
+ * starts moving again).
*/
newLeftIndex = entryPtr->scanMarkIndex
@@ -2691,7 +2645,7 @@ EntryScanTo(entryPtr, x)
if (newLeftIndex < 0) {
newLeftIndex = entryPtr->scanMarkIndex = 0;
entryPtr->scanMarkX = x;
- }
+ }
if (newLeftIndex != entryPtr->leftIndex) {
entryPtr->leftIndex = newLeftIndex;
@@ -2710,8 +2664,8 @@ EntryScanTo(entryPtr, x)
*
* EntrySelectTo --
*
- * Modify the selection by moving its un-anchored end. This could
- * make the selection either larger or smaller.
+ * Modify the selection by moving its un-anchored end. This could make
+ * the selection either larger or smaller.
*
* Results:
* None.
@@ -2723,9 +2677,9 @@ EntryScanTo(entryPtr, x)
*/
static void
-EntrySelectTo(entryPtr, index)
- Entry *entryPtr; /* Information about widget. */
- int index; /* Character index of element that is to
+EntrySelectTo(
+ Entry *entryPtr, /* Information about widget. */
+ int index) /* Character index of element that is to
* become the "other" end of the selection. */
{
int newFirst, newLast;
@@ -2771,15 +2725,15 @@ EntrySelectTo(entryPtr, index)
*
* EntryFetchSelection --
*
- * This procedure is called back by Tk when the selection is
- * requested by someone. It returns part or all of the selection
- * in a buffer provided by the caller.
+ * This function is called back by Tk when the selection is requested by
+ * someone. It returns part or all of the selection in a buffer provided
+ * by the caller.
*
* Results:
- * The return value is the number of non-NULL bytes stored
- * at buffer. Buffer is filled (or partially filled) with a
- * NULL-terminated string containing part or all of the selection,
- * as given by offset and maxBytes.
+ * The return value is the number of non-NULL bytes stored at buffer.
+ * Buffer is filled (or partially filled) with a NULL-terminated string
+ * containing part or all of the selection, as given by offset and
+ * maxBytes.
*
* Side effects:
* None.
@@ -2788,19 +2742,18 @@ EntrySelectTo(entryPtr, index)
*/
static int
-EntryFetchSelection(clientData, offset, buffer, maxBytes)
- ClientData clientData; /* Information about entry widget. */
- int offset; /* Byte offset within selection of first
+EntryFetchSelection(
+ 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. */
+ char *buffer, /* Location in which to place selection. */
+ int maxBytes) /* Maximum number of bytes to place at buffer,
+ * not including terminating NUL character. */
{
Entry *entryPtr = (Entry *) clientData;
int byteCount;
- CONST char *string;
- CONST char *selStart, *selEnd;
+ const char *string;
+ const char *selStart, *selEnd;
if ((entryPtr->selectFirst < 0) || !(entryPtr->exportSelection)) {
return -1;
@@ -2826,32 +2779,32 @@ EntryFetchSelection(clientData, offset, buffer, maxBytes)
*
* EntryLostSelection --
*
- * This procedure is called back by Tk when the selection is
- * grabbed away from an entry widget.
+ * This function is called back by Tk when the selection is grabbed away
+ * from an entry widget.
*
* Results:
* None.
*
* Side effects:
- * The existing selection is unhighlighted, and the window is
- * marked as not containing a selection.
+ * The existing selection is unhighlighted, and the window is marked as
+ * not containing a selection.
*
*----------------------------------------------------------------------
*/
static void
-EntryLostSelection(clientData)
- ClientData clientData; /* Information about entry widget. */
+EntryLostSelection(
+ ClientData clientData) /* Information about entry widget. */
{
Entry *entryPtr = (Entry *) clientData;
entryPtr->flags &= ~GOT_SELECTION;
/*
- * On Windows and Mac systems, we want to remember the selection
- * for the next time the focus enters the window. On Unix, we need
- * to clear the selection since it is always visible. This is
- * controlled by ::tk::AlwaysShowSelection.
+ * On Windows and Mac systems, we want to remember the selection for the
+ * next time the focus enters the window. On Unix, we need to clear the
+ * selection since it is always visible.
+ * This is controlled by ::tk::AlwaysShowSelection.
*/
if (TkpAlwaysShowSelection(entryPtr->tkwin)
@@ -2873,26 +2826,26 @@ EntryLostSelection(clientData)
* None.
*
* Side effects:
- * Information gets redisplayed. Right now we don't do selective
- * redisplays: the whole window will be redrawn. This doesn't
- * seem to hurt performance noticeably, but if it does then this
- * could be changed.
+ * Information gets redisplayed. Right now we don't do selective
+ * redisplays: the whole window will be redrawn. This doesn't seem to
+ * hurt performance noticeably, but if it does then this could be
+ * changed.
*
*----------------------------------------------------------------------
*/
static void
-EventuallyRedraw(entryPtr)
- Entry *entryPtr; /* Information about widget. */
+EventuallyRedraw(
+ Entry *entryPtr) /* Information about widget. */
{
if ((entryPtr->flags & ENTRY_DELETED) || !Tk_IsMapped(entryPtr->tkwin)) {
return;
}
/*
- * Right now we don't do selective redisplays: the whole window
- * will be redrawn. This doesn't seem to hurt performance noticeably,
- * but if it does then this could be changed.
+ * Right now we don't do selective redisplays: the whole window will be
+ * redrawn. This doesn't seem to hurt performance noticeably, but if it
+ * does then this could be changed.
*/
if (!(entryPtr->flags & REDRAW_PENDING)) {
@@ -2906,13 +2859,12 @@ EventuallyRedraw(entryPtr)
*
* EntryVisibleRange --
*
- * Return information about the range of the entry that is
- * currently visible.
+ * Return information about the range of the entry that is currently
+ * visible.
*
* Results:
- * *firstPtr and *lastPtr are modified to hold fractions between
- * 0 and 1 identifying the range of characters visible in the
- * entry.
+ * *firstPtr and *lastPtr are modified to hold fractions between 0 and 1
+ * identifying the range of characters visible in the entry.
*
* Side effects:
* None.
@@ -2921,11 +2873,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
+EntryVisibleRange(
+ 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;
@@ -2956,10 +2908,10 @@ EntryVisibleRange(entryPtr, firstPtr, lastPtr)
*
* EntryUpdateScrollbar --
*
- * This procedure is invoked whenever information has changed in
- * an entry in a way that would invalidate a scrollbar display.
- * If there is an associated scrollbar, then this procedure updates
- * it by invoking a Tcl command.
+ * This function is invoked whenever information has changed in an entry
+ * in a way that would invalidate a scrollbar display. If there is an
+ * associated scrollbar, then this function updates it by invoking a Tcl
+ * command.
*
* Results:
* None.
@@ -2972,10 +2924,10 @@ EntryVisibleRange(entryPtr, firstPtr, lastPtr)
*/
static void
-EntryUpdateScrollbar(entryPtr)
- Entry *entryPtr; /* Information about widget. */
+EntryUpdateScrollbar(
+ Entry *entryPtr) /* Information about widget. */
{
- char args[TCL_DOUBLE_SPACE * 2];
+ char firstStr[TCL_DOUBLE_SPACE], lastStr[TCL_DOUBLE_SPACE];
int code;
double first, last;
Tcl_Interp *interp;
@@ -2987,8 +2939,10 @@ EntryUpdateScrollbar(entryPtr)
interp = entryPtr->interp;
Tcl_Preserve((ClientData) interp);
EntryVisibleRange(entryPtr, &first, &last);
- sprintf(args, " %g %g", first, last);
- code = Tcl_VarEval(interp, entryPtr->scrollCmd, args, (char *) NULL);
+ Tcl_PrintDouble(NULL, first, firstStr);
+ Tcl_PrintDouble(NULL, last, lastStr);
+ code = Tcl_VarEval(interp, entryPtr->scrollCmd, " ", firstStr, " ",
+ lastStr, NULL);
if (code != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (horizontal scrolling command executed by ");
@@ -2996,7 +2950,7 @@ EntryUpdateScrollbar(entryPtr)
Tcl_AddErrorInfo(interp, ")");
Tcl_BackgroundError(interp);
}
- Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);
+ Tcl_SetResult(interp, NULL, TCL_STATIC);
Tcl_Release((ClientData) interp);
}
@@ -3005,22 +2959,22 @@ EntryUpdateScrollbar(entryPtr)
*
* EntryBlinkProc --
*
- * This procedure is called as a timer handler to blink the
- * insertion cursor off and on.
+ * This function is called as a timer handler to blink the insertion
+ * cursor off and on.
*
* Results:
* None.
*
* Side effects:
- * The cursor gets turned on or off, redisplay gets invoked,
- * and this procedure reschedules itself.
+ * The cursor gets turned on or off, redisplay gets invoked, and this
+ * function reschedules itself.
*
*----------------------------------------------------------------------
*/
static void
-EntryBlinkProc(clientData)
- ClientData clientData; /* Pointer to record describing entry. */
+EntryBlinkProc(
+ ClientData clientData) /* Pointer to record describing entry. */
{
Entry *entryPtr = (Entry *) clientData;
@@ -3046,9 +3000,9 @@ EntryBlinkProc(clientData)
*
* EntryFocusProc --
*
- * This procedure is called whenever the entry gets or loses the
- * input focus. It's also called whenever the window is reconfigured
- * while it has the focus.
+ * This function is called whenever the entry gets or loses the input
+ * focus. It's also called whenever the window is reconfigured while it
+ * has the focus.
*
* Results:
* None.
@@ -3060,9 +3014,9 @@ EntryBlinkProc(clientData)
*/
static void
-EntryFocusProc(entryPtr, gotFocus)
- Entry *entryPtr; /* Entry that got or lost focus. */
- int gotFocus; /* 1 means window is getting focus, 0 means
+EntryFocusProc(
+ Entry *entryPtr, /* Entry that got or lost focus. */
+ int gotFocus) /* 1 means window is getting focus, 0 means
* it's losing it. */
{
Tcl_DeleteTimerHandler(entryPtr->insertBlinkHandler);
@@ -3076,7 +3030,7 @@ EntryFocusProc(entryPtr, gotFocus)
if (entryPtr->validate == VALIDATE_ALL ||
entryPtr->validate == VALIDATE_FOCUS ||
entryPtr->validate == VALIDATE_FOCUSIN) {
- EntryValidateChange(entryPtr, (char *) NULL,
+ EntryValidateChange(entryPtr, NULL,
entryPtr->string, -1, VALIDATE_FOCUSIN);
}
} else {
@@ -3085,7 +3039,7 @@ EntryFocusProc(entryPtr, gotFocus)
if (entryPtr->validate == VALIDATE_ALL ||
entryPtr->validate == VALIDATE_FOCUS ||
entryPtr->validate == VALIDATE_FOCUSOUT) {
- EntryValidateChange(entryPtr, (char *) NULL,
+ EntryValidateChange(entryPtr, NULL,
entryPtr->string, -1, VALIDATE_FOCUSOUT);
}
}
@@ -3097,41 +3051,40 @@ EntryFocusProc(entryPtr, gotFocus)
*
* EntryTextVarProc --
*
- * This procedure is invoked when someone changes the variable
- * whose contents are to be displayed in an entry.
+ * This function is invoked when someone changes the variable whose
+ * contents are to be displayed in an entry.
*
* Results:
* NULL is always returned.
*
* Side effects:
- * The text displayed in the entry will change to match the
- * variable.
+ * The text displayed in the entry will change to match the variable.
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static char *
-EntryTextVarProc(clientData, interp, name1, name2, flags)
- ClientData clientData; /* Information about button. */
- Tcl_Interp *interp; /* Interpreter containing variable. */
- CONST char *name1; /* Not used. */
- CONST char *name2; /* Not used. */
- int flags; /* Information about what happened. */
+EntryTextVarProc(
+ ClientData clientData, /* Information about button. */
+ Tcl_Interp *interp, /* Interpreter containing variable. */
+ const char *name1, /* Not used. */
+ const char *name2, /* Not used. */
+ int flags) /* Information about what happened. */
{
Entry *entryPtr = (Entry *) clientData;
- CONST char *value;
+ const char *value;
if (entryPtr->flags & ENTRY_DELETED) {
/*
* Just abort early if we entered here while being deleted.
*/
- return (char *) NULL;
+ return NULL;
}
/*
- * If the variable is unset, then immediately recreate it unless
- * the whole interpreter is going away.
+ * If the variable is unset, then immediately recreate it unless the whole
+ * interpreter is going away.
*/
if (flags & TCL_TRACE_UNSETS) {
@@ -3143,14 +3096,13 @@ EntryTextVarProc(clientData, interp, name1, name2, flags)
EntryTextVarProc, clientData);
entryPtr->flags |= ENTRY_VAR_TRACED;
}
- return (char *) NULL;
+ return NULL;
}
/*
- * Update the entry's text with the value of the variable, unless
- * the entry already has that value (this happens when the variable
- * changes value because we changed it because someone typed in
- * the entry).
+ * Update the entry's text with the value of the variable, unless the
+ * entry already has that value (this happens when the variable changes
+ * value because we changed it because someone typed in the entry).
*/
value = Tcl_GetVar(interp, entryPtr->textVarName, TCL_GLOBAL_ONLY);
@@ -3158,7 +3110,7 @@ EntryTextVarProc(clientData, interp, name1, name2, flags)
value = "";
}
EntrySetValue(entryPtr, value);
- return (char *) NULL;
+ return NULL;
}
/*
@@ -3166,25 +3118,25 @@ EntryTextVarProc(clientData, interp, name1, name2, flags)
*
* EntryValidate --
*
- * This procedure is invoked when any character is added or
- * removed from the entry widget, or a focus has trigerred validation.
+ * This function is invoked when any character is added or removed from
+ * the entry widget, or a focus has trigerred validation.
*
* Results:
- * TCL_OK if the validatecommand passes the new string.
- * TCL_BREAK if the vcmd executed OK, but rejects the string.
- * TCL_ERROR if an error occurred while executing the vcmd
- * or a valid Tcl_Bool is not returned.
+
+ * TCL_OK if the validatecommand passes the new string. TCL_BREAK if the
+ * vcmd executed OK, but rejects the string. TCL_ERROR if an error
+ * occurred while executing the vcmd or a valid Tcl_Bool is not returned.
*
* Side effects:
- * An error condition may arise
+ * An error condition may arise
*
*--------------------------------------------------------------
*/
static int
-EntryValidate(entryPtr, cmd)
- register Entry *entryPtr; /* Entry that needs validation. */
- register char *cmd; /* Validation command (NULL-terminated
+EntryValidate(
+ register Entry *entryPtr, /* Entry that needs validation. */
+ register char *cmd) /* Validation command (NULL-terminated
* string). */
{
register Tcl_Interp *interp = entryPtr->interp;
@@ -3193,9 +3145,10 @@ EntryValidate(entryPtr, cmd)
code = Tcl_EvalEx(interp, cmd, -1, TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
/*
- * We accept TCL_OK and TCL_RETURN as valid return codes from the
- * command callback.
+ * We accept TCL_OK and TCL_RETURN as valid return codes from the command
+ * callback.
*/
+
if (code != TCL_OK && code != TCL_RETURN) {
Tcl_AddErrorInfo(interp, "\n\t(in validation command executed by ");
Tcl_AddErrorInfo(interp, Tk_PathName(entryPtr->tkwin));
@@ -3207,8 +3160,9 @@ EntryValidate(entryPtr, cmd)
/*
* The command callback should return an acceptable Tcl boolean.
*/
+
if (Tcl_GetBooleanFromObj(interp, Tcl_GetObjResult(interp),
- &bool) != TCL_OK) {
+ &bool) != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\nvalid boolean not returned by validation command");
Tcl_BackgroundError(interp);
@@ -3225,45 +3179,45 @@ EntryValidate(entryPtr, cmd)
*
* EntryValidateChange --
*
- * This procedure is invoked when any character is added or
- * removed from the entry widget, or a focus has trigerred validation.
+ * This function is invoked when any character is added or removed from
+ * the entry widget, or a focus has trigerred validation.
*
* Results:
- * TCL_OK if the validatecommand accepts the new string,
- * TCL_ERROR if any problems occured with validatecommand.
+ * TCL_OK if the validatecommand accepts the new string, TCL_ERROR if any
+ * problems occured with validatecommand.
*
* Side effects:
- * The insertion/deletion may be aborted, and the
- * validatecommand might turn itself off (if an error
- * or loop condition arises).
+ * The insertion/deletion may be aborted, and the validatecommand might
+ * turn itself off (if an error or loop condition arises).
*
*--------------------------------------------------------------
*/
static int
-EntryValidateChange(entryPtr, change, new, index, type)
- register Entry *entryPtr; /* Entry that needs validation. */
- char *change; /* Characters to be added/deleted
- * (NULL-terminated string). */
- CONST char *new; /* Potential new value of entry string */
- int index; /* index of insert/delete, -1 otherwise */
- int type; /* forced, delete, insert,
- * focusin or focusout */
+EntryValidateChange(
+ register Entry *entryPtr, /* Entry that needs validation. */
+ char *change, /* Characters to be added/deleted
+ * (NUL-terminated string). */
+ const char *newValue, /* Potential new value of entry string */
+ int index, /* index of insert/delete, -1 otherwise */
+ int type) /* forced, delete, insert, focusin or
+ * focusout */
{
int code, varValidate = (entryPtr->flags & VALIDATE_VAR);
char *p;
Tcl_DString script;
-
+
if (entryPtr->validateCmd == NULL ||
entryPtr->validate == VALIDATE_NONE) {
return (varValidate ? TCL_ERROR : TCL_OK);
}
/*
- * If we're already validating, then we're hitting a loop condition
- * Return and set validate to 0 to disallow further validations
- * and prevent current validation from finishing
+ * If we're already validating, then we're hitting a loop condition Return
+ * and set validate to 0 to disallow further validations and prevent
+ * current validation from finishing
*/
+
if (entryPtr->flags & VALIDATING) {
entryPtr->validate = VALIDATE_NONE;
return (varValidate ? TCL_ERROR : TCL_OK);
@@ -3277,7 +3231,7 @@ EntryValidateChange(entryPtr, change, new, index, type)
Tcl_DStringInit(&script);
ExpandPercents(entryPtr, entryPtr->validateCmd,
- change, new, index, type, &script);
+ change, newValue, index, type, &script);
Tcl_DStringAppend(&script, "", 1);
p = Tcl_DStringValue(&script);
@@ -3285,10 +3239,10 @@ EntryValidateChange(entryPtr, change, new, index, type)
Tcl_DStringFree(&script);
/*
- * If e->validate has become VALIDATE_NONE during the validation, or
- * we now have VALIDATE_VAR set (from EntrySetValue) and didn't before,
- * it means that a loop condition almost occured. Do not allow
- * this validation result to finish.
+ * If e->validate has become VALIDATE_NONE during the validation, or we
+ * now have VALIDATE_VAR set (from EntrySetValue) and didn't before, it
+ * means that a loop condition almost occured. Do not allow this
+ * validation result to finish.
*/
if (entryPtr->validate == VALIDATE_NONE
@@ -3297,8 +3251,8 @@ EntryValidateChange(entryPtr, change, new, index, type)
}
/*
- * It's possible that the user deleted the entry during validation.
- * In that case, abort future validation and return an error.
+ * It's possible that the user deleted the entry during validation. In
+ * that case, abort future validation and return an error.
*/
if (entryPtr->flags & ENTRY_DELETED) {
@@ -3307,20 +3261,19 @@ EntryValidateChange(entryPtr, change, new, index, type)
/*
* If validate will return ERROR, then disallow further validations
- * Otherwise, if it didn't accept the new string (returned TCL_BREAK)
- * then eval the invalidCmd (if it's set)
+ * Otherwise, if it didn't accept the new string (returned TCL_BREAK) then
+ * eval the invalidCmd (if it's set)
*/
if (code == TCL_ERROR) {
entryPtr->validate = VALIDATE_NONE;
} else if (code == TCL_BREAK) {
/*
- * If we were doing forced validation (like via a variable
- * trace) and the command returned 0, the we turn off validation
- * because we assume that textvariables have precedence in
- * managing the value. We also don't call the invcmd, as it
- * may want to do entry manipulation which the setting of the
- * var will later wipe anyway.
+ * If we were doing forced validation (like via a variable trace) and
+ * the command returned 0, the we turn off validation because we
+ * assume that textvariables have precedence in managing the value.
+ * We also don't call the invcmd, as it may want to do entry
+ * manipulation which the setting of the var will later wipe anyway.
*/
if (varValidate) {
@@ -3328,13 +3281,13 @@ EntryValidateChange(entryPtr, change, new, index, type)
} else if (entryPtr->invalidCmd != NULL) {
Tcl_DStringInit(&script);
ExpandPercents(entryPtr, entryPtr->invalidCmd,
- change, new, index, type, &script);
+ change, newValue, index, type, &script);
Tcl_DStringAppend(&script, "", 1);
p = Tcl_DStringValue(&script);
if (Tcl_EvalEx(entryPtr->interp, p, -1,
TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT) != TCL_OK) {
Tcl_AddErrorInfo(entryPtr->interp,
- "\n\t(in invalidcommand executed by entry)");
+ "\n\t(in invalidcommand executed by entry)");
Tcl_BackgroundError(entryPtr->interp);
code = TCL_ERROR;
entryPtr->validate = VALIDATE_NONE;
@@ -3342,8 +3295,9 @@ EntryValidateChange(entryPtr, change, new, index, type)
Tcl_DStringFree(&script);
/*
- * It's possible that the user deleted the entry during validation.
- * In that case, abort future validation and return an error.
+ * It's possible that the user deleted the entry during
+ * validation. In that case, abort future validation and return an
+ * error.
*/
if (entryPtr->flags & ENTRY_DELETED) {
@@ -3362,13 +3316,12 @@ EntryValidateChange(entryPtr, change, new, index, type)
*
* ExpandPercents --
*
- * Given a command and an event, produce a new command
- * by replacing % constructs in the original command
- * with information from the X event.
+ * Given a command and an event, produce a new command by replacing %
+ * constructs in the original command with information from the X event.
*
* Results:
- * The new expanded command is appended to the dynamic string
- * given by dsPtr.
+ * The new expanded command is appended to the dynamic string given by
+ * dsPtr.
*
* Side effects:
* None.
@@ -3377,23 +3330,23 @@ EntryValidateChange(entryPtr, change, new, index, type)
*/
static void
-ExpandPercents(entryPtr, before, change, new, index, type, dsPtr)
- register Entry *entryPtr; /* Entry that needs validation. */
- register CONST char *before;
- /* Command containing percent
- * expressions to be replaced. */
- char *change; /* Characters to added/deleted
- * (NULL-terminated string). */
- CONST char *new; /* Potential new value of entry string */
- int index; /* index of insert/delete */
- int type; /* INSERT or DELETE */
- Tcl_DString *dsPtr; /* Dynamic string in which to append
- * new command. */
+ExpandPercents(
+ register Entry *entryPtr, /* Entry that needs validation. */
+ register const char *before,
+ /* Command containing percent expressions to
+ * be replaced. */
+ const char *change, /* Characters to added/deleted (NUL-terminated
+ * string). */
+ const char *newValue, /* Potential new value of entry string */
+ int index, /* index of insert/delete */
+ int type, /* INSERT or DELETE */
+ Tcl_DString *dsPtr) /* Dynamic string in which to append new
+ * command. */
{
int spaceNeeded, cvtFlags; /* Used to substitute string as proper Tcl
* list element. */
int number, length;
- register CONST char *string;
+ register const char *string;
Tcl_UniChar ch;
char numStorage[2*TCL_INTEGER_SPACE];
@@ -3402,14 +3355,18 @@ ExpandPercents(entryPtr, before, change, new, index, type, dsPtr)
break;
}
/*
- * Find everything up to the next % character and append it
- * to the result string.
+ * Find everything up to the next % character and append it to the
+ * result string.
*/
string = before;
- /* No need to convert '%', as it is in ascii range */
+
+ /*
+ * No need to convert '%', as it is in ascii range.
+ */
+
string = Tcl_UtfFindFirst(before, '%');
- if (string == (char *) NULL) {
+ if (string == NULL) {
Tcl_DStringAppend(dsPtr, before, -1);
break;
} else if (string != before) {
@@ -3418,7 +3375,7 @@ ExpandPercents(entryPtr, before, change, new, index, type, dsPtr)
}
/*
- * There's a percent sequence here. Process it.
+ * There's a percent sequence here. Process it.
*/
before++; /* skip over % */
@@ -3431,80 +3388,82 @@ ExpandPercents(entryPtr, before, change, new, index, type, dsPtr)
/*
* -command %-substitution
*/
+
switch (ch) {
- case 's': /* Current string value of spinbox */
- string = entryPtr->string;
- break;
- case 'd': /* direction, up or down */
- string = change;
- break;
- case 'W': /* widget name */
- string = Tk_PathName(entryPtr->tkwin);
- break;
- default:
- length = Tcl_UniCharToUtf(ch, numStorage);
- numStorage[length] = '\0';
- string = numStorage;
- break;
+ case 's': /* Current string value of spinbox */
+ string = entryPtr->string;
+ break;
+ case 'd': /* direction, up or down */
+ string = change;
+ break;
+ case 'W': /* widget name */
+ string = Tk_PathName(entryPtr->tkwin);
+ break;
+ default:
+ length = Tcl_UniCharToUtf(ch, numStorage);
+ numStorage[length] = '\0';
+ string = numStorage;
+ break;
}
} else {
/*
* -validatecommand / -invalidcommand %-substitution
*/
+
switch (ch) {
- case 'd': /* Type of call that caused validation */
- switch (type) {
- case VALIDATE_INSERT:
- number = 1;
- break;
- case VALIDATE_DELETE:
- number = 0;
- break;
- default:
- number = -1;
- break;
- }
- sprintf(numStorage, "%d", number);
- string = numStorage;
- break;
- case 'i': /* index of insert/delete */
- sprintf(numStorage, "%d", index);
- string = numStorage;
+ case 'd': /* Type of call that caused validation */
+ switch (type) {
+ case VALIDATE_INSERT:
+ number = 1;
break;
- case 'P': /* 'Peeked' new value of the string */
- string = new;
+ case VALIDATE_DELETE:
+ number = 0;
break;
- case 's': /* Current string value of spinbox */
- string = entryPtr->string;
- break;
- case 'S': /* string to be inserted/deleted, if any */
- string = change;
- break;
- case 'v': /* type of validation currently set */
- string = validateStrings[entryPtr->validate];
+ default:
+ number = -1;
break;
- case 'V': /* type of validation in effect */
- switch (type) {
- case VALIDATE_INSERT:
- case VALIDATE_DELETE:
- string = validateStrings[VALIDATE_KEY];
- break;
- case VALIDATE_FORCED:
- string = "forced";
- break;
- default:
- string = validateStrings[type];
- break;
- }
+ }
+ sprintf(numStorage, "%d", number);
+ string = numStorage;
+ break;
+ case 'i': /* index of insert/delete */
+ sprintf(numStorage, "%d", index);
+ string = numStorage;
+ break;
+ case 'P': /* 'Peeked' new value of the string */
+ string = newValue;
+ break;
+ case 's': /* Current string value of spinbox */
+ string = entryPtr->string;
+ break;
+ case 'S': /* string to be inserted/deleted, if any */
+ string = change;
+ break;
+ case 'v': /* type of validation currently set */
+ string = validateStrings[entryPtr->validate];
+ break;
+ case 'V': /* type of validation in effect */
+ switch (type) {
+ case VALIDATE_INSERT:
+ case VALIDATE_DELETE:
+ string = validateStrings[VALIDATE_KEY];
break;
- case 'W': /* widget name */
- string = Tk_PathName(entryPtr->tkwin);
+ case VALIDATE_FORCED:
+ string = "forced";
break;
default:
- length = Tcl_UniCharToUtf(ch, numStorage);
- numStorage[length] = '\0';
- string = numStorage;
+ string = validateStrings[type];
break;
+ }
+ break;
+ case 'W': /* widget name */
+ string = Tk_PathName(entryPtr->tkwin);
+ break;
+ default:
+ length = Tcl_UniCharToUtf(ch, numStorage);
+ numStorage[length] = '\0';
+ string = numStorage;
+ break;
}
}
@@ -3523,9 +3482,8 @@ ExpandPercents(entryPtr, before, change, new, index, type, dsPtr)
*
* Tk_SpinboxObjCmd --
*
- * This procedure is invoked to process the "spinbox" Tcl
- * command. See the user documentation for details on what
- * it does.
+ * This function is invoked to process the "spinbox" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -3537,11 +3495,11 @@ ExpandPercents(entryPtr, before, change, new, index, type, dsPtr)
*/
int
-Tk_SpinboxObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* NULL. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_SpinboxObjCmd(
+ ClientData clientData, /* NULL. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
register Entry *entryPtr;
register Spinbox *sbPtr;
@@ -3555,28 +3513,28 @@ Tk_SpinboxObjCmd(clientData, interp, objc, objv)
}
tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
- Tcl_GetString(objv[1]), (char *) NULL);
+ Tcl_GetString(objv[1]), NULL);
if (tkwin == NULL) {
return TCL_ERROR;
}
/*
- * Create the option table for this widget class. If it has already
- * been created, Tk will return the cached value.
+ * Create the option table for this widget class. If it has already been
+ * created, Tk will return the cached value.
*/
optionTable = Tk_CreateOptionTable(interp, sbOptSpec);
/*
- * Initialize the fields of the structure that won't be initialized
- * by ConfigureEntry, or that ConfigureEntry requires to be
- * initialized already (e.g. resource pointers). Only the non-NULL/0
- * data must be initialized as memset covers the rest.
+ * Initialize the fields of the structure that won't be initialized by
+ * ConfigureEntry, or that ConfigureEntry requires to be initialized
+ * already (e.g. resource pointers). Only the non-NULL/0 data must be
+ * initialized as memset covers the rest.
*/
sbPtr = (Spinbox *) ckalloc(sizeof(Spinbox));
entryPtr = (Entry *) sbPtr;
- memset((VOID *) sbPtr, 0, sizeof(Spinbox));
+ memset(sbPtr, 0, sizeof(Spinbox));
entryPtr->tkwin = tkwin;
entryPtr->display = Tk_Display(tkwin);
@@ -3618,7 +3576,7 @@ Tk_SpinboxObjCmd(clientData, interp, objc, objv)
sbPtr->buRelief = TK_RELIEF_FLAT;
/*
- * Keep a hold of the associated tkwin until we destroy the listbox,
+ * Keep a hold of the associated tkwin until we destroy the spinbox,
* otherwise Tk might free it while we still need it.
*/
@@ -3640,7 +3598,7 @@ Tk_SpinboxObjCmd(clientData, interp, objc, objv)
if (ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0) != TCL_OK) {
goto error;
}
-
+
Tcl_SetResult(interp, Tk_PathName(entryPtr->tkwin), TCL_STATIC);
return TCL_OK;
@@ -3654,9 +3612,9 @@ Tk_SpinboxObjCmd(clientData, interp, objc, objv)
*
* SpinboxWidgetObjCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to a widget managed by this module.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the Tcl command that corresponds
+ * to a widget managed by this module. See the user documentation for
+ * details on what it does.
*
* Results:
* A standard Tcl result.
@@ -3668,11 +3626,11 @@ Tk_SpinboxObjCmd(clientData, interp, objc, objv)
*/
static int
-SpinboxWidgetObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Information about spinbox widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+SpinboxWidgetObjCmd(
+ ClientData clientData, /* Information about spinbox widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
Entry *entryPtr = (Entry *) clientData;
Spinbox *sbPtr = (Spinbox *) clientData;
@@ -3685,8 +3643,8 @@ SpinboxWidgetObjCmd(clientData, interp, objc, objv)
}
/*
- * Parse the widget command by looking up the second token in
- * the list of valid command names.
+ * Parse the widget command by looking up the second token in the list of
+ * valid command names.
*/
result = Tcl_GetIndexFromObj(interp, objv[1], sbCmdNames,
@@ -3697,471 +3655,454 @@ SpinboxWidgetObjCmd(clientData, interp, objc, objv)
Tcl_Preserve((ClientData) entryPtr);
switch ((enum sbCmd) cmdIndex) {
- case SB_CMD_BBOX: {
- int index, x, y, width, height;
- char buf[TCL_INTEGER_SPACE * 4];
+ case SB_CMD_BBOX: {
+ int index, x, y, width, height;
+ char buf[TCL_INTEGER_SPACE * 4];
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "index");
- goto error;
- }
- if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]),
- &index) != TCL_OK) {
- goto error;
- }
- if ((index == entryPtr->numChars) && (index > 0)) {
- index--;
- }
- 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 SB_CMD_CGET: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "option");
- goto error;
- }
-
- objPtr = Tk_GetOptionValue(interp, (char *) entryPtr,
- entryPtr->optionTable, objv[2], entryPtr->tkwin);
- if (objPtr == NULL) {
- goto error;
- } else {
- Tcl_SetObjResult(interp, objPtr);
- }
- break;
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
+ goto error;
+ }
+ if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]),
+ &index) != TCL_OK) {
+ goto error;
+ }
+ if ((index == entryPtr->numChars) && (index > 0)) {
+ index--;
}
+ 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 SB_CMD_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;
+ case SB_CMD_CGET:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option");
+ goto error;
}
- case SB_CMD_DELETE: {
- int first, last;
+ objPtr = Tk_GetOptionValue(interp, (char *) entryPtr,
+ entryPtr->optionTable, objv[2], entryPtr->tkwin);
+ if (objPtr == NULL) {
+ goto error;
+ } else {
+ Tcl_SetObjResult(interp, objPtr);
+ }
+ break;
- if ((objc < 3) || (objc > 4)) {
- Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
+ case SB_CMD_CONFIGURE:
+ if (objc <= 3) {
+ objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr,
+ entryPtr->optionTable,
+ (objc == 3) ? objv[2] : NULL,
+ entryPtr->tkwin);
+ if (objPtr == NULL) {
goto error;
- }
- 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;
- }
- }
- if ((last >= first) && (entryPtr->state == STATE_NORMAL)) {
- DeleteChars(entryPtr, first, last - first);
+ Tcl_SetObjResult(interp, objPtr);
}
- break;
+ } else {
+ result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0);
}
+ break;
+
+ case SB_CMD_DELETE: {
+ int first, last;
- case SB_CMD_GET: {
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL);
+ if ((objc < 3) || (objc > 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
+ goto error;
+ }
+ 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;
}
- Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1);
- break;
}
+ if ((last >= first) && (entryPtr->state == STATE_NORMAL)) {
+ DeleteChars(entryPtr, first, last - first);
+ }
+ break;
+ }
- case SB_CMD_ICURSOR: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "pos");
+ case SB_CMD_GET:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ goto error;
+ }
+ Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1);
+ break;
+
+ case SB_CMD_ICURSOR:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pos");
+ goto error;
+ }
+ if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]),
+ &entryPtr->insertPos) != TCL_OK) {
+ goto error;
+ }
+ EventuallyRedraw(entryPtr);
+ break;
+
+ case SB_CMD_IDENTIFY: {
+ int x, y, elem;
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ goto error;
+ }
+ if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) ||
+ (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
+ goto error;
+ }
+ elem = GetSpinboxElement(sbPtr, x, y);
+ if (elem != SEL_NONE) {
+ Tcl_SetStringObj(Tcl_GetObjResult(interp),
+ selElementNames[elem], -1);
+ }
+ break;
+ }
+
+ case SB_CMD_INDEX: {
+ int index;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "string");
+ goto error;
+ }
+ if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]),
+ &index) != TCL_OK) {
+ goto error;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
+ break;
+ }
+
+ case SB_CMD_INSERT: {
+ int index;
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index text");
+ goto error;
+ }
+ 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 SB_CMD_INVOKE:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "elemName");
+ goto error;
+ }
+ result = Tcl_GetIndexFromObj(interp, objv[2],
+ selElementNames, "element", 0, &cmdIndex);
+ if (result != TCL_OK) {
+ goto error;
+ }
+ if (entryPtr->state != STATE_DISABLED) {
+ if (SpinboxInvoke(interp, sbPtr, cmdIndex) != TCL_OK) {
goto error;
}
- if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]),
- &entryPtr->insertPos) != TCL_OK) {
- goto error;
- }
- EventuallyRedraw(entryPtr);
- break;
}
-
- case SB_CMD_IDENTIFY: {
- int x, y, elem;
+ break;
+ case SB_CMD_SCAN: {
+ int x;
+ char *minorCmd;
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x");
+ 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",
+ NULL);
+ goto error;
+ }
+ break;
+ }
+
+ case SB_CMD_SELECTION: {
+ int index, index2;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
+ goto error;
+ }
+
+ /*
+ * Parse the selection sub-command, using the command table
+ * "sbSelCmdNames" defined above.
+ */
+
+ result = Tcl_GetIndexFromObj(interp, objv[2], sbSelCmdNames,
+ "selection option", 0, &selIndex);
+ if (result != TCL_OK) {
+ goto error;
+ }
+
+ /*
+ * Disabled entries don't allow the selection to be modified, but
+ * 'selection present' must return a boolean.
+ */
+
+ if ((entryPtr->state == STATE_DISABLED)
+ && (selIndex != SB_SEL_PRESENT)) {
+ goto done;
+ }
+
+ switch (selIndex) {
+ case SB_SEL_ADJUST:
if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ Tcl_WrongNumArgs(interp, 3, objv, "index");
goto error;
}
- if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) ||
- (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
+ if (GetEntryIndex(interp, entryPtr,
+ Tcl_GetString(objv[3]), &index) != TCL_OK) {
goto error;
}
- elem = GetSpinboxElement(sbPtr, x, y);
- if (elem != SEL_NONE) {
- Tcl_SetStringObj(Tcl_GetObjResult(interp),
- selElementNames[elem], -1);
+ 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 SB_CMD_INDEX: {
- int index;
+ case SB_SEL_CLEAR:
if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "string");
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
goto error;
}
- if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]),
- &index) != TCL_OK) {
- goto error;
+ if (entryPtr->selectFirst >= 0) {
+ entryPtr->selectFirst = -1;
+ entryPtr->selectLast = -1;
+ EventuallyRedraw(entryPtr);
}
- Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
- break;
- }
-
- case SB_CMD_INSERT: {
- int index;
+ goto done;
+ case SB_SEL_FROM:
if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "index text");
+ Tcl_WrongNumArgs(interp, 3, objv, "index");
goto error;
}
- 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]));
+ if (GetEntryIndex(interp, entryPtr,
+ Tcl_GetString(objv[3]), &index) != TCL_OK) {
+ goto error;
}
+ entryPtr->selectAnchor = index;
break;
- }
- case SB_CMD_INVOKE: {
+ case SB_SEL_PRESENT:
if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "elemName");
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
goto error;
}
- result = Tcl_GetIndexFromObj(interp, objv[2],
- selElementNames, "element", 0, &cmdIndex);
- if (result != TCL_OK) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewBooleanObj((entryPtr->selectFirst >= 0)));
+ goto done;
+
+ case SB_SEL_RANGE:
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "start end");
goto error;
}
- if (entryPtr->state != STATE_DISABLED) {
- if (SpinboxInvoke(interp, sbPtr, cmdIndex) != TCL_OK) {
- goto error;
- }
- }
- break;
- }
-
- case SB_CMD_SCAN: {
- int x;
- char *minorCmd;
-
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x");
+ if (GetEntryIndex(interp, entryPtr,
+ Tcl_GetString(objv[3]), &index) != TCL_OK) {
goto error;
}
- if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) {
- goto error;
+ if (GetEntryIndex(interp, entryPtr,
+ Tcl_GetString(objv[4]),& index2) != 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);
+ if (index >= index2) {
+ entryPtr->selectFirst = -1;
+ entryPtr->selectLast = -1;
} else {
- Tcl_AppendResult(interp, "bad scan option \"",
- Tcl_GetString(objv[2]), "\": must be mark or dragto",
- (char *) NULL);
- goto error;
+ 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 SB_CMD_SELECTION: {
- int index, index2;
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
+ case SB_SEL_TO:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index");
goto error;
}
-
- /*
- * Parse the selection sub-command, using the command
- * table "sbSelCmdNames" defined above.
- */
-
- result = Tcl_GetIndexFromObj(interp, objv[2], sbSelCmdNames,
- "selection option", 0, &selIndex);
- if (result != TCL_OK) {
- goto error;
+ if (GetEntryIndex(interp, entryPtr,
+ Tcl_GetString(objv[3]), &index) != TCL_OK) {
+ goto error;
}
+ EntrySelectTo(entryPtr, index);
+ break;
- /*
- * Disabled entries don't allow the selection to be modified,
- * but 'selection present' must return a boolean.
- */
-
- if ((entryPtr->state == STATE_DISABLED)
- && (selIndex != SB_SEL_PRESENT)) {
- goto done;
+ case SB_SEL_ELEMENT:
+ if ((objc < 3) || (objc > 4)) {
+ Tcl_WrongNumArgs(interp, 3, objv, "?elemName?");
+ goto error;
}
+ if (objc == 3) {
+ Tcl_SetStringObj(Tcl_GetObjResult(interp),
+ selElementNames[sbPtr->selElement], -1);
+ } else {
+ int lastElement = sbPtr->selElement;
- switch (selIndex) {
- case SB_SEL_ADJUST: {
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 3, objv, "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 SB_SEL_CLEAR: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL);
- goto error;
- }
- if (entryPtr->selectFirst >= 0) {
- entryPtr->selectFirst = -1;
- entryPtr->selectLast = -1;
- EventuallyRedraw(entryPtr);
- }
- goto done;
- }
-
- case SB_SEL_FROM: {
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 3, objv, "index");
- goto error;
- }
- if (GetEntryIndex(interp, entryPtr,
- Tcl_GetString(objv[3]), &index) != TCL_OK) {
- goto error;
- }
- entryPtr->selectAnchor = index;
- break;
- }
-
- case SB_SEL_PRESENT: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL);
- goto error;
- }
- Tcl_SetObjResult(interp,
- Tcl_NewBooleanObj((entryPtr->selectFirst >= 0)));
- goto done;
+ result = Tcl_GetIndexFromObj(interp, objv[3], selElementNames,
+ "selection element", 0, &(sbPtr->selElement));
+ if (result != TCL_OK) {
+ goto error;
}
-
- case SB_SEL_RANGE: {
- if (objc != 5) {
- Tcl_WrongNumArgs(interp, 3, objv, "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;
- }
+ if (lastElement != sbPtr->selElement) {
EventuallyRedraw(entryPtr);
- break;
- }
-
- case SB_SEL_TO: {
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 3, objv, "index");
- goto error;
- }
- if (GetEntryIndex(interp, entryPtr,
- Tcl_GetString(objv[3]), &index) != TCL_OK) {
- goto error;
- }
- EntrySelectTo(entryPtr, index);
- break;
- }
-
- case SB_SEL_ELEMENT: {
- if ((objc < 3) || (objc > 4)) {
- Tcl_WrongNumArgs(interp, 3, objv, "?elemName?");
- goto error;
- }
- if (objc == 3) {
- Tcl_SetStringObj(Tcl_GetObjResult(interp),
- selElementNames[sbPtr->selElement], -1);
- } else {
- int lastElement = sbPtr->selElement;
-
- result = Tcl_GetIndexFromObj(interp, objv[3],
- selElementNames, "selection element", 0,
- &(sbPtr->selElement));
- if (result != TCL_OK) {
- goto error;
- }
- if (lastElement != sbPtr->selElement) {
- EventuallyRedraw(entryPtr);
- }
- }
- break;
}
}
break;
}
+ break;
+ }
+
+ case SB_CMD_SET:
+ if (objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?string?");
+ goto error;
+ }
+ if (objc == 3) {
+ EntryValueChanged(entryPtr, Tcl_GetString(objv[2]));
+ }
+ Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1);
+ break;
- case SB_CMD_SET: {
- if (objc > 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?string?");
- goto error;
- }
- if (objc == 3) {
- EntryValueChanged(entryPtr, Tcl_GetString(objv[2]));
- }
- Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1);
- break;
+ case SB_CMD_VALIDATE: {
+ int code;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ goto error;
}
+ selIndex = entryPtr->validate;
+ entryPtr->validate = VALIDATE_ALL;
+ code = EntryValidateChange(entryPtr, NULL, entryPtr->string,
+ -1, VALIDATE_FORCED);
+ if (entryPtr->validate != VALIDATE_NONE) {
+ entryPtr->validate = selIndex;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj((code == TCL_OK)));
+ break;
+ }
- case SB_CMD_VALIDATE: {
- int code;
+ case SB_CMD_XVIEW: {
+ int index;
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL);
+ if (objc == 2) {
+ double first, last;
+ char buf[TCL_DOUBLE_SPACE];
+
+ EntryVisibleRange(entryPtr, &first, &last);
+ Tcl_PrintDouble(NULL, first, buf);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ Tcl_PrintDouble(NULL, last, buf);
+ Tcl_AppendResult(interp, " ", buf, NULL);
+ goto done;
+ } else if (objc == 3) {
+ if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]),
+ &index) != TCL_OK) {
goto error;
}
- selIndex = entryPtr->validate;
- entryPtr->validate = VALIDATE_ALL;
- code = EntryValidateChange(entryPtr, (char *) NULL,
- entryPtr->string, -1, VALIDATE_FORCED);
- if (entryPtr->validate != VALIDATE_NONE) {
- entryPtr->validate = selIndex;
- }
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj((code == TCL_OK)));
- break;
- }
+ } else {
+ double fraction;
+ int count;
- case SB_CMD_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->xWidth)
- / entryPtr->avgWidth) - 2;
- if (charsPerPage < 1) {
- charsPerPage = 1;
- }
- index += count * charsPerPage;
- break;
- }
- case TK_SCROLL_UNITS: {
- index += count;
- break;
- }
+ 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->xWidth)
+ / entryPtr->avgWidth) - 2;
+ if (charsPerPage < 1) {
+ charsPerPage = 1;
}
+ index += count * charsPerPage;
+ break;
}
- if (index >= entryPtr->numChars) {
- index = entryPtr->numChars - 1;
+ case TK_SCROLL_UNITS:
+ index += count;
+ break;
}
- 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);
+ break;
+ }
}
- done:
+ done:
Tcl_Release((ClientData) entryPtr);
return result;
- error:
+ error:
Tcl_Release((ClientData) entryPtr);
return TCL_ERROR;
}
@@ -4183,11 +4124,10 @@ SpinboxWidgetObjCmd(clientData, interp, objc, objv)
*/
static int
-GetSpinboxElement(sbPtr, x, y)
- Spinbox *sbPtr; /* Spinbox for which the index is being
+GetSpinboxElement(
+ Spinbox *sbPtr, /* Spinbox for which the index is being
* specified. */
- int x; /* x coord */
- int y; /* y coord */
+ int x, int y) /* Widget-relative coordinates. */
{
Entry *entryPtr = (Entry *) sbPtr;
@@ -4211,25 +4151,25 @@ GetSpinboxElement(sbPtr, x, y)
*
* SpinboxInvoke --
*
- * This procedure is invoked when the invoke method for the
- * widget is called.
+ * This function is invoked when the invoke method for the widget is
+ * called.
*
* Results:
* TCL_OK.
*
* Side effects:
- * An background error condition may arise when invoking the
- * callback. The widget value may change.
+ * An background error condition may arise when invoking the callback.
+ * The widget value may change.
*
*--------------------------------------------------------------
*/
static int
-SpinboxInvoke(interp, sbPtr, element)
- register Tcl_Interp *interp; /* Current interpreter. */
- register Spinbox *sbPtr; /* Spinbox to invoke. */
- int element; /* element to invoke, either the "up"
- * or "down" button. */
+SpinboxInvoke(
+ register Tcl_Interp *interp,/* Current interpreter. */
+ register Spinbox *sbPtr, /* Spinbox to invoke. */
+ int element) /* Element to invoke, either the "up" or
+ * "down" button. */
{
Entry *entryPtr = (Entry *) sbPtr;
char *type;
@@ -4237,16 +4177,16 @@ SpinboxInvoke(interp, sbPtr, element)
Tcl_DString script;
switch (element) {
- case SEL_BUTTONUP:
- type = "up";
- up = 1;
- break;
- case SEL_BUTTONDOWN:
- type = "down";
- up = 0;
- break;
- default:
- return TCL_OK;
+ case SEL_BUTTONUP:
+ type = "up";
+ up = 1;
+ break;
+ case SEL_BUTTONDOWN:
+ type = "down";
+ up = 0;
+ break;
+ default:
+ return TCL_OK;
}
if (fabs(sbPtr->increment) > MIN_DBL_VAL) {
@@ -4256,11 +4196,11 @@ SpinboxInvoke(interp, sbPtr, element)
Tcl_ListObjIndex(interp, sbPtr->listObj, sbPtr->eIndex, &objPtr);
if (strcmp(Tcl_GetString(objPtr), entryPtr->string)) {
/*
- * Somehow the string changed from what we expected,
- * so let's do a search on the list to see if the current
- * value is there. If not, move to the first element of
- * the list.
+ * Somehow the string changed from what we expected, so let's
+ * do a search on the list to see if the current value is
+ * there. If not, move to the first element of the list.
*/
+
int i, listc, elemLen, length = entryPtr->numChars;
char *bytes;
Tcl_Obj **listv;
@@ -4298,45 +4238,46 @@ SpinboxInvoke(interp, sbPtr, element)
} else if (!DOUBLES_EQ(sbPtr->fromValue, sbPtr->toValue)) {
double dvalue;
- if (Tcl_GetDouble(NULL, entryPtr->string, &dvalue) != TCL_OK) {
+ if (sscanf(entryPtr->string, "%lf", &dvalue) == 0) {
/*
- * If the string is empty, or isn't a valid double value,
- * just use the -from value
+ * If the string doesn't scan as a double value, just
+ * use the -from value
*/
+
dvalue = sbPtr->fromValue;
- } else {
- if (up) {
- dvalue += sbPtr->increment;
- if (dvalue > sbPtr->toValue) {
- if (sbPtr->wrap) {
- dvalue = sbPtr->fromValue;
- } else {
- dvalue = sbPtr->toValue;
- }
- } else if (dvalue < sbPtr->fromValue) {
- /*
- * It's possible that when pressing up, we are
- * still less than the fromValue, because the
- * user may have manipulated the value by hand.
- */
+ } else if (up) {
+ dvalue += sbPtr->increment;
+ if (dvalue > sbPtr->toValue) {
+ if (sbPtr->wrap) {
dvalue = sbPtr->fromValue;
+ } else {
+ dvalue = sbPtr->toValue;
}
- } else {
- dvalue -= sbPtr->increment;
- if (dvalue < sbPtr->fromValue) {
- if (sbPtr->wrap) {
- dvalue = sbPtr->toValue;
- } else {
- dvalue = sbPtr->fromValue;
- }
- } else if (dvalue > sbPtr->toValue) {
- /*
- * It's possible that when pressing down, we are
- * still greater than the toValue, because the
- * user may have manipulated the value by hand.
- */
+ } else if (dvalue < sbPtr->fromValue) {
+ /*
+ * It's possible that when pressing up, we are still less
+ * than the fromValue, because the user may have
+ * manipulated the value by hand.
+ */
+
+ dvalue = sbPtr->fromValue;
+ }
+ } else {
+ dvalue -= sbPtr->increment;
+ if (dvalue < sbPtr->fromValue) {
+ if (sbPtr->wrap) {
dvalue = sbPtr->toValue;
+ } else {
+ dvalue = sbPtr->fromValue;
}
+ } else if (dvalue > sbPtr->toValue) {
+ /*
+ * It's possible that when pressing down, we are still
+ * greater than the toValue, because the user may have
+ * manipulated the value by hand.
+ */
+
+ dvalue = sbPtr->toValue;
}
}
sprintf(sbPtr->formatBuf, sbPtr->valueFormat, dvalue);
@@ -4357,9 +4298,11 @@ SpinboxInvoke(interp, sbPtr, element)
if (code != TCL_OK) {
Tcl_AddErrorInfo(interp, "\n\t(in command executed by spinbox)");
Tcl_BackgroundError(interp);
+
/*
* Yes, it's an error, but a bg one, so we return OK
*/
+
return TCL_OK;
}
@@ -4374,9 +4317,9 @@ SpinboxInvoke(interp, sbPtr, element)
*
* ComputeFormat --
*
- * This procedure is invoked to recompute the "format" fields
- * of a spinbox's widget record, which determines how the value
- * of the dial is converted to a string.
+ * This function is invoked to recompute the "format" fields of a
+ * spinbox's widget record, which determines how the value of the dial is
+ * converted to a string.
*
* Results:
* Tcl result code.
@@ -4386,17 +4329,18 @@ SpinboxInvoke(interp, sbPtr, element)
*
*----------------------------------------------------------------------
*/
+
static int
-ComputeFormat(sbPtr)
- Spinbox *sbPtr; /* Information about dial widget. */
+ComputeFormat(
+ Spinbox *sbPtr) /* Information about dial widget. */
{
double maxValue, x;
int mostSigDigit, numDigits, leastSigDigit, afterDecimal;
int eDigits, fDigits;
/*
- * Compute the displacement from the decimal of the most significant
- * digit required for any number in the dial's range.
+ * Compute the displacement from the decimal of the most significant digit
+ * required for any number in the dial's range.
*/
if (sbPtr->reqFormat) {
@@ -4418,6 +4362,7 @@ ComputeFormat(sbPtr)
/*
* A increment was specified, so use it.
*/
+
leastSigDigit = (int) floor(log10(sbPtr->increment));
} else {
leastSigDigit = 0;
@@ -4428,13 +4373,13 @@ ComputeFormat(sbPtr)
}
/*
- * Compute the number of characters required using "e" format and
- * "f" format, and then choose whichever one takes fewer characters.
+ * Compute the number of characters required using "e" format and "f"
+ * format, and then choose whichever one takes fewer characters.
*/
eDigits = numDigits + 4;
if (numDigits > 1) {
- eDigits++; /* Decimal point. */
+ eDigits++; /* Decimal point. */
}
afterDecimal = numDigits - mostSigDigit - 1;
if (afterDecimal < 0) {
@@ -4442,10 +4387,10 @@ ComputeFormat(sbPtr)
}
fDigits = (mostSigDigit >= 0) ? mostSigDigit + afterDecimal : afterDecimal;
if (afterDecimal > 0) {
- fDigits++; /* Decimal point. */
+ fDigits++; /* Decimal point. */
}
if (mostSigDigit < 0) {
- fDigits++; /* Zero to left of decimal point. */
+ fDigits++; /* Zero to left of decimal point. */
}
if (fDigits <= eDigits) {
sprintf(sbPtr->digitFormat, "%%.%df", afterDecimal);
@@ -4455,3 +4400,11 @@ ComputeFormat(sbPtr)
sbPtr->valueFormat = sbPtr->digitFormat;
return TCL_OK;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkEntry.h b/generic/tkEntry.h
index 3bb2f1d..7f8aa1f 100644
--- a/generic/tkEntry.h
+++ b/generic/tkEntry.h
@@ -1,13 +1,12 @@
/*
* tkEntry.h --
- *
- * This module defined the structures for the Entry & SpinBox widgets.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * This module defined the structures for the Entry & SpinBox widgets.
*
- * Copyright (c) 2002 Apple Computer, Inc.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
+ * Copyright (c) 2002 Apple Computer, Inc.
*/
#ifndef _TKENTRY
@@ -18,8 +17,8 @@
#endif
#ifdef BUILD_tk
-# undef TCL_STORAGE_CLASS
-# define TCL_STORAGE_CLASS DLLEXPORT
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
#endif
enum EntryType {
@@ -27,16 +26,16 @@ enum EntryType {
};
/*
- * A data structure of the following type is kept for each Entry
- * widget managed by this file:
+ * A data structure of the following type is kept for each Entry widget
+ * managed by this file:
*/
typedef struct {
- Tk_Window tkwin; /* Window that embodies the entry. NULL
- * means that the window has been destroyed
- * but the data structures haven't yet been
- * cleaned up.*/
- Display *display; /* Display containing widget. Used, among
+ Tk_Window tkwin; /* Window that embodies the entry. NULL means
+ * that the window has been destroyed but the
+ * data structures haven't yet been cleaned
+ * up.*/
+ Display *display; /* Display containing widget. Used, among
* other things, so that resources can be
* freed even after tkwin has gone away. */
Tcl_Interp *interp; /* Interpreter associated with entry. */
@@ -48,9 +47,9 @@ typedef struct {
/*
* Fields that are set by widget commands other than "configure".
*/
-
+
CONST char *string; /* Pointer to storage for string;
- * NULL-terminated; malloc-ed. */
+ * NULL-terminated; malloc-ed. */
int insertPos; /* Character index before which next typed
* character will be inserted. */
@@ -58,8 +57,8 @@ typedef struct {
* Information about what's selected, if any.
*/
- int selectFirst; /* Character index of first 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"
@@ -81,11 +80,11 @@ typedef struct {
Tk_3DBorder normalBorder; /* Used for drawing border around whole
* window, plus used for background. */
- Tk_3DBorder disabledBorder; /* Used for drawing border around whole
- * window in disabled state, plus used for
+ Tk_3DBorder disabledBorder; /* Used for drawing border around whole window
+ * in disabled state, plus used for
* background. */
- Tk_3DBorder readonlyBorder; /* Used for drawing border around whole
- * window in readonly state, plus used for
+ Tk_3DBorder readonlyBorder; /* Used for drawing border around whole window
+ * in readonly state, plus used for
* background. */
int borderWidth; /* Width of 3-D border around window. */
Tk_Cursor cursor; /* Current cursor for window, or None. */
@@ -94,12 +93,12 @@ typedef struct {
Tk_Font tkfont; /* Information about text font, or NULL. */
XColor *fgColorPtr; /* Text color in normal mode. */
XColor *dfgColorPtr; /* Text color in disabled mode. */
- XColor *highlightBgColorPtr;/* Color for drawing traversal highlight
- * area when highlight is off. */
+ XColor *highlightBgColorPtr;/* Color for drawing traversal highlight area
+ * when highlight is off. */
XColor *highlightColorPtr; /* Color for drawing traversal highlight. */
- int highlightWidth; /* Width in pixels of highlight to draw
- * around widget when it has the focus.
- * <= 0 means don't draw a highlight. */
+ int highlightWidth; /* Width in pixels of highlight to draw around
+ * widget when it has the focus. <= 0 means
+ * don't draw a highlight. */
Tk_3DBorder insertBorder; /* Used to draw vertical bar for insertion
* cursor. */
int insertBorderWidth; /* Width of 3-D border around insert cursor. */
@@ -115,44 +114,46 @@ typedef struct {
* characters. */
int selBorderWidth; /* Width of border around selection. */
XColor *selFgColorPtr; /* Foreground color for selected text. */
- 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
- * contents of this variable and vice versa. */
- char *takeFocus; /* Value of -takefocus option; not used in
- * the C code, but used by keyboard traversal
- * scripts. Malloc'ed, but may be NULL. */
+ 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
+ * contents of this variable and vice
+ * versa. */
+ char *takeFocus; /* Value of -takefocus option; not used in the
+ * C code, but used by keyboard traversal
+ * scripts. Malloc'ed, but may be NULL. */
int prefWidth; /* Desired width of window, measured in
* average characters. */
char *scrollCmd; /* Command prefix for communicating with
- * scrollbar(s). Malloc'ed. NULL means
- * no command to issue. */
- char *showChar; /* Value of -show option. If non-NULL, first
+ * scrollbar(s). Malloc'ed. NULL means no
+ * command to issue. */
+ char *showChar; /* Value of -show option. If non-NULL, first
* character is used for displaying all
- * characters in entry. Malloc'ed.
- * This is only used by the Entry widget. */
+ * characters in entry. Malloc'ed. This is
+ * only used by the Entry widget. */
/*
* Fields whose values are derived from the current values of the
* configuration settings above.
*/
- CONST char *displayString; /* String to use when displaying. This may
- * be a pointer to string, or a pointer to
+ CONST 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. */
+ * length as string but whose characters are
+ * all equal to showChar. */
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. */
+ 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. */
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). */
+ * 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 leftX; /* X position at which character at leftIndex
@@ -166,23 +167,22 @@ typedef struct {
GC selTextGC; /* For drawing selected text. */
GC highlightGC; /* For drawing traversal highlight. */
int avgWidth; /* Width of average character. */
- int xWidth; /* Extra width to reserve for widget.
- * Used by spinboxes for button space. */
- int flags; /* Miscellaneous flags; see below for
+ int xWidth; /* Extra width to reserve for widget. Used by
+ * spinboxes for button space. */
+ int flags; /* Miscellaneous flags; see below for
* definitions. */
- int validate; /* Non-zero means try to validate */
- char *validateCmd; /* Command prefix to use when invoking
- * validate command. NULL means don't
- * invoke commands. Malloc'ed. */
+ int validate; /* Non-zero means try to validate */
+ char *validateCmd; /* Command prefix to use when invoking
+ * validate command. NULL means don't invoke
+ * commands. Malloc'ed. */
char *invalidCmd; /* Command called when a validation returns 0
* (successfully fails), defaults to {}. */
-
} Entry;
/*
- * A data structure of the following type is kept for each spinbox
- * widget managed by this file:
+ * A data structure of the following type is kept for each spinbox widget
+ * managed by this file:
*/
typedef struct {
@@ -200,8 +200,8 @@ typedef struct {
Tk_Cursor bCursor; /* cursor for buttons, or None. */
int bdRelief; /* 3-D effect: TK_RELIEF_RAISED, etc. */
int buRelief; /* 3-D effect: TK_RELIEF_RAISED, etc. */
- char *command; /* Command to invoke for spin buttons.
- * NULL means no command to issue. */
+ char *command; /* Command to invoke for spin buttons. NULL
+ * means no command to issue. */
/*
* Spinbox specific fields for use with configuration settings above.
@@ -216,38 +216,37 @@ typedef struct {
int repeatInterval; /* repeat interval */
double fromValue; /* Value corresponding to left/top of dial */
- double toValue; /* Value corresponding to right/bottom
- * of dial */
- double increment; /* If > 0, all values are rounded to an
- * even multiple of this value. */
+ double toValue; /* Value corresponding to right/bottom of
+ * dial */
+ double increment; /* If > 0, all values are rounded to an even
+ * multiple of this value. */
char *formatBuf; /* string into which to format value.
* Malloc'ed. */
char *reqFormat; /* Sprintf conversion specifier used for the
- * value that the users requests. Malloc'ed. */
- char *valueFormat; /* Sprintf conversion specifier used for
- * the value. */
+ * value that the users requests. Malloc'ed */
+ char *valueFormat; /* Sprintf conversion specifier used for the
+ * value. */
char digitFormat[10]; /* Sprintf conversion specifier computed from
- * digits and other information; used for
- * the value. */
+ * digits and other information; used for the
+ * value. */
char *valueStr; /* Values List. Malloc'ed. */
Tcl_Obj *listObj; /* Pointer to the list object being used */
int eIndex; /* Holds the current index into elements */
int nElements; /* Holds the current count of elements */
-
} Spinbox;
/*
- * Assigned bits of "flags" fields of Entry structures, and what those
- * bits mean:
+ * Assigned bits of "flags" fields of Entry structures, and what those bits
+ * mean:
*
* REDRAW_PENDING: Non-zero means a DoWhenIdle handler has
* already been queued to redisplay the entry.
* BORDER_NEEDED: Non-zero means 3-D border must be redrawn
- * around window during redisplay. Normally
- * only text portion needs to be redrawn.
+ * around window during redisplay. Normally only
+ * text portion needs to be redrawn.
* CURSOR_ON: Non-zero means insert cursor is displayed at
- * present. 0 means it isn't displayed.
+ * present. 0 means it isn't displayed.
* GOT_FOCUS: Non-zero means this window has the input
* focus.
* UPDATE_SCROLLBAR: Non-zero means scrollbar should be updated
@@ -268,40 +267,40 @@ typedef struct {
#define GOT_FOCUS 8
#define UPDATE_SCROLLBAR 0x10
#define GOT_SELECTION 0x20
-#define ENTRY_DELETED 0x40
-#define VALIDATING 0x80
-#define VALIDATE_VAR 0x100
-#define VALIDATE_ABORT 0x200
-#define ENTRY_VAR_TRACED 0x400
+#define ENTRY_DELETED 0x40
+#define VALIDATING 0x80
+#define VALIDATE_VAR 0x100
+#define VALIDATE_ABORT 0x200
+#define ENTRY_VAR_TRACED 0x400
/*
- * 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.
+ * 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, STATE_READONLY
};
-/*
+/*
* This is the element index corresponding to the strings in selElementNames.
* If you modify them, you must modify the numbers here.
*/
-
+
enum selelement {
SEL_NONE, SEL_BUTTONDOWN, SEL_BUTTONUP, SEL_NULL, SEL_ENTRY
};
/*
- * Declaration of procedures used in the implementation of the native side
- * of the Entry widget.
+ * Declaration of functions used in the implementation of the native side of
+ * the Entry widget.
*/
-int TkpDrawEntryBorderAndFocus(Entry *entryPtr, Drawable d, int isSpinbox);
-int TkpDrawSpinboxButtons(Spinbox *sbPtr, Drawable d);
+MODULE_SCOPE int TkpDrawEntryBorderAndFocus(Entry *entryPtr,
+ Drawable d, int isSpinbox);
+MODULE_SCOPE int TkpDrawSpinboxButtons(Spinbox *sbPtr, Drawable d);
-# undef TCL_STORAGE_CLASS
-# define TCL_STORAGE_CLASS DLLIMPORT
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLIMPORT
-#endif /* _TKBUTTON */
+#endif /* _TKENTRY */
diff --git a/generic/tkError.c b/generic/tkError.c
index dabf898..6617c37 100644
--- a/generic/tkError.c
+++ b/generic/tkError.c
@@ -1,109 +1,98 @@
-/*
+/*
* tkError.c --
*
- * This file provides a high-performance mechanism for
- * selectively dealing with errors that occur in talking
- * to the X server. This is useful, for example, when
- * communicating with a window that may not exist.
+ * This file provides a high-performance mechanism for selectively
+ * dealing with errors that occur in talking to the X server. This is
+ * useful, for example, when communicating with a window that may not
+ * exist.
*
* Copyright (c) 1990-1994 The Regents of the University of California.
* Copyright (c) 1994-1995 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
/*
- * The default X error handler gets saved here, so that it can
- * be invoked if an error occurs that we can't handle.
+ * The default X error handler gets saved here, so that it can be invoked if
+ * an error occurs that we can't handle.
*/
-static int (*defaultHandler) _ANSI_ARGS_((Display *display,
- XErrorEvent *eventPtr)) = NULL;
-
+typedef int (*TkXErrorHandler)(Display *display, XErrorEvent *eventPtr);
+static TkXErrorHandler defaultHandler = NULL;
/*
* Forward references to procedures declared later in this file:
*/
-static int ErrorProc _ANSI_ARGS_((Display *display,
- XErrorEvent *errEventPtr));
+static int ErrorProc(Display *display, XErrorEvent *errEventPtr);
/*
*--------------------------------------------------------------
*
* Tk_CreateErrorHandler --
*
- * Arrange for all a given procedure to be invoked whenever
- * certain errors occur.
+ * Arrange for all a given procedure to be invoked whenever certain
+ * errors occur.
*
* Results:
- * The return value is a token identifying the handler;
- * it must be passed to Tk_DeleteErrorHandler to delete the
- * handler.
+ * The return value is a token identifying the handler; it must be passed
+ * to Tk_DeleteErrorHandler to delete the handler.
*
* Side effects:
- * If an X error occurs that matches the error, request,
- * and minor arguments, then errorProc will be invoked.
- * ErrorProc should have the following structure:
+ * If an X error occurs that matches the error, request, and minor
+ * arguments, then errorProc will be invoked. ErrorProc should have the
+ * following structure:
*
* int
- * errorProc(clientData, errorEventPtr)
- * caddr_t clientData;
- * XErrorEvent *errorEventPtr;
- * {
+ * errorProc(caddr_t clientData, XErrorEvent *errorEventPtr) {
* }
*
- * The clientData argument will be the same as the clientData
- * argument to this procedure, and errorEvent will describe
- * the error. If errorProc returns 0, it means that it
- * completely "handled" the error: no further processing
- * should be done. If errorProc returns 1, it means that it
- * didn't know how to deal with the error, so we should look
- * for other error handlers, or invoke the default error
- * handler if no other handler returns zero. Handlers are
- * invoked in order of age: youngest handler first.
+ * The clientData argument will be the same as the clientData argument to
+ * this procedure, and errorEvent will describe the error. If errorProc
+ * returns 0, it means that it completely "handled" the error: no further
+ * processing should be done. If errorProc returns 1, it means that it
+ * didn't know how to deal with the error, so we should look for other
+ * error handlers, or invoke the default error handler if no other
+ * handler returns zero. Handlers are invoked in order of age: youngest
+ * handler first.
*
- * Note: errorProc will only be called for errors associated
- * with X requests made AFTER this call, but BEFORE the handler
- * is deleted by calling Tk_DeleteErrorHandler.
+ * Note: errorProc will only be called for errors associated with X
+ * requests made AFTER this call, but BEFORE the handler is deleted by
+ * calling Tk_DeleteErrorHandler.
*
*--------------------------------------------------------------
*/
Tk_ErrorHandler
-Tk_CreateErrorHandler(display, error, request, minorCode, errorProc, clientData)
- Display *display; /* Display for which to handle
+Tk_CreateErrorHandler(
+ Display *display, /* Display for which to handle errors. */
+ int error, /* Consider only errors with this error_code
+ * (-1 means consider all errors). */
+ int request, /* Consider only errors with this major
+ * request code (-1 means consider all major
+ * codes). */
+ int minorCode, /* Consider only errors with this minor
+ * request code (-1 means consider all minor
+ * codes). */
+ Tk_ErrorProc *errorProc, /* Procedure to invoke when a matching error
+ * occurs. NULL means just ignore matching
* errors. */
- int error; /* Consider only errors with this
- * error_code (-1 means consider
- * all errors). */
- int request; /* Consider only errors with this
- * major request code (-1 means
- * consider all major codes). */
- int minorCode; /* Consider only errors with this
- * minor request code (-1 means
- * consider all minor codes). */
- Tk_ErrorProc *errorProc; /* Procedure to invoke when a
- * matching error occurs. NULL means
- * just ignore matching errors. */
- ClientData clientData; /* Arbitrary value to pass to
- * errorProc. */
+ ClientData clientData) /* Arbitrary value to pass to errorProc. */
{
register TkErrorHandler *errorPtr;
register TkDisplay *dispPtr;
/*
- * Find the display. If Tk doesn't know about this display then
- * it's an error: panic.
+ * Find the display. If Tk doesn't know about this display then it's an
+ * error: panic.
*/
dispPtr = TkGetDisplay(display);
if (dispPtr == NULL) {
- panic("Unknown display passed to Tk_CreateErrorHandler");
+ Tcl_Panic("Unknown display passed to Tk_CreateErrorHandler");
}
/*
@@ -144,22 +133,19 @@ Tk_CreateErrorHandler(display, error, request, minorCode, errorProc, clientData)
* None.
*
* Side effects:
- * The handler denoted by the "handler" argument will not
- * be invoked for any X errors associated with requests
- * made after this call. However, if errors arrive later
- * for requests made BEFORE this call, then the handler
- * will still be invoked. Call XSync if you want to be
- * sure that all outstanding errors have been received
- * and processed.
+ * The handler denoted by the "handler" argument will not be invoked for
+ * any X errors associated with requests made after this call. However,
+ * if errors arrive later for requests made BEFORE this call, then the
+ * handler will still be invoked. Call XSync if you want to be sure that
+ * all outstanding errors have been received and processed.
*
*--------------------------------------------------------------
*/
void
-Tk_DeleteErrorHandler(handler)
- Tk_ErrorHandler handler; /* Token for handler to delete;
- * was previous return value from
- * Tk_CreateErrorHandler. */
+Tk_DeleteErrorHandler(
+ Tk_ErrorHandler handler) /* Token for handler to delete; was previous
+ * return value from Tk_CreateErrorHandler. */
{
register TkErrorHandler *errorPtr = (TkErrorHandler *) handler;
register TkDisplay *dispPtr = errorPtr->dispPtr;
@@ -167,17 +153,15 @@ Tk_DeleteErrorHandler(handler)
errorPtr->lastRequest = NextRequest(dispPtr->display) - 1;
/*
- * Every once-in-a-while, cleanup handlers that are no longer
- * active. We probably won't be able to free the handler that
- * was just deleted (need to wait for any outstanding requests to
- * be processed by server), but there may be previously-deleted
- * handlers that are now ready for garbage collection. To reduce
- * the cost of the cleanup, let a few dead handlers pile up, then
- * clean them all at once. This adds a bit of overhead to errors
- * that might occur while the dead handlers are hanging around,
- * but reduces the overhead of scanning the list to clean up
- * (particularly if there are many handlers that stay around
- * forever).
+ * Every once-in-a-while, cleanup handlers that are no longer active. We
+ * probably won't be able to free the handler that was just deleted (need
+ * to wait for any outstanding requests to be processed by server), but
+ * there may be previously-deleted handlers that are now ready for garbage
+ * collection. To reduce the cost of the cleanup, let a few dead handlers
+ * pile up, then clean them all at once. This adds a bit of overhead to
+ * errors that might occur while the dead handlers are hanging around, but
+ * reduces the overhead of scanning the list to clean up (particularly if
+ * there are many handlers that stay around forever).
*/
dispPtr->deleteCount += 1;
@@ -211,35 +195,33 @@ Tk_DeleteErrorHandler(handler)
*
* ErrorProc --
*
- * This procedure is invoked by the X system when error
- * events arrive.
+ * This procedure is invoked by the X system when error events arrive.
*
* Results:
- * If it returns, the return value is zero. However,
- * it is possible that one of the error handlers may
- * just exit.
+ * If it returns, the return value is zero. However, it is possible that
+ * one of the error handlers may just exit.
*
* Side effects:
- * This procedure does two things. First, it uses the
- * serial # in the error event to eliminate handlers whose
- * expiration serials are now in the past. Second, it
- * invokes any handlers that want to deal with the error.
+ * This procedure does two things. First, it uses the serial # in the
+ * error event to eliminate handlers whose expiration serials are now in
+ * the past. Second, it invokes any handlers that want to deal with the
+ * error.
*
*--------------------------------------------------------------
*/
static int
-ErrorProc(display, errEventPtr)
- Display *display; /* Display for which error
- * occurred. */
- register XErrorEvent *errEventPtr; /* Information about error. */
+ErrorProc(
+ Display *display, /* Display for which error occurred. */
+ register XErrorEvent *errEventPtr)
+ /* Information about error. */
{
register TkDisplay *dispPtr;
register TkErrorHandler *errorPtr;
/*
- * See if we know anything about the display. If not, then
- * invoke the default error handler.
+ * See if we know anything about the display. If not, then invoke the
+ * default error handler.
*/
dispPtr = TkGetDisplay(display);
@@ -264,42 +246,47 @@ ErrorProc(display, errEventPtr)
&& (errorPtr->lastRequest < errEventPtr->serial))) {
continue;
}
- if (errorPtr->errorProc == NULL) {
+ if (errorPtr->errorProc == NULL || (*errorPtr->errorProc)(
+ errorPtr->clientData, errEventPtr) == 0) {
return 0;
- } else {
- if ((*errorPtr->errorProc)(errorPtr->clientData,
- errEventPtr) == 0) {
- return 0;
- }
}
}
/*
- * See if the error is a BadWindow error. If so, and it refers
- * to a window that still exists in our window table, then ignore
- * the error. Errors like this can occur if a window owned by us
- * is deleted by someone externally, like a window manager. We'll
- * ignore the errors at least long enough to clean up internally and
- * remove the entry from the window table.
+ * See if the error is a BadWindow error. If so, and it refers to a window
+ * that still exists in our window table, then ignore the error. Errors
+ * like this can occur if a window owned by us is deleted by someone
+ * externally, like a window manager. We'll ignore the errors at least
+ * long enough to clean up internally and remove the entry from the window
+ * table.
*
- * NOTE: For embedding, we must also check whether the window was
- * recently deleted. If so, it may be that Tk generated operations on
- * windows that were deleted by the container. Now we are getting
- * the errors (BadWindow) after Tk already deleted the window itself.
+ * NOTE: For embedding, we must also check whether the window was recently
+ * deleted. If so, it may be that Tk generated operations on windows that
+ * were deleted by the container. Now we are getting the errors
+ * (BadWindow) after Tk already deleted the window itself.
*/
- if ((errEventPtr->error_code == BadWindow) &&
- ((Tk_IdToWindow(display, (Window) errEventPtr->resourceid) !=
- NULL) ||
- (TkpWindowWasRecentlyDeleted((Window) errEventPtr->resourceid,
- dispPtr)))) {
- return 0;
+ if (errEventPtr->error_code == BadWindow) {
+ Window w = (Window) errEventPtr->resourceid;
+
+ if (Tk_IdToWindow(display, w) != NULL
+ || TkpWindowWasRecentlyDeleted(w, dispPtr)) {
+ return 0;
+ }
}
/*
- * We couldn't handle the error. Use the default handler.
+ * We couldn't handle the error. Use the default handler.
*/
- couldntHandle:
+ couldntHandle:
return (*defaultHandler)(display, errEventPtr);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkEvent.c b/generic/tkEvent.c
index 2b4943f..03e7283 100644
--- a/generic/tkEvent.c
+++ b/generic/tkEvent.c
@@ -1,69 +1,67 @@
-/*
+/*
* tkEvent.c --
*
- * This file provides basic low-level facilities for managing
- * X events in Tk.
+ * This file provides basic low-level facilities for managing X events in
+ * Tk.
*
* Copyright (c) 1990-1994 The Regents of the University of California.
* Copyright (c) 1994-1995 Sun Microsystems, Inc.
* Copyright (c) 1998-2000 Ajuba Solutions.
+ * Copyright (c) 2004 George Peter Staplin
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
-#include <signal.h>
/*
- * There's a potential problem if a handler is deleted while it's
- * current (i.e. its procedure is executing), since Tk_HandleEvent
- * will need to read the handler's "nextPtr" field when the procedure
- * returns. To handle this problem, structures of the type below
- * indicate the next handler to be processed for any (recursively
- * nested) dispatches in progress. The nextHandler fields get
- * updated if the handlers pointed to are deleted. Tk_HandleEvent
- * also needs to know if the entire window gets deleted; the winPtr
- * field is set to zero if that particular window gets deleted.
+ * There's a potential problem if a handler is deleted while it's current
+ * (i.e. its function is executing), since Tk_HandleEvent will need to read
+ * the handler's "nextPtr" field when the function returns. To handle this
+ * problem, structures of the type below indicate the next handler to be
+ * processed for any (recursively nested) dispatches in progress. The
+ * nextHandler fields get updated if the handlers pointed to are deleted.
+ * Tk_HandleEvent also needs to know if the entire window gets deleted; the
+ * winPtr field is set to zero if that particular window gets deleted.
*/
typedef struct InProgress {
- XEvent *eventPtr; /* Event currently being handled. */
- TkWindow *winPtr; /* Window for event. Gets set to None if
- * window is deleted while event is being
- * handled. */
- TkEventHandler *nextHandler; /* Next handler in search. */
- struct InProgress *nextPtr; /* Next higher nested search. */
+ XEvent *eventPtr; /* Event currently being handled. */
+ TkWindow *winPtr; /* Window for event. Gets set to None if
+ * window is deleted while event is being
+ * handled. */
+ TkEventHandler *nextHandler;/* Next handler in search. */
+ struct InProgress *nextPtr; /* Next higher nested search. */
} InProgress;
/*
- * For each call to Tk_CreateGenericHandler, an instance of the following
- * structure will be created. All of the active handlers are linked into a
- * list.
+ * For each call to Tk_CreateGenericHandler or Tk_CreateClientMessageHandler,
+ * an instance of the following structure will be created. All of the active
+ * handlers are linked into a list.
*/
typedef struct GenericHandler {
- Tk_GenericProc *proc; /* Procedure to dispatch on all X events. */
- ClientData clientData; /* Client data to pass to procedure. */
- int deleteFlag; /* Flag to set when this handler is deleted. */
+ Tk_GenericProc *proc; /* Function to dispatch on all X events. */
+ ClientData clientData; /* Client data to pass to function. */
+ int deleteFlag; /* Flag to set when this handler is
+ * deleted. */
struct GenericHandler *nextPtr;
/* Next handler in list of all generic
* handlers, or NULL for end of list. */
} GenericHandler;
/*
- * There's a potential problem if Tk_HandleEvent is entered recursively.
- * A handler cannot be deleted physically until we have returned from
- * calling it. Otherwise, we're looking at unallocated memory in advancing to
- * its `next' entry. We deal with the problem by using the `delete flag' and
+ * There's a potential problem if Tk_HandleEvent is entered recursively. A
+ * handler cannot be deleted physically until we have returned from calling
+ * it. Otherwise, we're looking at unallocated memory in advancing to 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 structure is used for queueing X-style events on the
- * Tcl event queue.
+ * The following structure is used for queueing X-style events on the Tcl
+ * event queue.
*/
typedef struct TkWindowEvent {
@@ -75,7 +73,7 @@ typedef struct TkWindowEvent {
* Array of event masks corresponding to each X event:
*/
-static unsigned long eventMasks[TK_LASTEVENT] = {
+static unsigned long realEventMasks[MappingNotify+1] = {
0,
0,
KeyPressMask, /* KeyPress */
@@ -113,106 +111,694 @@ static unsigned long eventMasks[TK_LASTEVENT] = {
0, /* SelectionNotify */
ColormapChangeMask, /* ColormapNotify */
0, /* ClientMessage */
- 0, /* Mapping Notify */
+ 0 /* Mapping Notify */
+};
+
+static unsigned long virtualEventMasks[TK_LASTEVENT-VirtualEvent] = {
VirtualEventMask, /* VirtualEvents */
ActivateMask, /* ActivateNotify */
ActivateMask, /* DeactivateNotify */
MouseWheelMask /* MouseWheelEvent */
};
+/*
+ * For each exit handler created with a call to TkCreateExitHandler or
+ * TkCreateThreadExitHandler there is a structure of the following type:
+ */
+
+typedef struct ExitHandler {
+ Tcl_ExitProc *proc; /* Function to call when process exits. */
+ ClientData clientData; /* One word of information to pass to proc. */
+ struct ExitHandler *nextPtr;/* Next in list of all exit handlers for this
+ * application, or NULL for end of list. */
+} ExitHandler;
/*
- * 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.
+ * 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.
*/
typedef struct ThreadSpecificData {
- int handlersActive; /* The following variable has a non-zero
- * value when a handler is active. */
- InProgress *pendingPtr; /* Topmost search in progress, or
- * NULL if none. */
+ int handlersActive; /* The following variable has a non-zero value
+ * when a handler is active. */
+ InProgress *pendingPtr; /* Topmost search in progress, or NULL if
+ * none. */
+
+ /*
+ * List of generic handler records.
+ */
+
+ GenericHandler *genericList;/* First handler in the list, or NULL. */
+ GenericHandler *lastGenericPtr;
+ /* Last handler in list. */
- GenericHandler *genericList; /* First handler in the list, or NULL. */
- GenericHandler *lastGenericPtr; /* Last handler in list. */
+ /*
+ * List of client message handler records.
+ */
- GenericHandler *cmList; /* First handler in the list, or NULL. */
+ GenericHandler *cmList; /* First handler in the list, or NULL. */
GenericHandler *lastCmPtr; /* Last handler in list. */
/*
- * If someone has called Tk_RestrictEvents, the information below
- * keeps track of it.
+ * If someone has called Tk_RestrictEvents, the information below keeps
+ * track of it.
*/
Tk_RestrictProc *restrictProc;
- /* Procedure to call. NULL means no
+ /* Function to call. NULL means no
* restrictProc is currently in effect. */
ClientData restrictArg; /* Argument to pass to restrictProc. */
+ ExitHandler *firstExitPtr; /* First in list of all exit handlers for this
+ * thread. */
+ int inExit; /* True when this thread is exiting. This is
+ * used as a hack to decide to close the
+ * standard channels. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
/*
- * Prototypes for procedures that are only referenced locally within
- * this file.
+ * There are both per-process and per-thread exit handlers. The first list is
+ * controlled by a mutex. The other is in thread local storage.
+ */
+
+static ExitHandler *firstExitPtr = NULL;
+ /* First in list of all exit handlers for
+ * application. */
+TCL_DECLARE_MUTEX(exitMutex)
+
+/*
+ * Prototypes for functions that are only referenced locally within this file.
+ */
+
+static void CleanUpTkEvent(XEvent *eventPtr);
+static void DelayedMotionProc(ClientData clientData);
+static int GetButtonMask(unsigned int Button);
+static unsigned long GetEventMaskFromXEvent(XEvent *eventPtr);
+static TkWindow * GetTkWindowFromXEvent(XEvent *eventPtr);
+static void InvokeClientMessageHandlers(ThreadSpecificData *tsdPtr,
+ Tk_Window tkwin, XEvent *eventPtr);
+static int InvokeFocusHandlers(TkWindow **winPtrPtr,
+ unsigned long mask, XEvent *eventPtr);
+static int InvokeGenericHandlers(ThreadSpecificData *tsdPtr,
+ XEvent *eventPtr);
+static int InvokeMouseHandlers(TkWindow *winPtr,
+ unsigned long mask, XEvent *eventPtr);
+static Window ParentXId(Display *display, Window w);
+static int RefreshKeyboardMappingIfNeeded(XEvent *eventPtr);
+static int TkXErrorHandler(ClientData clientData,
+ XErrorEvent *errEventPtr);
+static void UpdateButtonEventState(XEvent *eventPtr);
+static int WindowEventProc(Tcl_Event *evPtr, int flags);
+#ifdef TK_USE_INPUT_METHODS
+static void CreateXIC(TkWindow *winPtr);
+#endif /* TK_USE_INPUT_METHODS */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InvokeFocusHandlers --
+ *
+ * Call focus-related code to look at FocusIn, FocusOut, Enter, and Leave
+ * events; depending on its return value, ignore the event.
+ *
+ * Results:
+ * 0 further processing can be done on the event.
+ * 1 we are done with the event passed.
+ *
+ * Side effects:
+ * The *winPtrPtr in the caller may be changed to the TkWindow for the
+ * window with focus.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InvokeFocusHandlers(
+ TkWindow **winPtrPtr,
+ unsigned long mask,
+ XEvent *eventPtr)
+{
+ if ((mask & (FocusChangeMask|EnterWindowMask|LeaveWindowMask))
+ && (TkFocusFilterEvent(*winPtrPtr, eventPtr) == 0)) {
+ return 1;
+ }
+
+ /*
+ * MouseWheel events are not focus specific on Mac OS X.
+ */
+
+#ifdef MAC_OSX_TK
+#define FOCUS_DIRECTED_EVENT_MASK (KeyPressMask|KeyReleaseMask)
+#else
+#define FOCUS_DIRECTED_EVENT_MASK (KeyPressMask|KeyReleaseMask|MouseWheelMask)
+#endif
+
+ if (mask & FOCUS_DIRECTED_EVENT_MASK) {
+ (*winPtrPtr)->dispPtr->lastEventTime = eventPtr->xkey.time;
+ *winPtrPtr = TkFocusKeyEvent(*winPtrPtr, eventPtr);
+ if (*winPtrPtr == NULL) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InvokeMouseHandlers --
+ *
+ * Call a grab-related function to do special processing on pointer
+ * events.
+ *
+ * Results:
+ * 0 further processing can be done on the event.
+ * 1 we are done with the event passed.
+ *
+ * Side effects:
+ * New events may be queued from TkPointerEvent and grabs may be added
+ * and/or removed. The eventPtr may be changed by TkPointerEvent in some
+ * cases.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InvokeMouseHandlers(
+ TkWindow *winPtr,
+ unsigned long mask,
+ XEvent *eventPtr)
+{
+ if (mask & (ButtonPressMask|ButtonReleaseMask|PointerMotionMask
+ |EnterWindowMask|LeaveWindowMask)) {
+
+ if (mask & (ButtonPressMask|ButtonReleaseMask)) {
+ winPtr->dispPtr->lastEventTime = eventPtr->xbutton.time;
+ } else if (mask & PointerMotionMask) {
+ winPtr->dispPtr->lastEventTime = eventPtr->xmotion.time;
+ } else {
+ winPtr->dispPtr->lastEventTime = eventPtr->xcrossing.time;
+ }
+
+ if (TkPointerEvent(eventPtr, winPtr) == 0) {
+ /*
+ * The event should be ignored to make grab work correctly (as the
+ * comment for TkPointerEvent states).
+ */
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CreateXIC --
+ *
+ * Create the X input context for our winPtr.
+ * XIM is only ever enabled on Unix.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#if defined(TK_USE_INPUT_METHODS)
+static void
+CreateXIC(
+ TkWindow *winPtr)
+{
+ TkDisplay *dispPtr = winPtr->dispPtr;
+ long im_event_mask = 0L;
+ const char *preedit_attname = NULL;
+ XVaNestedList preedit_attlist = NULL;
+
+ if (dispPtr->inputStyle & XIMPreeditPosition) {
+ XPoint spot = {0, 0};
+
+ preedit_attname = XNPreeditAttributes;
+ preedit_attlist = XVaCreateNestedList(0,
+ XNSpotLocation, &spot,
+ XNFontSet, dispPtr->inputXfs,
+ NULL);
+ }
+
+ winPtr->inputContext = XCreateIC(dispPtr->inputMethod,
+ XNInputStyle, dispPtr->inputStyle,
+ XNClientWindow, winPtr->window,
+ XNFocusWindow, winPtr->window,
+ preedit_attname, preedit_attlist,
+ NULL);
+
+ if (preedit_attlist) {
+ XFree(preedit_attlist);
+ }
+
+
+ if (winPtr->inputContext == NULL) {
+ /* XCreateIC failed. */
+ return;
+ }
+
+ /*
+ * Adjust the window's event mask if the IM requires it.
+ */
+ XGetICValues(winPtr->inputContext, XNFilterEvents, &im_event_mask, NULL);
+ if ((winPtr->atts.event_mask & im_event_mask) != im_event_mask) {
+ winPtr->atts.event_mask |= im_event_mask;
+ XSelectInput(winPtr->display, winPtr->window, winPtr->atts.event_mask);
+ }
+}
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetTkWindowFromXEvent --
+ *
+ * Attempt to find which TkWindow is associated with an event. If it
+ * fails we attempt to get the TkWindow from the parent for a property
+ * notification.
+ *
+ * Results:
+ * The TkWindow associated with the event or NULL.
+ *
+ * Side effects:
+ * TkSelPropProc may influence selection on windows not known to Tk.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static TkWindow *
+GetTkWindowFromXEvent(
+ XEvent *eventPtr)
+{
+ TkWindow *winPtr;
+ Window parentXId, handlerWindow = eventPtr->xany.window;
+
+ if ((eventPtr->xany.type == StructureNotifyMask)
+ && (eventPtr->xmap.event != eventPtr->xmap.window)) {
+ handlerWindow = eventPtr->xmap.event;
+ }
+
+ winPtr = (TkWindow *) Tk_IdToWindow(eventPtr->xany.display, handlerWindow);
+
+ if (winPtr == NULL) {
+ /*
+ * There isn't a TkWindow structure for this window. However, if the
+ * event is a PropertyNotify event then call the selection manager (it
+ * deals beneath-the-table with certain properties). Also, if the
+ * window's parent is a Tk window that has the TK_PROP_PROPCHANGE flag
+ * set, then we must propagate the PropertyNotify event up to the
+ * parent.
+ */
+
+ if (eventPtr->type != PropertyNotify) {
+ return NULL;
+ }
+ TkSelPropProc(eventPtr);
+ parentXId = ParentXId(eventPtr->xany.display, handlerWindow);
+ if (parentXId == None) {
+ return NULL;
+ }
+ winPtr = (TkWindow *) Tk_IdToWindow(eventPtr->xany.display, parentXId);
+ if (winPtr == NULL) {
+ return NULL;
+ }
+ if (!(winPtr->flags & TK_PROP_PROPCHANGE)) {
+ return NULL;
+ }
+ }
+ return winPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetEventMaskFromXEvent --
+ *
+ * The event type is looked up in our eventMasks tables, and may be
+ * changed to a different mask depending on the state of the event and
+ * window members.
+ *
+ * Results:
+ * The mask for the event.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static unsigned long
+GetEventMaskFromXEvent(
+ XEvent *eventPtr)
+{
+ unsigned long mask;
+
+ /*
+ * Get the event mask from the correct table. Note that there are two
+ * tables here because that means we no longer need this code to rely on
+ * the exact value of VirtualEvent, which has caused us problems in the
+ * past when X11 changed the value of LASTEvent. [Bug ???]
+ */
+
+ if (eventPtr->xany.type <= MappingNotify) {
+ mask = realEventMasks[eventPtr->xany.type];
+ } else if (eventPtr->xany.type >= VirtualEvent
+ && eventPtr->xany.type<TK_LASTEVENT) {
+ mask = virtualEventMasks[eventPtr->xany.type - VirtualEvent];
+ } else {
+ mask = 0;
+ }
+
+ /*
+ * Events selected by StructureNotify require special handling. They look
+ * the same as those selected by SubstructureNotify. The only difference
+ * is whether the "event" and "window" fields are the same. Compare the
+ * two fields and convert StructureNotify to SubstructureNotify if
+ * necessary.
+ */
+
+ if (mask == StructureNotifyMask) {
+ if (eventPtr->xmap.event != eventPtr->xmap.window) {
+ mask = SubstructureNotifyMask;
+ }
+ }
+ return mask;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RefreshKeyboardMappingIfNeeded --
+ *
+ * If the event is a MappingNotify event, find its display and refresh
+ * the keyboard mapping information for the display.
+ *
+ * Results:
+ * 0 if the event was not a MappingNotify event
+ * 1 if the event was a MappingNotify event
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+RefreshKeyboardMappingIfNeeded(
+ XEvent *eventPtr)
+{
+ TkDisplay *dispPtr;
+
+ if (eventPtr->type == MappingNotify) {
+ dispPtr = TkGetDisplay(eventPtr->xmapping.display);
+ if (dispPtr != NULL) {
+ XRefreshKeyboardMapping(&eventPtr->xmapping);
+ dispPtr->bindInfoStale = 1;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetButtonMask --
+ *
+ * Return the proper Button${n}Mask for the button.
+ *
+ * Results:
+ * A button mask.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GetButtonMask(
+ unsigned int button)
+{
+ switch (button) {
+ case 1:
+ return Button1Mask;
+ case 2:
+ return Button2Mask;
+ case 3:
+ return Button3Mask;
+ case 4:
+ return Button4Mask;
+ case 5:
+ return Button5Mask;
+ }
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateButtonEventState --
+ *
+ * Update the button event state in our TkDisplay using the XEvent
+ * passed. We also may modify the the XEvent passed to fit some aspects
+ * of our TkDisplay.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The TkDisplay's private button state may be modified. The eventPtr's
+ * state may be updated to reflect masks stored in our TkDisplay that the
+ * event doesn't contain. The eventPtr may also be modified to not
+ * contain a button state for the window in which it was not pressed in.
+ *
+ *----------------------------------------------------------------------
*/
-static void DelayedMotionProc _ANSI_ARGS_((ClientData clientData));
-static int WindowEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
- int flags));
-static int TkXErrorHandler _ANSI_ARGS_((ClientData clientData,
- XErrorEvent *errEventPtr));
+static void
+UpdateButtonEventState(
+ XEvent *eventPtr)
+{
+ TkDisplay *dispPtr;
+ int allButtonsMask = Button1Mask | Button2Mask | Button3Mask
+ | Button4Mask | Button5Mask;
+ switch (eventPtr->type) {
+ case ButtonPress:
+ dispPtr = TkGetDisplay(eventPtr->xbutton.display);
+ dispPtr->mouseButtonWindow = eventPtr->xbutton.window;
+ eventPtr->xbutton.state |= dispPtr->mouseButtonState;
+
+ dispPtr->mouseButtonState |= GetButtonMask(eventPtr->xbutton.button);
+ break;
+
+ case ButtonRelease:
+ dispPtr = TkGetDisplay(eventPtr->xbutton.display);
+ dispPtr->mouseButtonWindow = None;
+ dispPtr->mouseButtonState &= ~GetButtonMask(eventPtr->xbutton.button);
+ eventPtr->xbutton.state |= dispPtr->mouseButtonState;
+ break;
+
+ case MotionNotify:
+ dispPtr = TkGetDisplay(eventPtr->xmotion.display);
+ if (dispPtr->mouseButtonState & allButtonsMask) {
+ if (eventPtr->xbutton.window != dispPtr->mouseButtonWindow) {
+ /*
+ * This motion event should not be interpreted as a button
+ * press + motion event since this is not the same window the
+ * button was pressed down in.
+ */
+
+ dispPtr->mouseButtonState &= ~allButtonsMask;
+ dispPtr->mouseButtonWindow = None;
+ } else {
+ eventPtr->xmotion.state |= dispPtr->mouseButtonState;
+ }
+ }
+ break;
+ }
+}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
+ *
+ * InvokeClientMessageHandlers --
+ *
+ * Iterate the list of handlers and invoke the function pointer for each.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Handlers may be deleted and events may be sent to handlers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+InvokeClientMessageHandlers(
+ ThreadSpecificData *tsdPtr,
+ Tk_Window tkwin,
+ XEvent *eventPtr)
+{
+ GenericHandler *prevPtr, *tmpPtr, *curPtr = tsdPtr->cmList;
+
+ for (prevPtr = NULL; curPtr != NULL; ) {
+ if (curPtr->deleteFlag) {
+ if (!tsdPtr->handlersActive) {
+ /*
+ * This handler needs to be deleted and there are no calls
+ * pending through any handlers, so now is a safe time to
+ * delete it.
+ */
+
+ tmpPtr = curPtr->nextPtr;
+ if (prevPtr == NULL) {
+ tsdPtr->cmList = tmpPtr;
+ } else {
+ prevPtr->nextPtr = tmpPtr;
+ }
+ if (tmpPtr == NULL) {
+ tsdPtr->lastCmPtr = prevPtr;
+ }
+ (void) ckfree((char *) curPtr);
+ curPtr = tmpPtr;
+ continue;
+ }
+ } else {
+ int done;
+
+ tsdPtr->handlersActive++;
+ done = (*(Tk_ClientMessageProc *)curPtr->proc)(tkwin, eventPtr);
+ tsdPtr->handlersActive--;
+ if (done) {
+ break;
+ }
+ }
+ prevPtr = curPtr;
+ curPtr = curPtr->nextPtr;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InvokeGenericHandlers --
+ *
+ * Iterate the list of handlers and invoke the function pointer for each.
+ * If the handler invoked returns a non-zero value then we are done.
+ *
+ * Results:
+ * 0 when the event wasn't handled by a handler. Non-zero when it was
+ * processed and handled by a handler.
+ *
+ * Side effects:
+ * Handlers may be deleted and events may be sent to handlers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InvokeGenericHandlers(
+ ThreadSpecificData *tsdPtr,
+ XEvent *eventPtr)
+{
+ GenericHandler *prevPtr, *tmpPtr, *curPtr = tsdPtr->genericList;
+
+ for (prevPtr = NULL; curPtr != NULL; ) {
+ if (curPtr->deleteFlag) {
+ if (!tsdPtr->handlersActive) {
+ /*
+ * This handler needs to be deleted and there are no calls
+ * pending through the handler, so now is a safe time to
+ * delete it.
+ */
+
+ tmpPtr = curPtr->nextPtr;
+ if (prevPtr == NULL) {
+ tsdPtr->genericList = tmpPtr;
+ } else {
+ prevPtr->nextPtr = tmpPtr;
+ }
+ if (tmpPtr == NULL) {
+ tsdPtr->lastGenericPtr = prevPtr;
+ }
+ (void) ckfree((char *) curPtr);
+ curPtr = tmpPtr;
+ continue;
+ }
+ } else {
+ int done;
+
+ tsdPtr->handlersActive++;
+ done = (*curPtr->proc)(curPtr->clientData, eventPtr);
+ tsdPtr->handlersActive--;
+ if (done) {
+ return done;
+ }
+ }
+ prevPtr = curPtr;
+ curPtr = curPtr->nextPtr;
+ }
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
*
* Tk_CreateEventHandler --
*
- * Arrange for a given procedure to be invoked whenever
- * events from a given class occur in a given window.
+ * Arrange for a given function to be invoked whenever events from a
+ * given class occur in a given window.
*
* Results:
* None.
*
* Side effects:
- * From now on, whenever an event of the type given by
- * mask occurs for token and is processed by Tk_HandleEvent,
- * proc will be called. See the manual entry for details
- * of the calling sequence and return value for proc.
+ * From now on, whenever an event of the type given by mask occurs for
+ * token and is processed by Tk_HandleEvent, proc will be called. See the
+ * manual entry for details of the calling sequence and return value for
+ * proc.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
void
-Tk_CreateEventHandler(token, mask, proc, clientData)
- Tk_Window token; /* Token for window in which to
- * create handler. */
- unsigned long mask; /* Events for which proc should
- * be called. */
- Tk_EventProc *proc; /* Procedure to call for each
- * selected event */
- ClientData clientData; /* Arbitrary data to pass to proc. */
+Tk_CreateEventHandler(
+ Tk_Window token, /* Token for window in which to create
+ * handler. */
+ unsigned long mask, /* Events for which proc should be called. */
+ Tk_EventProc *proc, /* Function to call for each selected event */
+ ClientData clientData) /* Arbitrary data to pass to proc. */
{
register TkEventHandler *handlerPtr;
register TkWindow *winPtr = (TkWindow *) token;
- int found;
/*
- * Skim through the list of existing handlers to (a) compute the
- * overall event mask for the window (so we can pass this new
- * value to the X system) and (b) see if there's already a handler
- * declared with the same callback and clientData (if so, just
- * change the mask). If no existing handler matches, then create
- * a new handler.
+ * Skim through the list of existing handlers to (a) compute the overall
+ * event mask for the window (so we can pass this new value to the X
+ * system) and (b) see if there's already a handler declared with the same
+ * callback and clientData (if so, just change the mask). If no existing
+ * handler matches, then create a new handler.
*/
- found = 0;
if (winPtr->handlerList == NULL) {
- handlerPtr = (TkEventHandler *) ckalloc(
- (unsigned) sizeof(TkEventHandler));
+ /*
+ * No event handlers defined at all, so must create.
+ */
+
+ handlerPtr = (TkEventHandler *) ckalloc(sizeof(TkEventHandler));
winPtr->handlerList = handlerPtr;
- goto initHandler;
} else {
+ int found = 0;
+
for (handlerPtr = winPtr->handlerList; ;
handlerPtr = handlerPtr->nextPtr) {
if ((handlerPtr->proc == proc)
@@ -224,31 +810,43 @@ Tk_CreateEventHandler(token, mask, proc, clientData)
break;
}
}
- }
- /*
- * Create a new handler if no matching old handler was found.
- */
+ /*
+ * If we found anything, we're done because we do not need to use
+ * XSelectInput; Tk always selects on all events anyway in order to
+ * support binding on classes, 'all' and other bind-tags.
+ */
+
+ if (found) {
+ return;
+ }
+
+ /*
+ * No event handler matched, so create a new one.
+ */
- if (!found) {
handlerPtr->nextPtr = (TkEventHandler *)
ckalloc(sizeof(TkEventHandler));
handlerPtr = handlerPtr->nextPtr;
- initHandler:
- handlerPtr->mask = mask;
- handlerPtr->proc = proc;
- handlerPtr->clientData = clientData;
- handlerPtr->nextPtr = NULL;
}
/*
- * No need to call XSelectInput: Tk always selects on all events
- * for all windows (needed to support bindings on classes and "all").
+ * Initialize the new event handler.
+ */
+
+ handlerPtr->mask = mask;
+ handlerPtr->proc = proc;
+ handlerPtr->clientData = clientData;
+ handlerPtr->nextPtr = NULL;
+
+ /*
+ * No need to call XSelectInput: Tk always selects on all events for all
+ * windows (needed to support bindings on classes and "all").
*/
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* Tk_DeleteEventHandler --
*
@@ -258,30 +856,29 @@ Tk_CreateEventHandler(token, mask, proc, clientData)
* None.
*
* Side effects:
- * If there existed a handler as described by the
- * parameters, the handler is deleted so that proc
- * will not be invoked again.
+ * If there existed a handler as described by the parameters, the handler
+ * is deleted so that proc will not be invoked again.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
void
-Tk_DeleteEventHandler(token, mask, proc, clientData)
- Tk_Window token; /* Same as corresponding arguments passed */
- unsigned long mask; /* previously to Tk_CreateEventHandler. */
- Tk_EventProc *proc;
- ClientData clientData;
+Tk_DeleteEventHandler(
+ Tk_Window token, /* Same as corresponding arguments passed */
+ unsigned long mask, /* previously to Tk_CreateEventHandler. */
+ Tk_EventProc *proc,
+ ClientData clientData)
{
register TkEventHandler *handlerPtr;
register InProgress *ipPtr;
TkEventHandler *prevPtr;
register TkWindow *winPtr = (TkWindow *) token;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
- * Find the event handler to be deleted, or return
- * immediately if it doesn't exist.
+ * Find the event handler to be deleted, or return immediately if it
+ * doesn't exist.
*/
for (handlerPtr = winPtr->handlerList, prevPtr = NULL; ;
@@ -296,8 +893,8 @@ Tk_DeleteEventHandler(token, mask, proc, clientData)
}
/*
- * If Tk_HandleEvent is about to process this handler, tell it to
- * process the next one instead.
+ * If Tk_HandleEvent is about to process this handler, tell it to process
+ * the next one instead.
*/
for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {
@@ -317,43 +914,42 @@ Tk_DeleteEventHandler(token, mask, proc, clientData)
}
ckfree((char *) handlerPtr);
-
/*
- * No need to call XSelectInput: Tk always selects on all events
- * for all windows (needed to support bindings on classes and "all").
+ * No need to call XSelectInput: Tk always selects on all events for all
+ * windows (needed to support bindings on classes and "all").
*/
}
-/*--------------------------------------------------------------
+/*----------------------------------------------------------------------
*
* Tk_CreateGenericHandler --
*
- * Register a procedure to be called on each X event, regardless
- * of display or window. Generic handlers are useful for capturing
- * events that aren't associated with windows, or events for windows
- * not managed by Tk.
+ * Register a function to be called on each X event, regardless of
+ * display or window. Generic handlers are useful for capturing events
+ * that aren't associated with windows, or events for windows not managed
+ * by Tk.
*
* Results:
* None.
*
* Side Effects:
- * From now on, whenever an X event is given to Tk_HandleEvent,
- * invoke proc, giving it clientData and the event as arguments.
+ * From now on, whenever an X event is given to Tk_HandleEvent, invoke
+ * proc, giving it clientData and the event as arguments.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
void
-Tk_CreateGenericHandler(proc, clientData)
- Tk_GenericProc *proc; /* Procedure to call on every event. */
- ClientData clientData; /* One-word value to pass to proc. */
+Tk_CreateGenericHandler(
+ Tk_GenericProc *proc, /* Function to call on every event. */
+ ClientData clientData) /* One-word value to pass to proc. */
{
GenericHandler *handlerPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
- handlerPtr = (GenericHandler *) ckalloc (sizeof (GenericHandler));
-
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+ handlerPtr = (GenericHandler *) ckalloc(sizeof(GenericHandler));
+
handlerPtr->proc = proc;
handlerPtr->clientData = clientData;
handlerPtr->deleteFlag = 0;
@@ -367,7 +963,7 @@ Tk_CreateGenericHandler(proc, clientData)
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* Tk_DeleteGenericHandler --
*
@@ -377,77 +973,76 @@ Tk_CreateGenericHandler(proc, clientData)
* None.
*
* Side Effects:
- * If there existed a handler as described by the parameters,
- * that handler is logically deleted so that proc will not be
- * invoked again. The physical deletion happens in the event
- * loop in Tk_HandleEvent.
+ * If there existed a handler as described by the parameters, that
+ * handler is logically deleted so that proc will not be invoked again.
+ * The physical deletion happens in the event loop in Tk_HandleEvent.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
void
-Tk_DeleteGenericHandler(proc, clientData)
- Tk_GenericProc *proc;
- ClientData clientData;
+Tk_DeleteGenericHandler(
+ Tk_GenericProc *proc,
+ ClientData clientData)
{
GenericHandler * handler;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
- for (handler = tsdPtr->genericList; handler; handler = handler->nextPtr) {
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+ for (handler=tsdPtr->genericList ; handler ; handler=handler->nextPtr) {
if ((handler->proc == proc) && (handler->clientData == clientData)) {
handler->deleteFlag = 1;
}
}
}
-/*--------------------------------------------------------------
+/*----------------------------------------------------------------------
*
* Tk_CreateClientMessageHandler --
*
- * Register a procedure to be called on each ClientMessage event.
+ * Register a function to be called on each ClientMessage event.
* ClientMessage handlers are useful for Drag&Drop extensions.
*
* Results:
* None.
*
* Side Effects:
- * From now on, whenever a ClientMessage event is received that isn't
- * a WM_PROTOCOL event or SelectionEvent, invoke proc, giving it
- * tkwin and the event as arguments.
+ * From now on, whenever a ClientMessage event is received that isn't a
+ * WM_PROTOCOL event or SelectionEvent, invoke proc, giving it tkwin and
+ * the event as arguments.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
void
-Tk_CreateClientMessageHandler(proc)
- Tk_ClientMessageProc *proc; /* Procedure to call on event. */
+Tk_CreateClientMessageHandler(
+ Tk_ClientMessageProc *proc) /* Function to call on event. */
{
GenericHandler *handlerPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
- * We use a GenericHandler struct, because it's basically the same,
- * except with an extra clientData field we'll never use.
+ * We use a GenericHandler struct, because it's basically the same, except
+ * with an extra clientData field we'll never use.
*/
- handlerPtr = (GenericHandler *)
- ckalloc (sizeof (GenericHandler));
- handlerPtr->proc = (Tk_GenericProc *) proc;
- handlerPtr->clientData = NULL; /* never used */
- handlerPtr->deleteFlag = 0;
- handlerPtr->nextPtr = NULL;
+ handlerPtr = (GenericHandler *) ckalloc(sizeof(GenericHandler));
+
+ handlerPtr->proc = (Tk_GenericProc *) proc;
+ handlerPtr->clientData = NULL; /* never used */
+ handlerPtr->deleteFlag = 0;
+ handlerPtr->nextPtr = NULL;
if (tsdPtr->cmList == NULL) {
- tsdPtr->cmList = handlerPtr;
+ tsdPtr->cmList = handlerPtr;
} else {
tsdPtr->lastCmPtr->nextPtr = handlerPtr;
}
- tsdPtr->lastCmPtr = handlerPtr;
+ tsdPtr->lastCmPtr = handlerPtr;
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* Tk_DeleteClientMessageHandler --
*
@@ -457,24 +1052,23 @@ Tk_CreateClientMessageHandler(proc)
* None.
*
* Side Effects:
- * If there existed a handler as described by the parameters,
- * that handler is logically deleted so that proc will not be
- * invoked again. The physical deletion happens in the event
- * loop in TkClientMessageEventProc.
+ * If there existed a handler as described by the parameters, that
+ * handler is logically deleted so that proc will not be invoked again.
+ * The physical deletion happens in the event loop in
+ * TkClientMessageEventProc.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
void
-Tk_DeleteClientMessageHandler(proc)
- Tk_ClientMessageProc *proc;
+Tk_DeleteClientMessageHandler(
+ Tk_ClientMessageProc *proc)
{
GenericHandler * handler;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- for (handler = tsdPtr->cmList; handler != NULL;
- handler = handler->nextPtr) {
+ for (handler=tsdPtr->cmList ; handler!=NULL ; handler=handler->nextPtr) {
if (handler->proc == (Tk_GenericProc *) proc) {
handler->deleteFlag = 1;
}
@@ -482,14 +1076,13 @@ Tk_DeleteClientMessageHandler(proc)
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* 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.
+ * This functions initializes all the event module structures used by the
+ * current thread. It must be called before any other function in this
+ * file is called.
*
* Results:
* None.
@@ -497,14 +1090,14 @@ Tk_DeleteClientMessageHandler(proc)
* Side Effects:
* None.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
void
-TkEventInit _ANSI_ARGS_((void))
+TkEventInit(void)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
tsdPtr->handlersActive = 0;
tsdPtr->pendingPtr = NULL;
@@ -517,28 +1110,26 @@ TkEventInit _ANSI_ARGS_((void))
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* TkXErrorHandler --
*
- * TkXErrorHandler is an error handler, to be installed
- * via Tk_CreateErrorHandler, that will set a flag if an
- * X error occurred.
+ * TkXErrorHandler is an error handler, to be installed via
+ * Tk_CreateErrorHandler, that will set a flag if an X error occurred.
*
* Results:
- * Always returns 0, indicating that the X error was
- * handled.
+ * Always returns 0, indicating that the X error was handled.
*
* Side effects:
* None.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static int
-TkXErrorHandler (clientData, errEventPtr)
- ClientData clientData; /* Pointer to flag we set */
- XErrorEvent *errEventPtr; /* X error info */
+TkXErrorHandler(
+ ClientData clientData, /* Pointer to flag we set. */
+ XErrorEvent *errEventPtr) /* X error info. */
{
int *error;
@@ -548,12 +1139,12 @@ TkXErrorHandler (clientData, errEventPtr)
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* ParentXId --
*
- * Returns the parent of the given window, or "None"
- * if the window doesn't exist.
+ * Returns the parent of the given window, or "None" if the window
+ * doesn't exist.
*
* Results:
* Returns an X window ID.
@@ -561,13 +1152,13 @@ TkXErrorHandler (clientData, errEventPtr)
* Side effects:
* None.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static Window
-ParentXId(display, w)
- Display *display;
- Window w;
+ParentXId(
+ Display *display,
+ Window w)
{
Tk_ErrorHandler handler;
int gotXError;
@@ -577,17 +1168,23 @@ ParentXId(display, w)
Window *childList;
unsigned int nChildren;
- /* Handle errors ourselves. */
+ /*
+ * Handle errors ourselves.
+ */
gotXError = 0;
handler = Tk_CreateErrorHandler(display, -1, -1, -1,
- TkXErrorHandler, (ClientData) (&gotXError));
+ TkXErrorHandler, (ClientData) (&gotXError));
- /* Get the parent window. */
+ /*
+ * Get the parent window.
+ */
status = XQueryTree(display, w, &root, &parent, &childList, &nChildren);
- /* Do some cleanup; gotta return "None" if we got an error. */
+ /*
+ * Do some cleanup; gotta return "None" if we got an error.
+ */
Tk_DeleteErrorHandler(handler);
XSync(display, False);
@@ -595,19 +1192,19 @@ ParentXId(display, w)
XFree(childList);
}
if (status == 0) {
- parent = None;
+ parent = None;
}
return parent;
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* Tk_HandleEvent --
*
- * Given an event, invoke all the handlers that have
- * been registered for the event.
+ * Given an event, invoke all the handlers that have been registered for
+ * the event.
*
* Results:
* None.
@@ -615,348 +1212,106 @@ ParentXId(display, w)
* Side effects:
* Depends on the handlers.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
void
-Tk_HandleEvent(eventPtr)
- XEvent *eventPtr; /* Event to dispatch. */
+Tk_HandleEvent(
+ XEvent *eventPtr) /* Event to dispatch. */
{
register TkEventHandler *handlerPtr;
- register GenericHandler *genericPtr;
- register GenericHandler *genPrevPtr;
TkWindow *winPtr;
unsigned long mask;
InProgress ip;
- Window handlerWindow;
- Window parentXId;
- TkDisplay *dispPtr;
- Tcl_Interp *interp = (Tcl_Interp *) NULL;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
- /*
- * Hack for simulated X-events: Correct the state field
- * of the event record to match with the ButtonPress
- * and ButtonRelease events.
- */
-
- if (eventPtr->type==ButtonPress) {
- dispPtr = TkGetDisplay(eventPtr->xbutton.display);
- dispPtr->mouseButtonWindow = eventPtr->xbutton.window;
- eventPtr->xbutton.state |= dispPtr->mouseButtonState;
- switch (eventPtr->xbutton.button) {
- case 1: dispPtr->mouseButtonState |= Button1Mask; break;
- case 2: dispPtr->mouseButtonState |= Button2Mask; break;
- case 3: dispPtr->mouseButtonState |= Button3Mask; break;
- }
- } else if (eventPtr->type==ButtonRelease) {
- dispPtr = TkGetDisplay(eventPtr->xbutton.display);
- dispPtr->mouseButtonWindow = 0;
- switch (eventPtr->xbutton.button) {
- case 1: dispPtr->mouseButtonState &= ~Button1Mask; break;
- case 2: dispPtr->mouseButtonState &= ~Button2Mask; break;
- case 3: dispPtr->mouseButtonState &= ~Button3Mask; break;
- }
- eventPtr->xbutton.state |= dispPtr->mouseButtonState;
- } else if (eventPtr->type==MotionNotify) {
- dispPtr = TkGetDisplay(eventPtr->xmotion.display);
- if (dispPtr->mouseButtonState & (Button1Mask|Button2Mask|Button3Mask)) {
- if (eventPtr->xbutton.window != dispPtr->mouseButtonWindow) {
- /*
- * This motion event should not be interpreted as a button
- * press + motion event since this is not the same window
- * the button was pressed down in.
- */
- dispPtr->mouseButtonState &=
- ~(Button1Mask|Button2Mask|Button3Mask);
- dispPtr->mouseButtonWindow = 0;
- } else {
- eventPtr->xmotion.state |= dispPtr->mouseButtonState;
- }
- }
- }
-
- /*
- * Next, invoke all the generic event handlers (those that are
- * invoked for all events). If a generic event handler reports that
- * an event is fully processed, go no further.
- */
+ Tcl_Interp *interp = NULL;
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- for (genPrevPtr = NULL, genericPtr = tsdPtr->genericList;
- genericPtr != NULL; ) {
- if (genericPtr->deleteFlag) {
- if (!tsdPtr->handlersActive) {
- GenericHandler *tmpPtr;
-
- /*
- * This handler needs to be deleted and there are no
- * calls pending through the handler, so now is a safe
- * time to delete it.
- */
-
- tmpPtr = genericPtr->nextPtr;
- if (genPrevPtr == NULL) {
- tsdPtr->genericList = tmpPtr;
- } else {
- genPrevPtr->nextPtr = tmpPtr;
- }
- if (tmpPtr == NULL) {
- tsdPtr->lastGenericPtr = genPrevPtr;
- }
- (void) ckfree((char *) genericPtr);
- genericPtr = tmpPtr;
- continue;
- }
- } else {
- int done;
-
- tsdPtr->handlersActive++;
- done = (*genericPtr->proc)(genericPtr->clientData, eventPtr);
- tsdPtr->handlersActive--;
- if (done) {
- return;
- }
- }
- genPrevPtr = genericPtr;
- genericPtr = genPrevPtr->nextPtr;
- }
+ UpdateButtonEventState(eventPtr);
/*
- * If the event is a MappingNotify event, find its display and
- * refresh the keyboard mapping information for the display.
- * After that there's nothing else to do with the event, so just
- * quit.
+ * If the generic handler processed this event we are done and can return.
*/
- if (eventPtr->type == MappingNotify) {
- dispPtr = TkGetDisplay(eventPtr->xmapping.display);
- if (dispPtr != NULL) {
- XRefreshKeyboardMapping(&eventPtr->xmapping);
- dispPtr->bindInfoStale = 1;
- }
- return;
+ if (InvokeGenericHandlers(tsdPtr, eventPtr)) {
+ goto releaseEventResources;
}
- /*
- * Events selected by StructureNotify require special handling.
- * They look the same as those selected by SubstructureNotify.
- * The only difference is whether the "event" and "window" fields
- * are the same. Compare the two fields and convert StructureNotify
- * to SubstructureNotify if necessary.
- */
-
- handlerWindow = eventPtr->xany.window;
- mask = eventMasks[eventPtr->xany.type];
- if (mask == StructureNotifyMask) {
- if (eventPtr->xmap.event != eventPtr->xmap.window) {
- mask = SubstructureNotifyMask;
- handlerWindow = eventPtr->xmap.event;
- }
- }
- winPtr = (TkWindow *) Tk_IdToWindow(eventPtr->xany.display, handlerWindow);
- if (winPtr == NULL) {
+ if (RefreshKeyboardMappingIfNeeded(eventPtr)) {
/*
- * There isn't a TkWindow structure for this window.
- * However, if the event is a PropertyNotify event then call
- * the selection manager (it deals beneath-the-table with
- * certain properties). Also, if the window's parent is a
- * Tk window that has the TK_PROP_PROPCHANGE flag set, then
- * we must propagate the PropertyNotify event up to the parent.
+ * We are done with a MappingNotify event.
*/
- if (eventPtr->type != PropertyNotify) {
- return;
- }
-
- TkSelPropProc(eventPtr);
-
- /* Get handlerWindow's parent. */
-
- parentXId = ParentXId(eventPtr->xany.display, handlerWindow);
- if (parentXId == None) {
- return;
- }
-
- winPtr = (TkWindow *) Tk_IdToWindow(eventPtr->xany.display, parentXId);
- if (winPtr == NULL) {
- return;
- }
+ goto releaseEventResources;
+ }
- if (!(winPtr->flags & TK_PROP_PROPCHANGE)) {
- return;
- }
+ mask = GetEventMaskFromXEvent(eventPtr);
+ winPtr = GetTkWindowFromXEvent(eventPtr);
- handlerWindow = parentXId;
+ if (winPtr == NULL) {
+ goto releaseEventResources;
}
/*
* Once a window has started getting deleted, don't process any more
- * events for it except for the DestroyNotify event. This check is
- * needed because a DestroyNotify handler could re-invoke the event
- * loop, causing other pending events to be handled for the window
- * (the window doesn't get totally expunged from our tables until
- * after the DestroyNotify event has been completely handled).
+ * events for it except for the DestroyNotify event. This check is needed
+ * because a DestroyNotify handler could re-invoke the event loop, causing
+ * other pending events to be handled for the window (the window doesn't
+ * get totally expunged from our tables until after the DestroyNotify
+ * event has been completely handled).
*/
if ((winPtr->flags & TK_ALREADY_DEAD)
&& (eventPtr->type != DestroyNotify)) {
- return;
+ goto releaseEventResources;
}
if (winPtr->mainPtr != NULL) {
+ int result;
+
+ interp = winPtr->mainPtr->interp;
- /*
- * Protect interpreter for this window from possible deletion
- * while we are dealing with the event for this window. Thus,
- * widget writers do not have to worry about protecting the
- * interpreter in their own code.
- */
-
- interp = winPtr->mainPtr->interp;
- Tcl_Preserve((ClientData) interp);
-
- /*
- * Call focus-related code to look at FocusIn, FocusOut, Enter,
- * and Leave events; depending on its return value, ignore the
- * event.
- */
-
- if ((mask & (FocusChangeMask|EnterWindowMask|LeaveWindowMask))
- && !TkFocusFilterEvent(winPtr, eventPtr)) {
- Tcl_Release((ClientData) interp);
- return;
- }
-
- /*
- * Redirect KeyPress and KeyRelease events to the focus window,
- * or ignore them entirely if there is no focus window. We also
- * route the MouseWheel event to the focus window. The MouseWheel
- * event is an extension to the X event set. Currently, it is only
- * available on the Windows version of Tk.
- */
-
-#ifdef MAC_OSX_TK
- /* MouseWheel events are not focus specific on Mac OS X */
- if (mask & (KeyPressMask|KeyReleaseMask)) {
-#else
- if (mask & (KeyPressMask|KeyReleaseMask|MouseWheelMask)) {
-#endif
- winPtr->dispPtr->lastEventTime = eventPtr->xkey.time;
- winPtr = TkFocusKeyEvent(winPtr, eventPtr);
- if (winPtr == NULL) {
- Tcl_Release((ClientData) interp);
- return;
- }
- }
-
/*
- * Call a grab-related procedure to do special processing on
- * pointer events.
+ * Protect interpreter for this window from possible deletion while we
+ * are dealing with the event for this window. Thus, widget writers do
+ * not have to worry about protecting the interpreter in their own
+ * code.
*/
-
- if (mask & (ButtonPressMask|ButtonReleaseMask|PointerMotionMask
- |EnterWindowMask|LeaveWindowMask)) {
- if (mask & (ButtonPressMask|ButtonReleaseMask)) {
- winPtr->dispPtr->lastEventTime = eventPtr->xbutton.time;
- } else if (mask & PointerMotionMask) {
- winPtr->dispPtr->lastEventTime = eventPtr->xmotion.time;
- } else {
- winPtr->dispPtr->lastEventTime = eventPtr->xcrossing.time;
- }
- if (TkPointerEvent(eventPtr, winPtr) == 0) {
- goto done;
- }
+
+ Tcl_Preserve((ClientData) interp);
+
+ result = ((InvokeFocusHandlers(&winPtr, mask, eventPtr))
+ || (InvokeMouseHandlers(winPtr, mask, eventPtr)));
+
+ if (result) {
+ goto releaseInterpreter;
}
}
-#ifdef TK_USE_INPUT_METHODS
/*
- * Pass the event to the input method(s), if there are any, and
- * discard the event if the input method(s) insist. Create the
- * input context for the window if it hasn't already been done
- * (XFilterEvent needs this context). XIM is only ever enabled on
- * Unix, but this hasn't been factored out of the generic code yet.
+ * Create the input context for the window if it hasn't already been done
+ * (XFilterEvent needs this context). When the event is a FocusIn event,
+ * set the input context focus to the receiving window. This code is only
+ * ever active for X11.
*/
- dispPtr = winPtr->dispPtr;
- if ((dispPtr->flags & TK_DISPLAY_USE_IM)) {
- long im_event_mask = 0L;
+
+#ifdef TK_USE_INPUT_METHODS
+ if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)) {
if (!(winPtr->flags & (TK_CHECKED_IC|TK_ALREADY_DEAD))) {
winPtr->flags |= TK_CHECKED_IC;
- if (dispPtr->inputMethod != NULL) {
-#if TK_XIM_SPOT
- if (dispPtr->flags & TK_DISPLAY_XIM_SPOT) {
- XVaNestedList preedit_attr;
- XPoint spot = {0, 0};
-
- if (dispPtr->inputXfs == NULL) {
- /*
- * We only need to create one XFontSet
- */
- char **missing_list;
- int missing_count;
- char *def_string;
-
- dispPtr->inputXfs = XCreateFontSet(dispPtr->display,
- "-*-*-*-R-Normal--14-130-75-75-*-*",
- &missing_list, &missing_count, &def_string);
- if (missing_count > 0) {
- XFreeStringList(missing_list);
- }
- }
-
- preedit_attr = XVaCreateNestedList(0, XNSpotLocation,
- &spot, XNFontSet, dispPtr->inputXfs, NULL);
- if (winPtr->inputContext != NULL)
- panic("inputContext not NULL");
- winPtr->inputContext = XCreateIC(dispPtr->inputMethod,
- XNInputStyle, XIMPreeditPosition|XIMStatusNothing,
- XNClientWindow, winPtr->window,
- XNFocusWindow, winPtr->window,
- XNPreeditAttributes, preedit_attr,
- NULL);
- XFree(preedit_attr);
- } else {
- if (winPtr->inputContext != NULL)
- panic("inputContext not NULL");
- winPtr->inputContext = XCreateIC(dispPtr->inputMethod,
- XNInputStyle, XIMPreeditNothing|XIMStatusNothing,
- XNClientWindow, winPtr->window,
- XNFocusWindow, winPtr->window,
- NULL);
- }
-#else
- if (winPtr->inputContext != NULL)
- panic("inputContext not NULL");
- winPtr->inputContext = XCreateIC(dispPtr->inputMethod,
- XNInputStyle, XIMPreeditNothing|XIMStatusNothing,
- XNClientWindow, winPtr->window,
- XNFocusWindow, winPtr->window,
- NULL);
-#endif
- }
- }
- if (winPtr->inputContext != NULL &&
- (eventPtr->xany.type == FocusIn)) {
- XGetICValues(winPtr->inputContext,
- XNFilterEvents, &im_event_mask, NULL);
- if (im_event_mask != 0L) {
- XSelectInput(winPtr->display, winPtr->window,
- winPtr->atts.event_mask | im_event_mask);
- XSetICFocus(winPtr->inputContext);
+ if (winPtr->dispPtr->inputMethod != NULL) {
+ CreateXIC(winPtr);
}
}
- if (eventPtr->type == KeyPress || eventPtr->type == KeyRelease) {
- if (XFilterEvent(eventPtr, None)) {
- goto done;
- }
+ if (eventPtr->type == FocusIn && winPtr->inputContext != NULL) {
+ XSetICFocus(winPtr->inputContext);
}
}
-#endif /* TK_USE_INPUT_METHODS */
+#endif
/*
- * For events where it hasn't already been done, update the current
- * time in the display.
+ * For events where it hasn't already been done, update the current time
+ * in the display.
*/
if (eventPtr->type == PropertyNotify) {
@@ -964,8 +1319,8 @@ Tk_HandleEvent(eventPtr)
}
/*
- * There's a potential interaction here with Tk_DeleteEventHandler.
- * Read the documentation for pendingPtr.
+ * There's a potential interaction here with Tk_DeleteEventHandler. Read
+ * the documentation for pendingPtr.
*/
ip.eventPtr = eventPtr;
@@ -983,49 +1338,8 @@ Tk_HandleEvent(eventPtr)
Tk_InternAtom((Tk_Window) winPtr, "WM_PROTOCOLS")) {
TkWmProtocolEventProc(winPtr, eventPtr);
} else {
- /*
- * Finally, invoke any ClientMessage event handlers.
- */
-
- for (genPrevPtr = NULL, genericPtr = tsdPtr->cmList;
- genericPtr != NULL; ) {
- if (genericPtr->deleteFlag) {
- if (!tsdPtr->handlersActive) {
- GenericHandler *tmpPtr;
-
- /*
- * This handler needs to be deleted and there are
- * no calls pending through any handlers, so now
- * is a safe time to delete it.
- */
-
- tmpPtr = genericPtr->nextPtr;
- if (genPrevPtr == NULL) {
- tsdPtr->cmList = tmpPtr;
- } else {
- genPrevPtr->nextPtr = tmpPtr;
- }
- if (tmpPtr == NULL) {
- tsdPtr->lastCmPtr = genPrevPtr;
- }
- (void) ckfree((char *) genericPtr);
- genericPtr = tmpPtr;
- continue;
- }
- } else {
- int done;
-
- tsdPtr->handlersActive++;
- done = (*(Tk_ClientMessageProc *)genericPtr->proc)
- ((Tk_Window) winPtr, eventPtr);
- tsdPtr->handlersActive--;
- if (done) {
- break;
- }
- }
- genPrevPtr = genericPtr;
- genericPtr = genPrevPtr->nextPtr;
- }
+ InvokeClientMessageHandlers(tsdPtr, (Tk_Window)winPtr,
+ eventPtr);
}
}
} else {
@@ -1040,44 +1354,53 @@ Tk_HandleEvent(eventPtr)
}
/*
- * Pass the event to the "bind" command mechanism. But, don't
- * do this for SubstructureNotify events. The "bind" command
- * doesn't support them anyway, and it's easier to filter out
- * these events here than in the lower-level procedures.
+ * Pass the event to the "bind" command mechanism. But, don't do this
+ * for SubstructureNotify events. The "bind" command doesn't support
+ * them anyway, and it's easier to filter out these events here than
+ * in the lower-level functions.
*/
/*
- * ...well, except when we use the tkwm patches, in which case
- * we DO handle CreateNotify events, so we gotta pass 'em through.
+ * ...well, except when we use the tkwm patches, in which case we DO
+ * handle CreateNotify events, so we gotta pass 'em through.
*/
if ((ip.winPtr != None)
&& ((mask != SubstructureNotifyMask)
- || (eventPtr->type == CreateNotify))) {
+ || (eventPtr->type == CreateNotify))) {
TkBindEventProc(winPtr, eventPtr);
}
}
tsdPtr->pendingPtr = ip.nextPtr;
-done:
/*
* Release the interpreter for this window so that it can be potentially
* deleted if requested.
*/
-
- if (interp != (Tcl_Interp *) NULL) {
- Tcl_Release((ClientData) interp);
+
+ releaseInterpreter:
+ if (interp != NULL) {
+ Tcl_Release((ClientData) interp);
}
+
+ /*
+ * Release the user_data from the event (if it is a virtual event and the
+ * field was non-NULL in the first place.) Note that this is done using a
+ * Tcl_Obj interface, and we set the field back to NULL afterwards out of
+ * paranoia. Also clean up any cached %A substitutions from key events.
+ */
+
+ releaseEventResources:
+ CleanUpTkEvent(eventPtr);
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* TkEventDeadWindow --
*
- * This procedure is invoked when it is determined that
- * a window is dead. It cleans up event-related information
- * about the window.
+ * This function is invoked when it is determined that a window is dead.
+ * It cleans up event-related information about the window.
*
* Results:
* None.
@@ -1085,31 +1408,30 @@ done:
* Side effects:
* Various things get cleaned up and recycled.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
void
-TkEventDeadWindow(winPtr)
- TkWindow *winPtr; /* Information about the window
- * that is being deleted. */
+TkEventDeadWindow(
+ TkWindow *winPtr) /* Information about the window that is being
+ * deleted. */
{
register TkEventHandler *handlerPtr;
register InProgress *ipPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
- * While deleting all the handlers, be careful to check for
- * Tk_HandleEvent being about to process one of the deleted
- * handlers. If it is, tell it to quit (all of the handlers
- * are being deleted).
+ * While deleting all the handlers, be careful to check for Tk_HandleEvent
+ * being about to process one of the deleted handlers. If it is, tell it
+ * to quit (all of the handlers are being deleted).
*/
while (winPtr->handlerList != NULL) {
handlerPtr = winPtr->handlerList;
winPtr->handlerList = handlerPtr->nextPtr;
- for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL;
- ipPtr = ipPtr->nextPtr) {
+ for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL;
+ ipPtr = ipPtr->nextPtr) {
if (ipPtr->nextHandler == handlerPtr) {
ipPtr->nextHandler = NULL;
}
@@ -1126,15 +1448,13 @@ TkEventDeadWindow(winPtr)
*
* TkCurrentTime --
*
- * Try to deduce the current time. "Current time" means the time
- * of the event that led to the current code being executed, which
- * means the time in the most recently-nested invocation of
- * Tk_HandleEvent.
+ * Try to deduce the current time. "Current time" means the time of the
+ * event that led to the current code being executed, which means the
+ * time in the most recently-nested invocation of Tk_HandleEvent.
*
* Results:
- * The return value is the time from the current event, or
- * CurrentTime if there is no current event or if the current
- * event contains no time.
+ * The return value is the time from the current event, or CurrentTime if
+ * there is no current event or if the current event contains no time.
*
* Side effects:
* None.
@@ -1143,31 +1463,31 @@ TkEventDeadWindow(winPtr)
*/
Time
-TkCurrentTime(dispPtr)
- TkDisplay *dispPtr; /* Display for which the time is desired. */
+TkCurrentTime(
+ TkDisplay *dispPtr) /* Display for which the time is desired. */
{
register XEvent *eventPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (tsdPtr->pendingPtr == NULL) {
return dispPtr->lastEventTime;
}
eventPtr = tsdPtr->pendingPtr->eventPtr;
switch (eventPtr->type) {
- case ButtonPress:
- case ButtonRelease:
- return eventPtr->xbutton.time;
- case KeyPress:
- case KeyRelease:
- return eventPtr->xkey.time;
- case MotionNotify:
- return eventPtr->xmotion.time;
- case EnterNotify:
- case LeaveNotify:
- return eventPtr->xcrossing.time;
- case PropertyNotify:
- return eventPtr->xproperty.time;
+ case ButtonPress:
+ case ButtonRelease:
+ return eventPtr->xbutton.time;
+ case KeyPress:
+ case KeyRelease:
+ return eventPtr->xkey.time;
+ case MotionNotify:
+ return eventPtr->xmotion.time;
+ case EnterNotify:
+ case LeaveNotify:
+ return eventPtr->xcrossing.time;
+ case PropertyNotify:
+ return eventPtr->xproperty.time;
}
return dispPtr->lastEventTime;
}
@@ -1177,15 +1497,14 @@ TkCurrentTime(dispPtr)
*
* Tk_RestrictEvents --
*
- * This procedure is used to globally restrict the set of events
- * that will be dispatched. The restriction is done by filtering
- * all incoming X events through a procedure that determines
- * whether they are to be processed immediately, deferred, or
- * discarded.
+ * This function is used to globally restrict the set of events that will
+ * be dispatched. The restriction is done by filtering all incoming X
+ * events through a function that determines whether they are to be
+ * processed immediately, deferred, or discarded.
*
* Results:
- * The return value is the previous restriction procedure in effect,
- * if there was one, or NULL if there wasn't.
+ * The return value is the previous restriction function in effect, if
+ * there was one, or NULL if there wasn't.
*
* Side effects:
* From now on, proc will be called to determine whether to process,
@@ -1195,16 +1514,15 @@ TkCurrentTime(dispPtr)
*/
Tk_RestrictProc *
-Tk_RestrictEvents(proc, arg, prevArgPtr)
- Tk_RestrictProc *proc; /* Procedure to call for each incoming
- * event. */
- ClientData arg; /* Arbitrary argument to pass to proc. */
- ClientData *prevArgPtr; /* Place to store information about previous
+Tk_RestrictEvents(
+ Tk_RestrictProc *proc, /* Function to call for each incoming event */
+ ClientData arg, /* Arbitrary argument to pass to proc. */
+ ClientData *prevArgPtr) /* Place to store information about previous
* argument. */
{
Tk_RestrictProc *prev;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
prev = tsdPtr->restrictProc;
*prevArgPtr = tsdPtr->restrictArg;
@@ -1218,7 +1536,7 @@ Tk_RestrictEvents(proc, arg, prevArgPtr)
*
* Tk_CollapseMotionEvents --
*
- * This procedure controls whether we collapse motion events in a
+ * This function controls whether we collapse motion events in a
* particular display or not.
*
* Results:
@@ -1231,10 +1549,10 @@ Tk_RestrictEvents(proc, arg, prevArgPtr)
*/
int
-Tk_CollapseMotionEvents(display, collapse)
- Display *display; /* Display handling these events. */
- int collapse; /* boolean value that specifies whether
- * motion events should be collapsed. */
+Tk_CollapseMotionEvents(
+ Display *display, /* Display handling these events. */
+ int collapse) /* Boolean value that specifies whether motion
+ * events should be collapsed. */
{
TkDisplay *dispPtr = (TkDisplay *) display;
int prev = (dispPtr->flags & TK_DISPLAY_COLLAPSE_MOTION_EVENTS);
@@ -1252,28 +1570,26 @@ Tk_CollapseMotionEvents(display, collapse)
*
* Tk_QueueWindowEvent --
*
- * Given an X-style window event, this procedure adds it to the
- * Tcl event queue at the given position. This procedure also
- * performs mouse motion event collapsing if possible.
+ * Given an X-style window event, this function adds it to the Tcl event
+ * queue at the given position. This function also performs mouse motion
+ * event collapsing if possible.
*
* Results:
* None.
*
* Side effects:
- * Adds stuff to the event queue, which will eventually be
- * processed.
+ * Adds stuff to the event queue, which will eventually be processed.
*
*----------------------------------------------------------------------
*/
void
-Tk_QueueWindowEvent(eventPtr, position)
- XEvent *eventPtr; /* Event to add to queue. This
- * procedures copies it before adding
- * it to the queue. */
- Tcl_QueuePosition position; /* Where to put it on the queue:
- * TCL_QUEUE_TAIL, TCL_QUEUE_HEAD,
- * or TCL_QUEUE_MARK. */
+Tk_QueueWindowEvent(
+ XEvent *eventPtr, /* Event to add to queue. This function copies
+ * it before adding it to the queue. */
+ Tcl_QueuePosition position) /* Where to put it on the queue:
+ * TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, or
+ * TCL_QUEUE_MARK. */
{
TkWindowEvent *wevPtr;
TkDisplay *dispPtr;
@@ -1292,10 +1608,11 @@ Tk_QueueWindowEvent(eventPtr, position)
}
/*
- * Don't filter motion events if the user
- * defaulting to true (1), which could be set to false (0) when the
- * user wishes to receive all the motion data)
+ * Don't filter motion events if the user defaulting to true (1), which
+ * could be set to false (0) when the user wishes to receive all the
+ * motion data)
*/
+
if (!(dispPtr->flags & TK_DISPLAY_COLLAPSE_MOTION_EVENTS)) {
wevPtr = (TkWindowEvent *) ckalloc(sizeof(TkWindowEvent));
wevPtr->header.proc = WindowEventProc;
@@ -1308,9 +1625,8 @@ Tk_QueueWindowEvent(eventPtr, position)
if ((eventPtr->type == MotionNotify) && (eventPtr->xmotion.window
== dispPtr->delayedMotionPtr->event.xmotion.window)) {
/*
- * The new event is a motion event in the same window as the
- * saved motion event. Just replace the saved event with the
- * new one.
+ * The new event is a motion event in the same window as the saved
+ * motion event. Just replace the saved event with the new one.
*/
dispPtr->delayedMotionPtr->event = *eventPtr;
@@ -1319,7 +1635,7 @@ Tk_QueueWindowEvent(eventPtr, position)
&& (eventPtr->type != NoExpose)
&& (eventPtr->type != Expose)) {
/*
- * The new event may conflict with the saved motion event. Queue
+ * The new event may conflict with the saved motion event. Queue
* the saved motion event now so that it will be processed before
* the new event.
*/
@@ -1335,13 +1651,13 @@ Tk_QueueWindowEvent(eventPtr, position)
wevPtr->event = *eventPtr;
if ((eventPtr->type == MotionNotify) && (position == TCL_QUEUE_TAIL)) {
/*
- * The new event is a motion event so don't queue it immediately;
- * save it around in case another motion event arrives that it can
- * be collapsed with.
+ * The new event is a motion event so don't queue it immediately; save
+ * it around in case another motion event arrives that it can be
+ * collapsed with.
*/
if (dispPtr->delayedMotionPtr != NULL) {
- panic("Tk_QueueWindowEvent found unexpected delayed motion event");
+ Tcl_Panic("Tk_QueueWindowEvent found unexpected delayed motion event");
}
dispPtr->delayedMotionPtr = wevPtr;
Tcl_DoWhenIdle(DelayedMotionProc, (ClientData) dispPtr);
@@ -1351,12 +1667,12 @@ Tk_QueueWindowEvent(eventPtr, position)
}
/*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* TkQueueEventForAllChildren --
*
- * Given an XEvent, recursively queue the event for this window and
- * all non-toplevel children of the given window.
+ * Given an XEvent, recursively queue the event for this window and all
+ * non-toplevel children of the given window.
*
* Results:
* None.
@@ -1364,23 +1680,23 @@ Tk_QueueWindowEvent(eventPtr, position)
* Side effects:
* Events queued.
*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
void
-TkQueueEventForAllChildren(winPtr, eventPtr)
- TkWindow *winPtr; /* Window to which event is sent. */
- XEvent *eventPtr; /* The event to be sent. */
+TkQueueEventForAllChildren(
+ TkWindow *winPtr, /* Window to which event is sent. */
+ XEvent *eventPtr) /* The event to be sent. */
{
TkWindow *childPtr;
if (!Tk_IsMapped(winPtr)) {
- return;
+ return;
}
-
+
eventPtr->xany.window = winPtr->window;
Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_TAIL);
-
+
childPtr = winPtr->childList;
while (childPtr != NULL) {
if (!Tk_TopWinHierarchy(childPtr)) {
@@ -1395,16 +1711,16 @@ TkQueueEventForAllChildren(winPtr, eventPtr)
*
* WindowEventProc --
*
- * This procedure is called by Tcl_DoOneEvent when a window event
- * reaches the front of the event queue. This procedure is responsible
- * for actually handling the event.
+ * This function is called by Tcl_DoOneEvent when a window event reaches
+ * the front of the event queue. This function is responsible for
+ * actually handling the event.
*
* Results:
- * Returns 1 if the event was handled, meaning it should be removed
- * from the queue. Returns 0 if the event was not handled, meaning
- * it should stay on the queue. The event isn't handled if the
- * TCL_WINDOW_EVENTS bit isn't set in flags, if a restrict proc
- * prevents the event from being handled.
+ * Returns 1 if the event was handled, meaning it should be removed from
+ * the queue. Returns 0 if the event was not handled, meaning it should
+ * stay on the queue. The event isn't handled if the TCL_WINDOW_EVENTS
+ * bit isn't set in flags, if a restrict proc prevents the event from
+ * being handled.
*
* Side effects:
* Whatever the event handlers for the event do.
@@ -1413,15 +1729,15 @@ TkQueueEventForAllChildren(winPtr, eventPtr)
*/
static int
-WindowEventProc(evPtr, flags)
- Tcl_Event *evPtr; /* Event to service. */
- int flags; /* Flags that indicate what events to
- * handle, such as TCL_WINDOW_EVENTS. */
+WindowEventProc(
+ Tcl_Event *evPtr, /* Event to service. */
+ int flags) /* Flags that indicate what events to handle,
+ * such as TCL_WINDOW_EVENTS. */
{
TkWindowEvent *wevPtr = (TkWindowEvent *) evPtr;
Tk_RestrictAction result;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (!(flags & TCL_WINDOW_EVENTS)) {
return 0;
@@ -1436,68 +1752,398 @@ WindowEventProc(evPtr, flags)
* TK_DELETE_EVENT: return and say we processed the event,
* even though we didn't do anything at all.
*/
+
+ CleanUpTkEvent(&wevPtr->event);
return 1;
}
}
}
Tk_HandleEvent(&wevPtr->event);
+ CleanUpTkEvent(&wevPtr->event);
return 1;
}
/*
*----------------------------------------------------------------------
*
+ * CleanUpTkEvent --
+ *
+ * This function is called to remove and deallocate any information in
+ * the event which is not directly in the event structure itself. It may
+ * be called multiple times per event, so it takes care to set the
+ * cleared pointer fields to NULL afterwards.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Makes the event no longer have any external resources.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+CleanUpTkEvent(
+ XEvent *eventPtr)
+{
+ switch (eventPtr->type) {
+ case KeyPress:
+ case KeyRelease: {
+ TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr;
+
+ if (kePtr->charValuePtr != NULL) {
+ ckfree(kePtr->charValuePtr);
+ kePtr->charValuePtr = NULL;
+ kePtr->charValueLen = 0;
+ }
+ break;
+ }
+
+ case VirtualEvent: {
+ XVirtualEvent *vePtr = (XVirtualEvent *) eventPtr;
+
+ if (vePtr->user_data != NULL) {
+ Tcl_DecrRefCount(vePtr->user_data);
+ vePtr->user_data = NULL;
+ }
+ break;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* DelayedMotionProc --
*
- * This procedure is invoked as an idle handler when a mouse motion
- * event has been delayed. It queues the delayed event so that it
- * will finally be serviced.
+ * This function is invoked as an idle handler when a mouse motion event
+ * has been delayed. It queues the delayed event so that it will finally
+ * be serviced.
*
* Results:
* None.
*
* Side effects:
- * The delayed mouse motion event gets added to the Tcl event
- * queue for servicing.
+ * The delayed mouse motion event gets added to the Tcl event queue for
+ * servicing.
*
*----------------------------------------------------------------------
*/
static void
-DelayedMotionProc(clientData)
- ClientData clientData; /* Pointer to display containing a delayed
+DelayedMotionProc(
+ ClientData clientData) /* Pointer to display containing a delayed
* motion event to be serviced. */
{
TkDisplay *dispPtr = (TkDisplay *) clientData;
if (dispPtr->delayedMotionPtr == NULL) {
- panic("DelayedMotionProc found no delayed mouse motion event");
+ Tcl_Panic("DelayedMotionProc found no delayed mouse motion event");
}
Tcl_QueueEvent(&dispPtr->delayedMotionPtr->header, TCL_QUEUE_TAIL);
dispPtr->delayedMotionPtr = NULL;
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
+ *
+ * TkCreateExitHandler --
+ *
+ * Same as Tcl_CreateExitHandler, but private to Tk.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects.
+ * Sets a handler with Tcl_CreateExitHandler if this is the first call.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkCreateExitHandler(
+ Tcl_ExitProc *proc, /* Function to invoke. */
+ ClientData clientData) /* Arbitrary value to pass to proc. */
+{
+ ExitHandler *exitPtr;
+
+ exitPtr = (ExitHandler *) ckalloc(sizeof(ExitHandler));
+ exitPtr->proc = proc;
+ exitPtr->clientData = clientData;
+ Tcl_MutexLock(&exitMutex);
+
+ /*
+ * The call to TclInExit() is disabled here. That's a private Tcl routine,
+ * and calling it is causing some trouble with portability of building Tk.
+ * We should avoid private Tcl routines generally.
+ *
+ * In this case, the TclInExit() call is being used only to prevent a
+ * Tcl_CreateExitHandler() call when Tcl finalization is in progress.
+ * That's a situation that shouldn't happen anyway. Recent changes within
+ * Tcl_Finalize now cause a Tcl_Panic() to happen if exit handlers get
+ * added after exit handling is complete. By disabling the guard here,
+ * that panic will serve to help us find the buggy conditions and correct
+ * them.
+ *
+ * We can restore this guard if we find we must (hopefully getting public
+ * access to TclInExit() if we discover extensions really do need this),
+ * but during alpha development, this is a good time to dig in and find
+ * the root causes of finalization bugs.
+ */
+
+ if (firstExitPtr == NULL/* && !TclInExit()*/) {
+ Tcl_CreateExitHandler(TkFinalize, NULL);
+ }
+ exitPtr->nextPtr = firstExitPtr;
+ firstExitPtr = exitPtr;
+ Tcl_MutexUnlock(&exitMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkDeleteExitHandler --
+ *
+ * Same as Tcl_DeleteExitHandler, but private to Tk.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects.
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkDeleteExitHandler(
+ Tcl_ExitProc *proc, /* Function that was previously registered. */
+ ClientData clientData) /* Arbitrary value to pass to proc. */
+{
+ ExitHandler *exitPtr, *prevPtr;
+
+ Tcl_MutexLock(&exitMutex);
+ for (prevPtr = NULL, exitPtr = firstExitPtr; exitPtr != NULL;
+ prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
+ if ((exitPtr->proc == proc)
+ && (exitPtr->clientData == clientData)) {
+ if (prevPtr == NULL) {
+ firstExitPtr = exitPtr->nextPtr;
+ } else {
+ prevPtr->nextPtr = exitPtr->nextPtr;
+ }
+ ckfree((char *) exitPtr);
+ break;
+ }
+ }
+ Tcl_MutexUnlock(&exitMutex);
+ return;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkCreateThreadExitHandler --
+ *
+ * Same as Tcl_CreateThreadExitHandler, but private to Tk.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Proc will be invoked with clientData as argument when the application
+ * exits.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkCreateThreadExitHandler(
+ Tcl_ExitProc *proc, /* Function to invoke. */
+ ClientData clientData) /* Arbitrary value to pass to proc. */
+{
+ ExitHandler *exitPtr;
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+ exitPtr = (ExitHandler *) ckalloc(sizeof(ExitHandler));
+ exitPtr->proc = proc;
+ exitPtr->clientData = clientData;
+
+ /*
+ * See comments in TkCreateExitHandler().
+ */
+
+ if (tsdPtr->firstExitPtr == NULL/* && !TclInExit()*/) {
+ Tcl_CreateThreadExitHandler(TkFinalizeThread, NULL);
+ }
+ exitPtr->nextPtr = tsdPtr->firstExitPtr;
+ tsdPtr->firstExitPtr = exitPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkDeleteThreadExitHandler --
+ *
+ * Same as Tcl_DeleteThreadExitHandler, but private to Tk.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * If there is an exit handler corresponding to proc and clientData then
+ * it is cancelled; if no such handler exists then nothing happens.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkDeleteThreadExitHandler(
+ Tcl_ExitProc *proc, /* Function that was previously registered. */
+ ClientData clientData) /* Arbitrary value to pass to proc. */
+{
+ ExitHandler *exitPtr, *prevPtr;
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+ for (prevPtr = NULL, exitPtr = tsdPtr->firstExitPtr; exitPtr != NULL;
+ prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
+ if ((exitPtr->proc == proc)
+ && (exitPtr->clientData == clientData)) {
+ if (prevPtr == NULL) {
+ tsdPtr->firstExitPtr = exitPtr->nextPtr;
+ } else {
+ prevPtr->nextPtr = exitPtr->nextPtr;
+ }
+ ckfree((char *) exitPtr);
+ return;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkFinalize --
+ *
+ * Runs our private exit handlers and removes itself from Tcl. This is
+ * benificial should we want to protect from dangling pointers should the
+ * Tk shared library be unloaded prior to Tcl which can happen on windows
+ * should the process be forcefully exiting from an exception handler.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects.
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkFinalize(
+ ClientData clientData) /* Arbitrary value to pass to proc. */
+{
+ ExitHandler *exitPtr;
+
+ Tcl_DeleteExitHandler(TkFinalize, NULL);
+
+ Tcl_MutexLock(&exitMutex);
+ for (exitPtr = firstExitPtr; exitPtr != NULL; exitPtr = firstExitPtr) {
+ /*
+ * Be careful to remove the handler from the list before invoking its
+ * callback. This protects us against double-freeing if the callback
+ * should call TkDeleteExitHandler on itself.
+ */
+
+ firstExitPtr = exitPtr->nextPtr;
+ Tcl_MutexUnlock(&exitMutex);
+ (*exitPtr->proc)(exitPtr->clientData);
+ ckfree((char *) exitPtr);
+ Tcl_MutexLock(&exitMutex);
+ }
+ firstExitPtr = NULL;
+ Tcl_MutexUnlock(&exitMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkFinalizeThread --
+ *
+ * Runs our private thread exit handlers and removes itself from Tcl.
+ * This is benificial should we want to protect from dangling pointers
+ * should the Tk shared library be unloaded prior to Tcl which can happen
+ * on Windows should the process be forcefully exiting from an exception
+ * handler.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects.
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkFinalizeThread(
+ ClientData clientData) /* Arbitrary value to pass to proc. */
+{
+ ExitHandler *exitPtr;
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+ Tcl_DeleteThreadExitHandler(TkFinalizeThread, NULL);
+
+ if (tsdPtr != NULL) {
+ tsdPtr->inExit = 1;
+
+ for (exitPtr = tsdPtr->firstExitPtr; exitPtr != NULL;
+ exitPtr = tsdPtr->firstExitPtr) {
+ /*
+ * Be careful to remove the handler from the list before invoking
+ * its callback. This protects us against double-freeing if the
+ * callback should call TkDeleteThreadExitHandler on itself.
+ */
+
+ tsdPtr->firstExitPtr = exitPtr->nextPtr;
+ (*exitPtr->proc)(exitPtr->clientData);
+ ckfree((char *) exitPtr);
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
*
* Tk_MainLoop --
*
- * Call Tcl_DoOneEvent over and over again in an infinite
- * loop as long as there exist any main windows.
+ * Call Tcl_DoOneEvent over and over again in an infinite loop as long as
+ * there exist any main windows.
*
* Results:
* None.
*
* Side effects:
- * Arbitrary; depends on handlers for events.
+ * Arbitrary; depends on handlers for events.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
void
-Tk_MainLoop()
+Tk_MainLoop(void)
{
while (Tk_GetNumMainWindows() > 0) {
Tcl_DoOneEvent(0);
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkFileFilter.c b/generic/tkFileFilter.c
index 3fa8303..547dd9b 100644
--- a/generic/tkFileFilter.c
+++ b/generic/tkFileFilter.c
@@ -6,33 +6,29 @@
*
* Copyright (c) 1996 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
#include "tkFileFilter.h"
-static int AddClause _ANSI_ARGS_((
- Tcl_Interp * interp, FileFilter * filterPtr,
- CONST char * patternsStr, CONST char * ostypesStr,
- int isWindows));
-static void FreeClauses _ANSI_ARGS_((FileFilter * filterPtr));
-static void FreeGlobPatterns _ANSI_ARGS_((
- FileFilterClause * clausePtr));
-static void FreeMacFileTypes _ANSI_ARGS_((
- FileFilterClause * clausePtr));
-static FileFilter * GetFilter _ANSI_ARGS_((FileFilterList * flistPtr,
- CONST char * name));
+static int AddClause(Tcl_Interp *interp,
+ FileFilter *filterPtr, Tcl_Obj *patternsObj,
+ Tcl_Obj *ostypesObj, int isWindows);
+static void FreeClauses(FileFilter *filterPtr);
+static void FreeGlobPatterns(FileFilterClause *clausePtr);
+static void FreeMacFileTypes(FileFilterClause *clausePtr);
+static FileFilter * GetFilter(FileFilterList *flistPtr, CONST char *name);
/*
*----------------------------------------------------------------------
*
* TkInitFileFilters --
*
- * Initializes a FileFilterList data structure. A FileFilterList
- * must be initialized EXACTLY ONCE before any calls to
- * TkGetFileFilters() is made. The usual flow of control is:
+ * Initializes a FileFilterList data structure. A FileFilterList must be
+ * initialized EXACTLY ONCE before any calls to TkGetFileFilters() is
+ * made. The usual flow of control is:
* TkInitFileFilters(&flist);
* TkGetFileFilters(&flist, ...);
* TkGetFileFilters(&flist, ...);
@@ -44,12 +40,13 @@ static FileFilter * GetFilter _ANSI_ARGS_((FileFilterList * flistPtr,
*
* Side effects:
* The fields in flistPtr are initialized.
+ *
*----------------------------------------------------------------------
*/
void
-TkInitFileFilters(flistPtr)
- FileFilterList * flistPtr; /* The structure to be initialized. */
+TkInitFileFilters(
+ FileFilterList *flistPtr) /* The structure to be initialized. */
{
flistPtr->filters = NULL;
flistPtr->filtersTail = NULL;
@@ -61,11 +58,11 @@ TkInitFileFilters(flistPtr)
*
* TkGetFileFilters --
*
- * This function is called by the Mac and Windows implementation
- * of tk_getOpenFile and tk_getSaveFile to translate the string
- * value of the -filetypes option of into an easy-to-parse C
- * structure (flistPtr). The caller of this function will then use
- * flistPtr to perform filetype matching in a platform specific way.
+ * This function is called by the Mac and Windows implementation of
+ * tk_getOpenFile and tk_getSaveFile to translate the string value of the
+ * -filetypes option into an easy-to-parse C structure (flistPtr). The
+ * caller of this function will then use flistPtr to perform filetype
+ * matching in a platform specific way.
*
* flistPtr must be initialized (See comments in TkInitFileFilters).
*
@@ -73,85 +70,74 @@ TkInitFileFilters(flistPtr)
* A standard TCL return value.
*
* Side effects:
- * The fields in flistPtr are changed according to string.
+ * The fields in flistPtr are changed according to 'types'.
+ *
*----------------------------------------------------------------------
*/
+
int
-TkGetFileFilters(interp, flistPtr, string, isWindows)
- Tcl_Interp *interp; /* Interpreter to use for error reporting. */
- FileFilterList * flistPtr; /* Stores the list of file filters. */
- char * string; /* Value of the -filetypes option. */
- int isWindows; /* True if we are running on Windows. */
+TkGetFileFilters(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ FileFilterList *flistPtr, /* Stores the list of file filters. */
+ Tcl_Obj *types, /* Value of the -filetypes option. */
+ int isWindows) /* True if we are running on Windows. */
{
- int listArgc;
- CONST char ** listArgv = NULL;
- CONST char ** typeInfo = NULL;
- int code = TCL_OK;
+ int listObjc;
+ Tcl_Obj ** listObjv = NULL;
int i;
- if (Tcl_SplitList(interp, string, &listArgc, &listArgv) != TCL_OK) {
+ if (types == NULL) {
+ return TCL_OK;
+ }
+
+ if (Tcl_ListObjGetElements(interp, types, &listObjc,
+ &listObjv) != TCL_OK) {
return TCL_ERROR;
}
- if (listArgc == 0) {
- goto done;
+ if (listObjc == 0) {
+ return TCL_OK;
}
/*
- * Free the filter information that have been allocated the previous
- * time -- the -filefilters option may have been used more than once in
- * the command line.
+ * Free the filter information that have been allocated the previous time;
+ * the -filefilters option may have been used more than once in the
+ * command line.
*/
TkFreeFileFilters(flistPtr);
- for (i = 0; i<listArgc; i++) {
+ for (i = 0; i<listObjc; i++) {
/*
- * Each file type should have two or three elements: the first one
- * is the name of the type and the second is the filter of the type.
- * The third is the Mac OSType ID, but we don't care about them here.
+ * Each file type should have two or three elements: the first one is
+ * the name of the type and the second is the filter of the type. The
+ * third is the Mac OSType ID, but we don't care about them here.
*/
+
int count;
- FileFilter * filterPtr;
+ FileFilter *filterPtr;
+ Tcl_Obj **typeInfo;
- if (Tcl_SplitList(interp, listArgv[i], &count, &typeInfo) != TCL_OK) {
- code = TCL_ERROR;
- goto done;
+ if (Tcl_ListObjGetElements(interp, listObjv[i], &count,
+ &typeInfo) != TCL_OK) {
+ return TCL_ERROR;
}
-
+
if (count != 2 && count != 3) {
- Tcl_AppendResult(interp, "bad file type \"", listArgv[i], "\", ",
- "should be \"typeName {extension ?extensions ...?} ",
- "?{macType ?macTypes ...?}?\"", NULL);
- code = TCL_ERROR;
- goto done;
+ Tcl_AppendResult(interp, "bad file type \"",
+ Tcl_GetString(listObjv[i]), "\", ",
+ "should be \"typeName {extension ?extensions ...?} ",
+ "?{macType ?macTypes ...?}?\"", NULL);
+ return TCL_ERROR;
}
- filterPtr = GetFilter(flistPtr, typeInfo[0]);
-
- if (count == 2) {
- code = AddClause(interp, filterPtr, typeInfo[1], NULL,
- isWindows);
- } else {
- code = AddClause(interp, filterPtr, typeInfo[1], typeInfo[2],
- isWindows);
- }
- if (code != TCL_OK) {
- goto done;
- }
+ filterPtr = GetFilter(flistPtr, Tcl_GetString(typeInfo[0]));
- if (typeInfo) {
- ckfree((char*)typeInfo);
+ if (AddClause(interp, filterPtr, typeInfo[1],
+ (count==2 ? NULL : typeInfo[2]), isWindows) != TCL_OK) {
+ return TCL_ERROR;
}
- typeInfo = NULL;
}
- done:
- if (typeInfo) {
- ckfree((char*)typeInfo);
- }
- if (listArgv) {
- ckfree((char*)listArgv);
- }
- return code;
+ return TCL_OK;
}
/*
@@ -166,19 +152,20 @@ TkGetFileFilters(interp, flistPtr, string, isWindows)
*
* Side effects:
* The fields allocated by TkGetFileFilters() are freed.
+ *
*----------------------------------------------------------------------
*/
void
-TkFreeFileFilters(flistPtr)
- FileFilterList * flistPtr; /* List of file filters to free */
+TkFreeFileFilters(
+ FileFilterList *flistPtr) /* List of file filters to free */
{
- FileFilter * filterPtr, *toFree;
+ FileFilter *filterPtr, *toFree;
filterPtr=flistPtr->filters;
- while (filterPtr) {
+ while (filterPtr != NULL) {
toFree = filterPtr;
- filterPtr=filterPtr->next;
+ filterPtr = filterPtr->next;
FreeClauses(toFree);
ckfree((char*)toFree->name);
ckfree((char*)toFree);
@@ -198,41 +185,82 @@ TkFreeFileFilters(flistPtr)
*
* Side effects:
* The list of filter clauses are updated in filterPtr.
+ *
*----------------------------------------------------------------------
*/
-static int AddClause(interp, filterPtr, patternsStr, ostypesStr, isWindows)
- Tcl_Interp * interp; /* Interpreter to use for error reporting. */
- FileFilter * filterPtr; /* Stores the new filter clause */
- CONST char * patternsStr; /* A TCL list of glob patterns. */
- CONST char * ostypesStr; /* A TCL list of Mac OSType strings. */
- int isWindows; /* True if we are running on Windows; False
- * if we are running on the Mac; Glob
- * patterns need to be processed differently
- * on these two platforms */
+static int
+AddClause(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ FileFilter *filterPtr, /* Stores the new filter clause */
+ Tcl_Obj *patternsObj, /* A Tcl list of glob patterns. */
+ Tcl_Obj *ostypesObj, /* A Tcl list of Mac OSType strings. */
+ int isWindows) /* True if we are running on Windows; False if
+ * we are running on the Mac; Glob patterns
+ * need to be processed differently on these
+ * two platforms */
{
- CONST char ** globList = NULL;
- int globCount;
- CONST char ** ostypeList = NULL;
- int ostypeCount;
- FileFilterClause * clausePtr;
- int i;
- int code = TCL_OK;
+ Tcl_Obj **globList = NULL, **ostypeList = NULL;
+ int globCount, ostypeCount, i, code = TCL_OK;
+ FileFilterClause *clausePtr;
+ Tcl_Encoding macRoman = NULL;
- if (Tcl_SplitList(interp, patternsStr, &globCount, &globList)!= TCL_OK) {
+ if (Tcl_ListObjGetElements(interp, patternsObj,
+ &globCount, &globList) != TCL_OK) {
code = TCL_ERROR;
goto done;
}
- if (ostypesStr != NULL) {
- if (Tcl_SplitList(interp, ostypesStr, &ostypeCount, &ostypeList)
- != TCL_OK) {
+ if (ostypesObj != NULL) {
+ if (Tcl_ListObjGetElements(interp, ostypesObj,
+ &ostypeCount, &ostypeList) != TCL_OK) {
code = TCL_ERROR;
goto done;
}
+
+ /*
+ * We probably need this encoding now...
+ */
+
+ macRoman = Tcl_GetEncoding(NULL, "macRoman");
+
+ /*
+ * Might be cleaner to use 'Tcl_GetOSTypeFromObj' but that is actually
+ * static to the MacOS X/Darwin version of Tcl, and would therefore
+ * require further code refactoring.
+ */
+
for (i=0; i<ostypeCount; i++) {
- if (strlen(ostypeList[i]) != 4) {
+ int len;
+ CONST char *strType = Tcl_GetStringFromObj(ostypeList[i], &len);
+
+ /*
+ * If len is < 4, it is definitely an error. If equal or longer,
+ * we need to use the macRoman encoding to determine the correct
+ * length (assuming there may be non-ascii characters, e.g.,
+ * embedded nulls or accented characters in the string, the
+ * macRoman length will be different).
+ *
+ * If we couldn't load the encoding, then we can't actually check
+ * the correct length. But here we assume we're probably operating
+ * on unix/windows with a minimal set of encodings and so don't
+ * care about MacOS types. So we won't signal an error.
+ */
+
+ if (len >= 4 && macRoman != NULL) {
+ Tcl_DString osTypeDS;
+
+ /*
+ * Convert utf to macRoman, since MacOS types are defined to
+ * be 4 macRoman characters long
+ */
+
+ Tcl_UtfToExternalDString(macRoman, strType, len, &osTypeDS);
+ len = Tcl_DStringLength(&osTypeDS);
+ Tcl_DStringFree(&osTypeDS);
+ }
+ if (len != 4) {
Tcl_AppendResult(interp, "bad Macintosh file type \"",
- ostypeList[i], "\"", NULL);
+ Tcl_GetString(ostypeList[i]), "\"", NULL);
code = TCL_ERROR;
goto done;
}
@@ -240,7 +268,7 @@ static int AddClause(interp, filterPtr, patternsStr, ostypesStr, isWindows)
}
/*
- * Add the clause into the list of clauses
+ * Add the clause into the list of clauses
*/
clausePtr = (FileFilterClause*)ckalloc(sizeof(FileFilterClause));
@@ -259,40 +287,40 @@ static int AddClause(interp, filterPtr, patternsStr, ostypesStr, isWindows)
if (globCount > 0 && globList != NULL) {
for (i=0; i<globCount; i++) {
- GlobPattern * globPtr = (GlobPattern*)ckalloc(sizeof(GlobPattern));
+ GlobPattern *globPtr = (GlobPattern*)ckalloc(sizeof(GlobPattern));
int len;
-
- len = (strlen(globList[i]) + 1) * sizeof(char);
- if (globList[i][0] && globList[i][0] != '*') {
+ CONST char *str = Tcl_GetStringFromObj(globList[i], &len);
+ len = (len + 1) * sizeof(char);
+
+ if (str[0] && str[0] != '*') {
/*
* Prepend a "*" to patterns that do not have a leading "*"
*/
+
globPtr->pattern = (char*)ckalloc((unsigned int) len+1);
globPtr->pattern[0] = '*';
- strcpy(globPtr->pattern+1, globList[i]);
- }
- else if (isWindows) {
- if (strcmp(globList[i], "*") == 0) {
- globPtr->pattern = (char*)ckalloc(4*sizeof(char));
+ strcpy(globPtr->pattern+1, str);
+ } else if (isWindows) {
+ if (strcmp(str, "*") == 0) {
+ globPtr->pattern = (char*)ckalloc(4 * sizeof(char));
strcpy(globPtr->pattern, "*.*");
- }
- else if (strcmp(globList[i], "") == 0) {
+ } else if (strcmp(str, "") == 0) {
/*
* An empty string means "match all files with no
* extensions"
* BUG: "*." actually matches with all files on Win95
*/
- globPtr->pattern = (char*)ckalloc(3*sizeof(char));
+
+ globPtr->pattern = (char *) ckalloc(3 * sizeof(char));
strcpy(globPtr->pattern, "*.");
- }
- else {
- globPtr->pattern = (char*)ckalloc((unsigned int) len);
- strcpy(globPtr->pattern, globList[i]);
+ } else {
+ globPtr->pattern = (char *) ckalloc((unsigned int) len);
+ strcpy(globPtr->pattern, str);
}
} else {
- globPtr->pattern = (char*)ckalloc((unsigned int) len);
- strcpy(globPtr->pattern, globList[i]);
+ globPtr->pattern = (char *) ckalloc((unsigned int) len);
+ strcpy(globPtr->pattern, str);
}
/*
@@ -308,13 +336,27 @@ static int AddClause(interp, filterPtr, patternsStr, ostypesStr, isWindows)
globPtr->next = NULL;
}
}
- if (ostypeCount > 0 && ostypeList != NULL) {
+ if (ostypeList != NULL && ostypeCount > 0) {
+ if (macRoman == NULL) {
+ macRoman = Tcl_GetEncoding(NULL, "macRoman");
+ }
for (i=0; i<ostypeCount; i++) {
- MacFileType * mfPtr = (MacFileType*)ckalloc(sizeof(MacFileType));
- CONST char *string = ostypeList[i];
+ Tcl_DString osTypeDS;
+ int len;
+ MacFileType *mfPtr = (MacFileType *) ckalloc(sizeof(MacFileType));
+ CONST char *strType = Tcl_GetStringFromObj(ostypeList[i], &len);
+ char *string;
+ /*
+ * Convert utf to macRoman, since MacOS types are defined to be 4
+ * macRoman characters long
+ */
+
+ Tcl_UtfToExternalDString(macRoman, strType, len, &osTypeDS);
+ string = Tcl_DStringValue(&osTypeDS);
mfPtr->type = (OSType) string[0] << 24 | (OSType) string[1] << 16 |
(OSType) string[2] << 8 | (OSType) string[3];
+ Tcl_DStringFree(&osTypeDS);
/*
* Add the Mac type pattern into the list of Mac types
@@ -331,15 +373,11 @@ static int AddClause(interp, filterPtr, patternsStr, ostypesStr, isWindows)
}
done:
- if (globList) {
- ckfree((char*)globList);
+ if (macRoman != NULL) {
+ Tcl_FreeEncoding(macRoman);
}
- if (ostypeList) {
- ckfree((char*)ostypeList);
- }
-
return code;
-}
+}
/*
*----------------------------------------------------------------------
@@ -353,28 +391,30 @@ static int AddClause(interp, filterPtr, patternsStr, ostypesStr, isWindows)
*
* Side effects:
* The list of filters are updated in flistPtr.
+ *
*----------------------------------------------------------------------
*/
-static FileFilter * GetFilter(flistPtr, name)
- FileFilterList * flistPtr; /* The FileFilterList that contains the
- * newly created filter */
- CONST char * name; /* Name of the filter. It is usually displayed
+static FileFilter *
+GetFilter(
+ FileFilterList *flistPtr, /* The FileFilterList that contains the newly
+ * created filter */
+ CONST char *name) /* Name of the filter. It is usually displayed
* in the "File Types" listbox in the file
* dialogs. */
{
- FileFilter * filterPtr;
+ FileFilter *filterPtr = flistPtr->filters;
- for (filterPtr=flistPtr->filters; filterPtr; filterPtr=filterPtr->next) {
- if (strcmp(filterPtr->name, name)==0) {
+ for (; filterPtr; filterPtr=filterPtr->next) {
+ if (strcmp(filterPtr->name, name) == 0) {
return filterPtr;
}
}
- filterPtr = (FileFilter*)ckalloc(sizeof(FileFilter));
+ filterPtr = (FileFilter *) ckalloc(sizeof(FileFilter));
filterPtr->clauses = NULL;
filterPtr->clausesTail = NULL;
- filterPtr->name = (char*)ckalloc((strlen(name)+1) * sizeof(char));
+ filterPtr->name = (char *) ckalloc((strlen(name)+1) * sizeof(char));
strcpy(filterPtr->name, name);
if (flistPtr->filters == NULL) {
@@ -401,22 +441,23 @@ static FileFilter * GetFilter(flistPtr, name)
*
* Side effects:
* The list of clauses in filterPtr->clauses are freed.
+ *
*----------------------------------------------------------------------
*/
static void
-FreeClauses(filterPtr)
- FileFilter * filterPtr; /* FileFilter whose clauses are to be freed */
+FreeClauses(
+ FileFilter *filterPtr) /* FileFilter whose clauses are to be freed */
{
- FileFilterClause * clausePtr, * toFree;
+ FileFilterClause *clausePtr = filterPtr->clauses;
+
+ while (clausePtr != NULL) {
+ FileFilterClause *toFree = clausePtr;
+ clausePtr = clausePtr->next;
- clausePtr = filterPtr->clauses;
- while (clausePtr) {
- toFree = clausePtr;
- clausePtr=clausePtr->next;
FreeGlobPatterns(toFree);
FreeMacFileTypes(toFree);
- ckfree((char*)toFree);
+ ckfree((char *) toFree);
}
filterPtr->clauses = NULL;
filterPtr->clausesTail = NULL;
@@ -434,22 +475,22 @@ FreeClauses(filterPtr)
*
* Side effects:
* The list of glob patterns in clausePtr->patterns are freed.
+ *
*----------------------------------------------------------------------
*/
static void
-FreeGlobPatterns(clausePtr)
- FileFilterClause * clausePtr;/* The clause whose patterns are to be freed*/
+FreeGlobPatterns(
+ FileFilterClause *clausePtr)/* The clause whose patterns are to be freed*/
{
- GlobPattern * globPtr, * toFree;
+ GlobPattern *globPtr = clausePtr->patterns;
- globPtr = clausePtr->patterns;
- while (globPtr) {
- toFree = globPtr;
- globPtr=globPtr->next;
+ while (globPtr != NULL) {
+ GlobPattern *toFree = globPtr;
+ globPtr = globPtr->next;
- ckfree((char*)toFree->pattern);
- ckfree((char*)toFree);
+ ckfree((char *) toFree->pattern);
+ ckfree((char *) toFree);
}
clausePtr->patterns = NULL;
}
@@ -466,21 +507,29 @@ FreeGlobPatterns(clausePtr)
*
* Side effects:
* The list of Mac file types in clausePtr->macTypes are freed.
+ *
*----------------------------------------------------------------------
*/
static void
-FreeMacFileTypes(clausePtr)
- FileFilterClause * clausePtr; /* The clause whose mac types are to be
- * freed */
+FreeMacFileTypes(
+ FileFilterClause *clausePtr)/* The clause whose mac types are to be
+ * freed */
{
- MacFileType * mfPtr, * toFree;
+ MacFileType *mfPtr = clausePtr->macTypes;
- mfPtr = clausePtr->macTypes;
- while (mfPtr) {
- toFree = mfPtr;
- mfPtr=mfPtr->next;
- ckfree((char*)toFree);
+ while (mfPtr != NULL) {
+ MacFileType *toFree = mfPtr;
+ mfPtr = mfPtr->next;
+ ckfree((char *) toFree);
}
clausePtr->macTypes = NULL;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkFileFilter.h b/generic/tkFileFilter.h
index 6df986f..24002df 100644
--- a/generic/tkFileFilter.h
+++ b/generic/tkFileFilter.h
@@ -1,13 +1,13 @@
/*
* tkFileFilter.h --
*
- * Declarations for the file filter processing routines needed by
- * the file selection dialogs.
+ * Declarations for the file filter processing routines needed by the
+ * file selection dialogs.
*
* Copyright (c) 1996 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TK_FILE_FILTER
@@ -21,65 +21,65 @@
#endif
typedef struct GlobPattern {
- struct GlobPattern * next; /* Chains to the next glob pattern
- * in a glob pattern list */
- char * pattern; /* String value of the pattern, such
- * as "*.txt" or "*.*"
- */
+ struct GlobPattern *next; /* Chains to the next glob pattern in a glob
+ * pattern list */
+ char *pattern; /* String value of the pattern, such as
+ * "*.txt" or "*.*" */
} GlobPattern;
typedef struct MacFileType {
- struct MacFileType * next; /* Chains to the next mac file type
- * in a mac file type list */
- OSType type; /* Mac file type, such as 'TEXT' or
- * 'GIFF' */
+ struct MacFileType *next; /* Chains to the next mac file type in a mac
+ * file type list */
+ OSType type; /* Mac file type, such as 'TEXT' or 'GIFF' */
} MacFileType;
typedef struct FileFilterClause {
- struct FileFilterClause * next; /* Chains to the next clause in
- * a clause list */
- GlobPattern * patterns; /* Head of glob pattern type list */
- GlobPattern * patternsTail; /* Tail of glob pattern type list */
- MacFileType * macTypes; /* Head of mac file type list */
- MacFileType * macTypesTail; /* Tail of mac file type list */
+ struct FileFilterClause *next;
+ /* Chains to the next clause in a clause
+ * list */
+ GlobPattern *patterns; /* Head of glob pattern type list */
+ GlobPattern *patternsTail; /* Tail of glob pattern type list */
+ MacFileType *macTypes; /* Head of mac file type list */
+ MacFileType *macTypesTail; /* Tail of mac file type list */
} FileFilterClause;
typedef struct FileFilter {
- struct FileFilter * next; /* Chains to the next filter
- * in a filter list */
- char * name; /* Name of the file filter,
- * such as "Text Documents" */
- FileFilterClause * clauses; /* Head of the clauses list */
- FileFilterClause * clausesTail; /* Tail of the clauses list */
+ struct FileFilter *next; /* Chains to the next filter in a filter
+ * list */
+ char *name; /* Name of the file filter, such as "Text
+ * Documents" */
+ FileFilterClause *clauses; /* Head of the clauses list */
+ FileFilterClause *clausesTail;
+ /* Tail of the clauses list */
} FileFilter;
-/*----------------------------------------------------------------------
+/*
+ *----------------------------------------------------------------------
+ *
* FileFilterList --
*
- * The routine TkGetFileFilters() translates the string value of the
- * -filefilters option into a FileFilterList structure, which consists
- * of a list of file filters.
+ * The routine TkGetFileFilters() translates the string value of the
+ * -filefilters option into a FileFilterList structure, which consists of
+ * a list of file filters.
+ *
+ * Each file filter consists of one or more clauses. Each clause has one
+ * or more glob patterns and/or one or more Mac file types
*
- * Each file filter consists of one or more clauses. Each clause has
- * one or more glob patterns and/or one or more Mac file types
*----------------------------------------------------------------------
*/
typedef struct FileFilterList {
- FileFilter * filters; /* Head of the filter list */
- FileFilter * filtersTail; /* Tail of the filter list */
- int numFilters; /* number of filters in the list */
+ FileFilter *filters; /* Head of the filter list */
+ FileFilter *filtersTail; /* Tail of the filter list */
+ int numFilters; /* number of filters in the list */
} FileFilterList;
-EXTERN void TkFreeFileFilters _ANSI_ARGS_((
- FileFilterList * flistPtr));
-EXTERN void TkInitFileFilters _ANSI_ARGS_((
- FileFilterList * flistPtr));
-EXTERN int TkGetFileFilters _ANSI_ARGS_ ((Tcl_Interp *interp,
- FileFilterList * flistPtr, char * string,
- int isWindows));
+MODULE_SCOPE void TkFreeFileFilters(FileFilterList *flistPtr);
+MODULE_SCOPE void TkInitFileFilters(FileFilterList *flistPtr);
+MODULE_SCOPE int TkGetFileFilters(Tcl_Interp *interp,
+ FileFilterList *flistPtr, Tcl_Obj *valuePtr,
+ int isWindows);
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLIMPORT
-
#endif
diff --git a/generic/tkFocus.c b/generic/tkFocus.c
index 93e1617..85093ee 100644
--- a/generic/tkFocus.c
+++ b/generic/tkFocus.c
@@ -1,23 +1,20 @@
-/*
+/*
* tkFocus.c --
*
- * This file contains procedures that manage the input
- * focus for Tk.
+ * This file contains functions that manage the input focus for Tk.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
-#include "tkPort.h"
-
/*
- * For each top-level window that has ever received the focus, there
- * is a record of the following type:
+ * For each top-level window that has ever received the focus, there is a
+ * record of the following type:
*/
typedef struct TkToplevelFocusInfo {
@@ -31,19 +28,17 @@ typedef struct TkToplevelFocusInfo {
} ToplevelFocusInfo;
/*
- * One of the following structures exists for each display used by
- * each application. These are linked together from the TkMainInfo
- * structure. These structures are needed because it isn't
- * sufficient to store a single piece of focus information in each
- * display or in each application: we need the cross-product.
- * There needs to be separate information for each display, because
- * it's possible to have multiple focus windows active simultaneously
- * on different displays. There also needs to be separate information
- * for each application, because of embedding: if an embedded
- * application has the focus, its container application also has
- * the focus. Thus we keep a list of structures for each application:
- * the same display can appear in structures for several applications
- * at once.
+ * One of the following structures exists for each display used by each
+ * application. These are linked together from the TkMainInfo structure.
+ * These structures are needed because it isn't sufficient to store a single
+ * piece of focus information in each display or in each application: we need
+ * the cross-product. There needs to be separate information for each display,
+ * because it's possible to have multiple focus windows active simultaneously
+ * on different displays. There also needs to be separate information for each
+ * application, because of embedding: if an embedded application has the
+ * focus, its container application also has the focus. Thus we keep a list of
+ * structures for each application: the same display can appear in structures
+ * for several applications at once.
*/
typedef struct TkDisplayFocusInfo {
@@ -58,49 +53,54 @@ typedef struct TkDisplayFocusInfo {
* supposed to receive the X input focus as
* soon as it is mapped (needed to handle the
* fact that X won't allow the focus on an
- * unmapped window). NULL means no delayed
+ * unmapped window). NULL means no delayed
* focus op in progress for this display. */
- int forceFocus; /* Associated with focusOnMapPtr: non-zero
+ int forceFocus; /* Associated with focusOnMapPtr: non-zero
* means claim the focus even if some other
* application currently has it. */
unsigned long focusSerial; /* Serial number of last request this
* application made to change the focus on
- * this display. Used to identify stale
- * focus notifications coming from the
- * X server. */
+ * this display. Used to identify stale focus
+ * notifications coming from the X server. */
struct TkDisplayFocusInfo *nextPtr;
- /* Next in list of all display focus
- * records for a given application. */
+ /* Next in list of all display focus records
+ * for a given application. */
} DisplayFocusInfo;
/*
- * 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
- * those that we generated.
+ * 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 those that we generated.
*/
-#define GENERATED_EVENT_MAGIC ((Bool) 0x547321ac)
+#define GENERATED_EVENT_MAGIC ((Bool) 0x547321ac)
/*
- * Forward declarations for procedures defined in this file:
+ * Debugging support...
*/
+#define DEBUG(dispPtr, arguments) \
+ if ((dispPtr)->focusDebug) { \
+ printf arguments; \
+ }
+
+/*
+ * Forward declarations for functions defined in this file:
+ */
-static DisplayFocusInfo *FindDisplayFocusInfo _ANSI_ARGS_((TkMainInfo *mainPtr,
- TkDisplay *dispPtr));
-static void FocusMapProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void GenerateFocusEvents _ANSI_ARGS_((TkWindow *sourcePtr,
- TkWindow *destPtr));
+static DisplayFocusInfo*FindDisplayFocusInfo(TkMainInfo *mainPtr,
+ TkDisplay *dispPtr);
+static void FocusMapProc(ClientData clientData, XEvent *eventPtr);
+static void GenerateFocusEvents(TkWindow *sourcePtr,
+ TkWindow *destPtr);
/*
*--------------------------------------------------------------
*
* Tk_FocusObjCmd --
*
- * This procedure is invoked to process the "focus" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "focus" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -112,15 +112,14 @@ static void GenerateFocusEvents _ANSI_ARGS_((TkWindow *sourcePtr,
*/
int
-Tk_FocusObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_FocusObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
static CONST char *focusOptions[] = {
- "-displayof", "-force", "-lastfor", (char *) NULL
+ "-displayof", "-force", "-lastfor", NULL
};
Tk_Window tkwin = (Tk_Window) clientData;
TkWindow *winPtr = (TkWindow *) clientData;
@@ -142,17 +141,17 @@ Tk_FocusObjCmd(clientData, interp, objc, objv)
}
/*
- * If invoked with a single argument beginning with "." then focus
- * on that window.
+ * If invoked with a single argument beginning with "." then focus on that
+ * window.
*/
if (objc == 2) {
- windowName = Tcl_GetStringFromObj(objv[1], NULL);
+ windowName = Tcl_GetString(objv[1]);
/*
* The empty string case exists for backwards compatibility.
*/
-
+
if (windowName[0] == '\0') {
return TCL_OK;
}
@@ -161,13 +160,15 @@ Tk_FocusObjCmd(clientData, interp, objc, objv)
if (newPtr == NULL) {
return TCL_ERROR;
}
- if (!(newPtr->flags & TK_ALREADY_DEAD)) {
- TkSetFocusWin(newPtr, 0);
- }
+ TkSetFocusWin(newPtr, 0);
return TCL_OK;
}
}
+ /*
+ * We have a subcommand to parse and act upon.
+ */
+
if (Tcl_GetIndexFromObj(interp, objv[1], focusOptions, "option", 0,
&index) != TCL_OK) {
return TCL_ERROR;
@@ -177,63 +178,58 @@ Tk_FocusObjCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
switch (index) {
- case 0: { /* -displayof */
- windowName = Tcl_GetStringFromObj(objv[2], 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;
+ case 0: /* -displayof */
+ windowName = Tcl_GetString(objv[2]);
+ 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);
}
- case 1: { /* -force */
- windowName = Tcl_GetStringFromObj(objv[2], NULL);
+ break;
+ case 1: /* -force */
+ windowName = Tcl_GetString(objv[2]);
- /*
- * 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;
- }
- TkSetFocusWin(newPtr, 1);
- break;
+ /*
+ * The empty string case exists for backwards compatibility.
+ */
+
+ if (windowName[0] == '\0') {
+ return TCL_OK;
}
- case 2: { /* -lastfor */
- windowName = Tcl_GetStringFromObj(objv[2], NULL);
- newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin);
- if (newPtr == NULL) {
- return TCL_ERROR;
+ newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin);
+ if (newPtr == NULL) {
+ return TCL_ERROR;
+ }
+ TkSetFocusWin(newPtr, 1);
+ break;
+ case 2: /* -lastfor */
+ windowName = Tcl_GetString(objv[2]);
+ 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_HIERARCHY)) {
+ continue;
}
- for (topLevelPtr = newPtr; topLevelPtr != NULL;
- topLevelPtr = topLevelPtr->parentPtr) {
- if (topLevelPtr->flags & TK_TOP_HIERARCHY) {
- 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);
+ 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;
}
}
- break;
- }
- default: {
- panic("bad const entries to focusOptions in focus command");
+ Tcl_SetResult(interp, topLevelPtr->pathName, TCL_STATIC);
+ return TCL_OK;
}
+ break;
+ default:
+ Tcl_Panic("bad const entries to focusOptions in focus command");
}
return TCL_OK;
}
@@ -243,13 +239,13 @@ Tk_FocusObjCmd(clientData, interp, objc, objv)
*
* TkFocusFilterEvent --
*
- * This procedure is invoked by Tk_HandleEvent when it encounters
- * a FocusIn, FocusOut, Enter, or Leave event.
+ * This function is invoked by Tk_HandleEvent when it encounters a
+ * FocusIn, FocusOut, Enter, or Leave event.
*
* Results:
- * A return value of 1 means that Tk_HandleEvent should process
- * the event normally (i.e. event handlers should be invoked).
- * A return value of 0 means that this event should be ignored.
+ * A return value of 1 means that Tk_HandleEvent should process the event
+ * normally (i.e. event handlers should be invoked). A return value of 0
+ * means that this event should be ignored.
*
* Side effects:
* Additional events may be generated, and the focus may switch.
@@ -258,27 +254,25 @@ Tk_FocusObjCmd(clientData, interp, objc, objv)
*/
int
-TkFocusFilterEvent(winPtr, eventPtr)
- TkWindow *winPtr; /* Window that focus event is directed to. */
- XEvent *eventPtr; /* FocusIn, FocusOut, Enter, or Leave
+TkFocusFilterEvent(
+ TkWindow *winPtr, /* Window that focus event is directed to. */
+ XEvent *eventPtr) /* FocusIn, FocusOut, Enter, or Leave
* event. */
{
/*
- * Design notes: the window manager and X server work together to
- * transfer the focus among top-level windows. This procedure takes
- * care of transferring the focus from a top-level or wrapper window
- * to the actual window within that top-level that has the focus.
- * We do this by synthesizing X events to move the focus around.
- * None of the FocusIn and FocusOut events generated by X are ever
- * used outside of this procedure; only the synthesized events get
- * through to the rest of the application. At one point (e.g.
- * Tk4.0b1) Tk used to call X to move the focus from a top-level to
- * one of its descendants, then just pass through the events
- * generated by X. This approach didn't work very well, for a
- * variety of reasons. For example, if X generates the events they
- * go at the back of the event queue, which could cause problems if
- * other things have already happened, such as moving the focus to
- * yet another window.
+ * Design notes: the window manager and X server work together to transfer
+ * the focus among top-level windows. This function takes care of
+ * transferring the focus from a top-level or wrapper window to the actual
+ * window within that top-level that has the focus. We do this by
+ * synthesizing X events to move the focus around. None of the FocusIn and
+ * FocusOut events generated by X are ever used outside of this function;
+ * only the synthesized events get through to the rest of the application.
+ * At one point (e.g. Tk4.0b1) Tk used to call X to move the focus from a
+ * top-level to one of its descendants, then just pass through the events
+ * generated by X. This approach didn't work very well, for a variety of
+ * reasons. For example, if X generates the events they go at the back of
+ * the event queue, which could cause problems if other things have
+ * already happened, such as moving the focus to yet another window.
*/
ToplevelFocusInfo *tlFocusPtr;
@@ -288,8 +282,8 @@ TkFocusFilterEvent(winPtr, eventPtr)
int retValue, delta;
/*
- * If this was a generated event, just turn off the generated
- * flag and pass the event through to Tk bindings.
+ * If this was a generated event, just turn off the generated flag and
+ * pass the event through to Tk bindings.
*/
if (eventPtr->xfocus.send_event == GENERATED_EVENT_MAGIC) {
@@ -298,11 +292,11 @@ TkFocusFilterEvent(winPtr, eventPtr)
}
/*
- * Check for special events generated by embedded applications to
- * request the input focus. If this is one of those events, make
- * the change in focus and return without any additional processing
- * of the event (note: the "detail" field of the event indicates
- * whether to claim the focus even if we don't already have it).
+ * Check for special events generated by embedded applications to request
+ * the input focus. If this is one of those events, make the change in
+ * focus and return without any additional processing of the event (note:
+ * the "detail" field of the event indicates whether to claim the focus
+ * even if we don't already have it).
*/
if ((eventPtr->xfocus.mode == EMBEDDED_APP_WANTS_FOCUS)
@@ -312,10 +306,9 @@ TkFocusFilterEvent(winPtr, eventPtr)
}
/*
- * This was not a generated event. We'll return 1 (so that the
- * event will be processed) if it's an Enter or Leave event, and
- * 0 (so that the event won't be processed) if it's a FocusIn or
- * FocusOut event.
+ * This was not a generated event. We'll return 1 (so that the event will
+ * be processed) if it's an Enter or Leave event, and 0 (so that the event
+ * won't be processed) if it's a FocusIn or FocusOut event.
*/
retValue = 0;
@@ -323,26 +316,26 @@ TkFocusFilterEvent(winPtr, eventPtr)
if (eventPtr->type == FocusIn) {
/*
* Skip FocusIn events that cause confusion
- * NotifyVirtual and NotifyNonlinearVirtual - Virtual events occur
- * on windows in between the origin and destination of the
- * focus change. For FocusIn we may see this when focus
- * goes into an embedded child. We don't care about this,
- * although we may end up getting a NotifyPointer later.
- * NotifyInferior - focus is coming to us from an embedded child.
- * When focus is on an embeded focus, we still think we have
- * the focus, too, so this message doesn't change our state.
- * NotifyPointerRoot - should never happen because this is sent
- * to the root window.
+ * NotifyVirtual and NotifyNonlinearVirtual - Virtual events occur on
+ * windows in between the origin and destination of the focus
+ * change. For FocusIn we may see this when focus goes into an
+ * embedded child. We don't care about this, although we may end
+ * up getting a NotifyPointer later.
+ * NotifyInferior - focus is coming to us from an embedded child. When
+ * focus is on an embeded focus, we still think we have the
+ * focus, too, so this message doesn't change our state.
+ * NotifyPointerRoot - should never happen because this is sent to the
+ * root window.
*
* Interesting FocusIn events are
* NotifyAncestor - focus is coming from our parent, probably the root.
* NotifyNonlinear - focus is coming from a different branch, probably
* another toplevel.
- * NotifyPointer - implicit focus because of the mouse position.
- * This is only interesting on toplevels, when it means that the
- * focus has been set to the root window but the mouse is over
- * this toplevel. We take the focus implicitly (probably no
- * window manager)
+ * NotifyPointer - implicit focus because of the mouse position. This
+ * is only interesting on toplevels, when it means that the focus
+ * has been set to the root window but the mouse is over this
+ * toplevel. We take the focus implicitly (probably no window
+ * manager)
*/
if ((eventPtr->xfocus.detail == NotifyVirtual)
@@ -355,12 +348,12 @@ TkFocusFilterEvent(winPtr, eventPtr)
/*
* Skip FocusOut events that cause confusion.
* NotifyPointer - the pointer is in us or a child, and we are losing
- * focus because of an XSetInputFocus. Other focus events
- * will set our state properly.
- * NotifyPointerRoot - should never happen because this is sent
- * to the root window.
- * NotifyInferior - focus leaving us for an embedded child. We
- * retain a notion of focus when an embedded child has focus.
+ * focus because of an XSetInputFocus. Other focus events will
+ * set our state properly.
+ * NotifyPointerRoot - should never happen because this is sent to the
+ * root window.
+ * NotifyInferior - focus leaving us for an embedded child. We retain
+ * a notion of focus when an embedded child has focus.
*
* Interesting events are:
* NotifyAncestor - focus is going to root.
@@ -392,8 +385,8 @@ TkFocusFilterEvent(winPtr, eventPtr)
}
/*
- * If there is a grab in effect and this window is outside the
- * grabbed tree, then ignore the event.
+ * If there is a grab in effect and this window is outside the grabbed
+ * tree, then ignore the event.
*/
if (TkGrabState(winPtr) == TK_GRAB_EXCLUDED) {
@@ -401,16 +394,15 @@ TkFocusFilterEvent(winPtr, eventPtr)
}
/*
- * It is possible that there were outstanding FocusIn and FocusOut
- * events on their way to us at the time the focus was changed
- * internally with the "focus" command. If so, these events could
- * potentially cause us to lose the focus (switch it to the window
- * of the last FocusIn event) even though the focus change occurred
- * after those events. The following code detects this and ignores
- * the stale events.
+ * It is possible that there were outstanding FocusIn and FocusOut events
+ * on their way to us at the time the focus was changed internally with
+ * the "focus" command. If so, these events could potentially cause us to
+ * lose the focus (switch it to the window of the last FocusIn event) even
+ * though the focus change occurred after those events. The following code
+ * detects this and ignores the stale events.
*
- * Note: the focusSerial is only generated by TkpChangeFocus,
- * whereas in Tk 4.2 there was always a nop marker generated.
+ * Note: the focusSerial is only generated by TkpChangeFocus, whereas in
+ * Tk 4.2 there was always a nop marker generated.
*/
delta = eventPtr->xfocus.serial - displayFocusPtr->focusSerial;
@@ -440,6 +432,7 @@ TkFocusFilterEvent(winPtr, eventPtr)
/*
* Ignore event if newFocus window is already dead!
*/
+
if (newFocusPtr->flags & TK_ALREADY_DEAD) {
return retValue;
}
@@ -451,7 +444,7 @@ TkFocusFilterEvent(winPtr, eventPtr)
/*
* NotifyPointer gets set when the focus has been set to the root
- * window but we have the pointer. We'll treat this like an implicit
+ * window but we have the pointer. We'll treat this like an implicit
* focus in event so that upon Leave events we release focus.
*/
@@ -463,12 +456,12 @@ TkFocusFilterEvent(winPtr, eventPtr)
}
}
} else if (eventPtr->type == FocusOut) {
- GenerateFocusEvents(displayFocusPtr->focusWinPtr, (TkWindow *) NULL);
+ GenerateFocusEvents(displayFocusPtr->focusWinPtr, NULL);
/*
- * Reset dispPtr->focusPtr, but only if it currently is the same
- * as this application's focusWinPtr: this check is needed to
- * handle embedded applications in the same process.
+ * Reset dispPtr->focusPtr, but only if it currently is the same as
+ * this application's focusWinPtr: this check is needed to handle
+ * embedded applications in the same process.
*/
if (dispPtr->focusPtr == displayFocusPtr->focusWinPtr) {
@@ -478,25 +471,22 @@ TkFocusFilterEvent(winPtr, eventPtr)
} else if (eventPtr->type == EnterNotify) {
/*
* If there is no window manager, or if the window manager isn't
- * moving the focus around (e.g. the disgusting "NoTitleFocus"
- * option has been selected in twm), then we won't get FocusIn
- * or FocusOut events. Instead, the "focus" field will be set
- * in an Enter event to indicate that we've already got the focus
- * when the mouse enters the window (even though we didn't get
- * a FocusIn event). Watch for this and grab the focus when it
- * happens. Note: if this is an embedded application then don't
- * accept the focus implicitly like this; the container
- * application will give us the focus explicitly if it wants us
- * to have it.
+ * moving the focus around (e.g. the disgusting "NoTitleFocus" option
+ * has been selected in twm), then we won't get FocusIn or FocusOut
+ * events. Instead, the "focus" field will be set in an Enter event to
+ * indicate that we've already got the focus when the mouse enters the
+ * window (even though we didn't get a FocusIn event). Watch for this
+ * and grab the focus when it happens. Note: if this is an embedded
+ * application then don't accept the focus implicitly like this; the
+ * container application will give us the focus explicitly if it wants
+ * us to have it.
*/
if (eventPtr->xcrossing.focus &&
- (displayFocusPtr->focusWinPtr == NULL)
+ (displayFocusPtr->focusWinPtr == NULL)
&& !(winPtr->flags & TK_EMBEDDED)) {
- if (dispPtr->focusDebug) {
- printf("Focussed implicitly on %s\n",
- newFocusPtr->pathName);
- }
+ DEBUG(dispPtr,
+ ("Focussed implicitly on %s\n", newFocusPtr->pathName));
GenerateFocusEvents(displayFocusPtr->focusWinPtr, newFocusPtr);
displayFocusPtr->focusWinPtr = newFocusPtr;
@@ -507,22 +497,19 @@ TkFocusFilterEvent(winPtr, eventPtr)
/*
* If the pointer just left a window for which we automatically
* claimed the focus on enter, move the focus back to the root
- * window, where it was before we claimed it above. Note:
+ * window, where it was before we claimed it above. Note:
* dispPtr->implicitWinPtr may not be the same as
- * displayFocusPtr->focusWinPtr (e.g. because the "focus"
- * command was used to redirect the focus after it arrived at
- * dispPtr->implicitWinPtr)!! In addition, we generate events
+ * displayFocusPtr->focusWinPtr (e.g. because the "focus" command
+ * was used to redirect the focus after it arrived at
+ * dispPtr->implicitWinPtr)!! In addition, we generate events
* because the window manager won't give us a FocusOut event when
- * we focus on the root.
+ * we focus on the root.
*/
if ((dispPtr->implicitWinPtr != NULL)
&& !(winPtr->flags & TK_EMBEDDED)) {
- if (dispPtr->focusDebug) {
- printf("Defocussed implicit Async\n");
- }
- GenerateFocusEvents(displayFocusPtr->focusWinPtr,
- (TkWindow *) NULL);
+ DEBUG(dispPtr, ("Defocussed implicit Async\n"));
+ GenerateFocusEvents(displayFocusPtr->focusWinPtr, NULL);
XSetInputFocus(dispPtr->display, PointerRoot, RevertToPointerRoot,
CurrentTime);
displayFocusPtr->focusWinPtr = NULL;
@@ -537,8 +524,8 @@ TkFocusFilterEvent(winPtr, eventPtr)
*
* TkSetFocusWin --
*
- * This procedure is invoked to change the focus window for a
- * given display in a given application.
+ * This function is invoked to change the focus window for a given
+ * display in a given application.
*
* Results:
* None.
@@ -551,24 +538,32 @@ TkFocusFilterEvent(winPtr, eventPtr)
*/
void
-TkSetFocusWin(winPtr, force)
- TkWindow *winPtr; /* Window that is to be the new focus for
- * its display and application. */
- int force; /* If non-zero, set the X focus to this
- * window even if the application doesn't
- * currently have the X focus. */
+TkSetFocusWin(
+ TkWindow *winPtr, /* Window that is to be the new focus for its
+ * display and application. */
+ int force) /* If non-zero, set the X focus to this window
+ * even if the application doesn't currently
+ * have the X focus. */
{
ToplevelFocusInfo *tlFocusPtr;
DisplayFocusInfo *displayFocusPtr;
TkWindow *topLevelPtr;
int allMapped, serial;
+ /*
+ * Don't set focus if window is already dead. [Bug 3574708]
+ */
+
+ if (winPtr->flags & TK_ALREADY_DEAD) {
+ return;
+ }
+
displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr);
/*
- * If force is set, we should make sure we grab the focus regardless
- * of the current focus window since under Windows, we may need to
- * take control away from another application.
+ * If force is set, we should make sure we grab the focus regardless of
+ * the current focus window since under Windows, we may need to take
+ * control away from another application.
*/
if (winPtr == displayFocusPtr->focusWinPtr && !force) {
@@ -576,18 +571,19 @@ TkSetFocusWin(winPtr, force)
}
/*
- * Find the top-level window for winPtr, then find (or create)
- * a record for the top-level. Also see whether winPtr and all its
- * ancestors are mapped.
+ * Find the top-level window for winPtr, then find (or create) a record
+ * for the top-level. Also see whether winPtr and all its ancestors are
+ * mapped.
*/
allMapped = 1;
for (topLevelPtr = winPtr; ; topLevelPtr = topLevelPtr->parentPtr) {
if (topLevelPtr == NULL) {
/*
- * The window is being deleted. No point in worrying about
- * giving it the focus.
+ * The window is being deleted. No point in worrying about giving
+ * it the focus.
*/
+
return;
}
if (!(topLevelPtr->flags & TK_MAPPED)) {
@@ -599,11 +595,11 @@ TkSetFocusWin(winPtr, force)
}
/*
- * If the new focus window isn't mapped, then we can't focus on it
- * (X will generate an error, for example). Instead, create an
- * event handler that will set the focus to this window once it gets
- * mapped. At the same time, delete any old handler that might be
- * around; it's no longer relevant.
+ * If the new focus window isn't mapped, then we can't focus on it (X will
+ * generate an error, for example). Instead, create an event handler that
+ * will set the focus to this window once it gets mapped. At the same
+ * time, delete any old handler that might be around; it's no longer
+ * relevant.
*/
if (displayFocusPtr->focusOnMapPtr != NULL) {
@@ -637,16 +633,15 @@ TkSetFocusWin(winPtr, force)
tlFocusPtr->focusWinPtr = winPtr;
/*
- * Reset the window system's focus window and generate focus events,
- * with two special cases:
+ * Reset the window system's focus window and generate focus events, with
+ * two special cases:
*
- * 1. If the application is embedded and doesn't currently have the
- * focus, don't set the focus directly. Instead, see if the
- * embedding code can claim the focus from the enclosing
- * container.
- * 2. Otherwise, if the application doesn't currently have the
- * focus, don't change the window system's focus unless it was
- * already in this application or "force" was specified.
+ * 1. If the application is embedded and doesn't currently have the focus,
+ * don't set the focus directly. Instead, see if the embedding code can
+ * claim the focus from the enclosing container.
+ * 2. Otherwise, if the application doesn't currently have the focus,
+ * don't change the window system's focus unless it was already in this
+ * application or "force" was specified.
*/
if ((topLevelPtr->flags & TK_EMBEDDED)
@@ -654,12 +649,11 @@ TkSetFocusWin(winPtr, force)
TkpClaimFocus(topLevelPtr, force);
} else if ((displayFocusPtr->focusWinPtr != NULL) || force) {
/*
- * Generate events to shift focus between Tk windows.
- * We do this regardless of what TkpChangeFocus does with
- * the real X focus so that Tk widgets track focus commands
- * when there is no window manager. GenerateFocusEvents will
- * set up a serial number marker so we discard focus events
- * that are triggered by the ChangeFocus.
+ * Generate events to shift focus between Tk windows. We do this
+ * regardless of what TkpChangeFocus does with the real X focus so
+ * that Tk widgets track focus commands when there is no window
+ * manager. GenerateFocusEvents will set up a serial number marker so
+ * we discard focus events that are triggered by the ChangeFocus.
*/
serial = TkpChangeFocus(TkpGetWrapperWindow(topLevelPtr), force);
@@ -677,13 +671,13 @@ TkSetFocusWin(winPtr, force)
*
* TkGetFocusWin --
*
- * Given a window, this procedure returns the current focus
- * window for its application and display.
+ * Given a window, this function returns the current focus window for its
+ * application and display.
*
* Results:
- * The return value is a pointer to the window that currently
- * has the input focus for the specified application and
- * display, or NULL if none.
+ * The return value is a pointer to the window that currently has the
+ * input focus for the specified application and display, or NULL if
+ * none.
*
* Side effects:
* None.
@@ -692,14 +686,14 @@ TkSetFocusWin(winPtr, force)
*/
TkWindow *
-TkGetFocusWin(winPtr)
- TkWindow *winPtr; /* Window that selects an application
- * and a display. */
+TkGetFocusWin(
+ TkWindow *winPtr) /* Window that selects an application and a
+ * display. */
{
DisplayFocusInfo *displayFocusPtr;
if (winPtr == NULL) {
- return (TkWindow *) NULL;
+ return NULL;
}
displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr);
@@ -711,16 +705,16 @@ TkGetFocusWin(winPtr)
*
* TkFocusKeyEvent --
*
- * Given a window and a key press or release event that arrived for
- * the window, use information about the keyboard focus to compute
- * which window should really get the event. In addition, update
- * the event to refer to its new window.
+ * Given a window and a key press or release event that arrived for the
+ * window, use information about the keyboard focus to compute which
+ * window should really get the event. In addition, update the event to
+ * refer to its new window.
*
* Results:
- * The return value is a pointer to the window that has the input
- * focus in winPtr's application, or NULL if winPtr's application
- * doesn't have the input focus. If a non-NULL value is returned,
- * eventPtr will be updated to refer properly to the focus window.
+ * The return value is a pointer to the window that has the input focus
+ * in winPtr's application, or NULL if winPtr's application doesn't have
+ * the input focus. If a non-NULL value is returned, eventPtr will be
+ * updated to refer properly to the focus window.
*
* Side effects:
* None.
@@ -729,11 +723,11 @@ TkGetFocusWin(winPtr)
*/
TkWindow *
-TkFocusKeyEvent(winPtr, eventPtr)
- TkWindow *winPtr; /* Window that selects an application
- * and a display. */
- XEvent *eventPtr; /* X event to redirect (should be KeyPress
- * or KeyRelease). */
+TkFocusKeyEvent(
+ TkWindow *winPtr, /* Window that selects an application and a
+ * display. */
+ XEvent *eventPtr) /* X event to redirect (should be KeyPress or
+ * KeyRelease). */
{
DisplayFocusInfo *displayFocusPtr;
TkWindow *focusWinPtr;
@@ -760,9 +754,9 @@ TkFocusKeyEvent(winPtr, eventPtr)
if ((focusWinPtr != NULL) && (focusWinPtr->mainPtr == winPtr->mainPtr)) {
/*
- * Map the x and y coordinates to make sense in the context of
- * the focus window, if possible (make both -1 if the map-from
- * and map-to windows don't share the same screen).
+ * Map the x and y coordinates to make sense in the context of the
+ * focus window, if possible (make both -1 if the map-from and map-to
+ * windows don't share the same screen).
*/
if ((focusWinPtr->display != winPtr->display)
@@ -779,13 +773,13 @@ TkFocusKeyEvent(winPtr, eventPtr)
}
/*
- * The event doesn't belong to us. Perhaps, due to embedding, it
- * really belongs to someone else. Give the embedding code a chance
- * to redirect the event.
+ * The event doesn't belong to us. Perhaps, due to embedding, it really
+ * belongs to someone else. Give the embedding code a chance to redirect
+ * the event.
*/
TkpRedirectKeyEvent(winPtr, eventPtr);
- return (TkWindow *) NULL;
+ return NULL;
}
/*
@@ -793,9 +787,8 @@ TkFocusKeyEvent(winPtr, eventPtr)
*
* TkFocusDeadWindow --
*
- * This procedure is invoked when it is determined that
- * a window is dead. It cleans up focus-related information
- * about the window.
+ * This function is invoked when it is determined that a window is dead.
+ * It cleans up focus-related information about the window.
*
* Results:
* None.
@@ -807,25 +800,26 @@ TkFocusKeyEvent(winPtr, eventPtr)
*/
void
-TkFocusDeadWindow(winPtr)
- register TkWindow *winPtr; /* Information about the window
- * that is being deleted. */
+TkFocusDeadWindow(
+ register TkWindow *winPtr) /* Information about the window that is being
+ * deleted. */
{
ToplevelFocusInfo *tlFocusPtr, *prevPtr;
DisplayFocusInfo *displayFocusPtr;
TkDisplay *dispPtr = winPtr->dispPtr;
/*
- * Certain special windows like those used for send and clipboard
- * have no mainPtr.
+ * Certain special windows like those used for send and clipboard have no
+ * mainPtr.
*/
- if (winPtr->mainPtr == NULL)
- return;
+ if (winPtr->mainPtr == NULL) {
+ return;
+ }
/*
- * Search for focus records that refer to this window either as
- * the top-level window or the current focus window.
+ * Search for focus records that refer to this window either as the
+ * top-level window or the current focus window.
*/
displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr);
@@ -834,16 +828,14 @@ TkFocusDeadWindow(winPtr)
prevPtr = tlFocusPtr, tlFocusPtr = tlFocusPtr->nextPtr) {
if (winPtr == tlFocusPtr->topLevelPtr) {
/*
- * The top-level window is the one being deleted: free
- * the focus record and release the focus back to PointerRoot
- * if we acquired it implicitly.
+ * The top-level window is the one being deleted: free the focus
+ * record and release the focus back to PointerRoot if we acquired
+ * it implicitly.
*/
if (dispPtr->implicitWinPtr == winPtr) {
- if (dispPtr->focusDebug) {
- printf("releasing focus to root after %s died\n",
- tlFocusPtr->topLevelPtr->pathName);
- }
+ DEBUG(dispPtr, ("releasing focus to root after %s died\n",
+ tlFocusPtr->topLevelPtr->pathName));
dispPtr->implicitWinPtr = NULL;
displayFocusPtr->focusWinPtr = NULL;
dispPtr->focusPtr = NULL;
@@ -861,18 +853,15 @@ TkFocusDeadWindow(winPtr)
break;
} else if (winPtr == tlFocusPtr->focusWinPtr) {
/*
- * The deleted window had the focus for its top-level:
- * move the focus to the top-level itself.
+ * The deleted window had the focus for its top-level: move the
+ * focus to the top-level itself.
*/
tlFocusPtr->focusWinPtr = tlFocusPtr->topLevelPtr;
if ((displayFocusPtr->focusWinPtr == winPtr)
&& !(tlFocusPtr->topLevelPtr->flags & TK_ALREADY_DEAD)) {
- if (dispPtr->focusDebug) {
- printf("forwarding focus to %s after %s died\n",
- tlFocusPtr->topLevelPtr->pathName,
- winPtr->pathName);
- }
+ DEBUG(dispPtr, ("forwarding focus to %s after %s died\n",
+ tlFocusPtr->topLevelPtr->pathName, winPtr->pathName));
GenerateFocusEvents(displayFocusPtr->focusWinPtr,
tlFocusPtr->topLevelPtr);
displayFocusPtr->focusWinPtr = tlFocusPtr->topLevelPtr;
@@ -888,9 +877,7 @@ TkFocusDeadWindow(winPtr)
*/
if (displayFocusPtr->focusWinPtr == winPtr) {
- if (dispPtr->focusDebug) {
- printf("focus cleared after %s died\n", winPtr->pathName);
- }
+ DEBUG(dispPtr, ("focus cleared after %s died\n", winPtr->pathName));
displayFocusPtr->focusWinPtr = NULL;
}
@@ -904,8 +891,8 @@ TkFocusDeadWindow(winPtr)
*
* GenerateFocusEvents --
*
- * This procedure is called to create FocusIn and FocusOut events to
- * move the input focus from one window to another.
+ * This function is called to create FocusIn and FocusOut events to move
+ * the input focus from one window to another.
*
* Results:
* None.
@@ -917,12 +904,11 @@ TkFocusDeadWindow(winPtr)
*/
static void
-GenerateFocusEvents(sourcePtr, destPtr)
- TkWindow *sourcePtr; /* Window that used to have the focus (may
- * be NULL). */
- TkWindow *destPtr; /* New window to have the focus (may be
+GenerateFocusEvents(
+ TkWindow *sourcePtr, /* Window that used to have the focus (may be
+ * NULL). */
+ TkWindow *destPtr) /* New window to have the focus (may be
* NULL). */
-
{
XEvent event;
TkWindow *winPtr;
@@ -948,26 +934,26 @@ GenerateFocusEvents(sourcePtr, destPtr)
*
* FocusMapProc --
*
- * This procedure is called as an event handler for VisibilityNotify
- * events, if a window receives the focus at a time when its
- * toplevel isn't mapped. The procedure is needed because X
- * won't allow the focus to be set to an unmapped window; we
- * detect when the toplevel is mapped and set the focus to it then.
+ * This function is called as an event handler for VisibilityNotify
+ * events, if a window receives the focus at a time when its toplevel
+ * isn't mapped. The function is needed because X won't allow the focus
+ * to be set to an unmapped window; we detect when the toplevel is mapped
+ * and set the focus to it then.
*
* Results:
* None.
*
* Side effects:
- * If this is a map event, the focus gets set to the toplevel
- * given by clientData.
+ * If this is a map event, the focus gets set to the toplevel given by
+ * clientData.
*
*----------------------------------------------------------------------
*/
static void
-FocusMapProc(clientData, eventPtr)
- ClientData clientData; /* Toplevel window. */
- XEvent *eventPtr; /* Information about event. */
+FocusMapProc(
+ ClientData clientData, /* Toplevel window. */
+ XEvent *eventPtr) /* Information about event. */
{
TkWindow *winPtr = (TkWindow *) clientData;
DisplayFocusInfo *displayFocusPtr;
@@ -975,10 +961,8 @@ FocusMapProc(clientData, eventPtr)
if (eventPtr->type == VisibilityNotify) {
displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr,
winPtr->dispPtr);
- if (winPtr->dispPtr->focusDebug) {
- printf("auto-focussing on %s, force %d\n", winPtr->pathName,
- displayFocusPtr->forceFocus);
- }
+ DEBUG(winPtr->dispPtr, ("auto-focussing on %s, force %d\n",
+ winPtr->pathName, displayFocusPtr->forceFocus));
Tk_DeleteEventHandler((Tk_Window) winPtr, VisibilityChangeMask,
FocusMapProc, clientData);
displayFocusPtr->focusOnMapPtr = NULL;
@@ -991,9 +975,9 @@ FocusMapProc(clientData, eventPtr)
*
* FindDisplayFocusInfo --
*
- * Given an application and a display, this procedure locate the
- * focus record for that combination. If no such record exists,
- * it creates a new record and initializes it.
+ * Given an application and a display, this function locate the focus
+ * record for that combination. If no such record exists, it creates a
+ * new record and initializes it.
*
* Results:
* The return value is a pointer to the record.
@@ -1005,10 +989,10 @@ FocusMapProc(clientData, eventPtr)
*/
static DisplayFocusInfo *
-FindDisplayFocusInfo(mainPtr, dispPtr)
- TkMainInfo *mainPtr; /* Record that identifies a particular
+FindDisplayFocusInfo(
+ TkMainInfo *mainPtr, /* Record that identifies a particular
* application. */
- TkDisplay *dispPtr; /* Display whose focus information is
+ TkDisplay *dispPtr) /* Display whose focus information is
* needed. */
{
DisplayFocusInfo *displayFocusPtr;
@@ -1022,7 +1006,7 @@ FindDisplayFocusInfo(mainPtr, dispPtr)
}
/*
- * The record doesn't exist yet. Make a new one.
+ * The record doesn't exist yet. Make a new one.
*/
displayFocusPtr = (DisplayFocusInfo *) ckalloc(sizeof(DisplayFocusInfo));
@@ -1053,21 +1037,154 @@ FindDisplayFocusInfo(mainPtr, dispPtr)
*/
void
-TkFocusFree(mainPtr)
- TkMainInfo *mainPtr; /* Record that identifies a particular
+TkFocusFree(
+ TkMainInfo *mainPtr) /* Record that identifies a particular
* application. */
{
- DisplayFocusInfo *displayFocusPtr;
- ToplevelFocusInfo *tlFocusPtr;
-
while (mainPtr->displayFocusPtr != NULL) {
- displayFocusPtr = mainPtr->displayFocusPtr;
+ DisplayFocusInfo *displayFocusPtr = mainPtr->displayFocusPtr;
+
mainPtr->displayFocusPtr = mainPtr->displayFocusPtr->nextPtr;
ckfree((char *) displayFocusPtr);
}
while (mainPtr->tlFocusPtr != NULL) {
- tlFocusPtr = mainPtr->tlFocusPtr;
+ ToplevelFocusInfo *tlFocusPtr = mainPtr->tlFocusPtr;
+
mainPtr->tlFocusPtr = mainPtr->tlFocusPtr->nextPtr;
ckfree((char *) tlFocusPtr);
}
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkFocusSplit --
+ *
+ * Adjust focus window for a newly managed toplevel, thus splitting
+ * the toplevel into two toplevels.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * A new record is allocated for the new toplevel window.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkFocusSplit(winPtr)
+ TkWindow *winPtr; /* Window is the new toplevel
+ * Any focus point at or below window
+ * must be moved to this new toplevel */
+{
+ ToplevelFocusInfo *tlFocusPtr;
+ TkWindow *topLevelPtr;
+ TkWindow *subWinPtr;
+
+ FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr);
+
+ /*
+ * Find the top-level window for winPtr, then find (or create)
+ * a record for the top-level. Also see whether winPtr and all its
+ * ancestors are mapped.
+ */
+
+ for (topLevelPtr = winPtr; ; topLevelPtr = topLevelPtr->parentPtr) {
+ if (topLevelPtr == NULL) {
+ /*
+ * The window is being deleted. No point in worrying about
+ * giving it the focus.
+ */
+ return;
+ }
+ if (topLevelPtr->flags & TK_TOP_HIERARCHY) {
+ break;
+ }
+ }
+
+ /* Search all focus records to find child windows of winPtr */
+ for (tlFocusPtr = winPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL;
+ tlFocusPtr = tlFocusPtr->nextPtr) {
+ if (tlFocusPtr->topLevelPtr == topLevelPtr) {
+ break;
+ }
+ }
+
+ if (tlFocusPtr == NULL) {
+ /* No focus record for this toplevel, nothing to do. */
+ return;
+ }
+
+ /* See if current focusWin is child of the new toplevel */
+ for (subWinPtr = tlFocusPtr->focusWinPtr;
+ subWinPtr && subWinPtr != winPtr && subWinPtr != topLevelPtr;
+ subWinPtr = subWinPtr->parentPtr) {}
+
+ if (subWinPtr == winPtr) {
+ /* Move focus to new toplevel */
+ ToplevelFocusInfo *newTlFocusPtr;
+
+ newTlFocusPtr = (ToplevelFocusInfo *) ckalloc(sizeof(ToplevelFocusInfo));
+ newTlFocusPtr->topLevelPtr = winPtr;
+ newTlFocusPtr->focusWinPtr = tlFocusPtr->focusWinPtr;
+ newTlFocusPtr->nextPtr = winPtr->mainPtr->tlFocusPtr;
+ winPtr->mainPtr->tlFocusPtr = newTlFocusPtr;
+ /* Move old toplevel's focus to the toplevel itself */
+ tlFocusPtr->focusWinPtr = topLevelPtr;
+ }
+ /* If it's not, then let focus progress naturally */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkFocusJoin --
+ *
+ * Remove the focus record for this window that is nolonger managed
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * A tlFocusPtr record is removed
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkFocusJoin(winPtr)
+ TkWindow *winPtr; /* Window is no longer a toplevel */
+{
+ ToplevelFocusInfo *tlFocusPtr;
+ ToplevelFocusInfo *tmpPtr;
+
+ /*
+ * Remove old toplevel record
+ */
+ if (winPtr && winPtr->mainPtr && winPtr->mainPtr->tlFocusPtr
+ && winPtr->mainPtr->tlFocusPtr->topLevelPtr == winPtr) {
+ tmpPtr = winPtr->mainPtr->tlFocusPtr;
+ winPtr->mainPtr->tlFocusPtr = tmpPtr->nextPtr;
+ ckfree((char *)tmpPtr);
+ } else {
+ for (tlFocusPtr = winPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL;
+ tlFocusPtr = tlFocusPtr->nextPtr) {
+ if (tlFocusPtr->nextPtr &&
+ tlFocusPtr->nextPtr->topLevelPtr == winPtr) {
+ tmpPtr = tlFocusPtr->nextPtr;
+ tlFocusPtr->nextPtr = tmpPtr->nextPtr;
+ ckfree((char *)tmpPtr);
+ break;
+ }
+ }
+ }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkFont.c b/generic/tkFont.c
index 95feec3..1a6474f 100644
--- a/generic/tkFont.c
+++ b/generic/tkFont.c
@@ -1,44 +1,42 @@
-/*
+/*
* tkFont.c --
*
- * This file maintains a database of fonts for the Tk toolkit.
- * It also provides several utility procedures for measuring and
- * displaying text.
+ * This file maintains a database of fonts for the Tk toolkit. It also
+ * provides several utility functions for measuring and displaying text.
*
* Copyright (c) 1990-1994 The Regents of the University of California.
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
#include "tkFont.h"
/*
- * The following structure is used to keep track of all the fonts that
- * exist in the current application. It must be stored in the
- * TkMainInfo for the application.
+ * The following structure is used to keep track of all the fonts that exist
+ * in the current application. It must be stored in the TkMainInfo for the
+ * application.
*/
-
+
typedef struct TkFontInfo {
- Tcl_HashTable fontCache; /* Map a string to an existing Tk_Font.
- * Keys are string font names, values are
- * TkFont pointers. */
+ Tcl_HashTable fontCache; /* Map a string to an existing Tk_Font. 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
- * strings, values are NamedFont pointers. */
+ * a named font description. Keys are strings,
+ * values are NamedFont pointers. */
TkMainInfo *mainPtr; /* Application that owns this structure. */
int updatePending; /* Non-zero when a World Changed event has
- * already been queued to handle a change to
- * a named font. */
+ * already been queued to handle a change to a
+ * named font. */
} TkFontInfo;
/*
* 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
+ * for each named font that has been defined. The named font is only deleted
* when the last reference to it goes away.
*/
@@ -48,84 +46,83 @@ typedef struct NamedFont {
* last reference goes away. */
TkFontAttributes fa; /* Desired attributes for named font. */
} NamedFont;
-
+
/*
- * The following two structures are used to keep track of string
- * measurement information when using the text layout facilities.
+ * The following two structures are used to keep track of string measurement
+ * information when using the text layout facilities.
*
* A LayoutChunk represents a contiguous range of text that can be measured
- * and displayed by low-level text calls. In general, chunks will be
- * delimited by newlines and tabs. Low-level, platform-specific things
- * like kerning and non-integer character widths may occur between the
- * characters in a single chunk, but not between characters in different
- * chunks.
- *
- * A TextLayout is a collection of LayoutChunks. It can be displayed with
- * respect to any origin. It is the implementation of the Tk_TextLayout
- * opaque token.
+ * and displayed by low-level text calls. In general, chunks will be delimited
+ * by newlines and tabs. Low-level, platform-specific things like kerning and
+ * non-integer character widths may occur between the characters in a single
+ * chunk, but not between characters in different chunks.
+ *
+ * A TextLayout is a collection of LayoutChunks. It can be displayed with
+ * respect to any origin. It is the implementation of the Tk_TextLayout opaque
+ * token.
*/
typedef struct LayoutChunk {
- CONST char *start; /* Pointer to simple string to be displayed.
+ 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
+ * this chunk is displayed. Can be less than
* numChars if extra space characters were
- * absorbed by the end of the chunk. This
- * will be < 0 if this is a chunk that is
- * holding a tab or newline. */
+ * absorbed by the end of the chunk. This will
+ * be < 0 if this is a chunk that is holding a
+ * tab or newline. */
int x, y; /* The origin of the first character in this
* chunk with respect to the upper-left hand
* corner of the TextLayout. */
- int totalWidth; /* Width in pixels of this chunk. Used
- * when hit testing the invisible spaces at
- * the end of a chunk. */
+ int totalWidth; /* Width in pixels of this chunk. Used when
+ * hit testing the invisible spaces at the end
+ * of a chunk. */
int displayWidth; /* Width in pixels of the displayable
- * characters in this chunk. Can be less than
+ * characters in this chunk. Can be less than
* width if extra space characters were
* absorbed by the end of the chunk. */
} LayoutChunk;
typedef struct TextLayout {
Tk_Font tkfont; /* The font used when laying out the text. */
- CONST char *string; /* The string that was layed out. */
- int width; /* The maximum width of all lines in the
- * text layout. */
- int numChunks; /* Number of chunks actually used in
- * following array. */
- LayoutChunk chunks[1]; /* Array of chunks. The actual size will
- * be maxChunks. THIS FIELD MUST BE THE LAST
- * IN THE STRUCTURE. */
+ const char *string; /* The string that was layed out. */
+ int width; /* The maximum width of all lines in the text
+ * layout. */
+ int numChunks; /* Number of chunks actually used in following
+ * array. */
+ LayoutChunk chunks[1]; /* Array of chunks. The actual size will be
+ * maxChunks. THIS FIELD MUST BE THE LAST IN
+ * THE STRUCTURE. */
} TextLayout;
/*
* The following structures are used as two-way maps between the values for
- * the fields in the TkFontAttributes structure and the strings used in
- * Tcl, when parsing both option-value format and style-list format font
- * name strings.
+ * the fields in the TkFontAttributes structure and the strings used in Tcl,
+ * when parsing both option-value format and style-list format font name
+ * strings.
*/
-static TkStateMap weightMap[] = {
+static const TkStateMap weightMap[] = {
{TK_FW_NORMAL, "normal"},
{TK_FW_BOLD, "bold"},
{TK_FW_UNKNOWN, NULL}
};
-static TkStateMap slantMap[] = {
+static const TkStateMap slantMap[] = {
{TK_FS_ROMAN, "roman"},
{TK_FS_ITALIC, "italic"},
{TK_FS_UNKNOWN, NULL}
};
-static TkStateMap underlineMap[] = {
+static const TkStateMap underlineMap[] = {
{1, "underline"},
{0, NULL}
};
-static TkStateMap overstrikeMap[] = {
+static const TkStateMap overstrikeMap[] = {
{1, "overstrike"},
{0, NULL}
};
@@ -135,7 +132,7 @@ static TkStateMap overstrikeMap[] = {
* TkFontAttributes.
*/
-static TkStateMap xlfdWeightMap[] = {
+static const TkStateMap xlfdWeightMap[] = {
{TK_FW_NORMAL, "normal"},
{TK_FW_NORMAL, "medium"},
{TK_FW_NORMAL, "book"},
@@ -144,16 +141,16 @@ static TkStateMap xlfdWeightMap[] = {
{TK_FW_BOLD, "demi"},
{TK_FW_BOLD, "demibold"},
{TK_FW_NORMAL, NULL} /* Assume anything else is "normal". */
-};
+};
-static TkStateMap xlfdSlantMap[] = {
+static const TkStateMap xlfdSlantMap[] = {
{TK_FS_ROMAN, "r"},
{TK_FS_ITALIC, "i"},
{TK_FS_OBLIQUE, "o"},
{TK_FS_ROMAN, NULL} /* Assume anything else is "roman". */
};
-static TkStateMap xlfdSetwidthMap[] = {
+static const TkStateMap xlfdSetwidthMap[] = {
{TK_SW_NORMAL, "normal"},
{TK_SW_CONDENSE, "narrow"},
{TK_SW_CONDENSE, "semicondensed"},
@@ -162,11 +159,11 @@ static TkStateMap xlfdSetwidthMap[] = {
};
/*
- * The following structure and defines specify the valid builtin options
- * when configuring a set of font attributes.
+ * The following structure and defines specify the valid builtin options when
+ * configuring a set of font attributes.
*/
-static CONST char *fontOpt[] = {
+static const char *fontOpt[] = {
"-family",
"-size",
"-weight",
@@ -185,10 +182,10 @@ static CONST char *fontOpt[] = {
#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.
+ * 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[] = {
@@ -226,7 +223,7 @@ static char *gothicAliases[] = {
/* 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
+ NULL
};
static char *dingbatsAliases[] = {
@@ -245,43 +242,46 @@ static char **fontAliases[] = {
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.
+ * 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. */
+ "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. */
+ "times", "palatino", "mincho",
+ /* All platforms. */
+ "song ti", /* Unix. */
+ "ms serif", "simplified arabic",
+ /* Windows. */
+ "latinski", /* Mac. */
NULL
};
static char *sansClass[] = {
- "helvetica", "gothic", /* All platforms. */
- /* Unix. */
+ "helvetica", "gothic", /* All platforms. */
+ /* Unix. */
"ms sans serif", "traditional arabic",
- /* Windows. */
- "bastion", /* Mac. */
+ /* Windows. */
+ "bastion", /* Mac. */
NULL
};
static char *monoClass[] = {
- "courier", "gothic", /* All platforms. */
- "fangsong ti", /* Unix. */
- "simplified arabic fixed", /* Windows. */
- "monaco", "pryamoy", /* Mac. */
+ "courier", "gothic", /* All platforms. */
+ "fangsong ti", /* Unix. */
+ "simplified arabic fixed", /* Windows. */
+ "monaco", "pryamoy", /* Mac. */
NULL
};
@@ -299,9 +299,9 @@ static char **fontFallbacks[] = {
};
/*
- * 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.
+ * 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[] = {
@@ -314,43 +314,35 @@ static char *globalFontClass[] = {
};
#define GetFontAttributes(tkfont) \
- ((CONST TkFontAttributes *) &((TkFont *) (tkfont))->fa)
+ ((const TkFontAttributes *) &((TkFont *) (tkfont))->fa)
#define GetFontMetrics(tkfont) \
- ((CONST TkFontMetrics *) &((TkFont *) (tkfont))->fm)
-
-
-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,
- int *maxPtr, CONST char *start, int numChars,
- int curX, int newX, int y));
-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 UpdateDependentFonts _ANSI_ARGS_((TkFontInfo *fiPtr,
- Tk_Window tkwin, Tcl_HashEntry *namedHashPtr));
+ ((const TkFontMetrics *) &((TkFont *) (tkfont))->fm)
+
+
+static int ConfigAttributesObj(Tcl_Interp *interp,
+ Tk_Window tkwin, int objc, Tcl_Obj *const objv[],
+ TkFontAttributes *faPtr);
+static void DupFontObjProc(Tcl_Obj *srcObjPtr, Tcl_Obj *dupObjPtr);
+static int FieldSpecified(const char *field);
+static void FreeFontObjProc(Tcl_Obj *objPtr);
+static int GetAttributeInfoObj(Tcl_Interp *interp,
+ const TkFontAttributes *faPtr, Tcl_Obj *objPtr);
+static LayoutChunk * NewChunk(TextLayout **layoutPtrPtr, int *maxPtr,
+ const char *start, int numChars, int curX,
+ int newX, int y);
+static int ParseFontNameObj(Tcl_Interp *interp, Tk_Window tkwin,
+ Tcl_Obj *objPtr, TkFontAttributes *faPtr);
+static void RecomputeWidgets(TkWindow *winPtr);
+static int SetFontFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static void TheWorldHasChanged(ClientData clientData);
+static void UpdateDependentFonts(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.
+ * object, used for drawing. The internalRep.twoPtrValue.ptr1 field of each
+ * font object points to the TkFont structure for the font, or NULL.
*/
Tcl_ObjType tkFontObjType = {
@@ -360,29 +352,29 @@ Tcl_ObjType tkFontObjType = {
NULL, /* updateStringProc */
SetFontFromAny /* setFromAnyProc */
};
-
/*
*---------------------------------------------------------------------------
*
* TkFontPkgInit --
*
- * This procedure is called when an application is created. It
- * initializes all the structures that are used by the font
- * package on a per application basis.
+ * This function is called when an application is created. It initializes
+ * all the structures that are used by the font package on a per
+ * application basis.
*
* Results:
- * Stores a token in the mainPtr to hold information needed by this
- * package on a per application basis.
+ * Stores a token in the mainPtr to hold information needed by this
+ * package on a per application basis.
*
* Side effects:
* Memory allocated.
*
*---------------------------------------------------------------------------
*/
+
void
-TkFontPkgInit(mainPtr)
- TkMainInfo *mainPtr; /* The application being created. */
+TkFontPkgInit(
+ TkMainInfo *mainPtr) /* The application being created. */
{
TkFontInfo *fiPtr;
@@ -401,9 +393,9 @@ TkFontPkgInit(mainPtr)
*
* TkFontPkgFree --
*
- * This procedure is called when an application is deleted. It
- * deletes all the structures that were used by the font package
- * for this application.
+ * This function is called when an application is deleted. It deletes all
+ * the structures that were used by the font package for this
+ * application.
*
* Results:
* None.
@@ -415,8 +407,8 @@ TkFontPkgInit(mainPtr)
*/
void
-TkFontPkgFree(mainPtr)
- TkMainInfo *mainPtr; /* The application being deleted. */
+TkFontPkgFree(
+ TkMainInfo *mainPtr) /* The application being deleted. */
{
TkFontInfo *fiPtr;
Tcl_HashEntry *hPtr, *searchPtr;
@@ -431,15 +423,17 @@ TkFontPkgFree(mainPtr)
searchPtr = Tcl_NextHashEntry(&search)) {
fontsLeft++;
#ifdef DEBUG_FONTS
- fprintf(stderr, "Font %s still in cache.\n",
+ fprintf(stderr, "Font %s still in cache.\n",
Tcl_GetHashKey(&fiPtr->fontCache, searchPtr));
#endif
}
+
#ifdef PURIFY
if (fontsLeft) {
- panic("TkFontPkgFree: all fonts should have been freed already");
+ Tcl_Panic("TkFontPkgFree: all fonts should have been freed already");
}
#endif
+
Tcl_DeleteHashTable(&fiPtr->fontCache);
hPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search);
@@ -457,10 +451,10 @@ TkFontPkgFree(mainPtr)
/*
*---------------------------------------------------------------------------
*
- * Tk_FontObjCmd --
+ * Tk_FontObjCmd --
*
- * This procedure is implemented to process the "font" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is implemented to process the "font" Tcl command. See
+ * the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -472,16 +466,16 @@ TkFontPkgFree(mainPtr)
*/
int
-Tk_FontObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_FontObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
int index;
Tk_Window tkwin;
TkFontInfo *fiPtr;
- static CONST char *optionStrings[] = {
+ static const char *optionStrings[] = {
"actual", "configure", "create", "delete",
"families", "measure", "metrics", "names",
NULL
@@ -504,259 +498,320 @@ Tk_FontObjCmd(clientData, interp, objc, objv)
}
switch ((enum options) index) {
- case FONT_ACTUAL: {
- int skip, result;
- Tk_Font tkfont;
- Tcl_Obj *objPtr;
- CONST TkFontAttributes *faPtr;
+ case FONT_ACTUAL: {
+ int skip, result, n;
+ const char *s;
+ Tk_Font tkfont;
+ Tcl_Obj *optPtr, *charPtr, *resultPtr;
+ Tcl_UniChar uniChar = 0;
+ const TkFontAttributes *faPtr;
+ TkFontAttributes fa;
- skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
- if (skip < 0) {
- return TCL_ERROR;
- }
- if ((objc < 3) || (objc - skip > 4)) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "font ?-displayof window? ?option?");
- return TCL_ERROR;
- }
- tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
- if (tkfont == NULL) {
- return TCL_ERROR;
- }
- objc -= skip;
- objv += skip;
- faPtr = GetFontAttributes(tkfont);
- objPtr = NULL;
- if (objc > 3) {
- objPtr = objv[3];
- }
- result = GetAttributeInfoObj(interp, faPtr, objPtr);
- Tk_FreeFont(tkfont);
- return result;
+ /*
+ * Params 0 and 1 are 'font actual'. Param 2 is the font name. 3-4 may
+ * be '-displayof $window'
+ */
+
+ skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
+ if (skip < 0) {
+ return TCL_ERROR;
}
- case FONT_CONFIGURE: {
- int result;
- char *string;
- Tcl_Obj *objPtr;
- NamedFont *nfPtr;
- Tcl_HashEntry *namedHashPtr;
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "fontname ?options?");
- return TCL_ERROR;
- }
- 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_AppendResult(interp, "named font \"", string,
- "\" doesn't exist", NULL);
- return TCL_ERROR;
- }
- if (objc == 3) {
- objPtr = NULL;
- } else if (objc == 4) {
- objPtr = objv[3];
+ /*
+ * Next parameter may be an option.
+ */
+
+ n = skip + 3;
+ optPtr = NULL;
+ charPtr = NULL;
+ if (n < objc) {
+ s = Tcl_GetString(objv[n]);
+ if (s[0] == '-' && s[1] != '-') {
+ optPtr = objv[n];
+ ++n;
} else {
- result = ConfigAttributesObj(interp, tkwin, objc - 3,
- objv + 3, &nfPtr->fa);
- UpdateDependentFonts(fiPtr, tkwin, namedHashPtr);
- return result;
+ optPtr = NULL;
}
- return GetAttributeInfoObj(interp, &nfPtr->fa, objPtr);
}
- case FONT_CREATE: {
- int skip, i;
- char *name;
- char buf[16 + TCL_INTEGER_SPACE];
- TkFontAttributes fa;
- Tcl_HashEntry *namedHashPtr;
- skip = 3;
- if (objc < 3) {
- name = NULL;
- } else {
- name = Tcl_GetString(objv[2]);
- if (name[0] == '-') {
- name = NULL;
- }
- }
- if (name == NULL) {
- /*
- * No font name specified. Generate one of the form "fontX".
- */
+ /*
+ * Next parameter may be '--' to mark end of options.
+ */
- for (i = 1; ; i++) {
- sprintf(buf, "font%d", i);
- namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, buf);
- if (namedHashPtr == NULL) {
- break;
- }
- }
- name = buf;
- skip = 2;
+ if (n < objc) {
+ if (!strcmp(Tcl_GetString(objv[n]), "--")) {
+ ++n;
}
- TkInitFontAttributes(&fa);
- if (ConfigAttributesObj(interp, tkwin, objc - skip, objv + skip,
- &fa) != TCL_OK) {
- return TCL_ERROR;
- }
- if (CreateNamedFont(interp, tkwin, name, &fa) != TCL_OK) {
+ }
+
+ /*
+ * Next parameter is the character to get font information for.
+ */
+
+ if (n < objc) {
+ charPtr = objv[n];
+ ++n;
+ }
+
+ /*
+ * If there were fewer than 3 args, or args remain, that's an error.
+ */
+
+ if (objc < 3 || n < objc) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "font ?-displayof window? ?option? ?--? ?char?");
+ return TCL_ERROR;
+ }
+
+ /*
+ * The 'charPtr' arg must be a single Unicode.
+ */
+
+ if (charPtr != NULL) {
+ if (Tcl_GetCharLength(charPtr) != 1) {
+ resultPtr = Tcl_NewStringObj(
+ "expected a single character but got \"", -1);
+ Tcl_AppendLimitedToObj(resultPtr, Tcl_GetString(charPtr),
+ -1, 40, "...");
+ Tcl_AppendToObj(resultPtr, "\"", -1);
+ Tcl_SetObjResult(interp, resultPtr);
return TCL_ERROR;
}
- Tcl_AppendResult(interp, name, NULL);
- break;
+ uniChar = Tcl_GetUniChar(charPtr, 0);
+ }
+
+ /*
+ * Find the font.
+ */
+
+ tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
+ if (tkfont == NULL) {
+ return TCL_ERROR;
}
- case FONT_DELETE: {
- int i;
- char *string;
- NamedFont *nfPtr;
- Tcl_HashEntry *namedHashPtr;
+ /*
+ * Determine the font attributes.
+ */
+
+ if (charPtr == NULL) {
+ faPtr = GetFontAttributes(tkfont);
+ } else {
+ TkpGetFontAttrsForChar(tkwin, tkfont, uniChar, &fa);
+ faPtr = &fa;
+ }
+ result = GetAttributeInfoObj(interp, faPtr, optPtr);
+
+ Tk_FreeFont(tkfont);
+ return result;
+ }
+ case FONT_CONFIGURE: {
+ int result;
+ char *string;
+ Tcl_Obj *objPtr;
+ NamedFont *nfPtr;
+ Tcl_HashEntry *namedHashPtr;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "fontname ?options?");
+ return TCL_ERROR;
+ }
+ 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_AppendResult(interp, "named font \"", string,
+ "\" doesn't exist", NULL);
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ objPtr = NULL;
+ } else if (objc == 4) {
+ objPtr = objv[3];
+ } else {
+ result = ConfigAttributesObj(interp, tkwin, objc - 3, objv + 3,
+ &nfPtr->fa);
+ UpdateDependentFonts(fiPtr, tkwin, namedHashPtr);
+ return result;
+ }
+ return GetAttributeInfoObj(interp, &nfPtr->fa, objPtr);
+ }
+ case FONT_CREATE: {
+ int skip, i;
+ char *name;
+ char buf[16 + TCL_INTEGER_SPACE];
+ TkFontAttributes fa;
+ Tcl_HashEntry *namedHashPtr;
+
+ skip = 3;
+ if (objc < 3) {
+ name = NULL;
+ } else {
+ name = Tcl_GetString(objv[2]);
+ if (name[0] == '-') {
+ name = NULL;
+ }
+ }
+ if (name == NULL) {
/*
- * Delete the named font. If there are still widgets using this
- * font, then it isn't deleted right away.
+ * No font name specified. Generate one of the form "fontX".
*/
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "fontname ?fontname ...?");
- return TCL_ERROR;
- }
- for (i = 2; i < objc; i++) {
- string = Tcl_GetString(objv[i]);
- namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, string);
+ for (i = 1; ; i++) {
+ sprintf(buf, "font%d", i);
+ namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, buf);
if (namedHashPtr == NULL) {
- Tcl_AppendResult(interp, "named font \"", string,
- "\" doesn't exist", (char *) NULL);
- return TCL_ERROR;
- }
- nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr);
- if (nfPtr->refCount != 0) {
- nfPtr->deletePending = 1;
- } else {
- Tcl_DeleteHashEntry(namedHashPtr);
- ckfree((char *) nfPtr);
+ break;
}
}
- break;
+ name = buf;
+ skip = 2;
+ }
+ TkInitFontAttributes(&fa);
+ if (ConfigAttributesObj(interp, tkwin, objc - skip, objv + skip,
+ &fa) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (TkCreateNamedFont(interp, tkwin, name, &fa) != TCL_OK) {
+ return TCL_ERROR;
}
- case FONT_FAMILIES: {
- int skip;
+ Tcl_AppendResult(interp, name, NULL);
+ break;
+ }
+ case FONT_DELETE: {
+ int i, result = TCL_OK;
+ char *string;
- skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
- if (skip < 0) {
- return TCL_ERROR;
- }
- if (objc - skip != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
- return TCL_ERROR;
- }
- TkpGetFontFamilies(interp, tkwin);
- break;
+ /*
+ * Delete the named font. If there are still widgets using this font,
+ * then it isn't deleted right away.
+ */
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "fontname ?fontname ...?");
+ return TCL_ERROR;
}
- case FONT_MEASURE: {
- char *string;
- Tk_Font tkfont;
- int length, skip;
- Tcl_Obj *resultPtr;
-
- skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
- if (skip < 0) {
- return TCL_ERROR;
- }
- if (objc - skip != 4) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "font ?-displayof window? text");
- return TCL_ERROR;
- }
- tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
- if (tkfont == NULL) {
- return TCL_ERROR;
- }
- string = Tcl_GetStringFromObj(objv[3 + skip], &length);
- resultPtr = Tcl_GetObjResult(interp);
- Tcl_SetIntObj(resultPtr, Tk_TextWidth(tkfont, string, length));
- Tk_FreeFont(tkfont);
- break;
+ for (i = 2; i < objc && result == TCL_OK; i++) {
+ string = Tcl_GetString(objv[i]);
+ result = TkDeleteNamedFont(interp, tkwin, string);
+ }
+ return result;
+ }
+ case FONT_FAMILIES: {
+ int skip;
+
+ skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);
+ if (skip < 0) {
+ return TCL_ERROR;
}
- case FONT_METRICS: {
- Tk_Font tkfont;
- int skip, index, i;
- CONST TkFontMetrics *fmPtr;
- static CONST char *switches[] = {
- "-ascent", "-descent", "-linespace", "-fixed", NULL
- };
+ if (objc - skip != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
+ return TCL_ERROR;
+ }
+ TkpGetFontFamilies(interp, tkwin);
+ break;
+ }
+ case FONT_MEASURE: {
+ char *string;
+ Tk_Font tkfont;
+ int length = 0, skip = 0;
+ Tcl_Obj *resultPtr;
+ if (objc > 4) {
skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
if (skip < 0) {
return TCL_ERROR;
}
- if ((objc < 3) || ((objc - skip) > 4)) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "font ?-displayof window? ?option?");
- return TCL_ERROR;
- }
- tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
- if (tkfont == NULL) {
+ }
+ if (objc - skip != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "font ?-displayof window? text");
+ return TCL_ERROR;
+ }
+ tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
+ if (tkfont == NULL) {
+ return TCL_ERROR;
+ }
+ string = Tcl_GetStringFromObj(objv[3 + skip], &length);
+ resultPtr = Tcl_GetObjResult(interp);
+ Tcl_SetIntObj(resultPtr, Tk_TextWidth(tkfont, string, length));
+ Tk_FreeFont(tkfont);
+ break;
+ }
+ case FONT_METRICS: {
+ Tk_Font tkfont;
+ int skip, index, i;
+ const TkFontMetrics *fmPtr;
+ static const char *switches[] = {
+ "-ascent", "-descent", "-linespace", "-fixed", NULL
+ };
+
+ skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
+ if (skip < 0) {
+ return TCL_ERROR;
+ }
+ if ((objc < 3) || ((objc - skip) > 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "font ?-displayof window? ?option?");
+ return TCL_ERROR;
+ }
+ tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
+ if (tkfont == NULL) {
+ return TCL_ERROR;
+ }
+ objc -= skip;
+ 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_AppendResult(interp, buf, NULL);
+ } else {
+ if (Tcl_GetIndexFromObj(interp, objv[3], switches, "metric", 0,
+ &index) != TCL_OK) {
+ Tk_FreeFont(tkfont);
return TCL_ERROR;
}
- objc -= skip;
- 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_AppendResult(interp, buf, NULL);
- } else {
- if (Tcl_GetIndexFromObj(interp, objv[3], switches,
- "metric", 0, &index) != TCL_OK) {
- Tk_FreeFont(tkfont);
- return TCL_ERROR;
- }
- i = 0; /* Needed only to prevent compiler
- * warning. */
- switch (index) {
- case 0: i = fmPtr->ascent; break;
- case 1: i = fmPtr->descent; break;
- case 2: i = fmPtr->ascent + fmPtr->descent; break;
- case 3: i = fmPtr->fixed; break;
- }
- Tcl_SetIntObj(Tcl_GetObjResult(interp), i);
+ i = 0; /* Needed only to prevent compiler warning. */
+ switch (index) {
+ case 0: i = fmPtr->ascent; break;
+ case 1: i = fmPtr->descent; break;
+ case 2: i = fmPtr->ascent + fmPtr->descent; break;
+ case 3: i = fmPtr->fixed; break;
}
- Tk_FreeFont(tkfont);
- break;
+ Tcl_SetIntObj(Tcl_GetObjResult(interp), i);
}
- case FONT_NAMES: {
- char *string;
- 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, resultPtr, strPtr);
- }
- namedHashPtr = Tcl_NextHashEntry(&search);
+ Tk_FreeFont(tkfont);
+ break;
+ }
+ case FONT_NAMES: {
+ char *string;
+ 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, resultPtr, strPtr);
}
- break;
+ namedHashPtr = Tcl_NextHashEntry(&search);
}
+ break;
+ }
}
return TCL_OK;
}
@@ -766,10 +821,10 @@ Tk_FontObjCmd(clientData, interp, objc, objv)
*
* 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
- * uses the brute force approach and prepares every widget to
- * recompute its geometry.
+ * Called when the attributes of a named font changes. Updates all the
+ * instantiated fonts that depend on that named font and then uses the
+ * brute force approach and prepares every widget to recompute its
+ * geometry.
*
* Results:
* None.
@@ -781,10 +836,10 @@ Tk_FontObjCmd(clientData, interp, objc, objv)
*/
static void
-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. */
+UpdateDependentFonts(
+ TkFontInfo *fiPtr, /* Info about application's fonts. */
+ Tk_Window tkwin, /* A window in the application. */
+ Tcl_HashEntry *namedHashPtr)/* The named font that is changing. */
{
Tcl_HashEntry *cacheHashPtr;
Tcl_HashSearch search;
@@ -794,8 +849,8 @@ UpdateDependentFonts(fiPtr, tkwin, namedHashPtr)
nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr);
if (nfPtr->refCount == 0) {
/*
- * Well nobody's using this named font, so don't have to tell
- * any widgets to recompute themselves.
+ * Well nobody's using this named font, so don't have to tell any
+ * widgets to recompute themselves.
*/
return;
@@ -818,8 +873,8 @@ UpdateDependentFonts(fiPtr, tkwin, namedHashPtr)
}
static void
-TheWorldHasChanged(clientData)
- ClientData clientData; /* Info about application's fonts. */
+TheWorldHasChanged(
+ ClientData clientData) /* Info about application's fonts. */
{
TkFontInfo *fiPtr;
@@ -830,8 +885,8 @@ TheWorldHasChanged(clientData)
}
static void
-RecomputeWidgets(winPtr)
- TkWindow *winPtr; /* Window to which command is sent. */
+RecomputeWidgets(
+ TkWindow *winPtr) /* Window to which command is sent. */
{
Tk_ClassWorldChangedProc *proc;
proc = Tk_GetClassProc(winPtr->classProcsPtr, worldChangedProc);
@@ -842,22 +897,23 @@ RecomputeWidgets(winPtr)
/*
* Notify all the descendants of this window that the world has changed.
*
- * This could be done recursively or iteratively. The recursive version
- * is easier to implement and understand, and typically, windows with a
- * -font option will be leaf nodes in the widget heirarchy (buttons,
- * labels, etc.), so the recursion depth will be shallow.
+ * This could be done recursively or iteratively. The recursive version is
+ * easier to implement and understand, and typically, windows with a -font
+ * option will be leaf nodes in the widget heirarchy (buttons, labels,
+ * etc.), so the recursion depth will be shallow.
*
- * However, the additional overhead of the recursive calls may become
- * a performance problem if typical usage alters such that -font'ed widgets
- * appear high in the heirarchy, causing deep recursion. This could happen
+ * However, the additional overhead of the recursive calls may become a
+ * performance problem if typical usage alters such that -font'ed widgets
+ * appear high in the heirarchy, causing deep recursion. This could happen
* with text widgets, or more likely with the (not yet existant) labeled
- * frame widget. With these widgets it is possible, even likely, that a
+ * frame widget. With these widgets it is possible, even likely, that a
* -font'ed widget (text or labeled frame) will not be a leaf node, but
- * will instead have many descendants. If this is ever found to cause
- * a performance problem, it may be worth investigating an iterative
- * version of the code below.
+ * will instead have many descendants. If this is ever found to cause a
+ * performance problem, it may be worth investigating an iterative version
+ * of the code below.
*/
- for (winPtr = winPtr->childList; winPtr != NULL; winPtr = winPtr->nextPtr) {
+
+ for (winPtr=winPtr->childList ; winPtr!=NULL ; winPtr=winPtr->nextPtr) {
RecomputeWidgets(winPtr);
}
}
@@ -865,56 +921,57 @@ RecomputeWidgets(winPtr)
/*
*---------------------------------------------------------------------------
*
- * CreateNamedFont --
+ * TkCreateNamedFont --
*
- * Create the specified named font with the given attributes in the
- * named font table associated with the interp.
+ * Create the specified named font with the given attributes in the named
+ * font table associated with the interp.
*
* 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 the interp's result.
+ * 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 the interp's result.
*
* Side effects:
* Assume there used to exist a named font by the specified name, and
* that the named font had been deleted, but there were still some
- * widgets using the named font at the time it was deleted. If a
- * new named font is created with the same name, all those widgets
- * that were using the old named font will be redisplayed using
- * the new named font's attributes.
+ * widgets using the named font at the time it was deleted. If a new
+ * named font is created with the same name, all those widgets that were
+ * using the old named font will be redisplayed using the new named
+ * font's attributes.
*
*---------------------------------------------------------------------------
*/
-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. */
- TkFontAttributes *faPtr; /* Attributes for the new named font. */
+int
+TkCreateNamedFont(
+ Tcl_Interp *interp, /* Interp for error return (can be NULL). */
+ Tk_Window tkwin, /* A window associated with interp. */
+ const char *name, /* Name for the new named font. */
+ TkFontAttributes *faPtr) /* Attributes for the new named font. */
{
TkFontInfo *fiPtr;
Tcl_HashEntry *namedHashPtr;
- int new;
- NamedFont *nfPtr;
+ int isNew;
+ NamedFont *nfPtr;
fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;
- namedHashPtr = Tcl_CreateHashEntry(&fiPtr->namedTable, name, &new);
-
- if (new == 0) {
+ namedHashPtr = Tcl_CreateHashEntry(&fiPtr->namedTable, name, &isNew);
+
+ if (!isNew) {
nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr);
if (nfPtr->deletePending == 0) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "named font \"", name,
- "\" already exists", (char *) NULL);
+ if (interp) {
+ Tcl_AppendResult(interp, "named font \"", name,
+ "\" already exists", NULL);
+ }
return TCL_ERROR;
}
/*
- * Recreating a named font with the same name as a previous
- * named font. Some widgets were still using that named
- * font, so they need to get redisplayed.
+ * Recreating a named font with the same name as a previous named
+ * font. Some widgets were still using that named font, so they need
+ * to get redisplayed.
*/
nfPtr->fa = *faPtr;
@@ -927,7 +984,7 @@ CreateNamedFont(interp, tkwin, name, faPtr)
nfPtr->deletePending = 0;
Tcl_SetHashValue(namedHashPtr, nfPtr);
nfPtr->fa = *faPtr;
- nfPtr->refCount = 0;
+ nfPtr->refCount = 0;
nfPtr->deletePending = 0;
return TCL_OK;
}
@@ -935,76 +992,116 @@ CreateNamedFont(interp, tkwin, name, faPtr)
/*
*---------------------------------------------------------------------------
*
- * Tk_GetFont --
+ * TkDeleteNamedFont --
+ *
+ * Delete the named font. If there are still widgets using this font,
+ * then it isn't deleted right away.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TkDeleteNamedFont(
+ Tcl_Interp *interp, /* Interp for error return (can be NULL). */
+ Tk_Window tkwin, /* A window associated with interp. */
+ CONST char *name) /* Name for the new named font. */
+{
+ TkFontInfo *fiPtr;
+ NamedFont *nfPtr;
+ Tcl_HashEntry *namedHashPtr;
+
+ fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;
+
+ namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, name);
+ if (namedHashPtr == NULL) {
+ if (interp) {
+ Tcl_AppendResult(interp, "named font \"", name,
+ "\" doesn't exist", NULL);
+ }
+ return TCL_ERROR;
+ }
+ nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr);
+ if (nfPtr->refCount != 0) {
+ nfPtr->deletePending = 1;
+ } else {
+ Tcl_DeleteHashEntry(namedHashPtr);
+ ckfree((char *) nfPtr);
+ }
+ return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tk_GetFont --
*
* Given a string description of a font, map the description to a
* corresponding Tk_Font that represents the font.
*
* 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 the interp's result.
+ * 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 the interp's result.
*
* 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() or Tk_FreeFontFromObj() so that the
- * database is cleaned up when fonts aren't in use anymore.
+ * The font is added to an internal database with a reference count. For
+ * each call to this function, 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.
*
*---------------------------------------------------------------------------
*/
Tk_Font
-Tk_GetFont(interp, tkwin, string)
- Tcl_Interp *interp; /* Interp for database and error return, or
- * NULL for no error messages. */
- Tk_Window tkwin; /* For display on which font will be used. */
- CONST char *string; /* String describing font, as: named font,
+Tk_GetFont(
+ Tcl_Interp *interp, /* Interp for database and error return. */
+ Tk_Window tkwin, /* For display on which font will be used. */
+ const char *string) /* String describing font, as: named font,
* native format, or parseable string. */
{
- Tk_Font tkfont;
+ Tk_Font tkfont;
Tcl_Obj *strPtr;
strPtr = Tcl_NewStringObj((char *) string, -1);
Tcl_IncrRefCount(strPtr);
tkfont = Tk_AllocFontFromObj(interp, tkwin, strPtr);
- Tcl_DecrRefCount(strPtr);
+ Tcl_DecrRefCount(strPtr);
return tkfont;
}
/*
*---------------------------------------------------------------------------
*
- * Tk_AllocFontFromObj --
+ * Tk_AllocFontFromObj --
*
* Given a string description of a font, map the description to a
* corresponding Tk_Font that represents the font.
*
* 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's result object (if non-NULL).
+ * 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's result object.
*
* 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() or Tk_FreeFontFromObj() so that the
- * database is cleaned up when fonts aren't in use anymore.
+ * The font is added to an internal database with a reference count. For
+ * each call to this function, 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.
*
*---------------------------------------------------------------------------
*/
Tk_Font
-Tk_AllocFontFromObj(interp, tkwin, objPtr)
- Tcl_Interp *interp; /* Interp for database and error return. */
- Tk_Window tkwin; /* For screen on which font will be used. */
- Tcl_Obj *objPtr; /* Object describing font, as: named font,
+Tk_AllocFontFromObj(
+ Tcl_Interp *interp, /* Interp for database and error return. */
+ 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;
Tcl_HashEntry *cacheHashPtr, *namedHashPtr;
TkFont *fontPtr, *firstFontPtr, *oldFontPtr;
- int new, descent;
+ int isNew, descent;
NamedFont *nfPtr;
fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;
@@ -1017,8 +1114,8 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr)
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.
+ * This is a stale reference: it refers to a TkFont that's no
+ * longer in use. Clear the reference.
*/
FreeFontObjProc(objPtr);
@@ -1030,17 +1127,17 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr)
}
/*
- * Next, search the list of fonts that have the name we want, to see
- * if one of them is for the right screen.
+ * 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;
+ isNew = 0;
if (oldFontPtr != NULL) {
cacheHashPtr = oldFontPtr->cacheHashPtr;
FreeFontObjProc(objPtr);
} else {
cacheHashPtr = Tcl_CreateHashEntry(&fiPtr->fontCache,
- Tcl_GetString(objPtr), &new);
+ Tcl_GetString(objPtr), &isNew);
}
firstFontPtr = (TkFont *) Tcl_GetHashValue(cacheHashPtr);
for (fontPtr = firstFontPtr; (fontPtr != NULL);
@@ -1048,13 +1145,13 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr)
if (Tk_Screen(tkwin) == fontPtr->screen) {
fontPtr->resourceRefCount++;
fontPtr->objRefCount++;
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) fontPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr;
return (Tk_Font) fontPtr;
}
}
/*
- * The desired font isn't in the table. Make a new one.
+ * The desired font isn't in the table. Make a new one.
*/
namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable,
@@ -1079,7 +1176,7 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr)
Tcl_Obj *dupObjPtr = Tcl_DuplicateObj(objPtr);
if (ParseFontNameObj(interp, tkwin, dupObjPtr, &fa) != TCL_OK) {
- if (new) {
+ if (isNew) {
Tcl_DeleteHashEntry(cacheHashPtr);
}
Tcl_DecrRefCount(dupObjPtr);
@@ -1095,6 +1192,19 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr)
}
}
+ /*
+ * Detect the system font engine going wrong and fail more gracefully.
+ */
+
+ if (fontPtr == NULL) {
+ if (isNew) {
+ Tcl_DeleteHashEntry(cacheHashPtr);
+ }
+ Tcl_AppendResult(interp, "failed to allocate font due to ",
+ "internal system font engine problem", NULL);
+ return NULL;
+ }
+
fontPtr->resourceRefCount = 1;
fontPtr->objRefCount = 1;
fontPtr->cacheHashPtr = cacheHashPtr;
@@ -1122,7 +1232,7 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr)
* Get information used for drawing underlines in generic code on a
* non-underlined font.
*/
-
+
descent = fontPtr->fm.descent;
fontPtr->underlinePos = descent / 2;
fontPtr->underlineHeight = TkFontGetPixels(tkwin, fontPtr->fa.size) / 10;
@@ -1131,9 +1241,9 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr)
}
if (fontPtr->underlinePos + fontPtr->underlineHeight > descent) {
/*
- * If this set of values would cause the bottom of the underline
- * bar to stick below the descent of the font, jack the underline
- * up a bit higher.
+ * If this set of values would cause the bottom of the underline bar
+ * to stick below the descent of the font, jack the underline up a bit
+ * higher.
*/
fontPtr->underlineHeight = descent - fontPtr->underlinePos;
@@ -1142,8 +1252,8 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr)
fontPtr->underlineHeight = 1;
}
}
-
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) fontPtr;
+
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr;
return (Tk_Font) fontPtr;
}
@@ -1152,31 +1262,31 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr)
*
* Tk_GetFontFromObj --
*
- * Find the font that corresponds to a given object. The font must
- * have already been created by Tk_GetFont or Tk_AllocFontFromObj.
+ * 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.
+ * 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.
+ * 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. */
+Tk_GetFontFromObj(
+ 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 != &tkFontObjType) {
- SetFontFromAny((Tcl_Interp *) NULL, objPtr);
+ SetFontFromAny(NULL, objPtr);
}
fontPtr = (TkFont *) objPtr->internalRep.twoPtrValue.ptr1;
@@ -1184,8 +1294,8 @@ Tk_GetFontFromObj(tkwin, objPtr)
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.
+ * This is a stale reference: it refers to a TkFont that's no
+ * longer in use. Clear the reference.
*/
FreeFontObjProc(objPtr);
@@ -1196,8 +1306,8 @@ Tk_GetFontFromObj(tkwin, objPtr)
}
/*
- * Next, search the list of fonts that have the name we want, to see
- * if one of them is for the right screen.
+ * 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) {
@@ -1211,13 +1321,13 @@ Tk_GetFontFromObj(tkwin, objPtr)
fontPtr = fontPtr->nextPtr) {
if (Tk_Screen(tkwin) == fontPtr->screen) {
fontPtr->objRefCount++;
- objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) fontPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr;
return (Tk_Font) fontPtr;
}
}
}
- panic("Tk_GetFontFromObj called with non-existent font!");
+ Tcl_Panic("Tk_GetFontFromObj called with non-existent font!");
return NULL;
}
@@ -1226,28 +1336,28 @@ Tk_GetFontFromObj(tkwin, objPtr)
*
* SetFontFromAny --
*
- * Convert the internal representation of a Tcl object to the
- * font internal form.
+ * 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 tkFontObjType.
- * The TkFont pointer is NULL.
+ * The object is left with its typePtr pointing to tkFontObjType. 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. */
+SetFontFromAny(
+ Tcl_Interp *interp, /* Used for error reporting if not NULL. */
+ Tcl_Obj *objPtr) /* The object to convert. */
{
- Tcl_ObjType *typePtr;
+ const Tcl_ObjType *typePtr;
/*
- * Free the old internalRep before setting the new one.
+ * Free the old internalRep before setting the new one.
*/
Tcl_GetString(objPtr);
@@ -1269,10 +1379,10 @@ SetFontFromAny(interp, objPtr)
* Given a font, return a textual string identifying it.
*
* Results:
- * The return value is the description that was passed to
- * Tk_GetFont() to create the font. The storage for the returned
- * string is only guaranteed to persist until the font is deleted.
- * The caller should not modify this string.
+ * The return value is the description that was passed to Tk_GetFont() to
+ * create the font. The storage for the returned string is only
+ * guaranteed to persist until the font is deleted. The caller should not
+ * modify this string.
*
* Side effects:
* None.
@@ -1280,9 +1390,9 @@ SetFontFromAny(interp, objPtr)
*---------------------------------------------------------------------------
*/
-CONST char *
-Tk_NameOfFont(tkfont)
- Tk_Font tkfont; /* Font whose name is desired. */
+const char *
+Tk_NameOfFont(
+ Tk_Font tkfont) /* Font whose name is desired. */
{
TkFont *fontPtr;
@@ -1293,7 +1403,7 @@ Tk_NameOfFont(tkfont)
/*
*---------------------------------------------------------------------------
*
- * Tk_FreeFont --
+ * Tk_FreeFont --
*
* Called to release a font allocated by Tk_GetFont().
*
@@ -1301,15 +1411,15 @@ Tk_NameOfFont(tkfont)
* None.
*
* Side effects:
- * The reference count associated with font is decremented, and
- * only deallocated when no one is using it.
+ * The reference count associated with font is decremented, and only
+ * deallocated when no one is using it.
*
*---------------------------------------------------------------------------
*/
void
-Tk_FreeFont(tkfont)
- Tk_Font tkfont; /* Font to be released. */
+Tk_FreeFont(
+ Tk_Font tkfont) /* Font to be released. */
{
TkFont *fontPtr, *prevPtr;
NamedFont *nfPtr;
@@ -1324,9 +1434,8 @@ Tk_FreeFont(tkfont)
}
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.
+ * 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);
@@ -1341,7 +1450,7 @@ Tk_FreeFont(tkfont)
if (prevPtr == fontPtr) {
if (fontPtr->nextPtr == NULL) {
Tcl_DeleteHashEntry(fontPtr->cacheHashPtr);
- } else {
+ } else {
Tcl_SetHashValue(fontPtr->cacheHashPtr, fontPtr->nextPtr);
}
} else {
@@ -1360,7 +1469,7 @@ Tk_FreeFont(tkfont)
/*
*---------------------------------------------------------------------------
*
- * Tk_FreeFontFromObj --
+ * 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.
@@ -1369,17 +1478,17 @@ Tk_FreeFont(tkfont)
* None.
*
* Side effects:
- * The reference count associated with font is decremented, and
- * only deallocated when no one is using it.
+ * 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_FreeFontFromObj(
+ 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));
}
@@ -1387,26 +1496,25 @@ Tk_FreeFontFromObj(tkwin, objPtr)
/*
*---------------------------------------------------------------------------
*
- * FreeFontObjProc --
+ * 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.
+ * 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.
+ * 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. */
+FreeFontObjProc(
+ Tcl_Obj *objPtr) /* The object we are releasing. */
{
TkFont *fontPtr = (TkFont *) objPtr->internalRep.twoPtrValue.ptr1;
@@ -1422,30 +1530,30 @@ FreeFontObjProc(objPtr)
/*
*---------------------------------------------------------------------------
*
- * DupFontObjProc --
+ * DupFontObjProc --
*
- * When a cached font object is duplicated, this is called to
- * update the internal reps.
+ * 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.
+ * 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. */
+DupFontObjProc(
+ 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;
+ dupObjPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr;
if (fontPtr != NULL) {
fontPtr->objRefCount++;
@@ -1457,10 +1565,10 @@ DupFontObjProc(srcObjPtr, dupObjPtr)
*
* Tk_FontId --
*
- * Given a font, return an opaque handle that should be selected
- * into the XGCValues structure in order to get the constructed
- * gc to use this font. This procedure would go away if the
- * XGCValues structure were replaced with a TkGCValues structure.
+ * Given a font, return an opaque handle that should be selected into the
+ * XGCValues structure in order to get the constructed gc to use this
+ * font. This function would go away if the XGCValues structure were
+ * replaced with a TkGCValues structure.
*
* Results:
* As above.
@@ -1472,8 +1580,9 @@ DupFontObjProc(srcObjPtr, dupObjPtr)
*/
Font
-Tk_FontId(tkfont)
- Tk_Font tkfont; /* Font that is going to be selected into GC. */
+Tk_FontId(
+ Tk_Font tkfont) /* Font that is going to be selected into
+ * GC. */
{
TkFont *fontPtr;
@@ -1486,26 +1595,27 @@ Tk_FontId(tkfont)
*
* Tk_GetFontMetrics --
*
- * Returns overall ascent and descent metrics for the given font.
- * These values can be used to space multiple lines of text and
- * to align the baselines of text in different fonts.
+ * Returns overall ascent and descent metrics for the given font. These
+ * values can be used to space multiple lines of text and to align the
+ * baselines of text in different fonts.
*
* Results:
- * If *heightPtr is non-NULL, it is filled with the overall height
- * of the font, which is the sum of the ascent and descent.
- * If *ascentPtr or *descentPtr is non-NULL, they are filled with
- * the ascent and/or descent information for the font.
+ * If *heightPtr is non-NULL, it is filled with the overall height of the
+ * font, which is the sum of the ascent and descent. If *ascentPtr or
+ * *descentPtr is non-NULL, they are filled with the ascent and/or
+ * descent information for the font.
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
+
void
-Tk_GetFontMetrics(tkfont, fmPtr)
- Tk_Font tkfont; /* Font in which metrics are calculated. */
- Tk_FontMetrics *fmPtr; /* Pointer to structure in which font
- * metrics for tkfont will be stored. */
+Tk_GetFontMetrics(
+ Tk_Font tkfont, /* Font in which metrics are calculated. */
+ Tk_FontMetrics *fmPtr) /* Pointer to structure in which font metrics
+ * for tkfont will be stored. */
{
TkFont *fontPtr;
@@ -1520,33 +1630,32 @@ Tk_GetFontMetrics(tkfont, fmPtr)
*
* Tk_PostscriptFontName --
*
- * Given a Tk_Font, return the name of the corresponding Postscript
- * font.
+ * Given a Tk_Font, return the name of the corresponding Postscript font.
*
* Results:
- * The return value is the pointsize of the given Tk_Font.
- * The name of the Postscript font is appended to dsPtr.
+ * The return value is the pointsize of the given Tk_Font. The name of
+ * the Postscript font is appended to dsPtr.
*
* Side effects:
- * If the font does not exist on the printer, the print job will
- * fail at print time. Given a "reasonable" Postscript printer,
- * the following Tk_Font font families should print correctly:
+ * If the font does not exist on the printer, the print job will fail at
+ * print time. Given a "reasonable" Postscript printer, the following
+ * Tk_Font font families should print correctly:
*
* Avant Garde, Arial, Bookman, Courier, Courier New, Geneva,
* Helvetica, Monaco, New Century Schoolbook, New York,
* Palatino, Symbol, Times, Times New Roman, Zapf Chancery,
* and Zapf Dingbats.
*
- * Any other Tk_Font font families may not print correctly
- * because the computed Postscript font name may be incorrect.
+ * Any other Tk_Font font families may not print correctly because the
+ * computed Postscript font name may be incorrect.
*
*---------------------------------------------------------------------------
*/
int
-Tk_PostscriptFontName(tkfont, dsPtr)
- Tk_Font tkfont; /* Font in which text will be printed. */
- Tcl_DString *dsPtr; /* Pointer to an initialized Tcl_DString to
+Tk_PostscriptFontName(
+ Tk_Font tkfont, /* Font in which text will be printed. */
+ Tcl_DString *dsPtr) /* Pointer to an initialized Tcl_DString to
* which the name of the Postscript font that
* corresponds to tkfont will be appended. */
{
@@ -1559,9 +1668,9 @@ Tk_PostscriptFontName(tkfont, dsPtr)
fontPtr = (TkFont *) tkfont;
/*
- * Convert the case-insensitive Tk_Font family name to the
- * case-sensitive Postscript family name. Take out any spaces and
- * capitalize the first letter of each word.
+ * Convert the case-insensitive Tk_Font family name to the case-sensitive
+ * Postscript family name. Take out any spaces and capitalize the first
+ * letter of each word.
*/
family = fontPtr->fa.family;
@@ -1589,8 +1698,8 @@ Tk_PostscriptFontName(tkfont, dsPtr)
/*
* Inline, capitalize the first letter of each word, lowercase the
* rest of the letters in each word, and then take out the spaces
- * between the words. This may make the DString shorter, which is
- * safe to do.
+ * between the words. This may make the DString shorter, which is safe
+ * to do.
*/
Tcl_DStringAppend(dsPtr, family, -1);
@@ -1607,7 +1716,7 @@ Tk_PostscriptFontName(tkfont, dsPtr)
ch = Tcl_UniCharToUpper(ch);
upper = 0;
} else {
- ch = Tcl_UniCharToLower(ch);
+ ch = Tcl_UniCharToLower(ch);
}
dest += Tcl_UniCharToUtf(ch, dest);
}
@@ -1655,14 +1764,12 @@ Tk_PostscriptFontName(tkfont, dsPtr)
slantString = NULL;
if (fontPtr->fa.slant == TK_FS_ROMAN) {
;
+ } else if ((strcmp(family, "Helvetica") == 0)
+ || (strcmp(family, "Courier") == 0)
+ || (strcmp(family, "AvantGarde") == 0)) {
+ slantString = "Oblique";
} else {
- if ((strcmp(family, "Helvetica") == 0)
- || (strcmp(family, "Courier") == 0)
- || (strcmp(family, "AvantGarde") == 0)) {
- slantString = "Oblique";
- } else {
- slantString = "Italic";
- }
+ slantString = "Italic";
}
/*
@@ -1671,7 +1778,7 @@ Tk_PostscriptFontName(tkfont, dsPtr)
*/
if ((slantString == NULL) && (weightString == NULL)) {
- if ((strcmp(family, "Times") == 0)
+ if ((strcmp(family, "Times") == 0)
|| (strcmp(family, "NewCenturySchlbk") == 0)
|| (strcmp(family, "Palatino") == 0)) {
Tcl_DStringAppend(dsPtr, "-Roman", -1);
@@ -1695,8 +1802,8 @@ Tk_PostscriptFontName(tkfont, dsPtr)
* Tk_TextWidth --
*
* A wrapper function for the more complicated interface of
- * Tk_MeasureChars. Computes how much space the given
- * simple string needs.
+ * Tk_MeasureChars. Computes how much space the given simple string
+ * needs.
*
* Results:
* The return value is the width (in pixels) of the given string.
@@ -1708,11 +1815,11 @@ Tk_PostscriptFontName(tkfont, dsPtr)
*/
int
-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 numBytes; /* Number of bytes to consider from
- * string, or < 0 for strlen(). */
+Tk_TextWidth(
+ Tk_Font tkfont, /* Font in which text will be measured. */
+ const char *string, /* String whose width will be computed. */
+ int numBytes) /* Number of bytes to consider from string, or
+ * < 0 for strlen(). */
{
int width;
@@ -1726,15 +1833,15 @@ Tk_TextWidth(tkfont, string, numBytes)
/*
*---------------------------------------------------------------------------
*
- * Tk_UnderlineChars --
+ * Tk_UnderlineChars, TkUnderlineCharsInContext --
*
- * This procedure draws an underline for a given range of characters
- * in a given string. It doesn't draw the characters (which are
- * assumed to have been displayed previously); it just draws the
- * underline. This procedure would mainly be used to quickly
- * underline a few characters without having to construct an
- * underlined font. To produce properly underlined text, the
- * appropriate underlined font should be constructed and used.
+ * These procedures draw an underline for a given range of characters in
+ * a given string. They don't draw the characters (which are assumed to
+ * have been displayed previously); they just draw the underline. These
+ * procedures would mainly be used to quickly underline a few characters
+ * without having to construct an underlined font. To produce properly
+ * underlined text, the appropriate underlined font should be constructed
+ * and used.
*
* Results:
* None.
@@ -1746,30 +1853,53 @@ Tk_TextWidth(tkfont, string, numBytes)
*/
void
-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
+Tk_UnderlineChars(
+ Display *display, /* Display on which to draw. */
+ Drawable drawable, /* Window or pixmap in which to draw. */
+ GC gc, /* Graphics context for actually drawing
* line. */
- Tk_Font tkfont; /* Font used in GC; must have been allocated
- * by Tk_GetFont(). Used for character
+ Tk_Font tkfont, /* Font used in GC; must have been allocated
+ * by Tk_GetFont(). Used for character
* dimensions, etc. */
- CONST char *string; /* String containing characters to be
+ const char *string, /* String containing characters to be
* underlined or overstruck. */
- int x, y; /* Coordinates at which first character of
+ int x, int y, /* Coordinates at which first character of
* string is drawn. */
- int firstByte; /* Index of first byte of first character. */
- int lastByte; /* Index of first byte after the last
+ int firstByte, /* Index of first byte of first character. */
+ int lastByte) /* Index of first byte after the last
+ * character. */
+{
+ TkUnderlineCharsInContext(display, drawable, gc, tkfont, string,
+ lastByte, x, y, firstByte, lastByte);
+}
+
+void
+TkUnderlineCharsInContext(
+ Display *display, /* Display on which to draw. */
+ Drawable drawable, /* Window or pixmap in which to draw. */
+ GC gc, /* Graphics context for actually drawing
+ * line. */
+ Tk_Font tkfont, /* Font used in GC; must have been allocated
+ * by Tk_GetFont(). Used for character
+ * dimensions, etc. */
+ const char *string, /* String containing characters to be
+ * underlined or overstruck. */
+ int numBytes, /* Number of bytes in string. */
+ int x, int y, /* Coordinates at which the first character of
+ * the whole string would be drawn. */
+ 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, firstByte, -1, 0, &startX);
- Tk_MeasureChars(tkfont, string, lastByte, -1, 0, &endX);
+
+ TkpMeasureCharsInContext(tkfont, string, numBytes, 0, firstByte, -1, 0,
+ &startX);
+ TkpMeasureCharsInContext(tkfont, string, numBytes, 0, lastByte, -1, 0,
+ &endX);
XFillRectangle(display, drawable, gc, x + startX,
y + fontPtr->underlinePos, (unsigned int) (endX - startX),
@@ -1781,66 +1911,60 @@ Tk_UnderlineChars(display, drawable, gc, tkfont, string, x, y, firstByte,
*
* Tk_ComputeTextLayout --
*
- * Computes the amount of screen space needed to display a
- * multi-line, justified string of text. Records all the
- * measurements that were done to determine to size and
- * positioning of the individual lines of text; this information
- * can be used by the Tk_DrawTextLayout() procedure to
+ * Computes the amount of screen space needed to display a multi-line,
+ * justified string of text. Records all the measurements that were done
+ * to determine to size and positioning of the individual lines of text;
+ * this information can be used by the Tk_DrawTextLayout() function to
* display the text quickly (without remeasuring it).
*
- * This procedure is useful for simple widgets that want to
- * display single-font, multi-line text and want Tk to handle the
- * details.
+ * This function is useful for simple widgets that want to display
+ * single-font, multi-line text and want Tk to handle the details.
*
* Results:
- * The return value is a Tk_TextLayout token that holds the
- * measurement information for the given string. The token is
- * only valid for the given string. If the string is freed,
- * the token is no longer valid and must also be freed. To free
- * the token, call Tk_FreeTextLayout().
+ * The return value is a Tk_TextLayout token that holds the measurement
+ * information for the given string. The token is only valid for the
+ * given string. If the string is freed, the token is no longer valid and
+ * must also be freed. To free the token, call Tk_FreeTextLayout().
*
- * The dimensions of the screen area needed to display the text
- * are stored in *widthPtr and *heightPtr.
+ * The dimensions of the screen area needed to display the text are
+ * stored in *widthPtr and *heightPtr.
*
* Side effects:
- * Memory is allocated to hold the measurement information.
+ * Memory is allocated to hold the measurement information.
*
*---------------------------------------------------------------------------
*/
Tk_TextLayout
-Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
- widthPtr, heightPtr)
- Tk_Font tkfont; /* Font that will be used to display text. */
- CONST char *string; /* String whose dimensions are to be
+Tk_ComputeTextLayout(
+ Tk_Font tkfont, /* Font that will be used to display text. */
+ const char *string, /* String whose dimensions are to be
* computed. */
- int numChars; /* Number of characters to consider from
+ int numChars, /* Number of characters to consider from
* string, or < 0 for strlen(). */
- int wrapLength; /* Longest permissible line length, in
- * pixels. <= 0 means no automatic wrapping:
- * just let lines get as long as needed. */
- Tk_Justify justify; /* How to justify lines. */
- int flags; /* Flag bits OR-ed together.
- * TK_IGNORE_TABS means that tab characters
- * should not be expanded. TK_IGNORE_NEWLINES
- * means that newline characters should not
- * cause a line break. */
- int *widthPtr; /* Filled with width of string. */
- int *heightPtr; /* Filled with height of string. */
+ int wrapLength, /* Longest permissible line length, in pixels.
+ * <= 0 means no automatic wrapping: just let
+ * lines get as long as needed. */
+ Tk_Justify justify, /* How to justify lines. */
+ int flags, /* Flag bits OR-ed together. TK_IGNORE_TABS
+ * means that tab characters should not be
+ * expanded. TK_IGNORE_NEWLINES means that
+ * newline characters should not cause a line
+ * break. */
+ int *widthPtr, /* Filled with width of string. */
+ int *heightPtr) /* Filled with height of string. */
{
TkFont *fontPtr;
- CONST char *start, *end, *special;
- int n, y, bytesThisChunk, maxChunks;
- int baseline, height, curX, newX, maxWidth;
+ const char *start, *end, *special;
+ int n, y, bytesThisChunk, maxChunks, curLine, layoutHeight;
+ int baseline, height, curX, newX, maxWidth, *lineLengths;
TextLayout *layoutPtr;
LayoutChunk *chunkPtr;
- CONST TkFontMetrics *fmPtr;
+ const TkFontMetrics *fmPtr;
Tcl_DString lineBuffer;
- int *lineLengths;
- int curLine, layoutHeight;
Tcl_DStringInit(&lineBuffer);
-
+
fontPtr = (TkFont *) tkfont;
if ((fontPtr == NULL) || (string == NULL)) {
if (widthPtr != NULL) {
@@ -1865,11 +1989,11 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
maxChunks = 1;
- layoutPtr = (TextLayout *) ckalloc(sizeof(TextLayout)
- + (maxChunks - 1) * sizeof(LayoutChunk));
- layoutPtr->tkfont = tkfont;
- layoutPtr->string = string;
- layoutPtr->numChunks = 0;
+ layoutPtr = (TextLayout *)
+ ckalloc(sizeof(TextLayout) + (maxChunks-1) * sizeof(LayoutChunk));
+ layoutPtr->tkfont = tkfont;
+ layoutPtr->string = string;
+ layoutPtr->numChunks = 0;
baseline = fmPtr->ascent;
maxWidth = 0;
@@ -1884,7 +2008,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
special = string;
flags &= TK_IGNORE_TABS | TK_IGNORE_NEWLINES;
- flags |= TK_WHOLE_WORDS | TK_AT_LEAST_ONE;
+ flags |= TK_WHOLE_WORDS | TK_AT_LEAST_ONE;
for (start = string; start < end; ) {
if (start >= special) {
/*
@@ -1892,7 +2016,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
*
* 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
+ * UTF-8. At some point we may need to support the full Unicode
* whitespace set.
*/
@@ -1912,7 +2036,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
/*
* Special points at the next special character (or the end of the
- * string). Process characters between start and special.
+ * string). Process characters between start and special.
*/
chunkPtr = NULL;
@@ -1924,7 +2048,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
if (bytesThisChunk > 0) {
chunkPtr = NewChunk(&layoutPtr, &maxChunks, start,
bytesThisChunk, curX, newX, baseline);
-
+
start += bytesThisChunk;
curX = newX;
}
@@ -1934,8 +2058,8 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
/*
* Handle the special character.
*
- * INTL: Special will be pointing at a 7-bit character so we
- * can safely treat it as a single byte.
+ * INTL: Special will be pointing at a 7-bit character so we can
+ * safely treat it as a single byte.
*/
chunkPtr = NULL;
@@ -1955,7 +2079,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
flags &= ~TK_AT_LEAST_ONE;
continue;
}
- } else {
+ } else {
NewChunk(&layoutPtr, &maxChunks, start, 1, curX, curX,
baseline)->numDisplayChars = -1;
start++;
@@ -1964,9 +2088,9 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
}
/*
- * No more characters are going to go on this line, either because
- * no more characters can fit or there are no more characters left.
- * Consume all extra spaces at end of line.
+ * No more characters are going to go on this line, either because no
+ * more characters can fit or there are no more characters left.
+ * Consume all extra spaces at end of line.
*/
while ((start < end) && isspace(UCHAR(*start))) { /* INTL: ISO space */
@@ -1983,12 +2107,12 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
start++;
}
if (chunkPtr != NULL) {
- CONST char *end;
+ const char *end;
/*
- * Append all the extra spaces on this line to the end of the
- * last text chunk. This is a little tricky because we are
- * switching back and forth between characters and bytes.
+ * Append all the extra spaces on this line to the end of the last
+ * text chunk. This is a little tricky because we are switching
+ * back and forth between characters and bytes.
*/
end = chunkPtr->start + chunkPtr->numBytes;
@@ -2002,7 +2126,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
}
}
- wrapLine:
+ wrapLine:
flags |= TK_AT_LEAST_ONE;
/*
@@ -2015,8 +2139,8 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
}
/*
- * Remember width of this line, so that all chunks on this line
- * can be centered or right justified, if necessary.
+ * Remember width of this line, so that all chunks on this line can be
+ * centered or right justified, if necessary.
*/
Tcl_DStringAppend(&lineBuffer, (char *) &curX, sizeof(curX));
@@ -2026,9 +2150,8 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
}
/*
- * If last line ends with a newline, then we need to make a 0 width
- * chunk on the next line. Otherwise "Hello" and "Hello\n" are the
- * same height.
+ * If last line ends with a newline, then we need to make a 0 width chunk
+ * on the next line. Otherwise "Hello" and "Hello\n" are the same height.
*/
if ((layoutPtr->numChunks > 0) && ((flags & TK_IGNORE_NEWLINES) == 0)) {
@@ -2039,7 +2162,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
Tcl_DStringAppend(&lineBuffer, (char *) &curX, sizeof(curX));
baseline += height;
}
- }
+ }
layoutPtr->width = maxWidth;
layoutHeight = baseline - fmPtr->ascent;
@@ -2047,9 +2170,9 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
layoutHeight = height;
/*
- * This fake chunk is used by the other procedures so that they can
- * pretend that there is a chunk with no chars in it, which makes
- * the coding simpler.
+ * This fake chunk is used by the other functions so that they can
+ * pretend that there is a chunk with no chars in it, which makes the
+ * coding simpler.
*/
layoutPtr->numChunks = 1;
@@ -2066,7 +2189,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
* Using maximum line length, shift all the chunks so that the lines
* are all justified correctly.
*/
-
+
curLine = 0;
chunkPtr = layoutPtr->chunks;
y = chunkPtr->y;
@@ -2104,8 +2227,8 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
*
* Tk_FreeTextLayout --
*
- * This procedure is called to release the storage associated with
- * a Tk_TextLayout when it is no longer needed.
+ * This function is called to release the storage associated with a
+ * Tk_TextLayout when it is no longer needed.
*
* Results:
* None.
@@ -2117,8 +2240,8 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags,
*/
void
-Tk_FreeTextLayout(textLayout)
- Tk_TextLayout textLayout; /* The text layout to be released. */
+Tk_FreeTextLayout(
+ Tk_TextLayout textLayout) /* The text layout to be released. */
{
TextLayout *layoutPtr;
@@ -2136,9 +2259,8 @@ Tk_FreeTextLayout(textLayout)
* Use the information in the Tk_TextLayout token to display a
* multi-line, justified string of text.
*
- * This procedure is useful for simple widgets that need to
- * display single-font, multi-line text and want Tk to handle
- * the details.
+ * This function is useful for simple widgets that need to display
+ * single-font, multi-line text and want Tk to handle the details.
*
* Results:
* None.
@@ -2150,25 +2272,25 @@ Tk_FreeTextLayout(textLayout)
*/
void
-Tk_DrawTextLayout(display, drawable, gc, layout, x, y, firstChar, lastChar)
- Display *display; /* Display on which to draw. */
- Drawable drawable; /* Window or pixmap in which to draw. */
- GC gc; /* Graphics context to use for drawing text. */
- Tk_TextLayout layout; /* Layout information, from a previous call
- * to Tk_ComputeTextLayout(). */
- int x, y; /* Upper-left hand corner of rectangle in
+Tk_DrawTextLayout(
+ Display *display, /* Display on which to draw. */
+ Drawable drawable, /* Window or pixmap in which to draw. */
+ GC gc, /* Graphics context to use for drawing text. */
+ Tk_TextLayout layout, /* Layout information, from a previous call to
+ * Tk_ComputeTextLayout(). */
+ int x, int y, /* Upper-left hand corner of rectangle in
* which to draw (pixels). */
- int firstChar; /* The index of the first character to draw
- * from the given text item. 0 specfies the
+ int firstChar, /* The index of the first character to draw
+ * from the given text item. 0 specfies the
* beginning. */
- int lastChar; /* The index just after the last character
- * to draw from the given text item. A number
- * < 0 means to draw all characters. */
+ int lastChar) /* The index just after the last character to
+ * draw from the given text item. A number < 0
+ * means to draw all characters. */
{
TextLayout *layoutPtr;
int i, numDisplayChars, drawX;
- CONST char *firstByte;
- CONST char *lastByte;
+ const char *firstByte;
+ const char *lastByte;
LayoutChunk *chunkPtr;
layoutPtr = (TextLayout *) layout;
@@ -2214,15 +2336,14 @@ Tk_DrawTextLayout(display, drawable, gc, layout, x, y, firstChar, lastChar)
*
* Tk_UnderlineTextLayout --
*
- * Use the information in the Tk_TextLayout token to display an
- * underline below an individual character. This procedure does
- * not draw the text, just the underline.
+ * Use the information in the Tk_TextLayout token to display an underline
+ * below an individual character. This function does not draw the text,
+ * just the underline.
*
- * This procedure is useful for simple widgets that need to
- * display single-font, multi-line text with an individual
- * character underlined and want Tk to handle the details.
- * To display larger amounts of underlined text, construct
- * and use an underlined font.
+ * This function is useful for simple widgets that need to display
+ * single-font, multi-line text with an individual character underlined
+ * and want Tk to handle the details. To display larger amounts of
+ * underlined text, construct and use an underlined font.
*
* Results:
* None.
@@ -2234,16 +2355,16 @@ Tk_DrawTextLayout(display, drawable, gc, layout, x, y, firstChar, lastChar)
*/
void
-Tk_UnderlineTextLayout(display, drawable, gc, layout, x, y, underline)
- Display *display; /* Display on which to draw. */
- Drawable drawable; /* Window or pixmap in which to draw. */
- GC gc; /* Graphics context to use for drawing text. */
- Tk_TextLayout layout; /* Layout information, from a previous call
- * to Tk_ComputeTextLayout(). */
- int x, y; /* Upper-left hand corner of rectangle in
+Tk_UnderlineTextLayout(
+ Display *display, /* Display on which to draw. */
+ Drawable drawable, /* Window or pixmap in which to draw. */
+ GC gc, /* Graphics context to use for drawing text. */
+ Tk_TextLayout layout, /* Layout information, from a previous call to
+ * Tk_ComputeTextLayout(). */
+ int x, int y, /* Upper-left hand corner of rectangle in
* which to draw (pixels). */
- int underline; /* Index of the single character to
- * underline, or -1 for no underline. */
+ int underline) /* Index of the single character to underline,
+ * or -1 for no underline. */
{
TextLayout *layoutPtr;
TkFont *fontPtr;
@@ -2254,7 +2375,7 @@ Tk_UnderlineTextLayout(display, drawable, gc, layout, x, y, underline)
layoutPtr = (TextLayout *) layout;
fontPtr = (TkFont *) layoutPtr->tkfont;
- XFillRectangle(display, drawable, gc, x + xx,
+ XFillRectangle(display, drawable, gc, x + xx,
y + yy + fontPtr->fm.ascent + fontPtr->underlinePos,
(unsigned int) width, (unsigned int) fontPtr->underlineHeight);
}
@@ -2266,25 +2387,25 @@ Tk_UnderlineTextLayout(display, drawable, gc, layout, x, y, underline)
* Tk_PointToChar --
*
* Use the information in the Tk_TextLayout token to determine the
- * character closest to the given point. The point must be
- * specified with respect to the upper-left hand corner of the
- * text layout, which is considered to be located at (0, 0).
+ * character closest to the given point. The point must be specified with
+ * respect to the upper-left hand corner of the text layout, which is
+ * considered to be located at (0, 0).
*
- * Any point whose y-value is less that 0 will be considered closest
- * to the first character in the text layout; any point whose y-value
- * is greater than the height of the text layout will be considered
- * closest to the last character in the text layout.
+ * Any point whose y-value is less that 0 will be considered closest to
+ * the first character in the text layout; any point whose y-value is
+ * greater than the height of the text layout will be considered closest
+ * to the last character in the text layout.
*
- * Any point whose x-value is less than 0 will be considered closest
- * to the first character on that line; any point whose x-value is
- * greater than the width of the text layout will be considered
- * closest to the last character on that line.
+ * Any point whose x-value is less than 0 will be considered closest to
+ * the first character on that line; any point whose x-value is greater
+ * than the width of the text layout will be considered closest to the
+ * last character on that line.
*
* Results:
- * The return value is the index of the character that was
- * closest to the point. Given a text layout with no characters,
- * the value 0 will always be returned, referring to a hypothetical
- * zero-width placeholder character.
+ * The return value is the index of the character that was closest to the
+ * point. Given a text layout with no characters, the value 0 will always
+ * be returned, referring to a hypothetical zero-width placeholder
+ * character.
*
* Side effects:
* None.
@@ -2293,12 +2414,12 @@ Tk_UnderlineTextLayout(display, drawable, gc, layout, x, y, underline)
*/
int
-Tk_PointToChar(layout, x, y)
- Tk_TextLayout layout; /* Layout information, from a previous call
- * to Tk_ComputeTextLayout(). */
- int x, y; /* Coordinates of point to check, with
- * respect to the upper-left corner of the
- * text layout. */
+Tk_PointToChar(
+ Tk_TextLayout layout, /* Layout information, from a previous call to
+ * Tk_ComputeTextLayout(). */
+ int x, int y) /* Coordinates of point to check, with respect
+ * to the upper-left corner of the text
+ * layout. */
{
TextLayout *layoutPtr;
LayoutChunk *chunkPtr, *lastPtr;
@@ -2307,8 +2428,8 @@ Tk_PointToChar(layout, x, y)
if (y < 0) {
/*
- * Point lies above any line in this layout. Return the index of
- * the first char.
+ * Point lies above any line in this layout. Return the index of the
+ * first char.
*/
return 0;
@@ -2327,30 +2448,30 @@ Tk_PointToChar(layout, x, y)
if (y < baseline + fontPtr->fm.descent) {
if (x < chunkPtr->x) {
/*
- * Point is to the left of all chunks on this line. Return
- * the index of the first character on this line.
+ * Point is to the left of all chunks on this line. Return the
+ * index of the first character on this line.
*/
return numChars;
}
if (x >= layoutPtr->width) {
/*
- * If point lies off right side of the text layout, return
- * the last char in the last chunk on this line. Without
- * this, it might return the index of the first char that
- * was located outside of the text layout.
+ * If point lies off right side of the text layout, return the
+ * last char in the last chunk on this line. Without this, it
+ * might return the index of the first char that was located
+ * outside of the text layout.
*/
x = INT_MAX;
}
/*
- * Examine all chunks on this line to see which one contains
- * the specified point.
+ * Examine all chunks on this line to see which one contains the
+ * specified point.
*/
lastPtr = chunkPtr;
- while ((i < layoutPtr->numChunks) && (chunkPtr->y == baseline)) {
+ while ((i < layoutPtr->numChunks) && (chunkPtr->y == baseline)) {
if (x < chunkPtr->x + chunkPtr->totalWidth) {
/*
* Point falls on one of the characters in this chunk.
@@ -2377,7 +2498,7 @@ Tk_PointToChar(layout, x, y)
/*
* Point is to the right of all chars in all the chunks on this
- * line. Return the index just past the last char in the last
+ * line. Return the index just past the last char in the last
* chunk on this line.
*/
@@ -2393,8 +2514,8 @@ Tk_PointToChar(layout, x, y)
}
/*
- * Point lies below any line in this text layout. Return the index
- * just past the last char.
+ * Point lies below any line in this text layout. Return the index just
+ * past the last char.
*/
return (lastPtr->start + lastPtr->numChars) - layoutPtr->string;
@@ -2405,29 +2526,28 @@ Tk_PointToChar(layout, x, y)
*
* Tk_CharBbox --
*
- * Use the information in the Tk_TextLayout token to return the
- * bounding box for the character specified by index.
+ * Use the information in the Tk_TextLayout token to return the bounding
+ * box for the character specified by index.
*
- * The width of the bounding box is the advance width of the
- * character, and does not include and left- or right-bearing.
- * Any character that extends partially outside of the
- * text layout is considered to be truncated at the edge. Any
- * character which is located completely outside of the text
- * layout is considered to be zero-width and pegged against
- * the edge.
+ * The width of the bounding box is the advance width of the character,
+ * and does not include and left- or right-bearing. Any character that
+ * extends partially outside of the text layout is considered to be
+ * truncated at the edge. Any character which is located completely
+ * outside of the text layout is considered to be zero-width and pegged
+ * against the edge.
*
* The height of the bounding box is the line height for this font,
- * extending from the top of the ascent to the bottom of the
- * descent. Information about the actual height of the individual
- * letter is not available.
+ * extending from the top of the ascent to the bottom of the descent.
+ * Information about the actual height of the individual letter is not
+ * available.
+ *
+ * A text layout that contains no characters is considered to contain a
+ * single zero-width placeholder character.
*
- * A text layout that contains no characters is considered to
- * contain a single zero-width placeholder character.
- *
* Results:
- * The return value is 0 if the index did not specify a character
- * in the text layout, or non-zero otherwise. In that case,
- * *bbox is filled with the bounding box of the character.
+ * The return value is 0 if the index did not specify a character in the
+ * text layout, or non-zero otherwise. In that case, *bbox is filled with
+ * the bounding box of the character.
*
* Side effects:
* None.
@@ -2436,25 +2556,26 @@ Tk_PointToChar(layout, x, y)
*/
int
-Tk_CharBbox(layout, index, xPtr, yPtr, widthPtr, heightPtr)
- Tk_TextLayout layout; /* Layout information, from a previous call to
- * Tk_ComputeTextLayout(). */
- int index; /* The index of the character whose bbox is
- * desired. */
- int *xPtr, *yPtr; /* Filled with the upper-left hand corner, in
- * pixels, of the bounding box for the character
- * specified by index, if non-NULL. */
- int *widthPtr, *heightPtr;
- /* Filled with the width and height of the
- * bounding box for the character specified by
- * index, if non-NULL. */
+Tk_CharBbox(
+ Tk_TextLayout layout, /* Layout information, from a previous call to
+ * Tk_ComputeTextLayout(). */
+ int index, /* The index of the character whose bbox is
+ * desired. */
+ int *xPtr, int *yPtr, /* Filled with the upper-left hand corner, in
+ * pixels, of the bounding box for the
+ * character specified by index, if
+ * non-NULL. */
+ int *widthPtr, int *heightPtr)
+ /* Filled with the width and height of the
+ * bounding box for the character specified by
+ * index, if non-NULL. */
{
TextLayout *layoutPtr;
LayoutChunk *chunkPtr;
- int i, x, w;
+ int i, x = 0, w;
Tk_Font tkfont;
TkFont *fontPtr;
- CONST char *end;
+ const char *end;
if (index < 0) {
return 0;
@@ -2476,7 +2597,7 @@ Tk_CharBbox(layout, index, xPtr, yPtr, widthPtr, heightPtr)
end = Tcl_UtfAtIndex(chunkPtr->start, index);
if (xPtr != NULL) {
Tk_MeasureChars(tkfont, chunkPtr->start,
- end - chunkPtr->start, -1, 0, &x);
+ end - chunkPtr->start, -1, 0, &x);
x += chunkPtr->x;
}
if (widthPtr != NULL) {
@@ -2488,25 +2609,26 @@ Tk_CharBbox(layout, index, xPtr, yPtr, widthPtr, heightPtr)
index -= chunkPtr->numChars;
chunkPtr++;
}
- if (index == 0) {
- /*
- * Special case to get location just past last char in layout.
- */
-
- chunkPtr--;
- x = chunkPtr->x + chunkPtr->totalWidth;
- w = 0;
- } else {
+ if (index != 0) {
return 0;
}
/*
- * Ensure that the bbox lies within the text layout. This forces all
- * chars that extend off the right edge of the text layout to have
- * truncated widths, and all chars that are completely off the right
- * edge of the text layout to peg to the edge and have 0 width.
+ * Special case to get location just past last char in layout.
+ */
+
+ chunkPtr--;
+ x = chunkPtr->x + chunkPtr->totalWidth;
+ w = 0;
+
+ /*
+ * Ensure that the bbox lies within the text layout. This forces all chars
+ * that extend off the right edge of the text layout to have truncated
+ * widths, and all chars that are completely off the right edge of the
+ * text layout to peg to the edge and have 0 width.
*/
- check:
+
+ check:
if (yPtr != NULL) {
*yPtr = chunkPtr->y - fontPtr->fm.ascent;
}
@@ -2535,16 +2657,15 @@ Tk_CharBbox(layout, index, xPtr, yPtr, widthPtr, heightPtr)
*
* Tk_DistanceToTextLayout --
*
- * Computes the distance in pixels from the given point to the
- * given text layout. Non-displaying space characters that occur
- * at the end of individual lines in the text layout are ignored
- * for hit detection purposes.
+ * Computes the distance in pixels from the given point to the given text
+ * layout. Non-displaying space characters that occur at the end of
+ * individual lines in the text layout are ignored for hit detection
+ * purposes.
*
* Results:
- * The return value is 0 if the point (x, y) is inside the text
- * layout. If the point isn't inside the text layout then the
- * return value is the distance in pixels from the point to the
- * text item.
+ * The return value is 0 if the point (x, y) is inside the text layout.
+ * If the point isn't inside the text layout then the return value is the
+ * distance in pixels from the point to the text item.
*
* Side effects:
* None.
@@ -2553,12 +2674,12 @@ Tk_CharBbox(layout, index, xPtr, yPtr, widthPtr, heightPtr)
*/
int
-Tk_DistanceToTextLayout(layout, x, y)
- Tk_TextLayout layout; /* Layout information, from a previous call
+Tk_DistanceToTextLayout(
+ Tk_TextLayout layout, /* Layout information, from a previous call
* to Tk_ComputeTextLayout(). */
- int x, y; /* Coordinates of point to check, with
- * respect to the upper-left corner of the
- * text layout (in pixels). */
+ int x, int y) /* Coordinates of point to check, with respect
+ * to the upper-left corner of the text layout
+ * (in pixels). */
{
int i, x1, x2, y1, y2, xDiff, yDiff, dist, minDist, ascent, descent;
LayoutChunk *chunkPtr;
@@ -2569,14 +2690,14 @@ Tk_DistanceToTextLayout(layout, x, y)
fontPtr = (TkFont *) layoutPtr->tkfont;
ascent = fontPtr->fm.ascent;
descent = fontPtr->fm.descent;
-
+
minDist = 0;
chunkPtr = layoutPtr->chunks;
for (i = 0; i < layoutPtr->numChunks; i++) {
if (chunkPtr->start[0] == '\n') {
/*
- * Newline characters are not counted when computing distance
- * (but tab characters would still be considered).
+ * Newline characters are not counted when computing distance (but
+ * tab characters would still be considered).
*/
chunkPtr++;
@@ -2620,15 +2741,15 @@ Tk_DistanceToTextLayout(layout, x, y)
*
* Tk_IntersectTextLayout --
*
- * Determines whether a text layout lies entirely inside,
- * entirely outside, or overlaps a given rectangle. Non-displaying
- * space characters that occur at the end of individual lines in
- * the text layout are ignored for intersection calculations.
+ * Determines whether a text layout lies entirely inside, entirely
+ * outside, or overlaps a given rectangle. Non-displaying space
+ * characters that occur at the end of individual lines in the text
+ * layout are ignored for intersection calculations.
*
* Results:
- * The return value is -1 if the text layout is entirely outside of
- * the rectangle, 0 if it overlaps, and 1 if it is entirely inside
- * of the rectangle.
+ * The return value is -1 if the text layout is entirely outside of the
+ * rectangle, 0 if it overlaps, and 1 if it is entirely inside of the
+ * rectangle.
*
* Side effects:
* None.
@@ -2637,15 +2758,15 @@ Tk_DistanceToTextLayout(layout, x, y)
*/
int
-Tk_IntersectTextLayout(layout, x, y, width, height)
- Tk_TextLayout layout; /* Layout information, from a previous call
- * to Tk_ComputeTextLayout(). */
- int x, y; /* Upper-left hand corner, in pixels, of
+Tk_IntersectTextLayout(
+ Tk_TextLayout layout, /* Layout information, from a previous call to
+ * Tk_ComputeTextLayout(). */
+ int x, int y, /* Upper-left hand corner, in pixels, of
* rectangular area to compare with text
- * layout. Coordinates are with respect to
- * the upper-left hand corner of the text
- * layout itself. */
- int width, height; /* The width and height of the above
+ * layout. Coordinates are with respect to the
+ * upper-left hand corner of the text layout
+ * itself. */
+ int width, int height) /* The width and height of the above
* rectangular area, in pixels. */
{
int result, i, x1, y1, x2, y2;
@@ -2656,19 +2777,19 @@ Tk_IntersectTextLayout(layout, x, y, width, height)
/*
* Scan the chunks one at a time, seeing whether each is entirely in,
- * entirely out, or overlapping the rectangle. If an overlap is
- * detected, return immediately; otherwise wait until all chunks have
- * been processed and see if they were all inside or all outside.
+ * entirely out, or overlapping the rectangle. If an overlap is detected,
+ * return immediately; otherwise wait until all chunks have been processed
+ * and see if they were all inside or all outside.
*/
-
+
layoutPtr = (TextLayout *) layout;
chunkPtr = layoutPtr->chunks;
fontPtr = (TkFont *) layoutPtr->tkfont;
- left = x;
- top = y;
- right = x + width;
- bottom = y + height;
+ left = x;
+ top = y;
+ right = x + width;
+ bottom = y + height;
result = 0;
for (i = 0; i < layoutPtr->numChunks; i++) {
@@ -2711,34 +2832,32 @@ Tk_IntersectTextLayout(layout, x, y, width, height)
*
* Tk_TextLayoutToPostscript --
*
- * Outputs the contents of a text layout in Postscript format.
- * The set of lines in the text layout will be rendered by the user
- * supplied Postscript function. The function should be of the form:
+ * Outputs the contents of a text layout in Postscript format. The set of
+ * lines in the text layout will be rendered by the user supplied
+ * Postscript function. The function should be of the form:
*
- * justify x y string function --
+ * justify x y string function --
*
* Justify is -1, 0, or 1, depending on whether the following string
- * should be left, center, or right justified, x and y is the
- * location for the origin of the string, string is the sequence
- * of characters to be printed, and function is the name of the
- * caller-provided function; the function should leave nothing
- * on the stack.
- *
- * The meaning of the origin of the string (x and y) depends on
- * the justification. For left justification, x is where the
- * left edge of the string should appear. For center justification,
- * x is where the center of the string should appear. And for right
- * justification, x is where the right edge of the string should
- * appear. This behavior is necessary because, for example, right
- * justified text on the screen is justified with screen metrics.
- * The same string needs to be justified with printer metrics on
- * the printer to appear in the correct place with respect to other
- * similarly justified strings. In all circumstances, y is the
- * location of the baseline for the string.
+ * should be left, center, or right justified, x and y is the location
+ * for the origin of the string, string is the sequence of characters to
+ * be printed, and function is the name of the caller-provided function;
+ * the function should leave nothing on the stack.
+ *
+ * The meaning of the origin of the string (x and y) depends on the
+ * justification. For left justification, x is where the left edge of the
+ * string should appear. For center justification, x is where the center
+ * of the string should appear. And for right justification, x is where
+ * the right edge of the string should appear. This behavior is necessary
+ * because, for example, right justified text on the screen is justified
+ * with screen metrics. The same string needs to be justified with
+ * printer metrics on the printer to appear in the correct place with
+ * respect to other similarly justified strings. In all circumstances, y
+ * is the location of the baseline for the string.
*
* Results:
- * The interp's result is modified to hold the Postscript code that
- * will render the text layout.
+ * The interp's result is modified to hold the Postscript code that will
+ * render the text layout.
*
* Side effects:
* None.
@@ -2747,20 +2866,17 @@ Tk_IntersectTextLayout(layout, x, y, width, height)
*/
void
-Tk_TextLayoutToPostscript(interp, layout)
- Tcl_Interp *interp; /* Filled with Postscript code. */
- Tk_TextLayout layout; /* The layout to be rendered. */
+Tk_TextLayoutToPostscript(
+ Tcl_Interp *interp, /* Filled with Postscript code. */
+ Tk_TextLayout layout) /* The layout to be rendered. */
{
#define MAXUSE 128
- char buf[MAXUSE+30];
+ char buf[MAXUSE+30], uindex[5] = "\0\0\0\0", one_char[5];
LayoutChunk *chunkPtr;
- int i, j, used, c, baseline;
+ int i, j, used, c, baseline, charsize;
Tcl_UniChar ch;
- CONST char *p, *last_p,*glyphname;
+ const char *p, *last_p, *glyphname;
TextLayout *layoutPtr;
- char uindex[5]="\0\0\0\0";
- char one_char[5];
- int charsize;
int bytecount=0;
layoutPtr = (TextLayout *) layout;
@@ -2787,23 +2903,24 @@ Tk_TextLayoutToPostscript(interp, layout)
p = chunkPtr->start;
for (j = 0; j < chunkPtr->numDisplayChars; 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.
+ * 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.
*/
- last_p=p;
- p +=(charsize= Tcl_UtfToUniChar(p,&ch));
- Tcl_UtfToExternal(interp,NULL,last_p,charsize,0,NULL,one_char,4,
- NULL,&bytecount,NULL);
- if (bytecount == 1) {
+
+ last_p = p;
+ p += (charsize = Tcl_UtfToUniChar(p,&ch));
+ Tcl_UtfToExternal(interp, NULL, last_p, charsize, 0, NULL,
+ one_char, 4, NULL, &bytecount, NULL);
+ if (bytecount == 1) {
c = UCHAR(one_char[0]);
/* c = UCHAR( ch & 0xFF) */;
if ((c == '(') || (c == ')') || (c == '\\') || (c < 0x20)
|| (c >= UCHAR(0x7f))) {
/*
- * Tricky point: the "03" is necessary in the sprintf
+ * Tricky point: the "03" is necessary in the sprintf
* below, so that a full three digits of octal are
- * always generated. Without the "03", a number
+ * always generated. Without the "03", a number
* following this sequence could be interpreted by
* Postscript as part of this sequence.
*/
@@ -2814,36 +2931,42 @@ Tk_TextLayoutToPostscript(interp, layout)
buf[used++] = c;
}
} else {
- /* This character doesn't belong to system character set.
- * So, we must use full glyph name */
- sprintf(uindex,"%04X",ch); /* endianness? */
- if ((glyphname = Tcl_GetVar2( interp , "::tk::psglyphs",uindex,0))) {
- if (used > 0 && buf [used-1] == '(')
+ /*
+ * This character doesn't belong to system character set.
+ * So, we must use full glyph name.
+ */
+
+ sprintf(uindex, "%04X", ch); /* endianness? */
+ glyphname = Tcl_GetVar2(interp,"::tk::psglyphs",uindex,0);
+ if (glyphname) {
+ if (used > 0 && buf [used-1] == '(') {
--used;
- else
+ } else {
buf[used++] = ')';
+ }
buf[used++] = '/';
- while( (*glyphname) && (used < (MAXUSE+27)))
+ while ((*glyphname) && (used < (MAXUSE+27))) {
buf[used++] = *glyphname++ ;
+ }
buf[used++] = '(';
}
-
+
}
if (used >= MAXUSE) {
buf[used] = '\0';
- Tcl_AppendResult(interp, buf, (char *) NULL);
+ Tcl_AppendResult(interp, buf, NULL);
used = 0;
}
}
}
if (used >= MAXUSE) {
/*
- * If there are a whole bunch of returns or tabs in a row,
- * then buf[] could get filled up.
+ * If there are a whole bunch of returns or tabs in a row, then
+ * buf[] could get filled up.
*/
-
+
buf[used] = '\0';
- Tcl_AppendResult(interp, buf, (char *) NULL);
+ Tcl_AppendResult(interp, buf, NULL);
used = 0;
}
chunkPtr++;
@@ -2852,7 +2975,7 @@ Tk_TextLayoutToPostscript(interp, layout)
buf[used++] = ']';
buf[used++] = '\n';
buf[used] = '\0';
- Tcl_AppendResult(interp, buf, (char *) NULL);
+ Tcl_AppendResult(interp, buf, NULL);
}
/*
@@ -2864,33 +2987,32 @@ Tk_TextLayoutToPostscript(interp, layout)
* initialized font attributes structure.
*
* Results:
- * A standard Tcl return value. If TCL_ERROR is returned, an
- * error message will be left in interp's result object (if non-NULL).
+ * A standard Tcl return value. If TCL_ERROR is returned, an error
+ * message will be left in interp's result object.
*
* Side effects:
* The fields of the font attributes structure get filled in with
- * information from argc/argv. If an error occurs while parsing,
- * the font attributes structure will contain all modifications
- * specified in the command line options up to the point of the
- * error.
+ * information from argc/argv. If an error occurs while parsing, the font
+ * attributes structure will contain all modifications specified in the
+ * command line options up to the point of the error.
*
*---------------------------------------------------------------------------
*/
static int
-ConfigAttributesObj(interp, tkwin, objc, objv, faPtr)
- Tcl_Interp *interp; /* Interp for error return, or NULL. */
- Tk_Window tkwin; /* For display on which font will be used. */
- int objc; /* Number of elements in argv. */
- Tcl_Obj *CONST objv[]; /* Command line options. */
- TkFontAttributes *faPtr; /* Font attributes structure whose fields
- * are to be modified. Structure must already
- * be properly initialized. */
+ConfigAttributesObj(
+ Tcl_Interp *interp, /* Interp for error return. */
+ Tk_Window tkwin, /* For display on which font will be used. */
+ int objc, /* Number of elements in argv. */
+ Tcl_Obj *const objv[], /* Command line options. */
+ TkFontAttributes *faPtr) /* Font attributes structure whose fields are
+ * to be modified. Structure must already be
+ * properly initialized. */
{
int i, n, index;
Tcl_Obj *optionPtr, *valuePtr;
char *value;
-
+
for (i = 0; i < objc; i += 2) {
optionPtr = objv[i];
valuePtr = objv[i + 1];
@@ -2901,63 +3023,55 @@ ConfigAttributesObj(interp, tkwin, objc, objv, faPtr)
}
if ((i+2 >= objc) && (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.
+ * 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.
*/
if (interp != NULL) {
Tcl_AppendResult(interp, "value for \"",
- Tcl_GetString(optionPtr), "\" option missing",
- (char *) NULL);
+ Tcl_GetString(optionPtr), "\" option missing", NULL);
}
return TCL_ERROR;
}
switch (index) {
- case FONT_FAMILY: {
- value = Tcl_GetString(valuePtr);
- faPtr->family = Tk_GetUid(value);
- break;
- }
- case FONT_SIZE: {
- if (Tcl_GetIntFromObj(interp, valuePtr, &n) != TCL_OK) {
- return TCL_ERROR;
- }
- faPtr->size = n;
- break;
+ case FONT_FAMILY:
+ value = Tcl_GetString(valuePtr);
+ faPtr->family = Tk_GetUid(value);
+ break;
+ case FONT_SIZE:
+ if (Tcl_GetIntFromObj(interp, valuePtr, &n) != TCL_OK) {
+ return TCL_ERROR;
}
- case FONT_WEIGHT: {
- n = TkFindStateNumObj(interp, optionPtr, weightMap, valuePtr);
- if (n == TK_FW_UNKNOWN) {
- return TCL_ERROR;
- }
- faPtr->weight = n;
- break;
+ faPtr->size = n;
+ break;
+ case FONT_WEIGHT:
+ n = TkFindStateNumObj(interp, optionPtr, weightMap, valuePtr);
+ if (n == TK_FW_UNKNOWN) {
+ return TCL_ERROR;
}
- case FONT_SLANT: {
- n = TkFindStateNumObj(interp, optionPtr, slantMap, valuePtr);
- if (n == TK_FS_UNKNOWN) {
- return TCL_ERROR;
- }
- faPtr->slant = n;
- break;
+ faPtr->weight = n;
+ break;
+ case FONT_SLANT:
+ n = TkFindStateNumObj(interp, optionPtr, slantMap, valuePtr);
+ if (n == TK_FS_UNKNOWN) {
+ return TCL_ERROR;
}
- case FONT_UNDERLINE: {
- if (Tcl_GetBooleanFromObj(interp, valuePtr, &n) != TCL_OK) {
- return TCL_ERROR;
- }
- faPtr->underline = n;
- break;
+ faPtr->slant = n;
+ break;
+ case FONT_UNDERLINE:
+ if (Tcl_GetBooleanFromObj(interp, valuePtr, &n) != TCL_OK) {
+ return TCL_ERROR;
}
- case FONT_OVERSTRIKE: {
- if (Tcl_GetBooleanFromObj(interp, valuePtr, &n) != TCL_OK) {
- return TCL_ERROR;
- }
- faPtr->overstrike = n;
- break;
+ faPtr->underline = n;
+ break;
+ case FONT_OVERSTRIKE:
+ if (Tcl_GetBooleanFromObj(interp, valuePtr, &n) != TCL_OK) {
+ return TCL_ERROR;
}
+ faPtr->overstrike = n;
+ break;
}
}
return TCL_OK;
@@ -2971,14 +3085,13 @@ ConfigAttributesObj(interp, tkwin, objc, objv, faPtr)
* Return information about the font attributes as a Tcl list.
*
* Results:
- * The return value is TCL_OK if the objPtr was non-NULL and
- * specified a valid font attribute, TCL_ERROR otherwise. If TCL_OK
- * is returned, the interp's result object is modified to hold a
- * description of either the current value of a single option, or a
- * list of all options and their current values for the given font
- * attributes. If TCL_ERROR is returned, the interp's result is
- * set to an error message describing that the objPtr did not refer
- * to a valid option.
+ * The return value is TCL_OK if the objPtr was non-NULL and specified a
+ * valid font attribute, TCL_ERROR otherwise. If TCL_OK is returned, the
+ * interp's result object is modified to hold a description of either the
+ * current value of a single option, or a list of all options and their
+ * current values for the given font attributes. If TCL_ERROR is
+ * returned, the interp's result is set to an error message describing
+ * that the objPtr did not refer to a valid option.
*
* Side effects:
* None.
@@ -2987,16 +3100,16 @@ ConfigAttributesObj(interp, tkwin, objc, objv, faPtr)
*/
static int
-GetAttributeInfoObj(interp, faPtr, objPtr)
- Tcl_Interp *interp; /* Interp to hold result. */
- 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. */
+GetAttributeInfoObj(
+ Tcl_Interp *interp, /* Interp to hold result. */
+ 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. */
{
int i, index, start, end;
- CONST char *str;
+ const char *str;
Tcl_Obj *optionPtr, *valuePtr, *resultPtr;
resultPtr = Tcl_GetObjResult(interp);
@@ -3015,32 +3128,32 @@ GetAttributeInfoObj(interp, faPtr, objPtr)
valuePtr = NULL;
for (i = start; i < end; i++) {
switch (i) {
- case FONT_FAMILY:
- str = faPtr->family;
- valuePtr = Tcl_NewStringObj(str, ((str == NULL) ? 0 : -1));
- break;
+ case FONT_FAMILY:
+ str = faPtr->family;
+ valuePtr = Tcl_NewStringObj(str, ((str == NULL) ? 0 : -1));
+ break;
- case FONT_SIZE:
- valuePtr = Tcl_NewIntObj(faPtr->size);
- break;
+ case FONT_SIZE:
+ 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_WEIGHT:
+ str = TkFindStateString(weightMap, faPtr->weight);
+ valuePtr = Tcl_NewStringObj(str, -1);
+ break;
- case FONT_UNDERLINE:
- valuePtr = Tcl_NewBooleanObj(faPtr->underline);
- break;
+ case FONT_SLANT:
+ str = TkFindStateString(slantMap, faPtr->slant);
+ valuePtr = Tcl_NewStringObj(str, -1);
+ break;
- case FONT_OVERSTRIKE:
- valuePtr = Tcl_NewBooleanObj(faPtr->overstrike);
- break;
+ case FONT_UNDERLINE:
+ valuePtr = Tcl_NewBooleanObj(faPtr->underline);
+ break;
+
+ case FONT_OVERSTRIKE:
+ valuePtr = Tcl_NewBooleanObj(faPtr->overstrike);
+ break;
}
if (objPtr != NULL) {
Tcl_SetObjResult(interp, valuePtr);
@@ -3058,8 +3171,8 @@ GetAttributeInfoObj(interp, faPtr, objPtr)
*
* ParseFontNameObj --
*
- * Converts a object into a set of font attributes that can be used
- * to construct a font.
+ * Converts a object into a set of font attributes that can be used to
+ * construct a font.
*
* The string rep of the object can be one of the following forms:
* XLFD (see X documentation)
@@ -3067,10 +3180,10 @@ GetAttributeInfoObj(interp, faPtr, objPtr)
* "-option value [-option value ...]"
*
* Results:
- * The return value is TCL_ERROR if the object was syntactically
- * invalid. In that case an error message is left in interp's
- * result object. Otherwise, fills the font attribute buffer with
- * the values parsed from the string and returns TCL_OK;
+ * The return value is TCL_ERROR if the object was syntactically invalid.
+ * In that case an error message is left in interp's result object.
+ * Otherwise, fills the font attribute buffer with the values parsed from
+ * the string and returns TCL_OK;
*
* Side effects:
* None.
@@ -3079,13 +3192,12 @@ GetAttributeInfoObj(interp, faPtr, objPtr)
*/
static int
-ParseFontNameObj(interp, tkwin, objPtr, faPtr)
- Tcl_Interp *interp; /* Interp for error return, or NULL if no
- * error messages are to be generated. */
- Tk_Window tkwin; /* For display on which font is used. */
- Tcl_Obj *objPtr; /* Parseable font description object. */
- TkFontAttributes *faPtr; /* Filled with attributes parsed from font
- * name. Any attributes that were not
+ParseFontNameObj(
+ Tcl_Interp *interp, /* Interp for error return. */
+ Tk_Window tkwin, /* For display on which font is used. */
+ Tcl_Obj *objPtr, /* Parseable font description object. */
+ TkFontAttributes *faPtr) /* Filled with attributes parsed from font
+ * name. Any attributes that were not
* specified in font name are filled with
* default values. */
{
@@ -3093,7 +3205,7 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr)
int objc, result, i, n;
Tcl_Obj **objv;
char *string;
-
+
TkInitFontAttributes(faPtr);
string = Tcl_GetString(objPtr);
@@ -3102,7 +3214,7 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr)
* This may be an XLFD or an "-option value" string.
*
* If the string begins with "-*" or a "-foundry-family-*" pattern,
- * then consider it an XLFD.
+ * then consider it an XLFD.
*/
if (string[1] == '*') {
@@ -3120,13 +3232,13 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr)
return ConfigAttributesObj(interp, tkwin, objc, objv, faPtr);
}
-
+
if (*string == '*') {
/*
- * 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.
+ * 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:
@@ -3134,18 +3246,32 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr)
if (result == TCL_OK) {
return TCL_OK;
}
+
+ /*
+ * If the string failed to parse but was considered to be a XLFD
+ * then it may be a "-option value" string with a hyphenated family
+ * name as per bug 2791352
+ */
+
+ if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (ConfigAttributesObj(interp, tkwin, objc, objv, faPtr) == TCL_OK) {
+ return TCL_OK;
+ }
}
/*
- * Wasn't an XLFD or "-option value" string. Try it as a
- * "font size style" list.
+ * Wasn't an XLFD or "-option value" string. Try it as a "font size style"
+ * list.
*/
if ((Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv) != TCL_OK)
|| (objc < 1)) {
if (interp != NULL) {
Tcl_AppendResult(interp, "font \"", string, "\" doesn't exist",
- (char *) NULL);
+ NULL);
}
return TCL_ERROR;
}
@@ -3193,7 +3319,7 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr)
if (interp != NULL) {
Tcl_AppendResult(interp, "unknown font style \"",
- Tcl_GetString(objv[i]), "\"", (char *) NULL);
+ Tcl_GetString(objv[i]), "\"", NULL);
}
return TCL_ERROR;
}
@@ -3205,9 +3331,8 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr)
*
* NewChunk --
*
- * Helper function for Tk_ComputeTextLayout(). Encapsulates a
- * measured set of characters in a chunk that can be quickly
- * drawn.
+ * 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.
@@ -3215,28 +3340,28 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr)
* 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.
+ * 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;
+NewChunk(
+ 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) {
@@ -3271,8 +3396,8 @@ NewChunk(layoutPtrPtr, maxPtr, start, numBytes, curX, newX, y)
*
* Results:
* Return value is TCL_ERROR if string was not a fully specified XLFD.
- * Otherwise, fills font attribute buffer with the values parsed
- * from the XLFD and returns TCL_OK.
+ * Otherwise, fills font attribute buffer with the values parsed from the
+ * XLFD and returns TCL_OK.
*
* Side effects:
* None.
@@ -3281,25 +3406,25 @@ NewChunk(layoutPtrPtr, maxPtr, start, numBytes, curX, newX, y)
*/
int
-TkFontParseXLFD(string, faPtr, xaPtr)
- CONST char *string; /* Parseable font description string. */
- TkFontAttributes *faPtr; /* Filled with attributes parsed from font
- * name. Any attributes that were not
+TkFontParseXLFD(
+ const char *string, /* Parseable font description string. */
+ 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
+ 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
+ * default values. May be NULL if such
* information is not desired. */
{
char *src;
- CONST char *str;
+ const char *str;
int i, j;
char *field[XLFD_NUMFIELDS + 2];
Tcl_DString ds;
TkXLFDAttributes xa;
-
+
if (xaPtr == NULL) {
xaPtr = &xa;
}
@@ -3338,13 +3463,13 @@ TkFontParseXLFD(string, faPtr, xaPtr)
/*
* 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 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 (as a native font name), but gives a syntax
- * error under Windows (as a parsed set of attributes)".
+ * 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 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 (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]))) {
@@ -3394,8 +3519,8 @@ TkFontParseXLFD(string, faPtr, xaPtr)
/* XLFD_ADD_STYLE ignored. */
/*
- * Pointsize in tenths of a point, but treat it as tenths of a pixel
- * for historical compatibility.
+ * Pointsize in tenths of a point, but treat it as tenths of a pixel for
+ * historical compatibility.
*/
faPtr->size = 12;
@@ -3422,7 +3547,7 @@ TkFontParseXLFD(string, faPtr, xaPtr)
}
/*
- * Pixel height of font. If specified, overrides pointsize.
+ * Pixel height of font. If specified, overrides pointsize.
*/
if (FieldSpecified(field[XLFD_PIXEL_SIZE])) {
@@ -3432,9 +3557,9 @@ TkFontParseXLFD(string, faPtr, xaPtr)
*
* [ N1 N2 N3 N4 ]
*
- * where N1 is the pixel size, and where N2, N3, and N4
- * are some additional numbers that I don't know
- * the purpose of, so I ignore them.
+ * where N1 is the pixel size, and where N2, N3, and N4 are some
+ * additional numbers that I don't know the purpose of, so I
+ * ignore them.
*/
faPtr->size = atoi(field[XLFD_PIXEL_SIZE] + 1);
@@ -3468,12 +3593,12 @@ TkFontParseXLFD(string, faPtr, xaPtr)
*
* FieldSpecified --
*
- * Helper function for TkParseXLFD(). Determines if a field in the
- * XLFD was set to a non-null, non-don't-care value.
+ * Helper function for TkParseXLFD(). Determines if a field in the XLFD
+ * was set to a non-null, non-don't-care value.
*
* Results:
- * The return value is 0 if the field in the XLFD was not set and
- * should be ignored, non-zero otherwise.
+ * The return value is 0 if the field in the XLFD was not set and should
+ * be ignored, non-zero otherwise.
*
* Side effects:
* None.
@@ -3482,11 +3607,12 @@ TkFontParseXLFD(string, faPtr, xaPtr)
*/
static int
-FieldSpecified(field)
- CONST char *field; /* The field of the XLFD to check. Strictly
- * speaking, only when the string is "*" does it mean
- * don't-care. However, an unspecified or question
- * mark is also interpreted as don't-care. */
+FieldSpecified(
+ const char *field) /* The field of the XLFD to check. Strictly
+ * speaking, only when the string is "*" does
+ * it mean don't-care. However, an unspecified
+ * or question mark is also interpreted as
+ * don't-care. */
{
char ch;
@@ -3513,11 +3639,11 @@ FieldSpecified(field)
*
*---------------------------------------------------------------------------
*/
-
+
int
-TkFontGetPixels(tkwin, size)
- Tk_Window tkwin; /* For point->pixel conversion factor. */
- int size; /* Font size. */
+TkFontGetPixels(
+ Tk_Window tkwin, /* For point->pixel conversion factor. */
+ int size) /* Font size. */
{
double d;
@@ -3547,11 +3673,11 @@ TkFontGetPixels(tkwin, size)
*
*---------------------------------------------------------------------------
*/
-
+
int
-TkFontGetPoints(tkwin, size)
- Tk_Window tkwin; /* For pixel->point conversion factor. */
- int size; /* Font size. */
+TkFontGetPoints(
+ Tk_Window tkwin, /* For pixel->point conversion factor. */
+ int size) /* Font size. */
{
double d;
@@ -3570,24 +3696,24 @@ TkFontGetPoints(tkwin, size)
*
* 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.
+ * 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.
+
+ * 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. */
-{
+TkFontGetAliasList(
+ const char *faceName) /* Font name to test for aliases. */
+{
int i, j;
for (i = 0; fontAliases[i] != NULL; i++) {
@@ -3605,9 +3731,8 @@ TkFontGetAliasList(faceName)
*
* 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.
+ * 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.
@@ -3617,9 +3742,9 @@ TkFontGetAliasList(faceName)
*
*-------------------------------------------------------------------------
*/
-
+
char ***
-TkFontGetFallbacks()
+TkFontGetFallbacks(void)
{
return fontFallbacks;
}
@@ -3642,9 +3767,9 @@ TkFontGetFallbacks()
*
*-------------------------------------------------------------------------
*/
-
+
char **
-TkFontGetGlobalClass()
+TkFontGetGlobalClass(void)
{
return globalFontClass;
}
@@ -3654,8 +3779,8 @@ TkFontGetGlobalClass()
*
* TkFontGetSymbolClass --
*
- * Get the list of fonts that are symbolic; used if the operating
- * system cannot apriori identify symbolic fonts on its own.
+ * Get the list of fonts that are symbolic; used if the operating system
+ * cannot apriori identify symbolic fonts on its own.
*
* Results:
* As above.
@@ -3665,9 +3790,9 @@ TkFontGetGlobalClass()
*
*-------------------------------------------------------------------------
*/
-
+
char **
-TkFontGetSymbolClass()
+TkFontGetSymbolClass(void)
{
return symbolClass;
}
@@ -3677,13 +3802,12 @@ TkFontGetSymbolClass()
*
* TkDebugFont --
*
- * This procedure returns debugging information about a font.
+ * This function 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.
+ * corresponding to "name". Each sublist has two elements that contain
+ * the resourceRefCount and objRefCount fields from the TkFont structure.
*
* Side effects:
* None.
@@ -3692,10 +3816,10 @@ TkFontGetSymbolClass()
*/
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. */
+TkDebugFont(
+ 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;
@@ -3707,14 +3831,14 @@ TkDebugFont(tkwin, name)
if (hashPtr != NULL) {
fontPtr = (TkFont *) Tcl_GetHashValue(hashPtr);
if (fontPtr == NULL) {
- panic("TkDebugFont found empty hash table entry");
+ Tcl_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_NewIntObj(fontPtr->objRefCount));
Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
}
}
@@ -3726,13 +3850,13 @@ TkDebugFont(tkwin, name)
*
* TkFontGetFirstTextLayout --
*
- * This procedure returns the first chunk of a Tk_TextLayout,
- * i.e. until the first font change on the first line (or the
- * whole first line if there is no such font change).
+ * This function returns the first chunk of a Tk_TextLayout, i.e. until
+ * the first font change on the first line (or the whole first line if
+ * there is no such font change).
*
* Results:
- * The return value is the byte length of the chunk, the chunk
- * itself is copied into dst and its Tk_Font into font.
+ * The return value is the byte length of the chunk, the chunk itself is
+ * copied into dst and its Tk_Font into font.
*
* Side effects:
* None.
@@ -3742,21 +3866,20 @@ TkDebugFont(tkwin, name)
int
TkFontGetFirstTextLayout(
- Tk_TextLayout layout, /* Layout information, from a previous call
- * to Tk_ComputeTextLayout(). */
- Tk_Font * font,
- char * dst)
+ Tk_TextLayout layout, /* Layout information, from a previous call to
+ * Tk_ComputeTextLayout(). */
+ Tk_Font *font,
+ char *dst)
{
- TextLayout *layoutPtr;
+ TextLayout *layoutPtr;
LayoutChunk *chunkPtr;
int numBytesInChunk;
layoutPtr = (TextLayout *)layout;
- if ((layoutPtr==NULL)
- || (layoutPtr->numChunks==0)
- || (layoutPtr->chunks->numDisplayChars <= 0)) {
- dst[0] = '\0';
- return 0;
+ if ((layoutPtr==NULL) || (layoutPtr->numChunks==0)
+ || (layoutPtr->chunks->numDisplayChars <= 0)) {
+ dst[0] = '\0';
+ return 0;
}
chunkPtr = layoutPtr->chunks;
numBytesInChunk = chunkPtr->numBytes;
@@ -3764,3 +3887,11 @@ TkFontGetFirstTextLayout(
*font = layoutPtr->tkfont;
return numBytesInChunk;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkFont.h b/generic/tkFont.h
index 71c598c..ef6336c 100644
--- a/generic/tkFont.h
+++ b/generic/tkFont.h
@@ -1,40 +1,40 @@
/*
* tkFont.h --
*
- * Declarations for interfaces between the generic and platform-
- * specific parts of the font package. This information is not
- * visible outside of the font package.
+ * Declarations for interfaces between the generic and platform-specific
+ * parts of the font package. This information is not visible outside of
+ * the font package.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKFONT
#define _TKFONT
#ifdef BUILD_tk
-# undef TCL_STORAGE_CLASS
-# define TCL_STORAGE_CLASS DLLEXPORT
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
#endif
/*
- * The following structure keeps track of the attributes of a font. It can
- * be used to keep track of either the desired attributes or the actual
+ * The following structure keeps track of the attributes of a font. It can be
+ * used to keep track of either the desired attributes or the actual
* attributes gotten when the font was instantiated.
*/
-typedef struct TkFontAttributes {
- Tk_Uid family; /* Font family, or NULL to represent
- * plaform-specific default system font. */
+struct TkFontAttributes {
+ 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. */
int underline; /* Non-zero for underline font. */
int overstrike; /* Non-zero for overstrike font. */
-} TkFontAttributes;
+};
/*
* Possible values for the "weight" field in a TkFontAttributes structure.
@@ -45,7 +45,7 @@ typedef struct TkFontAttributes {
#define TK_FW_NORMAL 0
#define TK_FW_BOLD 1
-#define TK_FW_UNKNOWN -1 /* Unknown weight. This value is used for
+#define TK_FW_UNKNOWN -1 /* Unknown weight. This value is used for
* error checking and is never actually stored
* in the weight field. */
@@ -53,21 +53,21 @@ typedef struct TkFontAttributes {
* Possible values for the "slant" field in a TkFontAttributes structure.
*/
-#define TK_FS_ROMAN 0
+#define TK_FS_ROMAN 0
#define TK_FS_ITALIC 1
-#define TK_FS_OBLIQUE 2 /* This value is only used when parsing X
- * font names to determine the closest
- * match. It is only stored in the
- * XLFDAttributes structure, never in the
- * slant field of the TkFontAttributes. */
+#define TK_FS_OBLIQUE 2 /* This value is only used when parsing X font
+ * names to determine the closest match. It is
+ * only stored in the XLFDAttributes
+ * structure, never in the slant field of the
+ * TkFontAttributes. */
-#define TK_FS_UNKNOWN -1 /* Unknown slant. This value is used for
- * error checking and is never actually stored
- * in the slant field. */
+#define TK_FS_UNKNOWN -1 /* Unknown slant. This value is used for error
+ * checking and is never actually stored in
+ * the slant field. */
/*
* The following structure keeps track of the metrics for an instantiated
- * font. The metrics are the physical properties of the font itself.
+ * font. The metrics are the physical properties of the font itself.
*/
typedef struct TkFontMetrics {
@@ -80,9 +80,9 @@ typedef struct TkFontMetrics {
/*
* The following structure is used to keep track of the generic information
- * about a font. Each platform-specific font is represented by a structure
- * with the following structure at its beginning, plus any platform-
- * specific stuff after that.
+ * about a font. Each platform-specific font is represented by a structure
+ * with the following structure at its beginning, plus any platform-specific
+ * stuff after that.
*/
typedef struct TkFont {
@@ -92,14 +92,14 @@ typedef struct 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. */
+ * 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,
@@ -110,9 +110,9 @@ typedef struct 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
- * on a non-underlined font). */
+ int underlinePos; /* Offset from baseline to origin of underline
+ * bar (used for drawing underlines on a
+ * non-underlined font). */
int underlineHeight; /* Height of underline bar (used for drawing
* underlines on a non-underlined font). */
@@ -122,33 +122,33 @@ typedef struct TkFont {
*/
Font fid; /* For backwards compatibility with XGCValues
- * structures. Remove when TkGCValues is
- * implemented. */
+ * structures. Remove when TkGCValues is
+ * implemented. */
TkFontAttributes fa; /* Actual font attributes obtained when the
* the font was created, as opposed to the
* desired attributes passed in to
- * TkpGetFontFromAttributes(). The desired
+ * TkpGetFontFromAttributes(). The desired
* metrics can be determined from the string
* 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. */
+ * the same name. All fonts with the same name
+ * (but different displays) are chained
+ * together off a single entry in a hash
+ * table. */
} TkFont;
/*
- * The following structure is used to return attributes when parsing an
- * XLFD. The extra information is of interest to the Unix-specific code
- * when attempting to find the closest matching font.
+ * The following structure is used to return attributes when parsing an XLFD.
+ * The extra information is of interest to the Unix-specific code when
+ * attempting to find the closest matching font.
*/
typedef struct TkXLFDAttributes {
Tk_Uid foundry; /* The foundry of the font. */
- int slant; /* The tristate value for the slant, which
- * is significant under X. */
+ int slant; /* The tristate value for the slant, which is
+ * significant under X. */
int setwidth; /* The proportionate width, see below for
* definition. */
Tk_Uid charset; /* The actual charset string. */
@@ -163,8 +163,8 @@ typedef struct TkXLFDAttributes {
#define TK_SW_NORMAL 0
#define TK_SW_CONDENSE 1
#define TK_SW_EXPAND 2
-#define TK_SW_UNKNOWN 3 /* Unknown setwidth. This value may be
- * stored in the setwidth field. */
+#define TK_SW_UNKNOWN 3 /* Unknown setwidth. This value may be stored
+ * in the setwidth field. */
/*
* The following defines specify the meaning of the fields in a fully
@@ -193,34 +193,34 @@ typedef struct TkXLFDAttributes {
#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));
-EXTERN int TkFontGetFirstTextLayout _ANSI_ARGS_((
- Tk_TextLayout layout, Tk_Font *font, char *dst));
+MODULE_SCOPE int TkFontParseXLFD(CONST char *string,
+ TkFontAttributes *faPtr, TkXLFDAttributes *xaPtr);
+MODULE_SCOPE char ** TkFontGetAliasList(CONST char *faceName);
+MODULE_SCOPE char *** TkFontGetFallbacks(void);
+MODULE_SCOPE int TkFontGetPixels(Tk_Window tkwin, int size);
+MODULE_SCOPE int TkFontGetPoints(Tk_Window tkwin, int size);
+MODULE_SCOPE char ** TkFontGetGlobalClass(void);
+MODULE_SCOPE char ** TkFontGetSymbolClass(void);
+MODULE_SCOPE int TkCreateNamedFont(Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *name, TkFontAttributes *faPtr);
+MODULE_SCOPE int TkDeleteNamedFont(Tcl_Interp *interp,
+ Tk_Window tkwin, CONST char *name);
+MODULE_SCOPE int TkFontGetFirstTextLayout(Tk_TextLayout layout,
+ Tk_Font *font, char *dst);
/*
- * Low-level API exported by platform-specific code to generic code.
+ * 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));
-EXTERN void TkpGetFontFamilies _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin));
-EXTERN TkFont * TkpGetNativeFont _ANSI_ARGS_((Tk_Window tkwin,
- CONST char *name));
-
-# undef TCL_STORAGE_CLASS
-# define TCL_STORAGE_CLASS DLLIMPORT
+MODULE_SCOPE void TkpDeleteFont(TkFont *tkFontPtr);
+MODULE_SCOPE void TkpFontPkgInit(TkMainInfo *mainPtr);
+MODULE_SCOPE TkFont * TkpGetFontFromAttributes(TkFont *tkFontPtr,
+ Tk_Window tkwin, CONST TkFontAttributes *faPtr);
+MODULE_SCOPE void TkpGetFontFamilies(Tcl_Interp *interp,
+ Tk_Window tkwin);
+MODULE_SCOPE TkFont * TkpGetNativeFont(Tk_Window tkwin, CONST char *name);
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLIMPORT
#endif /* _TKFONT */
diff --git a/generic/tkFrame.c b/generic/tkFrame.c
index e7a6dbe..e38fe87 100644
--- a/generic/tkFrame.c
+++ b/generic/tkFrame.c
@@ -1,20 +1,18 @@
-/*
+/*
* tkFrame.c --
*
* This module implements "frame", "labelframe" and "toplevel" widgets
- * for the Tk toolkit. Frames are windows with a background color
- * and possibly a 3-D effect, but not much else in the way of
- * attributes.
+ * for the Tk toolkit. Frames are windows with a background color and
+ * possibly a 3-D effect, but not much else in the way of attributes.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "default.h"
-#include "tkPort.h"
#include "tkInt.h"
/*
@@ -31,29 +29,29 @@ enum FrameType {
*/
typedef struct {
- Tk_Window tkwin; /* Window that embodies the frame. NULL
- * means that the window has been destroyed
- * but the data structures haven't yet been
- * cleaned up. */
- Display *display; /* Display containing widget. Used, among
+ Tk_Window tkwin; /* Window that embodies the frame. NULL means
+ * that the window has been destroyed but the
+ * data structures haven't yet been cleaned
+ * up. */
+ Display *display; /* Display containing widget. Used, among
* other things, so that resources can be
* freed even after tkwin has gone away. */
- Tcl_Interp *interp; /* Interpreter associated with widget. Used
- * to delete widget command. */
+ Tcl_Interp *interp; /* Interpreter associated with widget. Used to
+ * delete widget command. */
Tcl_Command widgetCmd; /* Token for frame's widget command. */
Tk_OptionTable optionTable; /* Table that defines configuration options
* available for this widget. */
char *className; /* Class name for widget (from configuration
- * option). Malloc-ed. */
+ * option). Malloc-ed. */
enum FrameType type; /* Type of widget, such as TYPE_FRAME. */
- char *screenName; /* Screen on which widget is created. Non-null
- * only for top-levels. Malloc-ed, may be
+ char *screenName; /* Screen on which widget is created. Non-null
+ * only for top-levels. Malloc-ed, may be
* NULL. */
char *visualName; /* Textual description of visual for window,
- * from -visual option. Malloc-ed, may be
+ * from -visual option. Malloc-ed, may be
* NULL. */
char *colormapName; /* Textual description of colormap for window,
- * from -colormap option. Malloc-ed, may be
+ * from -colormap option. Malloc-ed, may be
* NULL. */
char *menuName; /* Textual description of menu to use for
* menubar. Malloc-ed, may be NULL. */
@@ -61,32 +59,32 @@ typedef struct {
* allocated for this window, which must be
* freed when the window is deleted. */
Tk_3DBorder border; /* Structure used to draw 3-D border and
- * background. NULL means no background
- * or border. */
+ * background. NULL means no background or
+ * border. */
int borderWidth; /* Width of 3-D border (if any). */
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.
- * 0 means don't draw a highlight. */
+ 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. */
+ /* Color for drawing traversal highlight area
+ * when highlight is off. */
XColor *highlightColorPtr; /* Color for drawing traversal highlight. */
- int width; /* Width to request for window. <= 0 means
+ int width; /* Width to request for window. <= 0 means
* don't request any size. */
- int height; /* Height to request for window. <= 0 means
+ int height; /* Height to request for window. <= 0 means
* don't request any size. */
Tk_Cursor cursor; /* Current cursor for window, or None. */
- char *takeFocus; /* Value of -takefocus option; not used in
- * the C code, but used by keyboard traversal
- * scripts. Malloc'ed, but may be NULL. */
+ char *takeFocus; /* Value of -takefocus option; not used in the
+ * C code, but used by keyboard traversal
+ * scripts. Malloc'ed, but may be NULL. */
int isContainer; /* 1 means this window is a container, 0 means
* that it isn't. */
char *useThis; /* If the window is embedded, this points to
* the name of the window in which it is
- * embedded (malloc'ed). For non-embedded
+ * embedded (malloc'ed). For non-embedded
* windows this is NULL. */
- int flags; /* Various flags; see below for
+ int flags; /* Various flags; see below for
* definitions. */
Tcl_Obj *padXPtr; /* Value of -padx option: specifies how many
* pixels of extra space to leave on left and
@@ -99,46 +97,41 @@ typedef struct {
} Frame;
/*
- * A data structure of the following type is kept for each labelframe
- * widget managed by this file:
+ * A data structure of the following type is kept for each labelframe widget
+ * managed by this file:
*/
typedef struct {
Frame frame; /* A pointer to the generic frame structure.
* This must be the first element of the
* Labelframe. */
-
/*
* Labelframe specific configuration settings.
*/
-
Tcl_Obj *textPtr; /* Value of -text option: specifies text to
* display in button. */
- Tk_Font tkfont; /* Value of -font option: specifies font
- * to use for display text. */
+ Tk_Font tkfont; /* Value of -font option: specifies font to
+ * use for display text. */
XColor *textColorPtr; /* Value of -fg option: specifies foreground
* color in normal mode. */
int labelAnchor; /* Value of -labelanchor option: specifies
* where to place the label. */
- Tk_Window labelWin; /* Value of -labelwidget option: Window to
- * use as label for the frame. */
-
+ Tk_Window labelWin; /* Value of -labelwidget option: Window to use
+ * as label for the frame. */
/*
* Labelframe specific fields for use with configuration settings above.
*/
-
GC textGC; /* GC for drawing text in normal mode. */
Tk_TextLayout textLayout; /* Stored text layout information. */
XRectangle labelBox; /* The label's actual size and position. */
int labelReqWidth; /* The label's requested width. */
int labelReqHeight; /* The label's requested height. */
int labelTextX, labelTextY; /* Position of the text to be drawn. */
-
} Labelframe;
/*
- * The following macros define how many extra pixels to leave
- * around a label's text.
+ * The following macros define how many extra pixels to leave around a label's
+ * text.
*/
#define LABELSPACING 1
@@ -147,20 +140,19 @@ typedef struct {
/*
* Flag bits for frames:
*
- * REDRAW_PENDING: Non-zero means a DoWhenIdle handler
- * has already been queued to redraw
- * this window.
- * GOT_FOCUS: Non-zero means this widget currently
- * has the input focus.
+ * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has
+ * already been queued to redraw this window.
+ * GOT_FOCUS: Non-zero means this widget currently has the
+ * input focus.
*/
#define REDRAW_PENDING 1
#define GOT_FOCUS 4
/*
- * The following enum is used to define a type for the -labelanchor option
- * of the Labelframe widget. These values are used as indices into the
- * string table below.
+ * The following enum is used to define a type for the -labelanchor option of
+ * the Labelframe widget. These values are used as indices into the string
+ * table below.
*/
enum labelanchor {
@@ -170,34 +162,36 @@ enum labelanchor {
LABELANCHOR_W, LABELANCHOR_WN, LABELANCHOR_WS
};
-static CONST char *CONST labelAnchorStrings[] = {
+static CONST char *labelAnchorStrings[] = {
"e", "en", "es", "n", "ne", "nw", "s", "se", "sw", "w", "wn", "ws",
- (char *) NULL
+ NULL
};
/*
- * Information used for parsing configuration options. There are
- * one common table used by all and one table for each widget class.
+ * Information used for parsing configuration options. There are one common
+ * table used by all and one table for each widget class.
*/
-static CONST Tk_OptionSpec commonOptSpec[] = {
+static const Tk_OptionSpec commonOptSpec[] = {
{TK_OPTION_BORDER, "-background", "background", "Background",
DEF_FRAME_BG_COLOR, -1, Tk_Offset(Frame, border),
TK_OPTION_NULL_OK, (ClientData) DEF_FRAME_BG_MONO, 0},
- {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-background", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-background", 0},
{TK_OPTION_STRING, "-colormap", "colormap", "Colormap",
DEF_FRAME_COLORMAP, -1, Tk_Offset(Frame, colormapName),
TK_OPTION_NULL_OK, 0, 0},
+ /*
+ * Having -container is useless in a labelframe since a container has
+ * no border. It should be deprecated.
+ */
{TK_OPTION_BOOLEAN, "-container", "container", "Container",
- DEF_FRAME_CONTAINER, -1, Tk_Offset(Frame, isContainer),
- 0, 0, 0},
+ DEF_FRAME_CONTAINER, -1, Tk_Offset(Frame, isContainer), 0, 0, 0},
{TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
DEF_FRAME_CURSOR, -1, Tk_Offset(Frame, cursor),
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-height", "height", "Height",
- DEF_FRAME_HEIGHT, -1, Tk_Offset(Frame, height),
- 0, 0, 0},
+ DEF_FRAME_HEIGHT, -1, Tk_Offset(Frame, height), 0, 0, 0},
{TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
"HighlightBackground", DEF_FRAME_HIGHLIGHT_BG, -1,
Tk_Offset(Frame, highlightBgColorPtr), 0, 0, 0},
@@ -220,82 +214,71 @@ static CONST Tk_OptionSpec commonOptSpec[] = {
DEF_FRAME_VISUAL, -1, Tk_Offset(Frame, visualName),
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-width", "width", "Width",
- DEF_FRAME_WIDTH, -1, Tk_Offset(Frame, width),
- 0, 0, 0},
- {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0, 0, 0, 0}
+ DEF_FRAME_WIDTH, -1, Tk_Offset(Frame, width), 0, 0, 0},
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};
-static CONST Tk_OptionSpec frameOptSpec[] = {
- {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+static const Tk_OptionSpec frameOptSpec[] = {
+ {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
- DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth),
- 0, 0, 0},
+ DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), 0, 0, 0},
{TK_OPTION_STRING, "-class", "class", "Class",
- DEF_FRAME_CLASS, -1, Tk_Offset(Frame, className),
- 0, 0, 0},
+ DEF_FRAME_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0},
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
- DEF_FRAME_RELIEF, -1, Tk_Offset(Frame, relief),
- 0, 0, 0},
- {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0, 0, (ClientData) commonOptSpec, 0}
+ DEF_FRAME_RELIEF, -1, Tk_Offset(Frame, relief), 0, 0, 0},
+ {TK_OPTION_END, NULL, NULL, NULL,
+ NULL, 0, 0, 0, (ClientData) commonOptSpec, 0}
};
-static CONST Tk_OptionSpec toplevelOptSpec[] = {
- {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+static const Tk_OptionSpec toplevelOptSpec[] = {
+ {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
- DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth),
- 0, 0, 0},
+ DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), 0, 0, 0},
{TK_OPTION_STRING, "-class", "class", "Class",
- DEF_TOPLEVEL_CLASS, -1, Tk_Offset(Frame, className),
- 0, 0, 0},
+ DEF_TOPLEVEL_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0},
{TK_OPTION_STRING, "-menu", "menu", "Menu",
DEF_TOPLEVEL_MENU, -1, Tk_Offset(Frame, menuName),
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
- DEF_FRAME_RELIEF, -1, Tk_Offset(Frame, relief),
- 0, 0, 0},
+ DEF_FRAME_RELIEF, -1, Tk_Offset(Frame, relief), 0, 0, 0},
{TK_OPTION_STRING, "-screen", "screen", "Screen",
DEF_TOPLEVEL_SCREEN, -1, Tk_Offset(Frame, screenName),
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_STRING, "-use", "use", "Use",
DEF_TOPLEVEL_USE, -1, Tk_Offset(Frame, useThis),
TK_OPTION_NULL_OK, 0, 0},
- {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0, 0, (ClientData) commonOptSpec, 0}
+ {TK_OPTION_END, NULL, NULL, NULL,
+ NULL, 0, 0, 0, (ClientData) commonOptSpec, 0}
};
-static CONST Tk_OptionSpec labelframeOptSpec[] = {
- {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+static const Tk_OptionSpec labelframeOptSpec[] = {
+ {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
DEF_LABELFRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth),
- 0, 0, 0},
- {TK_OPTION_STRING, "-class", "class", "Class",
- DEF_LABELFRAME_CLASS, -1, Tk_Offset(Frame, className),
0, 0, 0},
- {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0},
+ {TK_OPTION_STRING, "-class", "class", "Class",
+ DEF_LABELFRAME_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0},
+ {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
+ NULL, 0, -1, 0, (ClientData) "-foreground", 0},
{TK_OPTION_FONT, "-font", "font", "Font",
DEF_LABELFRAME_FONT, -1, Tk_Offset(Labelframe, tkfont), 0, 0, 0},
{TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
DEF_LABELFRAME_FG, -1, Tk_Offset(Labelframe, textColorPtr), 0, 0, 0},
{TK_OPTION_STRING_TABLE, "-labelanchor", "labelAnchor", "LabelAnchor",
DEF_LABELFRAME_LABELANCHOR, -1, Tk_Offset(Labelframe, labelAnchor),
- 0, (ClientData) labelAnchorStrings, 0},
+ 0, (ClientData) labelAnchorStrings, 0},
{TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget",
- (char *) NULL, -1, Tk_Offset(Labelframe, labelWin),
- TK_OPTION_NULL_OK, 0, 0},
+ NULL, -1, Tk_Offset(Labelframe, labelWin), TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
- DEF_LABELFRAME_RELIEF, -1, Tk_Offset(Frame, relief),
- 0, 0, 0},
+ DEF_LABELFRAME_RELIEF, -1, Tk_Offset(Frame, relief), 0, 0, 0},
{TK_OPTION_STRING, "-text", "text", "Text",
DEF_LABELFRAME_TEXT, Tk_Offset(Labelframe, textPtr), -1,
TK_OPTION_NULL_OK, 0, 0},
- {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0, 0, (ClientData) commonOptSpec, 0}
+ {TK_OPTION_END, NULL, NULL, NULL,
+ NULL, 0, 0, 0, (ClientData) commonOptSpec, 0}
};
/*
@@ -305,48 +288,47 @@ static CONST Tk_OptionSpec labelframeOptSpec[] = {
static CONST char *classNames[] = {"Frame", "Toplevel", "Labelframe"};
/*
- * The following table maps from FrameType to the option template for
- * that class of widgets.
+ * The following table maps from FrameType to the option template for that
+ * class of widgets.
*/
-static CONST Tk_OptionSpec *CONST optionSpecs[] = {
+static const Tk_OptionSpec * const optionSpecs[] = {
frameOptSpec,
toplevelOptSpec,
labelframeOptSpec
};
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static void ComputeFrameGeometry _ANSI_ARGS_((Frame *framePtr));
-static int ConfigureFrame _ANSI_ARGS_((Tcl_Interp *interp,
- Frame *framePtr, int objc, Tcl_Obj *CONST objv[]));
-static int CreateFrame _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int objc, Tcl_Obj *CONST argv[],
- enum FrameType type, char *appName));
-static void DestroyFrame _ANSI_ARGS_((char *memPtr));
-static void DestroyFramePartly _ANSI_ARGS_((Frame *framePtr));
-static void DisplayFrame _ANSI_ARGS_((ClientData clientData));
-static void FrameCmdDeletedProc _ANSI_ARGS_((
- ClientData clientData));
-static void FrameEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void FrameLostSlaveProc _ANSI_ARGS_((
- ClientData clientData, Tk_Window tkwin));
-static void FrameRequestProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin));
-static void FrameStructureProc _ANSI_ARGS_((
- ClientData clientData, XEvent *eventPtr));
-static int FrameWidgetObjCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
-static void FrameWorldChanged _ANSI_ARGS_((
- ClientData instanceData));
-static void MapFrame _ANSI_ARGS_((ClientData clientData));
+static void ComputeFrameGeometry(Frame *framePtr);
+static int ConfigureFrame(Tcl_Interp *interp, Frame *framePtr,
+ int objc, Tcl_Obj *CONST objv[]);
+static int CreateFrame(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST argv[],
+ enum FrameType type, char *appName);
+static void DestroyFrame(char *memPtr);
+static void DestroyFramePartly(Frame *framePtr);
+static void DisplayFrame(ClientData clientData);
+static void FrameCmdDeletedProc(ClientData clientData);
+static void FrameEventProc(ClientData clientData,
+ XEvent *eventPtr);
+static void FrameLostSlaveProc(ClientData clientData,
+ Tk_Window tkwin);
+static void FrameRequestProc(ClientData clientData,
+ Tk_Window tkwin);
+static void FrameStructureProc(ClientData clientData,
+ XEvent *eventPtr);
+static int FrameWidgetObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]);
+static void FrameWorldChanged(ClientData instanceData);
+static void MapFrame(ClientData clientData);
/*
- * The structure below defines frame class behavior by means of procedures
- * that can be invoked from generic window code.
+ * The structure below defines frame class behavior by means of functions that
+ * can be invoked from generic window code.
*/
static Tk_ClassProcs frameClass = {
@@ -355,67 +337,63 @@ static Tk_ClassProcs frameClass = {
};
/*
- * The structure below defines the official type record for the
- * labelframe's geometry manager:
+ * The structure below defines the official type record for the labelframe's
+ * geometry manager:
*/
-static Tk_GeomMgr frameGeomType = {
- "labelframe", /* name */
- FrameRequestProc, /* requestProc */
- FrameLostSlaveProc /* lostSlaveProc */
+static const Tk_GeomMgr frameGeomType = {
+ "labelframe", /* name */
+ FrameRequestProc, /* requestProc */
+ FrameLostSlaveProc /* lostSlaveProc */
};
-
/*
*--------------------------------------------------------------
*
* Tk_FrameObjCmd, Tk_ToplevelObjCmd, Tk_LabelframeObjCmd --
*
- * These procedures are invoked to process the "frame",
- * "toplevel" and "labelframe" Tcl commands. See the user
- * documentation for details on what they do.
+ * These functions are invoked to process the "frame", "toplevel" and
+ * "labelframe" Tcl commands. See the user documentation for details on
+ * what they do.
*
* Results:
* A standard Tcl result.
*
* Side effects:
- * See the user documentation. These procedures are just wrappers;
- * they call CreateFrame to do all of the real work.
+ * See the user documentation. These functions are just wrappers; they
+ * call CreateFrame to do all of the real work.
*
*--------------------------------------------------------------
*/
int
-Tk_FrameObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Either NULL or pointer to option table. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_FrameObjCmd(
+ ClientData clientData, /* Either NULL or pointer to option table. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- return CreateFrame(clientData, interp, objc, objv, TYPE_FRAME,
- (char *) NULL);
+ return CreateFrame(clientData, interp, objc, objv, TYPE_FRAME, NULL);
}
int
-Tk_ToplevelObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Either NULL or pointer to option table. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_ToplevelObjCmd(
+ ClientData clientData, /* Either NULL or pointer to option table. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- return CreateFrame(clientData, interp, objc, objv, TYPE_TOPLEVEL,
- (char *) NULL);
+ return CreateFrame(clientData, interp, objc, objv, TYPE_TOPLEVEL, NULL);
}
int
-Tk_LabelframeObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Either NULL or pointer to option table. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_LabelframeObjCmd(
+ ClientData clientData, /* Either NULL or pointer to option table. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- return CreateFrame(clientData, interp, objc, objv, TYPE_LABELFRAME,
- (char *) NULL);
+ return CreateFrame(clientData, interp, objc, objv, TYPE_LABELFRAME, NULL);
}
/*
@@ -423,10 +401,10 @@ Tk_LabelframeObjCmd(clientData, interp, objc, objv)
*
* TkCreateFrame --
*
- * This procedure is the old command procedure for the "frame"
- * and "toplevel" commands. Now it is used directly by Tk_Init to
- * create a new main window. See the user documentation for the
- * "frame" and "toplevel" commands for details on what it does.
+ * This function is the old command function for the "frame" and
+ * "toplevel" commands. Now it is used directly by Tk_Init to create a
+ * new main window. See the user documentation for the "frame" and
+ * "toplevel" commands for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -438,20 +416,21 @@ Tk_LabelframeObjCmd(clientData, interp, objc, objv)
*/
int
-TkCreateFrame(clientData, interp, argc, argv, toplevel, appName)
- ClientData clientData; /* Either NULL or pointer to option table. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- char **argv; /* Argument strings. */
- int toplevel; /* Non-zero means create a toplevel window,
+TkCreateFrame(
+ ClientData clientData, /* Either NULL or pointer to option table. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ char **argv, /* Argument strings. */
+ int toplevel, /* Non-zero means create a toplevel window,
* zero means create a frame. */
- char *appName; /* Should only be non-NULL if there is no main
+ char *appName) /* Should only be non-NULL if there is no main
* window associated with the interpreter.
- * Gives the base name to use for the
- * new application. */
+ * Gives the base name to use for the new
+ * application. */
{
int result, i;
Tcl_Obj **objv = (Tcl_Obj **) ckalloc((argc+1) * sizeof(Tcl_Obj **));
+
for (i=0; i<argc; i++) {
objv[i] = Tcl_NewStringObj(argv[i], -1);
Tcl_IncrRefCount(objv[i]);
@@ -467,23 +446,23 @@ TkCreateFrame(clientData, interp, argc, argv, toplevel, appName)
}
static int
-CreateFrame(clientData, interp, objc, objv, type, appName)
- ClientData clientData; /* NULL. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
- enum FrameType type; /* What widget type to create. */
- char *appName; /* Should only be non-NULL if there are no
- * Main window associated with the interpreter.
- * Gives the base name to use for the
- * new application. */
+CreateFrame(
+ ClientData clientData, /* NULL. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[], /* Argument objects. */
+ enum FrameType type, /* What widget type to create. */
+ char *appName) /* Should only be non-NULL if there are no
+ * Main window associated with the
+ * interpreter. Gives the base name to use for
+ * the new application. */
{
Tk_Window tkwin;
Frame *framePtr;
Tk_OptionTable optionTable;
- Tk_Window new;
+ Tk_Window newWin;
CONST char *className, *screenName, *visualName, *colormapName, *arg, *useOption;
- int i, c, depth, length;
+ int i, c, length, depth;
unsigned int mask;
Colormap colormap;
Visual *visual;
@@ -494,17 +473,17 @@ CreateFrame(clientData, interp, objc, objv, type, appName)
}
/*
- * Create the option table for this widget class. If it has already
- * been created, the cached pointer will be returned.
+ * Create the option table for this widget class. If it has already been
+ * created, the cached pointer will be returned.
*/
optionTable = Tk_CreateOptionTable(interp, optionSpecs[type]);
/*
- * Pre-process the argument list. Scan through it to find any
- * "-class", "-screen", "-visual", and "-colormap" options. These
- * arguments need to be processed specially, before the window
- * is configured using the usual Tk mechanisms.
+ * Pre-process the argument list. Scan through it to find any "-class",
+ * "-screen", "-visual", and "-colormap" options. These arguments need to
+ * be processed specially, before the window is configured using the usual
+ * Tk mechanisms.
*/
className = colormapName = screenName = visualName = useOption = NULL;
@@ -515,8 +494,8 @@ CreateFrame(clientData, interp, objc, objv, type, appName)
continue;
}
c = arg[1];
- if ((c == 'c') && (strncmp(arg, "-class", (unsigned) length) == 0)
- && (length >= 3)) {
+ if ((c == 'c') && (length >= 3)
+ && (strncmp(arg, "-class", (unsigned) length) == 0)) {
className = Tcl_GetString(objv[i+1]);
} else if ((c == 'c')
&& (strncmp(arg, "-colormap", (unsigned) length) == 0)) {
@@ -534,18 +513,17 @@ CreateFrame(clientData, interp, objc, objv, type, appName)
}
/*
- * Create the window, and deal with the special options -use,
- * -classname, -colormap, -screenname, and -visual. These options
- * must be handle before calling ConfigureFrame below, and they must
- * also be processed in a particular order, for the following
- * reasons:
- * 1. Must set the window's class before calling ConfigureFrame,
- * so that unspecified options are looked up in the option
- * database using the correct class.
- * 2. Must set visual information before calling ConfigureFrame
- * so that colors are allocated in a proper colormap.
+ * Create the window, and deal with the special options -use, -classname,
+ * -colormap, -screenname, and -visual. These options must be handle
+ * before calling ConfigureFrame below, and they must also be processed in
+ * a particular order, for the following reasons:
+ * 1. Must set the window's class before calling ConfigureFrame, so that
+ * unspecified options are looked up in the option database using the
+ * correct class.
+ * 2. Must set visual information before calling ConfigureFrame so that
+ * colors are allocated in a proper colormap.
* 3. Must call TkpUseWindow before setting non-default visual
- * information, since TkpUseWindow changes the defaults.
+ * information, since TkpUseWindow changes the defaults.
*/
if (screenName == NULL) {
@@ -553,88 +531,93 @@ CreateFrame(clientData, interp, objc, objv, type, appName)
}
/*
- * Main window associated with interpreter.
- * If we're called by Tk_Init to create a
- * new application, then this is NULL.
+ * Main window associated with interpreter. If we're called by Tk_Init to
+ * create a new application, then this is NULL.
*/
tkwin = Tk_MainWindow(interp);
if (tkwin != NULL) {
- new = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]),
+ newWin = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]),
screenName);
} else if (appName == NULL) {
/*
- * This occurs when someone tried to create a frame/toplevel
- * while we are being destroyed. Let an error be thrown.
+ * This occurs when someone tried to create a frame/toplevel while we
+ * are being destroyed. Let an error be thrown.
*/
Tcl_AppendResult(interp, "unable to create widget \"",
- Tcl_GetString(objv[1]), "\"", (char *) NULL);
- new = NULL;
+ Tcl_GetString(objv[1]), "\"", NULL);
+ newWin = NULL;
} else {
/*
- * We were called from Tk_Init; create a new application.
+ * We were called from Tk_Init; create a new application.
*/
- new = TkCreateMainWindow(interp, screenName, appName);
+ newWin = TkCreateMainWindow(interp, screenName, appName);
}
- if (new == NULL) {
+ if (newWin == NULL) {
goto error;
+ } else {
+ /*
+ * Mark Tk frames as suitable candidates for [wm manage]
+ */
+ TkWindow *winPtr = (TkWindow *)newWin;
+ winPtr->flags |= TK_WM_MANAGEABLE;
}
if (className == NULL) {
- className = Tk_GetOption(new, "class", "Class");
+ className = Tk_GetOption(newWin, "class", "Class");
if (className == NULL) {
className = classNames[type];
}
}
- Tk_SetClass(new, className);
+ Tk_SetClass(newWin, className);
if (useOption == NULL) {
- useOption = Tk_GetOption(new, "use", "Use");
+ useOption = Tk_GetOption(newWin, "use", "Use");
}
if ((useOption != NULL) && (*useOption != 0)) {
- if (TkpUseWindow(interp, new, useOption) != TCL_OK) {
+ if (TkpUseWindow(interp, newWin, useOption) != TCL_OK) {
goto error;
}
}
if (visualName == NULL) {
- visualName = Tk_GetOption(new, "visual", "Visual");
+ visualName = Tk_GetOption(newWin, "visual", "Visual");
}
if (colormapName == NULL) {
- colormapName = Tk_GetOption(new, "colormap", "Colormap");
+ colormapName = Tk_GetOption(newWin, "colormap", "Colormap");
}
if ((colormapName != NULL) && (*colormapName == 0)) {
colormapName = NULL;
}
if (visualName != NULL) {
- visual = Tk_GetVisual(interp, new, visualName, &depth,
- (colormapName == NULL) ? &colormap : (Colormap *) NULL);
+ visual = Tk_GetVisual(interp, newWin, visualName, &depth,
+ (colormapName == NULL) ? &colormap : NULL);
if (visual == NULL) {
goto error;
}
- Tk_SetWindowVisual(new, visual, depth, colormap);
+ Tk_SetWindowVisual(newWin, visual, depth, colormap);
}
if (colormapName != NULL) {
- colormap = Tk_GetColormap(interp, new, colormapName);
+ colormap = Tk_GetColormap(interp, newWin, colormapName);
if (colormap == None) {
goto error;
}
- Tk_SetWindowColormap(new, colormap);
+ Tk_SetWindowColormap(newWin, colormap);
}
/*
- * For top-level windows, provide an initial geometry request of
- * 200x200, just so the window looks nicer on the screen if it
- * doesn't request a size for itself.
+ * For top-level windows, provide an initial geometry request of 200x200,
+ * just so the window looks nicer on the screen if it doesn't request a
+ * size for itself.
*/
if (type == TYPE_TOPLEVEL) {
- Tk_GeometryRequest(new, 200, 200);
+ Tk_GeometryRequest(newWin, 200, 200);
}
/*
- * Create the widget record, process configuration options, and
- * create event handlers. Then fill in a few additional fields
- * in the widget record from the special options.
+ * Create the widget record, process configuration options, and create
+ * event handlers. Then fill in a few additional fields in the widget
+ * record from the special options.
*/
if (type == TYPE_LABELFRAME) {
@@ -644,11 +627,11 @@ CreateFrame(clientData, interp, objc, objv, type, appName)
framePtr = (Frame *) ckalloc(sizeof(Frame));
memset((void *) framePtr, 0, (sizeof(Frame)));
}
- framePtr->tkwin = new;
- framePtr->display = Tk_Display(new);
+ framePtr->tkwin = newWin;
+ framePtr->display = Tk_Display(newWin);
framePtr->interp = interp;
framePtr->widgetCmd = Tcl_CreateObjCommand(interp,
- Tk_PathName(new), FrameWidgetObjCmd,
+ Tk_PathName(newWin), FrameWidgetObjCmd,
(ClientData) framePtr, FrameCmdDeletedProc);
framePtr->optionTable = optionTable;
framePtr->type = type;
@@ -665,14 +648,15 @@ CreateFrame(clientData, interp, objc, objv, type, appName)
/*
* Store backreference to frame widget in window structure.
*/
- Tk_SetClassProcs(new, &frameClass, (ClientData) framePtr);
+
+ Tk_SetClassProcs(newWin, &frameClass, (ClientData) framePtr);
mask = ExposureMask | StructureNotifyMask | FocusChangeMask;
if (type == TYPE_TOPLEVEL) {
- mask |= ActivateMask;
+ mask |= ActivateMask;
}
- Tk_CreateEventHandler(new, mask, FrameEventProc, (ClientData) framePtr);
- if ((Tk_InitOptions(interp, (char *) framePtr, optionTable, new)
+ Tk_CreateEventHandler(newWin, mask, FrameEventProc, (ClientData) framePtr);
+ if ((Tk_InitOptions(interp, (char *) framePtr, optionTable, newWin)
!= TCL_OK) ||
(ConfigureFrame(interp, framePtr, objc-2, objv+2) != TCL_OK)) {
goto error;
@@ -682,19 +666,19 @@ CreateFrame(clientData, interp, objc, objv, type, appName)
TkpMakeContainer(framePtr->tkwin);
} else {
Tcl_AppendResult(interp, "A window cannot have both the -use ",
- "and the -container option set.", (char *) NULL);
+ "and the -container option set.", NULL);
goto error;
}
}
if (type == TYPE_TOPLEVEL) {
Tcl_DoWhenIdle(MapFrame, (ClientData) framePtr);
}
- Tcl_SetResult(interp, Tk_PathName(new), TCL_STATIC);
+ Tcl_SetResult(interp, Tk_PathName(newWin), TCL_STATIC);
return TCL_OK;
- error:
- if (new != NULL) {
- Tk_DestroyWindow(new);
+ error:
+ if (newWin != NULL) {
+ Tk_DestroyWindow(newWin);
}
return TCL_ERROR;
}
@@ -704,9 +688,9 @@ CreateFrame(clientData, interp, objc, objv, type, appName)
*
* FrameWidgetObjCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to a frame widget. See the user
- * documentation for details on what it does.
+ * This function is invoked to process the Tcl command that corresponds
+ * to a frame widget. See the user documentation for details on what it
+ * does.
*
* Results:
* A standard Tcl result.
@@ -718,14 +702,14 @@ CreateFrame(clientData, interp, objc, objv, type, appName)
*/
static int
-FrameWidgetObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Information about frame widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+FrameWidgetObjCmd(
+ ClientData clientData, /* Information about frame widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
static CONST char *frameOptions[] = {
- "cget", "configure", (char *) NULL
+ "cget", "configure", NULL
};
enum options {
FRAME_CGET, FRAME_CONFIGURE
@@ -745,27 +729,26 @@ FrameWidgetObjCmd(clientData, interp, objc, objv)
}
Tcl_Preserve((ClientData) framePtr);
switch ((enum options) index) {
- case FRAME_CGET: {
+ case FRAME_CGET:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "option");
result = TCL_ERROR;
goto done;
}
- objPtr = Tk_GetOptionValue(interp, (char *) framePtr,
+ objPtr = Tk_GetOptionValue(interp, (char *) framePtr,
framePtr->optionTable, objv[2], framePtr->tkwin);
- if (objPtr == NULL) {
+ if (objPtr == NULL) {
result = TCL_ERROR;
goto done;
- } else {
+ } else {
Tcl_SetObjResult(interp, objPtr);
- }
+ }
break;
- }
- case FRAME_CONFIGURE: {
+ case FRAME_CONFIGURE:
if (objc <= 3) {
objPtr = Tk_GetOptionInfo(interp, (char *) framePtr,
framePtr->optionTable,
- (objc == 3) ? objv[2] : (Tcl_Obj *) NULL,
+ (objc == 3) ? objv[2] : NULL,
framePtr->tkwin);
if (objPtr == NULL) {
result = TCL_ERROR;
@@ -775,8 +758,8 @@ FrameWidgetObjCmd(clientData, interp, objc, objv)
}
} else {
/*
- * Don't allow the options -class, -colormap, -container,
- * -newcmap, -screen, -use, or -visual to be changed.
+ * Don't allow the options -class, -colormap, -container, -screen,
+ * -use, or -visual to be changed.
*/
for (i = 2; i < objc; i++) {
@@ -785,34 +768,47 @@ FrameWidgetObjCmd(clientData, interp, objc, objv)
continue;
}
c = arg[1];
- if (((c == 'c')
- && (strncmp(arg, "-class", (unsigned) length) == 0)
- && (length >= 2))
- || ((c == 'c')
- && (strncmp(arg, "-colormap", (unsigned) length) == 0)
- && (length >= 3))
- || ((c == 'c')
- && (strncmp(arg, "-container", (unsigned) length) == 0)
- && (length >= 3))
- || ((c == 's') && (framePtr->type == TYPE_TOPLEVEL)
- && (strncmp(arg, "-screen", (unsigned) length) == 0))
- || ((c == 'u') && (framePtr->type == TYPE_TOPLEVEL)
- && (strncmp(arg, "-use", (unsigned) length) == 0))
- || ((c == 'v')
- && (strncmp(arg, "-visual", (unsigned) length) ==0))) {
- Tcl_AppendResult(interp, "can't modify ", arg,
- " option after widget is created", (char *) NULL);
- result = TCL_ERROR;
- goto done;
+ if (((c == 'c') && (length >= 2)
+ && (strncmp(arg, "-class", (unsigned)length) == 0))
+ || ((c == 'c') && (length >= 3)
+ && (strncmp(arg, "-colormap", (unsigned)length) == 0))
+ || ((c == 'c') && (length >= 3)
+ && (strncmp(arg, "-container", (unsigned)length) == 0))
+ || ((c == 's') && (framePtr->type == TYPE_TOPLEVEL)
+ && (strncmp(arg, "-screen", (unsigned)length) == 0))
+ || ((c == 'u') && (framePtr->type == TYPE_TOPLEVEL)
+ && (strncmp(arg, "-use", (unsigned)length) == 0))
+ || ((c == 'v')
+ && (strncmp(arg, "-visual", (unsigned)length) == 0))) {
+
+ #ifdef SUPPORT_CONFIG_EMBEDDED
+ if (c == 'u') {
+ CONST char *string = Tcl_GetString(objv[i+1]);
+ if (TkpUseWindow(interp, framePtr->tkwin,
+ string) != TCL_OK) {
+ result = TCL_ERROR;
+ goto done;
+ }
+ } else {
+ Tcl_AppendResult(interp, "can't modify ", arg,
+ " option after widget is created", NULL);
+ result = TCL_ERROR;
+ goto done;
+ }
+ #else
+ Tcl_AppendResult(interp, "can't modify ", arg,
+ " option after widget is created", NULL);
+ result = TCL_ERROR;
+ goto done;
+ #endif
}
}
result = ConfigureFrame(interp, framePtr, objc-2, objv+2);
}
break;
- }
}
- done:
+ done:
Tcl_Release((ClientData) framePtr);
return result;
}
@@ -822,9 +818,9 @@ FrameWidgetObjCmd(clientData, interp, objc, objv)
*
* DestroyFrame --
*
- * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release
- * to clean up the internal structure of a frame at a safe time
- * (when no-one is using it anymore).
+ * This function is invoked by Tcl_EventuallyFree or Tcl_Release to clean
+ * up the internal structure of a frame at a safe time (when no-one is
+ * using it anymore).
*
* Results:
* None.
@@ -836,8 +832,8 @@ FrameWidgetObjCmd(clientData, interp, objc, objv)
*/
static void
-DestroyFrame(memPtr)
- char *memPtr; /* Info about frame widget. */
+DestroyFrame(
+ char *memPtr) /* Info about frame widget. */
{
register Frame *framePtr = (Frame *) memPtr;
register Labelframe *labelframePtr = (Labelframe *) memPtr;
@@ -859,10 +855,9 @@ DestroyFrame(memPtr)
*
* DestroyFramePartly --
*
- * This procedure is invoked to clean up everything that needs
- * tkwin to be defined when deleted. During the destruction
- * process tkwin is always set to NULL and this procedure must
- * be called before that happens.
+ * This function is invoked to clean up everything that needs tkwin to be
+ * defined when deleted. During the destruction process tkwin is always
+ * set to NULL and this function must be called before that happens.
*
* Results:
* None.
@@ -874,16 +869,15 @@ DestroyFrame(memPtr)
*/
static void
-DestroyFramePartly(framePtr)
- Frame *framePtr; /* Info about frame widget. */
+DestroyFramePartly(
+ Frame *framePtr) /* Info about frame widget. */
{
register Labelframe *labelframePtr = (Labelframe *) framePtr;
if (framePtr->type == TYPE_LABELFRAME && labelframePtr->labelWin != NULL) {
Tk_DeleteEventHandler(labelframePtr->labelWin, StructureNotifyMask,
FrameStructureProc, (ClientData) framePtr);
- Tk_ManageGeometry(labelframePtr->labelWin, (Tk_GeomMgr *) NULL,
- (ClientData) NULL);
+ Tk_ManageGeometry(labelframePtr->labelWin, NULL, (ClientData) NULL);
if (framePtr->tkwin != Tk_Parent(labelframePtr->labelWin)) {
Tk_UnmaintainGeometry(labelframePtr->labelWin, framePtr->tkwin);
}
@@ -892,7 +886,7 @@ DestroyFramePartly(framePtr)
}
Tk_FreeConfigOptions((char *) framePtr, framePtr->optionTable,
- framePtr->tkwin);
+ framePtr->tkwin);
}
/*
@@ -900,29 +894,28 @@ DestroyFramePartly(framePtr)
*
* ConfigureFrame --
*
- * This procedure is called to process an objv/objc list, plus
- * the Tk option database, in order to configure (or
- * reconfigure) a frame widget.
+ * This function is called to process an objv/objc list, plus the Tk
+ * option database, in order to configure (or reconfigure) a frame
+ * widget.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message.
+ * 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 text string, colors, font,
- * etc. get set for framePtr; old resources get freed, if there
- * were any.
+ * Configuration information, such as text string, colors, font, etc. get
+ * set for framePtr; old resources get freed, if there were any.
*
*----------------------------------------------------------------------
*/
static int
-ConfigureFrame(interp, framePtr, objc, objv)
- Tcl_Interp *interp; /* Used for error reporting. */
- register Frame *framePtr; /* 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. */
+ConfigureFrame(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ register Frame *framePtr, /* 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. */
{
Tk_SavedOptions savedOptions;
char *oldMenuName;
@@ -932,7 +925,7 @@ ConfigureFrame(interp, framePtr, objc, objv)
/*
* Need the old menubar name for the menu code to delete it.
*/
-
+
if (framePtr->menuName == NULL) {
oldMenuName = NULL;
} else {
@@ -945,7 +938,7 @@ ConfigureFrame(interp, framePtr, objc, objv)
}
if (Tk_SetOptions(interp, (char *) framePtr,
framePtr->optionTable, objc, objv,
- framePtr->tkwin, &savedOptions, (int *) NULL) != TCL_OK) {
+ framePtr->tkwin, &savedOptions, NULL) != TCL_OK) {
if (oldMenuName != NULL) {
ckfree(oldMenuName);
}
@@ -958,10 +951,11 @@ ConfigureFrame(interp, framePtr, objc, objv)
* A few of the options require additional processing.
*/
- if (((oldMenuName == NULL) && (framePtr->menuName != NULL))
+ if ((((oldMenuName == NULL) && (framePtr->menuName != NULL))
|| ((oldMenuName != NULL) && (framePtr->menuName == NULL))
|| ((oldMenuName != NULL) && (framePtr->menuName != NULL)
- && strcmp(oldMenuName, framePtr->menuName) != 0)) {
+ && strcmp(oldMenuName, framePtr->menuName) != 0))
+ && framePtr->type == TYPE_TOPLEVEL) {
TkSetWindowMenuBar(interp, framePtr->tkwin, oldMenuName,
framePtr->menuName);
}
@@ -987,8 +981,8 @@ ConfigureFrame(interp, framePtr, objc, objv)
}
/*
- * If a -labelwidget is specified, check that it is valid and set
- * up geometry management for it.
+ * If a -labelwidget is specified, check that it is valid and set up
+ * geometry management for it.
*/
if (framePtr->type == TYPE_LABELFRAME) {
@@ -996,8 +990,7 @@ ConfigureFrame(interp, framePtr, objc, objv)
if (oldWindow != NULL) {
Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
FrameStructureProc, (ClientData) framePtr);
- Tk_ManageGeometry(oldWindow, (Tk_GeomMgr *) NULL,
- (ClientData) NULL);
+ Tk_ManageGeometry(oldWindow, NULL, (ClientData) NULL);
Tk_UnmaintainGeometry(oldWindow, framePtr->tkwin);
Tk_UnmapWindow(oldWindow);
}
@@ -1005,10 +998,9 @@ ConfigureFrame(interp, framePtr, objc, objv)
Tk_Window ancestor, parent, sibling = NULL;
/*
- * Make sure that the frame is either the parent of the
- * window used as label or a descendant of that
- * parent. Also, don't allow a top-level window to be
- * managed inside the frame.
+ * Make sure that the frame is either the parent of the window
+ * used as label or a descendant of that parent. Also, don't
+ * allow a top-level window to be managed inside the frame.
*/
parent = Tk_Parent(labelframePtr->labelWin);
@@ -1022,7 +1014,7 @@ ConfigureFrame(interp, framePtr, objc, objv)
badWindow:
Tcl_AppendResult(interp, "can't use ",
Tk_PathName(labelframePtr->labelWin),
- " as label in this frame", (char *) NULL);
+ " as label in this frame", NULL);
labelframePtr->labelWin = NULL;
return TCL_ERROR;
}
@@ -1040,9 +1032,8 @@ ConfigureFrame(interp, framePtr, objc, objv)
(ClientData) framePtr);
/*
- * If the frame is not parent to the label, make
- * sure the label is above its sibling in the stacking
- * order.
+ * If the frame is not parent to the label, make sure the
+ * label is above its sibling in the stacking order.
*/
if (sibling != NULL) {
@@ -1062,22 +1053,22 @@ ConfigureFrame(interp, framePtr, objc, objv)
*
* FrameWorldChanged --
*
- * This procedure is called when the world has changed in some
- * way and the widget needs to recompute all its graphics contexts
- * and determine its new geometry.
+ * This function is called when the world has changed in some way and the
+ * widget needs to recompute all its graphics contexts and determine its
+ * new geometry.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Frame will be relayed out and redisplayed.
+ * Frame will be relayed out and redisplayed.
*
*---------------------------------------------------------------------------
*/
-
+
static void
-FrameWorldChanged(instanceData)
- ClientData instanceData; /* Information about widget. */
+FrameWorldChanged(
+ ClientData instanceData) /* Information about widget. */
{
Frame *framePtr = (Frame *) instanceData;
Labelframe *labelframePtr = (Labelframe *) framePtr;
@@ -1096,8 +1087,8 @@ FrameWorldChanged(instanceData)
if (framePtr->type == TYPE_LABELFRAME) {
/*
- * The textGC is needed even in the labelWin case, so it's
- * always created for a labelframe.
+ * The textGC is needed even in the labelWin case, so it's always
+ * created for a labelframe.
*/
gcValues.font = Tk_FontId(labelframePtr->tkfont);
@@ -1113,7 +1104,7 @@ FrameWorldChanged(instanceData)
/*
* Calculate label size.
*/
-
+
labelframePtr->labelReqWidth = labelframePtr->labelReqHeight = 0;
if (anyTextLabel) {
@@ -1129,13 +1120,13 @@ FrameWorldChanged(instanceData)
labelframePtr->labelReqHeight = Tk_ReqHeight(labelframePtr->labelWin);
}
- /*
- * Make sure label size is at least as big as the border.
- * This simplifies later calculations and gives a better
- * appearance with thick borders.
+ /*
+ * Make sure label size is at least as big as the border. This
+ * simplifies later calculations and gives a better appearance with
+ * thick borders.
*/
-
- if ((labelframePtr->labelAnchor >= LABELANCHOR_N) &&
+
+ if ((labelframePtr->labelAnchor >= LABELANCHOR_N) &&
(labelframePtr->labelAnchor <= LABELANCHOR_SW)) {
if (labelframePtr->labelReqHeight < framePtr->borderWidth) {
labelframePtr->labelReqHeight = framePtr->borderWidth;
@@ -1151,34 +1142,34 @@ FrameWorldChanged(instanceData)
* Calculate individual border widths.
*/
- bWidthBottom = bWidthTop = bWidthRight = bWidthLeft =
- framePtr->borderWidth + framePtr->highlightWidth;
+ bWidthBottom = bWidthTop = bWidthRight = bWidthLeft =
+ framePtr->borderWidth + framePtr->highlightWidth;
bWidthLeft += framePtr->padX;
bWidthRight += framePtr->padX;
bWidthTop += framePtr->padY;
bWidthBottom += framePtr->padY;
-
+
if (anyTextLabel || anyWindowLabel) {
switch (labelframePtr->labelAnchor) {
- case LABELANCHOR_E:
- case LABELANCHOR_EN:
- case LABELANCHOR_ES:
+ case LABELANCHOR_E:
+ case LABELANCHOR_EN:
+ case LABELANCHOR_ES:
bWidthRight += labelframePtr->labelReqWidth -
framePtr->borderWidth;
break;
- case LABELANCHOR_N:
- case LABELANCHOR_NE:
- case LABELANCHOR_NW:
+ case LABELANCHOR_N:
+ case LABELANCHOR_NE:
+ case LABELANCHOR_NW:
bWidthTop += labelframePtr->labelReqHeight - framePtr->borderWidth;
break;
- case LABELANCHOR_S:
- case LABELANCHOR_SE:
- case LABELANCHOR_SW:
+ case LABELANCHOR_S:
+ case LABELANCHOR_SE:
+ case LABELANCHOR_SW:
bWidthBottom += labelframePtr->labelReqHeight -
framePtr->borderWidth;
break;
- default:
+ default:
bWidthLeft += labelframePtr->labelReqWidth - framePtr->borderWidth;
break;
}
@@ -1197,11 +1188,12 @@ FrameWorldChanged(instanceData)
int minwidth = labelframePtr->labelReqWidth;
int minheight = labelframePtr->labelReqHeight;
int padding = framePtr->highlightWidth;
+
if (framePtr->borderWidth > 0) {
padding += framePtr->borderWidth + LABELMARGIN;
}
padding *= 2;
- if ((labelframePtr->labelAnchor >= LABELANCHOR_N) &&
+ if ((labelframePtr->labelAnchor >= LABELANCHOR_N) &&
(labelframePtr->labelAnchor <= LABELANCHOR_SW)) {
minwidth += padding;
minheight += framePtr->borderWidth + framePtr->highlightWidth;
@@ -1229,9 +1221,9 @@ FrameWorldChanged(instanceData)
*
* ComputeFrameGeometry --
*
- * This procedure is called to compute various geometrical
- * information for a frame, such as where various things get
- * displayed. It's called when the window is reconfigured.
+ * This function is called to compute various geometrical information for
+ * a frame, such as where various things get displayed. It's called when
+ * the window is reconfigured.
*
* Results:
* None.
@@ -1243,8 +1235,8 @@ FrameWorldChanged(instanceData)
*/
static void
-ComputeFrameGeometry(framePtr)
- register Frame *framePtr; /* Information about widget. */
+ComputeFrameGeometry(
+ register Frame *framePtr) /* Information about widget. */
{
int otherWidth, otherHeight, otherWidthT, otherHeightT, padding;
int maxWidth, maxHeight;
@@ -1256,12 +1248,13 @@ ComputeFrameGeometry(framePtr)
*/
if (framePtr->type != TYPE_LABELFRAME) return;
- if ((labelframePtr->textPtr == NULL) &&
- (labelframePtr->labelWin == NULL)) return;
+ if (labelframePtr->textPtr == NULL && labelframePtr->labelWin == NULL) {
+ return;
+ }
tkwin = framePtr->tkwin;
- /*
+ /*
* Calculate the available size for the label
*/
@@ -1270,15 +1263,15 @@ ComputeFrameGeometry(framePtr)
padding = framePtr->highlightWidth;
if (framePtr->borderWidth > 0) {
- padding += framePtr->borderWidth + LABELMARGIN;
+ padding += framePtr->borderWidth + LABELMARGIN;
}
padding *= 2;
maxHeight = Tk_Height(tkwin);
maxWidth = Tk_Width(tkwin);
- if ((labelframePtr->labelAnchor >= LABELANCHOR_N) &&
- (labelframePtr->labelAnchor <= LABELANCHOR_SW)) {
+ if ((labelframePtr->labelAnchor >= LABELANCHOR_N) &&
+ (labelframePtr->labelAnchor <= LABELANCHOR_SW)) {
maxWidth -= padding;
if (maxWidth < 1) maxWidth = 1;
} else {
@@ -1293,9 +1286,9 @@ ComputeFrameGeometry(framePtr)
}
/*
- * Calculate label and text position.
- * The text's position is based on the requested size (= the text's
- * real size) to get proper alignment if the text does not fit.
+ * Calculate label and text position. The text's position is based on the
+ * requested size (= the text's real size) to get proper alignment if the
+ * text does not fit.
*/
otherWidth = Tk_Width(tkwin) - labelframePtr->labelBox.width;
@@ -1305,64 +1298,64 @@ ComputeFrameGeometry(framePtr)
padding = framePtr->highlightWidth;
switch (labelframePtr->labelAnchor) {
- case LABELANCHOR_E:
- case LABELANCHOR_EN:
- case LABELANCHOR_ES:
- labelframePtr->labelTextX = otherWidthT - padding;
- labelframePtr->labelBox.x = otherWidth - padding;
- break;
- case LABELANCHOR_N:
- case LABELANCHOR_NE:
- case LABELANCHOR_NW:
- labelframePtr->labelTextY = padding;
- labelframePtr->labelBox.y = padding;
- break;
- case LABELANCHOR_S:
- case LABELANCHOR_SE:
- case LABELANCHOR_SW:
- labelframePtr->labelTextY = otherHeightT - padding;
- labelframePtr->labelBox.y = otherHeight - padding;
- break;
- default:
- labelframePtr->labelTextX = padding;
- labelframePtr->labelBox.x = padding;
- break;
+ case LABELANCHOR_E:
+ case LABELANCHOR_EN:
+ case LABELANCHOR_ES:
+ labelframePtr->labelTextX = otherWidthT - padding;
+ labelframePtr->labelBox.x = otherWidth - padding;
+ break;
+ case LABELANCHOR_N:
+ case LABELANCHOR_NE:
+ case LABELANCHOR_NW:
+ labelframePtr->labelTextY = padding;
+ labelframePtr->labelBox.y = padding;
+ break;
+ case LABELANCHOR_S:
+ case LABELANCHOR_SE:
+ case LABELANCHOR_SW:
+ labelframePtr->labelTextY = otherHeightT - padding;
+ labelframePtr->labelBox.y = otherHeight - padding;
+ break;
+ default:
+ labelframePtr->labelTextX = padding;
+ labelframePtr->labelBox.x = padding;
+ break;
}
if (framePtr->borderWidth > 0) {
- padding += framePtr->borderWidth + LABELMARGIN;
+ padding += framePtr->borderWidth + LABELMARGIN;
}
switch (labelframePtr->labelAnchor) {
- case LABELANCHOR_NW:
- case LABELANCHOR_SW:
- labelframePtr->labelTextX = padding;
- labelframePtr->labelBox.x = padding;
- break;
- case LABELANCHOR_N:
- case LABELANCHOR_S:
- labelframePtr->labelTextX = otherWidthT / 2;
- labelframePtr->labelBox.x = otherWidth / 2;
- break;
- case LABELANCHOR_NE:
- case LABELANCHOR_SE:
- labelframePtr->labelTextX = otherWidthT - padding;
- labelframePtr->labelBox.x = otherWidth - padding;
- break;
- case LABELANCHOR_EN:
- case LABELANCHOR_WN:
- labelframePtr->labelTextY = padding;
- labelframePtr->labelBox.y = padding;
- break;
- case LABELANCHOR_E:
- case LABELANCHOR_W:
- labelframePtr->labelTextY = otherHeightT / 2;
- labelframePtr->labelBox.y = otherHeight / 2;
- break;
- default:
+ case LABELANCHOR_NW:
+ case LABELANCHOR_SW:
+ labelframePtr->labelTextX = padding;
+ labelframePtr->labelBox.x = padding;
+ break;
+ case LABELANCHOR_N:
+ case LABELANCHOR_S:
+ labelframePtr->labelTextX = otherWidthT / 2;
+ labelframePtr->labelBox.x = otherWidth / 2;
+ break;
+ case LABELANCHOR_NE:
+ case LABELANCHOR_SE:
+ labelframePtr->labelTextX = otherWidthT - padding;
+ labelframePtr->labelBox.x = otherWidth - padding;
+ break;
+ case LABELANCHOR_EN:
+ case LABELANCHOR_WN:
+ labelframePtr->labelTextY = padding;
+ labelframePtr->labelBox.y = padding;
+ break;
+ case LABELANCHOR_E:
+ case LABELANCHOR_W:
+ labelframePtr->labelTextY = otherHeightT / 2;
+ labelframePtr->labelBox.y = otherHeight / 2;
+ break;
+ default:
labelframePtr->labelTextY = otherHeightT - padding;
labelframePtr->labelBox.y = otherHeight - padding;
- break;
+ break;
}
}
@@ -1371,21 +1364,20 @@ ComputeFrameGeometry(framePtr)
*
* DisplayFrame --
*
- * This procedure is invoked to display a frame widget.
+ * This function is invoked to display a frame widget.
*
* Results:
* None.
*
* Side effects:
- * Commands are output to X to display the frame in its
- * current mode.
+ * Commands are output to X to display the frame in its current mode.
*
*----------------------------------------------------------------------
*/
static void
-DisplayFrame(clientData)
- ClientData clientData; /* Information about widget. */
+DisplayFrame(
+ ClientData clientData) /* Information about widget. */
{
register Frame *framePtr = (Frame *) clientData;
register Tk_Window tkwin = framePtr->tkwin;
@@ -1394,8 +1386,7 @@ DisplayFrame(clientData)
TkRegion clipRegion = NULL;
framePtr->flags &= ~REDRAW_PENDING;
- if ((framePtr->tkwin == NULL) || !Tk_IsMapped(tkwin)
- || framePtr->isContainer) {
+ if ((framePtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
return;
}
@@ -1406,7 +1397,7 @@ DisplayFrame(clientData)
hlWidth = framePtr->highlightWidth;
if (hlWidth != 0) {
- GC fgGC, bgGC;
+ GC fgGC, bgGC;
bgGC = Tk_GCForColor(framePtr->highlightBgColorPtr,
Tk_WindowId(tkwin));
@@ -1429,11 +1420,11 @@ DisplayFrame(clientData)
if (framePtr->type != TYPE_LABELFRAME) {
/*
- * Pass to platform specific draw function. In general, it just
- * draws a simple rectangle, but it may "theme" the background.
+ * Pass to platform specific draw function. In general, it just draws
+ * a simple rectangle, but it may "theme" the background.
*/
- noLabel:
+ noLabel:
TkpDrawFrame(tkwin, framePtr->border, hlWidth,
framePtr->borderWidth, framePtr->relief);
} else {
@@ -1446,10 +1437,10 @@ DisplayFrame(clientData)
#ifndef TK_NO_DOUBLE_BUFFERING
/*
- * In order to avoid screen flashes, this procedure redraws the
- * frame into off-screen memory, then copies it back on-screen
- * in a single operation. This means there's no point in time
- * where the on-screen image has been cleared.
+ * In order to avoid screen flashes, this function redraws the frame
+ * into off-screen memory, then copies it back on-screen in a single
+ * operation. This means there's no point in time where the on-screen
+ * image has been cleared.
*/
pixmap = Tk_GetPixmap(framePtr->display, Tk_WindowId(tkwin),
@@ -1458,7 +1449,7 @@ DisplayFrame(clientData)
pixmap = Tk_WindowId(tkwin);
#endif /* TK_NO_DOUBLE_BUFFERING */
- /*
+ /*
* Clear the pixmap.
*/
@@ -1474,61 +1465,56 @@ DisplayFrame(clientData)
bdY2 = Tk_Height(tkwin) - hlWidth;
switch (labelframePtr->labelAnchor) {
- case LABELANCHOR_E:
- case LABELANCHOR_EN:
- case LABELANCHOR_ES:
- bdX2 -= (labelframePtr->labelBox.width - framePtr->borderWidth)
- / 2;
+ case LABELANCHOR_E:
+ case LABELANCHOR_EN:
+ case LABELANCHOR_ES:
+ bdX2 -= (labelframePtr->labelBox.width-framePtr->borderWidth) / 2;
break;
- case LABELANCHOR_N:
- case LABELANCHOR_NE:
- case LABELANCHOR_NW:
- /*
- * Since the glyphs of the text tend to be in the lower part
- * we favor a lower border position by rounding up.
+ case LABELANCHOR_N:
+ case LABELANCHOR_NE:
+ case LABELANCHOR_NW:
+ /*
+ * Since the glyphs of the text tend to be in the lower part we
+ * favor a lower border position by rounding up.
*/
- bdY1 += (labelframePtr->labelBox.height - framePtr->borderWidth +1)
- / 2;
+ bdY1 += (labelframePtr->labelBox.height-framePtr->borderWidth+1)/2;
break;
- case LABELANCHOR_S:
- case LABELANCHOR_SE:
- case LABELANCHOR_SW:
- bdY2 -= (labelframePtr->labelBox.height - framePtr->borderWidth)
- / 2;
+ case LABELANCHOR_S:
+ case LABELANCHOR_SE:
+ case LABELANCHOR_SW:
+ bdY2 -= (labelframePtr->labelBox.height-framePtr->borderWidth) / 2;
break;
- default:
- bdX1 += (labelframePtr->labelBox.width - framePtr->borderWidth)
- / 2;
+ default:
+ bdX1 += (labelframePtr->labelBox.width-framePtr->borderWidth) / 2;
break;
}
- /*
- * Draw border
- */
+ /*
+ * Draw border
+ */
Tk_Draw3DRectangle(tkwin, pixmap, framePtr->border, bdX1, bdY1,
bdX2 - bdX1, bdY2 - bdY1, framePtr->borderWidth,
framePtr->relief);
- if (labelframePtr->labelWin == NULL) {
- /*
- * Clear behind the label
- */
-
- Tk_Fill3DRectangle(tkwin, pixmap,
- framePtr->border, labelframePtr->labelBox.x,
- labelframePtr->labelBox.y, labelframePtr->labelBox.width,
- labelframePtr->labelBox.height, 0, TK_RELIEF_FLAT);
-
- /*
- * Draw label.
- * If there is not room for the entire label, use clipping to
- * get a nice appearance.
- */
-
+ if (labelframePtr->labelWin == NULL) {
+ /*
+ * Clear behind the label
+ */
+
+ Tk_Fill3DRectangle(tkwin, pixmap,
+ framePtr->border, labelframePtr->labelBox.x,
+ labelframePtr->labelBox.y, labelframePtr->labelBox.width,
+ labelframePtr->labelBox.height, 0, TK_RELIEF_FLAT);
+
+ /*
+ * Draw label. If there is not room for the entire label, use
+ * clipping to get a nice appearance.
+ */
+
if ((labelframePtr->labelBox.width < labelframePtr->labelReqWidth)
- || (labelframePtr->labelBox.height <
+ || (labelframePtr->labelBox.height <
labelframePtr->labelReqHeight)) {
clipRegion = TkCreateRegion();
TkUnionRectWithRegion(&labelframePtr->labelBox, clipRegion,
@@ -1537,37 +1523,37 @@ DisplayFrame(clientData)
clipRegion);
}
- Tk_DrawTextLayout(framePtr->display, pixmap,
- labelframePtr->textGC, labelframePtr->textLayout,
- labelframePtr->labelTextX + LABELSPACING,
- labelframePtr->labelTextY + LABELSPACING, 0, -1);
+ Tk_DrawTextLayout(framePtr->display, pixmap,
+ labelframePtr->textGC, labelframePtr->textLayout,
+ labelframePtr->labelTextX + LABELSPACING,
+ labelframePtr->labelTextY + LABELSPACING, 0, -1);
if (clipRegion != NULL) {
XSetClipMask(framePtr->display, labelframePtr->textGC, None);
TkDestroyRegion(clipRegion);
}
- } else {
+ } else {
/*
* Reposition and map the window (but in different ways depending
* on whether the frame is the window's parent).
*/
-
+
if (framePtr->tkwin == Tk_Parent(labelframePtr->labelWin)) {
if ((labelframePtr->labelBox.x != Tk_X(labelframePtr->labelWin))
|| (labelframePtr->labelBox.y !=
Tk_Y(labelframePtr->labelWin))
- || (labelframePtr->labelBox.width !=
+ || (labelframePtr->labelBox.width !=
Tk_Width(labelframePtr->labelWin))
- || (labelframePtr->labelBox.height !=
+ || (labelframePtr->labelBox.height !=
Tk_Height(labelframePtr->labelWin))) {
Tk_MoveResizeWindow(labelframePtr->labelWin,
- labelframePtr->labelBox.x, labelframePtr->labelBox.y,
+ labelframePtr->labelBox.x, labelframePtr->labelBox.y,
labelframePtr->labelBox.width,
labelframePtr->labelBox.height);
}
Tk_MapWindow(labelframePtr->labelWin);
} else {
- Tk_MaintainGeometry(labelframePtr->labelWin, framePtr->tkwin,
+ Tk_MaintainGeometry(labelframePtr->labelWin, framePtr->tkwin,
labelframePtr->labelBox.x, labelframePtr->labelBox.y,
labelframePtr->labelBox.width,
labelframePtr->labelBox.height);
@@ -1577,7 +1563,7 @@ DisplayFrame(clientData)
#ifndef TK_NO_DOUBLE_BUFFERING
/*
- * Everything's been redisplayed; now copy the pixmap onto the screen
+ * Everything's been redisplayed; now copy the pixmap onto the screen
* and free up the pixmap.
*/
@@ -1597,24 +1583,24 @@ DisplayFrame(clientData)
*
* FrameEventProc --
*
- * This procedure is invoked by the Tk dispatcher on
- * structure changes to a frame. For frames with 3D
- * borders, this procedure is also invoked for exposures.
+ * This function is invoked by the Tk dispatcher on structure changes to
+ * a frame. For frames with 3D borders, this function is also invoked for
+ * exposures.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up.
+ * When it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-FrameEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- register XEvent *eventPtr; /* Information about event. */
+FrameEventProc(
+ ClientData clientData, /* Information about window. */
+ register XEvent *eventPtr) /* Information about event. */
{
register Frame *framePtr = (Frame *) clientData;
@@ -1631,15 +1617,14 @@ FrameEventProc(clientData, eventPtr)
framePtr->menuName = NULL;
}
if (framePtr->tkwin != NULL) {
-
/*
- * If this window is a container, then this event could be
- * coming from the embedded application, in which case
- * Tk_DestroyWindow hasn't been called yet. When Tk_DestroyWindow
- * is called later, then another destroy event will be generated.
- * We need to be sure we ignore the second event, since the frame
- * could be gone by then. To do so, delete the event handler
- * explicitly (normally it's done implicitly by Tk_DestroyWindow).
+ * If this window is a container, then this event could be coming
+ * from the embedded application, in which case Tk_DestroyWindow
+ * hasn't been called yet. When Tk_DestroyWindow is called later,
+ * then another destroy event will be generated. We need to be
+ * sure we ignore the second event, since the frame could be gone
+ * by then. To do so, delete the event handler explicitly
+ * (normally it's done implicitly by Tk_DestroyWindow).
*/
/*
@@ -1647,13 +1632,13 @@ FrameEventProc(clientData, eventPtr)
* DestroyFrame, we must free all options now.
*/
- DestroyFramePartly(framePtr);
+ DestroyFramePartly(framePtr);
Tk_DeleteEventHandler(framePtr->tkwin,
ExposureMask|StructureNotifyMask|FocusChangeMask,
FrameEventProc, (ClientData) framePtr);
framePtr->tkwin = NULL;
- Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd);
+ Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd);
}
if (framePtr->flags & REDRAW_PENDING) {
Tcl_CancelIdleCall(DisplayFrame, (ClientData) framePtr);
@@ -1680,7 +1665,7 @@ FrameEventProc(clientData, eventPtr)
}
return;
- redraw:
+ redraw:
if ((framePtr->tkwin != NULL) && !(framePtr->flags & REDRAW_PENDING)) {
Tcl_DoWhenIdle(DisplayFrame, (ClientData) framePtr);
framePtr->flags |= REDRAW_PENDING;
@@ -1692,9 +1677,9 @@ FrameEventProc(clientData, eventPtr)
*
* FrameCmdDeletedProc --
*
- * 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.
+ * This function 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.
@@ -1706,8 +1691,8 @@ FrameEventProc(clientData, eventPtr)
*/
static void
-FrameCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+FrameCmdDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
Frame *framePtr = (Frame *) clientData;
Tk_Window tkwin = framePtr->tkwin;
@@ -1720,19 +1705,19 @@ FrameCmdDeletedProc(clientData)
}
/*
- * 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.
+ * This function 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 function destroys the
+ * widget.
*/
if (tkwin != NULL) {
- /*
- * Some options need tkwin to be freed, so we free them here,
- * before setting tkwin to NULL.
+ /*
+ * Some options need tkwin to be freed, so we free them here, before
+ * setting tkwin to NULL.
*/
- DestroyFramePartly(framePtr);
+ DestroyFramePartly(framePtr);
framePtr->tkwin = NULL;
Tk_DestroyWindow(tkwin);
@@ -1744,8 +1729,8 @@ FrameCmdDeletedProc(clientData)
*
* MapFrame --
*
- * This procedure is invoked as a when-idle handler to map a
- * newly-created top-level frame.
+ * This function is invoked as a when-idle handler to map a newly-created
+ * top-level frame.
*
* Results:
* None.
@@ -1757,16 +1742,16 @@ FrameCmdDeletedProc(clientData)
*/
static void
-MapFrame(clientData)
- ClientData clientData; /* Pointer to frame structure. */
+MapFrame(
+ ClientData clientData) /* Pointer to frame structure. */
{
Frame *framePtr = (Frame *) clientData;
/*
- * Wait for all other background events to be processed before
- * mapping window. This ensures that the window's correct geometry
- * will have been determined before it is first mapped, so that the
- * window manager doesn't get a false idea of its desired geometry.
+ * Wait for all other background events to be processed before mapping
+ * window. This ensures that the window's correct geometry will have been
+ * determined before it is first mapped, so that the window manager
+ * doesn't get a false idea of its desired geometry.
*/
Tcl_Preserve((ClientData) framePtr);
@@ -1776,8 +1761,8 @@ MapFrame(clientData)
}
/*
- * After each event, make sure that the window still exists
- * and quit if the window has been destroyed.
+ * After each event, make sure that the window still exists and quit
+ * if the window has been destroyed.
*/
if (framePtr->tkwin == NULL) {
@@ -1794,24 +1779,23 @@ MapFrame(clientData)
*
* TkInstallFrameMenu --
*
- * This function is needed when a Windows HWND is created
- * and a menubar has been set to the window with a system
- * menu. It notifies the menu package so that the system
- * menu can be rebuilt.
+ * This function is needed when a Windows HWND is created and a menubar
+ * has been set to the window with a system menu. It notifies the menu
+ * package so that the system menu can be rebuilt.
*
* Results:
* None.
*
* Side effects:
- * The system menu (if any) is created for the menubar
- * associated with this frame.
+ * The system menu (if any) is created for the menubar associated with
+ * this frame.
*
*--------------------------------------------------------------
*/
void
-TkInstallFrameMenu(tkwin)
- Tk_Window tkwin; /* The window that was just created. */
+TkInstallFrameMenu(
+ Tk_Window tkwin) /* The window that was just created. */
{
TkWindow *winPtr = (TkWindow *) tkwin;
@@ -1819,9 +1803,9 @@ TkInstallFrameMenu(tkwin)
Frame *framePtr;
framePtr = (Frame*) winPtr->instanceData;
if (framePtr == NULL) {
- panic("TkInstallFrameMenu couldn't get frame pointer");
+ Tcl_Panic("TkInstallFrameMenu couldn't get frame pointer");
}
- TkpMenuNotifyToplevelCreate(winPtr->mainPtr->interp,
+ TkpMenuNotifyToplevelCreate(winPtr->mainPtr->interp,
framePtr->menuName);
}
}
@@ -1831,32 +1815,30 @@ TkInstallFrameMenu(tkwin)
*
* FrameStructureProc --
*
- * This procedure is invoked whenever StructureNotify events
- * occur for a window that's managed as label for the frame.
- * This procudure's only purpose is to clean up when windows
- * are deleted.
+ * This function is invoked whenever StructureNotify events occur for a
+ * window that's managed as label for the frame. This procudure's only
+ * purpose is to clean up when windows are deleted.
*
* Results:
* None.
*
* Side effects:
- * The window is disassociated from the frame when it is
- * deleted.
+ * The window is disassociated from the frame when it is deleted.
*
*--------------------------------------------------------------
*/
static void
-FrameStructureProc(clientData, eventPtr)
- ClientData clientData; /* Pointer to record describing frame. */
- XEvent *eventPtr; /* Describes what just happened. */
+FrameStructureProc(
+ ClientData clientData, /* Pointer to record describing frame. */
+ XEvent *eventPtr) /* Describes what just happened. */
{
Labelframe *labelframePtr = (Labelframe *) clientData;
if (eventPtr->type == DestroyNotify) {
/*
- * This should only happen in a labelframe but it doesn't
- * hurt to be careful.
+ * This should only happen in a labelframe but it doesn't hurt to be
+ * careful.
*/
if (labelframePtr->frame.type == TYPE_LABELFRAME) {
@@ -1871,24 +1853,23 @@ FrameStructureProc(clientData, eventPtr)
*
* FrameRequestProc --
*
- * This procedure is invoked whenever a window that's associated
- * with a frame changes its requested dimensions.
+ * This function is invoked whenever a window that's associated with a
+ * frame changes its requested dimensions.
*
* Results:
* None.
*
* Side effects:
- * The size and location on the screen of the window may change.
- * depending on the options specified for the frame.
+ * The size and location on the screen of the window may change depending
+ * on the options specified for the frame.
*
*--------------------------------------------------------------
*/
static void
-FrameRequestProc(clientData, tkwin)
- ClientData clientData; /* Pointer to record for frame. */
- Tk_Window tkwin; /* Window that changed its desired
- * size. */
+FrameRequestProc(
+ ClientData clientData, /* Pointer to record for frame. */
+ Tk_Window tkwin) /* Window that changed its desired size. */
{
Frame *framePtr = (Frame *) clientData;
@@ -1900,8 +1881,8 @@ FrameRequestProc(clientData, tkwin)
*
* FrameLostSlaveProc --
*
- * This procedure is invoked by Tk whenever some other geometry
- * claims control over a slave that used to be managed by us.
+ * This function is invoked by Tk whenever some other geometry claims
+ * control over a slave that used to be managed by us.
*
* Results:
* None.
@@ -1913,19 +1894,19 @@ FrameRequestProc(clientData, tkwin)
*/
static void
-FrameLostSlaveProc(clientData, tkwin)
- ClientData clientData; /* Frame structure for slave window that
- * was stolen away. */
- Tk_Window tkwin; /* Tk's handle for the slave window. */
+FrameLostSlaveProc(
+ ClientData clientData, /* Frame structure for slave window that was
+ * stolen away. */
+ Tk_Window tkwin) /* Tk's handle for the slave window. */
{
Frame *framePtr = (Frame *) clientData;
Labelframe *labelframePtr = (Labelframe *) clientData;
/*
- * This should only happen in a labelframe but it doesn't
- * hurt to be careful.
+ * This should only happen in a labelframe but it doesn't hurt to be
+ * careful.
*/
-
+
if (labelframePtr->frame.type == TYPE_LABELFRAME) {
Tk_DeleteEventHandler(labelframePtr->labelWin, StructureNotifyMask,
FrameStructureProc, (ClientData) labelframePtr);
@@ -1938,20 +1919,46 @@ FrameLostSlaveProc(clientData, tkwin)
FrameWorldChanged((ClientData) framePtr);
}
+void
+TkMapTopFrame (tkwin)
+ Tk_Window tkwin;
+{
+ Frame *framePtr = ((TkWindow*)tkwin)->instanceData;
+ Tk_OptionTable optionTable;
+ if (Tk_IsTopLevel(tkwin) && framePtr->type == TYPE_FRAME) {
+ framePtr->type = TYPE_TOPLEVEL;
+ Tcl_DoWhenIdle(MapFrame, (ClientData)framePtr);
+ if (framePtr->menuName != NULL) {
+ TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin, NULL,
+ framePtr->menuName);
+ }
+ } else if (!Tk_IsTopLevel(tkwin) && framePtr->type == TYPE_TOPLEVEL) {
+ framePtr->type = TYPE_FRAME;
+ } else {
+ /* Not a frame or toplevel, skip it */
+ return;
+ }
+ /*
+ * The option table has already been created so
+ * the cached pointer will be returned.
+ */
+ optionTable = Tk_CreateOptionTable(framePtr->interp, optionSpecs[framePtr->type]);
+ framePtr->optionTable = optionTable;
+}
+
/*
*--------------------------------------------------------------
*
* TkToplevelWindowFromCommandToken --
*
- * If the given command name to the command for a toplevel window
- * in the given interpreter, return the tkwin for that toplevel
- * window. Note that this lookup can't be done using the
- * standard tkwin internal table because the command might have
- * been renamed.
+ * If the given command name to the command for a toplevel window in the
+ * given interpreter, return the tkwin for that toplevel window. Note
+ * that this lookup can't be done using the standard tkwin internal table
+ * because the command might have been renamed.
*
* Results:
- * A Tk_Window token, or NULL if the name does not refer to a
- * toplevel window.
+ * A Tk_Window token, or NULL if the name does not refer to a toplevel
+ * window.
*
* Side effects:
* None.
@@ -1960,9 +1967,9 @@ FrameLostSlaveProc(clientData, tkwin)
*/
Tk_Window
-TkToplevelWindowForCommand(interp, cmdName)
- Tcl_Interp *interp;
- CONST char *cmdName;
+TkToplevelWindowForCommand(
+ Tcl_Interp *interp,
+ CONST char *cmdName)
{
Tcl_CmdInfo cmdInfo;
Frame *framePtr;
@@ -1979,3 +1986,11 @@ TkToplevelWindowForCommand(interp, cmdName)
}
return framePtr->tkwin;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkGC.c b/generic/tkGC.c
index 46a3a56..800e4d3 100644
--- a/generic/tkGC.c
+++ b/generic/tkGC.c
@@ -1,24 +1,23 @@
-/*
+/*
* tkGC.c --
*
- * This file maintains a database of read-only graphics contexts
- * for the Tk toolkit, in order to allow GC's to be shared.
+ * This file maintains a database of read-only graphics contexts for the
+ * Tk toolkit, in order to allow GC's to be shared.
*
* Copyright (c) 1990-1994 The Regents of the University of California.
* Copyright (c) 1994 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
/*
- * One of the following data structures exists for each GC that is
- * currently active. The structure is indexed with two hash tables,
- * one based on the values in the graphics context and the other
- * based on the display and GC identifier.
+ * One of the following data structures exists for each GC that is currently
+ * active. The structure is indexed with two hash tables, one based on the
+ * values in the graphics context and the other based on the display and GC
+ * identifier.
*/
typedef struct {
@@ -37,48 +36,48 @@ typedef struct {
} ValueKey;
/*
- * Forward declarations for procedures defined in this file:
+ * Forward declarations for functions defined in this file:
*/
-static void GCInit _ANSI_ARGS_((TkDisplay *dispPtr));
+static void GCInit(TkDisplay *dispPtr);
/*
*----------------------------------------------------------------------
*
* Tk_GetGC --
*
- * Given a desired set of values for a graphics context, find
- * a read-only graphics context with the desired values.
+ * Given a desired set of values for a graphics context, find a read-only
+ * graphics context with the desired values.
*
* Results:
- * The return value is the X identifer for the desired graphics
- * context. The caller should never modify this GC, and should
- * call Tk_FreeGC when the GC is no longer needed.
+ * The return value is the X identifer for the desired graphics context.
+ * The caller should never modify this GC, and should call Tk_FreeGC when
+ * the GC is no longer needed.
*
* Side effects:
- * The GC is added to an internal database with a reference count.
- * For each call to this procedure, there should eventually be a call
- * to Tk_FreeGC, so that the database can be cleaned up when GC's
- * aren't needed anymore.
+ * The GC is added to an internal database with a reference count. For
+ * each call to this function, there should eventually be a call to
+ * Tk_FreeGC, so that the database can be cleaned up when GC's aren't
+ * needed anymore.
*
*----------------------------------------------------------------------
*/
GC
-Tk_GetGC(tkwin, valueMask, valuePtr)
- Tk_Window tkwin; /* Window in which GC will be used. */
- register unsigned long valueMask;
- /* 1 bits correspond to values specified
- * in *valuesPtr; other values are set
- * from defaults. */
- register XGCValues *valuePtr;
- /* Values are specified here for bits set
- * in valueMask. */
+Tk_GetGC(
+ Tk_Window tkwin, /* Window in which GC will be used. */
+ register unsigned long valueMask,
+ /* 1 bits correspond to values specified in
+ * *valuesPtr; other values are set from
+ * defaults. */
+ register XGCValues *valuePtr)
+ /* Values are specified here for bits set in
+ * valueMask. */
{
ValueKey valueKey;
Tcl_HashEntry *valueHashPtr, *idHashPtr;
register TkGC *gcPtr;
- int new;
+ int isNew;
Drawable d, freeDrawable;
TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
@@ -87,15 +86,15 @@ Tk_GetGC(tkwin, valueMask, valuePtr)
}
/*
- * Must zero valueKey at start to clear out pad bytes that may be
- * part of structure on some systems.
+ * Must zero valueKey at start to clear out pad bytes that may be part of
+ * structure on some systems.
*/
- memset((VOID *) &valueKey, 0, sizeof(valueKey));
+ memset(&valueKey, 0, sizeof(valueKey));
/*
- * First, check to see if there's already a GC that will work
- * for this request (exact matches only, sorry).
+ * First, check to see if there's already a GC that will work for this
+ * request (exact matches only, sorry).
*/
if (valueMask & GCFunction) {
@@ -216,24 +215,24 @@ Tk_GetGC(tkwin, valueMask, valuePtr)
valueKey.display = Tk_Display(tkwin);
valueKey.screenNum = Tk_ScreenNumber(tkwin);
valueKey.depth = Tk_Depth(tkwin);
- valueHashPtr = Tcl_CreateHashEntry(&dispPtr->gcValueTable,
- (char *) &valueKey, &new);
- if (!new) {
+ valueHashPtr = Tcl_CreateHashEntry(&dispPtr->gcValueTable,
+ (char *) &valueKey, &isNew);
+ if (!isNew) {
gcPtr = (TkGC *) Tcl_GetHashValue(valueHashPtr);
gcPtr->refCount++;
return gcPtr->gc;
}
/*
- * No GC is currently available for this set of values. Allocate a
- * new GC and add a new structure to the database.
+ * No GC is currently available for this set of values. Allocate a new GC
+ * and add a new structure to the database.
*/
gcPtr = (TkGC *) ckalloc(sizeof(TkGC));
/*
- * Find or make a drawable to use to specify the screen and depth
- * of the GC. We may have to make a small pixmap, to avoid doing
+ * Find or make a drawable to use to specify the screen and depth of the
+ * GC. We may have to make a small pixmap, to avoid doing
* Tk_MakeWindowExist on the window.
*/
@@ -254,10 +253,10 @@ Tk_GetGC(tkwin, valueMask, valuePtr)
gcPtr->display = valueKey.display;
gcPtr->refCount = 1;
gcPtr->valueHashPtr = valueHashPtr;
- idHashPtr = Tcl_CreateHashEntry(&dispPtr->gcIdTable,
- (char *) gcPtr->gc, &new);
- if (!new) {
- panic("GC already registered in Tk_GetGC");
+ idHashPtr = Tcl_CreateHashEntry(&dispPtr->gcIdTable,
+ (char *) gcPtr->gc, &isNew);
+ if (!isNew) {
+ Tcl_Panic("GC already registered in Tk_GetGC");
}
Tcl_SetHashValue(valueHashPtr, gcPtr);
Tcl_SetHashValue(idHashPtr, gcPtr);
@@ -273,43 +272,44 @@ Tk_GetGC(tkwin, valueMask, valuePtr)
*
* Tk_FreeGC --
*
- * This procedure is called to release a graphics context allocated by
+ * This function is called to release a graphics context allocated by
* Tk_GetGC.
*
* Results:
* None.
*
* Side effects:
- * The reference count associated with gc is decremented, and
- * gc is officially deallocated if no-one is using it anymore.
+ * The reference count associated with gc is decremented, and gc is
+ * officially deallocated if no-one is using it anymore.
*
*----------------------------------------------------------------------
*/
void
-Tk_FreeGC(display, gc)
- Display *display; /* Display for which gc was allocated. */
- GC gc; /* Graphics context to be released. */
+Tk_FreeGC(
+ Display *display, /* Display for which gc was allocated. */
+ GC gc) /* Graphics context to be released. */
{
Tcl_HashEntry *idHashPtr;
register TkGC *gcPtr;
TkDisplay *dispPtr = TkGetDisplay(display);
if (!dispPtr->gcInit) {
- panic("Tk_FreeGC called before Tk_GetGC");
+ Tcl_Panic("Tk_FreeGC called before Tk_GetGC");
}
if (dispPtr->gcInit < 0) {
/*
- * The GCCleanup has been called, and remaining GCs have been
- * freed. This may still get called by other things shutting
- * down, but the GCs should no longer be in use.
+ * The GCCleanup has been called, and remaining GCs have been freed.
+ * This may still get called by other things shutting down, but the
+ * GCs should no longer be in use.
*/
+
return;
}
idHashPtr = Tcl_FindHashEntry(&dispPtr->gcIdTable, (char *) gc);
if (idHashPtr == NULL) {
- panic("Tk_FreeGC received unknown gc argument");
+ Tcl_Panic("Tk_FreeGC received unknown gc argument");
}
gcPtr = (TkGC *) Tcl_GetHashValue(idHashPtr);
gcPtr->refCount--;
@@ -327,9 +327,8 @@ Tk_FreeGC(display, gc)
*
* TkGCCleanup --
*
- * Frees the structures used for GC management.
- * We need to have it called near the end, when other cleanup that
- * calls Tk_FreeGC is all done.
+ * Frees the structures used for GC management. We need to have it called
+ * near the end, when other cleanup that calls Tk_FreeGC is all done.
*
* Results:
* None.
@@ -341,22 +340,23 @@ Tk_FreeGC(display, gc)
*/
void
-TkGCCleanup(dispPtr)
- TkDisplay *dispPtr; /* display to clean up resources in */
+TkGCCleanup(
+ TkDisplay *dispPtr) /* display to clean up resources in */
{
Tcl_HashEntry *entryPtr;
Tcl_HashSearch search;
TkGC *gcPtr;
for (entryPtr = Tcl_FirstHashEntry(&dispPtr->gcIdTable, &search);
- entryPtr != NULL;
- entryPtr = Tcl_NextHashEntry(&search)) {
+ entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) {
gcPtr = (TkGC *) Tcl_GetHashValue(entryPtr);
+
/*
- * This call is not needed, as it is only used on Unix to restore
- * the Id to the stack pool, and we don't want to use them anymore.
+ * This call is not needed, as it is only used on Unix to restore the
+ * Id to the stack pool, and we don't want to use them anymore.
* Tk_FreeXId(gcPtr->display, (XID) XGContextFromGC(gcPtr->gc));
*/
+
XFreeGC(gcPtr->display, gcPtr->gc);
Tcl_DeleteHashEntry(gcPtr->valueHashPtr);
Tcl_DeleteHashEntry(entryPtr);
@@ -384,13 +384,21 @@ TkGCCleanup(dispPtr)
*/
static void
-GCInit(dispPtr)
- TkDisplay *dispPtr;
+GCInit(
+ TkDisplay *dispPtr)
{
if (dispPtr->gcInit < 0) {
- panic("called GCInit after GCCleanup");
+ Tcl_Panic("called GCInit after GCCleanup");
}
dispPtr->gcInit = 1;
Tcl_InitHashTable(&dispPtr->gcValueTable, sizeof(ValueKey)/sizeof(int));
Tcl_InitHashTable(&dispPtr->gcIdTable, TCL_ONE_WORD_KEYS);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkGeometry.c b/generic/tkGeometry.c
index d53b6dd..4c8e4f8 100644
--- a/generic/tkGeometry.c
+++ b/generic/tkGeometry.c
@@ -1,23 +1,22 @@
-/*
+/*
* tkGeometry.c --
*
- * This file contains generic Tk code for geometry management
- * (stuff that's used by all geometry managers).
+ * This file contains generic Tk code for geometry management (stuff
+ * that's used by all geometry managers).
*
* Copyright (c) 1990-1994 The Regents of the University of California.
* Copyright (c) 1994-1995 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
/*
- * Data structures of the following type are used by Tk_MaintainGeometry.
- * For each slave managed by Tk_MaintainGeometry, there is one of these
- * structures associated with its master.
+ * Data structures of the following type are used by Tk_MaintainGeometry. For
+ * each slave managed by Tk_MaintainGeometry, there is one of these structures
+ * associated with its master.
*/
typedef struct MaintainSlave {
@@ -29,68 +28,67 @@ typedef struct MaintainSlave {
* master. */
int width, height; /* Desired dimensions of slave. */
struct MaintainSlave *nextPtr;
- /* Next in list of Maintains associated
- * with master. */
+ /* Next in list of Maintains associated with
+ * master. */
} MaintainSlave;
/*
- * For each window that has been specified as a master to
- * Tk_MaintainGeometry, there is a structure of the following type:
+ * For each window that has been specified as a master to Tk_MaintainGeometry,
+ * there is a structure of the following type:
*/
typedef struct MaintainMaster {
- Tk_Window ancestor; /* The lowest ancestor of this window
- * for which we have *not* created a
- * StructureNotify handler. May be the
- * same as the window itself. */
- int checkScheduled; /* Non-zero means that there is already a
- * call to MaintainCheckProc scheduled as
- * an idle handler. */
- MaintainSlave *slavePtr; /* First in list of all slaves associated
- * with this master. */
+ Tk_Window ancestor; /* The lowest ancestor of this window for
+ * which we have *not* created a
+ * StructureNotify handler. May be the same as
+ * the window itself. */
+ int checkScheduled; /* Non-zero means that there is already a call
+ * to MaintainCheckProc scheduled as an idle
+ * handler. */
+ MaintainSlave *slavePtr; /* First in list of all slaves associated with
+ * this master. */
} MaintainMaster;
/*
* Prototypes for static procedures in this file:
*/
-static void MaintainCheckProc _ANSI_ARGS_((ClientData clientData));
-static void MaintainMasterProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void MaintainSlaveProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
+static void MaintainCheckProc(ClientData clientData);
+static void MaintainMasterProc(ClientData clientData,
+ XEvent *eventPtr);
+static void MaintainSlaveProc(ClientData clientData,
+ XEvent *eventPtr);
/*
*--------------------------------------------------------------
*
* Tk_ManageGeometry --
*
- * Arrange for a particular procedure to manage the geometry
- * of a given slave window.
+ * Arrange for a particular procedure to manage the geometry of a given
+ * slave window.
*
* Results:
* None.
*
* Side effects:
- * Proc becomes the new geometry manager for tkwin, replacing
- * any previous geometry manager. The geometry manager will
- * be notified (by calling procedures in *mgrPtr) when interesting
- * things happen in the future. If there was an existing geometry
- * manager for tkwin different from the new one, it is notified
- * by calling its lostSlaveProc.
+ * Proc becomes the new geometry manager for tkwin, replacing any
+ * previous geometry manager. The geometry manager will be notified (by
+ * calling procedures in *mgrPtr) when interesting things happen in the
+ * future. If there was an existing geometry manager for tkwin different
+ * from the new one, it is notified by calling its lostSlaveProc.
*
*--------------------------------------------------------------
*/
void
-Tk_ManageGeometry(tkwin, mgrPtr, clientData)
- Tk_Window tkwin; /* Window whose geometry is to
- * be managed by proc. */
- Tk_GeomMgr *mgrPtr; /* Static structure describing the
- * geometry manager. This structure
- * must never go away. */
- ClientData clientData; /* Arbitrary one-word argument to
- * pass to geometry manager procedures. */
+Tk_ManageGeometry(
+ Tk_Window tkwin, /* Window whose geometry is to be managed by
+ * proc. */
+ CONST Tk_GeomMgr *mgrPtr, /* Static structure describing the geometry
+ * manager. This structure must never go
+ * away. */
+ ClientData clientData) /* Arbitrary one-word argument to pass to
+ * geometry manager procedures. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -110,37 +108,35 @@ Tk_ManageGeometry(tkwin, mgrPtr, clientData)
*
* Tk_GeometryRequest --
*
- * This procedure is invoked by widget code to indicate
- * its preferences about the size of a window it manages.
- * In general, widget code should call this procedure
- * rather than Tk_ResizeWindow.
+ * This procedure is invoked by widget code to indicate its preferences
+ * about the size of a window it manages. In general, widget code should
+ * call this procedure rather than Tk_ResizeWindow.
*
* Results:
* None.
*
* Side effects:
- * The geometry manager for tkwin (if any) is invoked to
- * handle the request. If possible, it will reconfigure
- * tkwin and/or other windows to satisfy the request. The
- * caller gets no indication of success or failure, but it
- * will get X events if the window size was actually
+ * The geometry manager for tkwin (if any) is invoked to handle the
+ * request. If possible, it will reconfigure tkwin and/or other windows
+ * to satisfy the request. The caller gets no indication of success or
+ * failure, but it will get X events if the window size was actually
* changed.
*
*--------------------------------------------------------------
*/
void
-Tk_GeometryRequest(tkwin, reqWidth, reqHeight)
- Tk_Window tkwin; /* Window that geometry information
- * pertains to. */
- int reqWidth, reqHeight; /* Minimum desired dimensions for
- * window, in pixels. */
+Tk_GeometryRequest(
+ Tk_Window tkwin, /* Window that geometry information pertains
+ * to. */
+ int reqWidth, int reqHeight)/* Minimum desired dimensions for window, in
+ * pixels. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
/*
- * X gets very upset if a window requests a width or height of
- * zero, so rounds requested sizes up to at least 1.
+ * X gets very upset if a window requests a width or height of zero, so
+ * rounds requested sizes up to at least 1.
*/
if (reqWidth <= 0) {
@@ -165,9 +161,9 @@ Tk_GeometryRequest(tkwin, reqWidth, reqHeight)
*
* Tk_SetInternalBorderEx --
*
- * Notify relevant geometry managers that a window has an internal
- * border of a given width and that child windows should not be
- * placed on that border.
+ * Notify relevant geometry managers that a window has an internal border
+ * of a given width and that child windows should not be placed on that
+ * border.
*
* Results:
* None.
@@ -181,10 +177,10 @@ Tk_GeometryRequest(tkwin, reqWidth, reqHeight)
*/
void
-Tk_SetInternalBorderEx(tkwin, left, right, top, bottom)
- Tk_Window tkwin; /* Window that will have internal border. */
- int left, right; /* Width of internal border, in pixels. */
- int top, bottom;
+Tk_SetInternalBorderEx(
+ Tk_Window tkwin, /* Window that will have internal border. */
+ int left, int right, /* Width of internal border, in pixels. */
+ int top, int bottom)
{
register TkWindow *winPtr = (TkWindow *) tkwin;
register int changed = 0;
@@ -223,40 +219,40 @@ Tk_SetInternalBorderEx(tkwin, left, right, top, bottom)
/*
* All the slaves for which this is the master window must now be
- * repositioned to take account of the new internal border width.
- * To signal all the geometry managers to do this, just resize the
- * window to its current size. The ConfigureNotify event will
- * cause geometry managers to recompute everything.
+ * repositioned to take account of the new internal border width. To
+ * signal all the geometry managers to do this, just resize the window to
+ * its current size. The ConfigureNotify event will cause geometry
+ * managers to recompute everything.
*/
if (changed) {
Tk_ResizeWindow(tkwin, Tk_Width(tkwin), Tk_Height(tkwin));
}
}
+
/*
*----------------------------------------------------------------------
*
* Tk_SetInternalBorder --
*
- * Notify relevant geometry managers that a window has an internal
- * border of a given width and that child windows should not be
- * placed on that border.
+ * Notify relevant geometry managers that a window has an internal border
+ * of a given width and that child windows should not be placed on that
+ * border.
*
* Results:
* None.
*
* Side effects:
- * The border width is recorded for the window, and all geometry
- * managers of all children are notified so that can re-layout, if
- * necessary.
+ * The border width is recorded for the window, and all geometry managers
+ * of all children are notified so that can re-layout, if necessary.
*
*----------------------------------------------------------------------
*/
void
-Tk_SetInternalBorder(tkwin, width)
- Tk_Window tkwin; /* Window that will have internal border. */
- int width; /* Width of internal border, in pixels. */
+Tk_SetInternalBorder(
+ Tk_Window tkwin, /* Window that will have internal border. */
+ int width) /* Width of internal border, in pixels. */
{
Tk_SetInternalBorderEx(tkwin, width, width, width, width);
}
@@ -266,23 +262,23 @@ Tk_SetInternalBorder(tkwin, width)
*
* Tk_SetMinimumRequestSize --
*
- * Notify relevant geometry managers that a window has a minimum
- * request size.
+ * Notify relevant geometry managers that a window has a minimum request
+ * size.
*
* Results:
* None.
*
* Side effects:
- * The minimum request size is recorded for the window, and
- * a new size is requested for the window, if necessary.
+ * The minimum request size is recorded for the window, and a new size is
+ * requested for the window, if necessary.
*
*----------------------------------------------------------------------
*/
void
-Tk_SetMinimumRequestSize(tkwin, minWidth, minHeight)
- Tk_Window tkwin; /* Window that will have internal border. */
- int minWidth, minHeight; /* Minimum requested size, in pixels. */
+Tk_SetMinimumRequestSize(
+ Tk_Window tkwin, /* Window that will have internal border. */
+ int minWidth, int minHeight)/* Minimum requested size, in pixels. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -295,11 +291,11 @@ Tk_SetMinimumRequestSize(tkwin, minWidth, minHeight)
winPtr->minReqHeight = minHeight;
/*
- * The changed min size may cause geometry managers to get a
- * different result, so make them recompute.
- * To signal all the geometry managers to do this, just resize the
- * window to its current size. The ConfigureNotify event will
- * cause geometry managers to recompute everything.
+ * The changed min size may cause geometry managers to get a different
+ * result, so make them recompute. To signal all the geometry managers to
+ * do this, just resize the window to its current size. The
+ * ConfigureNotify event will cause geometry managers to recompute
+ * everything.
*/
Tk_ResizeWindow(tkwin, Tk_Width(tkwin), Tk_Height(tkwin));
@@ -310,40 +306,40 @@ Tk_SetMinimumRequestSize(tkwin, minWidth, minHeight)
*
* Tk_MaintainGeometry --
*
- * This procedure is invoked by geometry managers to handle slaves
- * whose master's are not their parents. It translates the desired
- * geometry for the slave into the coordinate system of the parent
- * and respositions the slave if it isn't already at the right place.
- * Furthermore, it sets up event handlers so that if the master (or
- * any of its ancestors up to the slave's parent) is mapped, unmapped,
- * or moved, then the slave will be adjusted to match.
+ * This procedure is invoked by geometry managers to handle slaves whose
+ * master's are not their parents. It translates the desired geometry for
+ * the slave into the coordinate system of the parent and respositions
+ * the slave if it isn't already at the right place. Furthermore, it sets
+ * up event handlers so that if the master (or any of its ancestors up to
+ * the slave's parent) is mapped, unmapped, or moved, then the slave will
+ * be adjusted to match.
*
* Results:
* None.
*
* Side effects:
- * Event handlers are created and state is allocated to keep track
- * of slave. Note: if slave was already managed for master by
- * Tk_MaintainGeometry, then the previous information is replaced
- * with the new information. The caller must eventually call
- * Tk_UnmaintainGeometry to eliminate the correspondence (or, the
- * state is automatically freed when either window is destroyed).
+ * Event handlers are created and state is allocated to keep track of
+ * slave. Note: if slave was already managed for master by
+ * Tk_MaintainGeometry, then the previous information is replaced with
+ * the new information. The caller must eventually call
+ * Tk_UnmaintainGeometry to eliminate the correspondence (or, the state
+ * is automatically freed when either window is destroyed).
*
*----------------------------------------------------------------------
*/
void
-Tk_MaintainGeometry(slave, master, x, y, width, height)
- Tk_Window slave; /* Slave for geometry management. */
- Tk_Window master; /* Master for slave; must be a descendant
- * of slave's parent. */
- int x, y; /* Desired position of slave within master. */
- int width, height; /* Desired dimensions for slave. */
+Tk_MaintainGeometry(
+ Tk_Window slave, /* Slave for geometry management. */
+ Tk_Window master, /* Master for slave; must be a descendant of
+ * slave's parent. */
+ int x, int y, /* Desired position of slave within master. */
+ int width, int height) /* Desired dimensions for slave. */
{
Tcl_HashEntry *hPtr;
MaintainMaster *masterPtr;
register MaintainSlave *slavePtr;
- int new, map;
+ int isNew, map;
Tk_Window ancestor, parent;
TkDisplay *dispPtr = ((TkWindow *) master)->dispPtr;
@@ -354,6 +350,7 @@ Tk_MaintainGeometry(slave, master, x, y, width, height)
* call to Tk_MoveResizeWindow; the parent/child relationship will
* take care of the rest.
*/
+
Tk_MoveResizeWindow(slave, x, y, width, height);
/*
@@ -361,6 +358,7 @@ Tk_MaintainGeometry(slave, master, x, y, width, height)
* until the master is mapped later (in which case mapping the slave
* is taken care of elsewhere).
*/
+
if (Tk_IsMapped(master)) {
Tk_MapWindow(slave);
}
@@ -373,14 +371,14 @@ Tk_MaintainGeometry(slave, master, x, y, width, height)
}
/*
- * See if there is already a MaintainMaster structure for the master;
- * if not, then create one.
+ * See if there is already a MaintainMaster structure for the master; if
+ * not, then create one.
*/
parent = Tk_Parent(slave);
- hPtr = Tcl_CreateHashEntry(&dispPtr->maintainHashTable,
- (char *) master, &new);
- if (!new) {
+ hPtr = Tcl_CreateHashEntry(&dispPtr->maintainHashTable,
+ (char *) master, &isNew);
+ if (!isNew) {
masterPtr = (MaintainMaster *) Tcl_GetHashValue(hPtr);
} else {
masterPtr = (MaintainMaster *) ckalloc(sizeof(MaintainMaster));
@@ -391,8 +389,8 @@ Tk_MaintainGeometry(slave, master, x, y, width, height)
}
/*
- * Create a MaintainSlave structure for the slave if there isn't
- * already one.
+ * Create a MaintainSlave structure for the slave if there isn't already
+ * one.
*/
for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
@@ -410,10 +408,10 @@ Tk_MaintainGeometry(slave, master, x, y, width, height)
(ClientData) slavePtr);
/*
- * Make sure that there are event handlers registered for all
- * the windows between master and slave's parent (including master
- * but not slave's parent). There may already be handlers for master
- * and some of its ancestors (masterPtr->ancestor tells how many).
+ * Make sure that there are event handlers registered for all the windows
+ * between master and slave's parent (including master but not slave's
+ * parent). There may already be handlers for master and some of its
+ * ancestors (masterPtr->ancestor tells how many).
*/
for (ancestor = master; ancestor != parent;
@@ -426,11 +424,11 @@ Tk_MaintainGeometry(slave, master, x, y, width, height)
}
/*
- * Fill in up-to-date information in the structure, then update the
- * window if it's not currently in the right place or state.
+ * Fill in up-to-date information in the structure, then update the window
+ * if it's not currently in the right place or state.
*/
- gotSlave:
+ gotSlave:
slavePtr->x = x;
slavePtr->y = y;
slavePtr->width = width;
@@ -464,26 +462,25 @@ Tk_MaintainGeometry(slave, master, x, y, width, height)
*
* Tk_UnmaintainGeometry --
*
- * This procedure cancels a previous Tk_MaintainGeometry call,
- * so that the relationship between slave and master is no longer
- * maintained.
+ * This procedure cancels a previous Tk_MaintainGeometry call, so that
+ * the relationship between slave and master is no longer maintained.
*
* Results:
* None.
*
* Side effects:
- * The slave is unmapped and state is released, so that slave won't
- * track master any more. If we weren't previously managing slave
- * relative to master, then this procedure has no effect.
+ * The slave is unmapped and state is released, so that slave won't track
+ * master any more. If we weren't previously managing slave relative to
+ * master, then this procedure has no effect.
*
*----------------------------------------------------------------------
*/
void
-Tk_UnmaintainGeometry(slave, master)
- Tk_Window slave; /* Slave for geometry management. */
- Tk_Window master; /* Master for slave; must be a descendant
- * of slave's parent. */
+Tk_UnmaintainGeometry(
+ Tk_Window slave, /* Slave for geometry management. */
+ Tk_Window master) /* Master for slave; must be a descendant of
+ * slave's parent. */
{
Tcl_HashEntry *hPtr;
MaintainMaster *masterPtr;
@@ -495,11 +492,11 @@ Tk_UnmaintainGeometry(slave, master)
/*
* If the slave is a direct descendant of the master,
* Tk_MaintainGeometry will not have set up any of the extra
- * infrastructure. Don't even bother to look for it, just return.
+ * infrastructure. Don't even bother to look for it, just return.
*/
return;
}
-
+
if (!dispPtr->geomInit) {
dispPtr->geomInit = 1;
Tcl_InitHashTable(&dispPtr->maintainHashTable, TCL_ONE_WORD_KEYS);
@@ -554,27 +551,27 @@ Tk_UnmaintainGeometry(slave, master)
*
* MaintainMasterProc --
*
- * This procedure is invoked by the Tk event dispatcher in
- * response to StructureNotify events on the master or one
- * of its ancestors, on behalf of Tk_MaintainGeometry.
+ * This procedure is invoked by the Tk event dispatcher in response to
+ * StructureNotify events on the master or one of its ancestors, on
+ * behalf of Tk_MaintainGeometry.
*
* Results:
* None.
*
* Side effects:
- * It schedules a call to MaintainCheckProc, which will eventually
- * caused the postions and mapped states to be recalculated for all
- * the maintained slaves of the master. Or, if the master window is
- * being deleted then state is cleaned up.
+ * It schedules a call to MaintainCheckProc, which will eventually caused
+ * the postions and mapped states to be recalculated for all the
+ * maintained slaves of the master. Or, if the master window is being
+ * deleted then state is cleaned up.
*
*----------------------------------------------------------------------
*/
static void
-MaintainMasterProc(clientData, eventPtr)
- ClientData clientData; /* Pointer to MaintainMaster structure
- * for the master window. */
- XEvent *eventPtr; /* Describes what just happened. */
+MaintainMasterProc(
+ ClientData clientData, /* Pointer to MaintainMaster structure for the
+ * master window. */
+ XEvent *eventPtr) /* Describes what just happened. */
{
MaintainMaster *masterPtr = (MaintainMaster *) clientData;
MaintainSlave *slavePtr;
@@ -589,9 +586,9 @@ MaintainMasterProc(clientData, eventPtr)
}
} else if (eventPtr->type == DestroyNotify) {
/*
- * Delete all of the state associated with this master, but
- * be careful not to use masterPtr after the last slave is
- * deleted, since its memory will have been freed.
+ * Delete all of the state associated with this master, but be careful
+ * not to use masterPtr after the last slave is deleted, since its
+ * memory will have been freed.
*/
done = 0;
@@ -610,25 +607,25 @@ MaintainMasterProc(clientData, eventPtr)
*
* MaintainSlaveProc --
*
- * This procedure is invoked by the Tk event dispatcher in
- * response to StructureNotify events on a slave being managed
- * by Tk_MaintainGeometry.
+ * This procedure is invoked by the Tk event dispatcher in response to
+ * StructureNotify events on a slave being managed by
+ * Tk_MaintainGeometry.
*
* Results:
* None.
*
* Side effects:
- * If the event is a DestroyNotify event then the Maintain state
- * and event handlers for this slave are deleted.
+ * If the event is a DestroyNotify event then the Maintain state and
+ * event handlers for this slave are deleted.
*
*----------------------------------------------------------------------
*/
static void
-MaintainSlaveProc(clientData, eventPtr)
- ClientData clientData; /* Pointer to MaintainSlave structure
- * for master-slave pair. */
- XEvent *eventPtr; /* Describes what just happened. */
+MaintainSlaveProc(
+ ClientData clientData, /* Pointer to MaintainSlave structure for
+ * master-slave pair. */
+ XEvent *eventPtr) /* Describes what just happened. */
{
MaintainSlave *slavePtr = (MaintainSlave *) clientData;
@@ -642,12 +639,11 @@ MaintainSlaveProc(clientData, eventPtr)
*
* MaintainCheckProc --
*
- * This procedure is invoked by the Tk event dispatcher as an
- * idle handler, when a master or one of its ancestors has been
- * reconfigured, mapped, or unmapped. Its job is to scan all of
- * the slaves for the master and reposition them, map them, or
- * unmap them as needed to maintain their geometry relative to
- * the master.
+ * This procedure is invoked by the Tk event dispatcher as an idle
+ * handler, when a master or one of its ancestors has been reconfigured,
+ * mapped, or unmapped. Its job is to scan all of the slaves for the
+ * master and reposition them, map them, or unmap them as needed to
+ * maintain their geometry relative to the master.
*
* Results:
* None.
@@ -659,9 +655,9 @@ MaintainSlaveProc(clientData, eventPtr)
*/
static void
-MaintainCheckProc(clientData)
- ClientData clientData; /* Pointer to MaintainMaster structure
- * for the master window. */
+MaintainCheckProc(
+ ClientData clientData) /* Pointer to MaintainMaster structure for the
+ * master window. */
{
MaintainMaster *masterPtr = (MaintainMaster *) clientData;
MaintainSlave *slavePtr;
@@ -696,3 +692,11 @@ MaintainCheckProc(clientData)
}
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkGet.c b/generic/tkGet.c
index 10643ea..9fc0d50 100644
--- a/generic/tkGet.c
+++ b/generic/tkGet.c
@@ -1,27 +1,25 @@
-/*
+/*
* tkGet.c --
*
- * This file contains a number of "Tk_GetXXX" procedures, which
- * parse text strings into useful forms for Tk. This file has
- * the simpler procedures, like Tk_GetDirection and Tk_GetUid.
- * The more complex procedures like Tk_GetColor are in separate
- * files.
+ * This file contains a number of "Tk_GetXXX" procedures, which parse
+ * text strings into useful forms for Tk. This file has the simpler
+ * functions, like Tk_GetDirection and Tk_GetUid. The more complex
+ * functions like Tk_GetColor are in separate files.
*
* Copyright (c) 1991-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
-#include "tkPort.h"
/*
- * One of these structures is created per thread to store
- * thread-specific data. In this case, it is used to house the
- * Tk_Uid structs used by each thread. The "dataKey" below is
- * used to locate the ThreadSpecificData for the current thread.
+ * One of these structures is created per thread to store thread-specific
+ * data. In this case, it is used to house the Tk_Uid structs used by each
+ * thread. The "dataKey" below is used to locate the ThreadSpecificData for
+ * the current thread.
*/
typedef struct ThreadSpecificData {
@@ -30,7 +28,7 @@ typedef struct ThreadSpecificData {
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
-static void FreeUidThreadExitProc _ANSI_ARGS_((ClientData clientData));
+static void FreeUidThreadExitProc(ClientData clientData);
/*
* The following tables defines the string values for reliefs, which are
@@ -38,12 +36,11 @@ static void FreeUidThreadExitProc _ANSI_ARGS_((ClientData clientData));
*/
static CONST char *anchorStrings[] = {
- "n", "ne", "e", "se", "s", "sw", "w", "nw", "center", (char *) NULL
+ "n", "ne", "e", "se", "s", "sw", "w", "nw", "center", NULL
};
static CONST char *justifyStrings[] = {
- "left", "right", "center", (char *) NULL
+ "left", "right", "center", NULL
};
-
/*
*----------------------------------------------------------------------
@@ -64,17 +61,17 @@ static CONST char *justifyStrings[] = {
*/
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
+Tk_GetAnchorFromObj(
+ 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,
+ code = Tcl_GetIndexFromObj(interp, objPtr, anchorStrings, "anchor", 0,
&index);
if (code == TCL_OK) {
*anchorPtr = (Tk_Anchor) index;
@@ -90,11 +87,10 @@ Tk_GetAnchorFromObj(interp, objPtr, anchorPtr)
* Given a string, return the corresponding Tk_Anchor.
*
* Results:
- * The return value is a standard Tcl return result. If
- * 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
- * the interp's result.
+ * The return value is a standard Tcl return result. If 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 the interp's result.
*
* Side effects:
* None.
@@ -103,62 +99,61 @@ Tk_GetAnchorFromObj(interp, objPtr, anchorPtr)
*/
int
-Tk_GetAnchor(interp, string, anchorPtr)
- Tcl_Interp *interp; /* Use this for error reporting. */
- CONST char *string; /* String describing a direction. */
- Tk_Anchor *anchorPtr; /* Where to store Tk_Anchor corresponding
- * to string. */
+Tk_GetAnchor(
+ Tcl_Interp *interp, /* Use this for error reporting. */
+ CONST char *string, /* String describing a direction. */
+ Tk_Anchor *anchorPtr) /* Where to store Tk_Anchor corresponding to
+ * string. */
{
switch (string[0]) {
- case 'n':
- if (string[1] == 0) {
- *anchorPtr = TK_ANCHOR_N;
- return TCL_OK;
- } else if ((string[1] == 'e') && (string[2] == 0)) {
- *anchorPtr = TK_ANCHOR_NE;
- return TCL_OK;
- } else if ((string[1] == 'w') && (string[2] == 0)) {
- *anchorPtr = TK_ANCHOR_NW;
- return TCL_OK;
- }
- goto error;
- case 's':
- if (string[1] == 0) {
- *anchorPtr = TK_ANCHOR_S;
- return TCL_OK;
- } else if ((string[1] == 'e') && (string[2] == 0)) {
- *anchorPtr = TK_ANCHOR_SE;
- return TCL_OK;
- } else if ((string[1] == 'w') && (string[2] == 0)) {
- *anchorPtr = TK_ANCHOR_SW;
- return TCL_OK;
- } else {
- goto error;
- }
- case 'e':
- if (string[1] == 0) {
- *anchorPtr = TK_ANCHOR_E;
- return TCL_OK;
- }
- goto error;
- case 'w':
- if (string[1] == 0) {
- *anchorPtr = TK_ANCHOR_W;
- return TCL_OK;
- }
- goto error;
- case 'c':
- if (strncmp(string, "center", strlen(string)) == 0) {
- *anchorPtr = TK_ANCHOR_CENTER;
- return TCL_OK;
- }
+ case 'n':
+ if (string[1] == 0) {
+ *anchorPtr = TK_ANCHOR_N;
+ return TCL_OK;
+ } else if ((string[1] == 'e') && (string[2] == 0)) {
+ *anchorPtr = TK_ANCHOR_NE;
+ return TCL_OK;
+ } else if ((string[1] == 'w') && (string[2] == 0)) {
+ *anchorPtr = TK_ANCHOR_NW;
+ return TCL_OK;
+ }
+ goto error;
+ case 's':
+ if (string[1] == 0) {
+ *anchorPtr = TK_ANCHOR_S;
+ return TCL_OK;
+ } else if ((string[1] == 'e') && (string[2] == 0)) {
+ *anchorPtr = TK_ANCHOR_SE;
+ return TCL_OK;
+ } else if ((string[1] == 'w') && (string[2] == 0)) {
+ *anchorPtr = TK_ANCHOR_SW;
+ return TCL_OK;
+ } else {
goto error;
+ }
+ case 'e':
+ if (string[1] == 0) {
+ *anchorPtr = TK_ANCHOR_E;
+ return TCL_OK;
+ }
+ goto error;
+ case 'w':
+ if (string[1] == 0) {
+ *anchorPtr = TK_ANCHOR_W;
+ return TCL_OK;
+ }
+ goto error;
+ case 'c':
+ if (strncmp(string, "center", strlen(string)) == 0) {
+ *anchorPtr = TK_ANCHOR_CENTER;
+ return TCL_OK;
+ }
+ goto error;
}
- error:
+ error:
Tcl_AppendResult(interp, "bad anchor position \"", string,
- "\": must be n, ne, e, se, s, sw, w, nw, or center",
- (char *) NULL);
+ "\": must be n, ne, e, se, s, sw, w, nw, or center", NULL);
return TCL_ERROR;
}
@@ -167,8 +162,7 @@ Tk_GetAnchor(interp, string, anchorPtr)
*
* Tk_NameOfAnchor --
*
- * Given a Tk_Anchor, return the string that corresponds
- * to it.
+ * Given a Tk_Anchor, return the string that corresponds to it.
*
* Results:
* None.
@@ -180,20 +174,20 @@ Tk_GetAnchor(interp, string, anchorPtr)
*/
CONST char *
-Tk_NameOfAnchor(anchor)
- Tk_Anchor anchor; /* Anchor for which identifying string
- * is desired. */
+Tk_NameOfAnchor(
+ Tk_Anchor anchor) /* Anchor for which identifying string is
+ * desired. */
{
switch (anchor) {
- case TK_ANCHOR_N: return "n";
- case TK_ANCHOR_NE: return "ne";
- case TK_ANCHOR_E: return "e";
- case TK_ANCHOR_SE: return "se";
- case TK_ANCHOR_S: return "s";
- case TK_ANCHOR_SW: return "sw";
- case TK_ANCHOR_W: return "w";
- case TK_ANCHOR_NW: return "nw";
- case TK_ANCHOR_CENTER: return "center";
+ case TK_ANCHOR_N: return "n";
+ case TK_ANCHOR_NE: return "ne";
+ case TK_ANCHOR_E: return "e";
+ case TK_ANCHOR_SE: return "se";
+ case TK_ANCHOR_S: return "s";
+ case TK_ANCHOR_SW: return "sw";
+ case TK_ANCHOR_W: return "w";
+ case TK_ANCHOR_NW: return "nw";
+ case TK_ANCHOR_CENTER: return "center";
}
return "unknown anchor position";
}
@@ -206,11 +200,10 @@ Tk_NameOfAnchor(anchor)
* Given a string, return the corresponding Tk JoinStyle.
*
* Results:
- * The return value is a standard Tcl return result. If
- * 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
- * the interp's result.
+ * The return value is a standard Tcl return result. If 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 the interp's result.
*
* Side effects:
* None.
@@ -219,11 +212,11 @@ Tk_NameOfAnchor(anchor)
*/
int
-Tk_GetJoinStyle(interp, string, joinPtr)
- Tcl_Interp *interp; /* Use this for error reporting. */
- CONST char *string; /* String describing a justification style. */
- int *joinPtr; /* Where to store join style corresponding
- * to string. */
+Tk_GetJoinStyle(
+ Tcl_Interp *interp, /* Use this for error reporting. */
+ CONST char *string, /* String describing a justification style. */
+ int *joinPtr) /* Where to store join style corresponding to
+ * string. */
{
int c;
size_t length;
@@ -245,8 +238,7 @@ Tk_GetJoinStyle(interp, string, joinPtr)
}
Tcl_AppendResult(interp, "bad join style \"", string,
- "\": must be bevel, miter, or round",
- (char *) NULL);
+ "\": must be bevel, miter, or round", NULL);
return TCL_ERROR;
}
@@ -255,8 +247,7 @@ Tk_GetJoinStyle(interp, string, joinPtr)
*
* Tk_NameOfJoinStyle --
*
- * Given a Tk JoinStyle, return the string that corresponds
- * to it.
+ * Given a Tk JoinStyle, return the string that corresponds to it.
*
* Results:
* None.
@@ -268,14 +259,14 @@ Tk_GetJoinStyle(interp, string, joinPtr)
*/
CONST char *
-Tk_NameOfJoinStyle(join)
- int join; /* Join style for which identifying string
- * is desired. */
+Tk_NameOfJoinStyle(
+ int join) /* Join style for which identifying string is
+ * desired. */
{
switch (join) {
- case JoinBevel: return "bevel";
- case JoinMiter: return "miter";
- case JoinRound: return "round";
+ case JoinBevel: return "bevel";
+ case JoinMiter: return "miter";
+ case JoinRound: return "round";
}
return "unknown join style";
}
@@ -288,11 +279,10 @@ Tk_NameOfJoinStyle(join)
* Given a string, return the corresponding Tk CapStyle.
*
* Results:
- * The return value is a standard Tcl return result. If
- * 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
- * the interp's result.
+ * The return value is a standard Tcl return result. If 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 the interp's result.
*
* Side effects:
* None.
@@ -301,11 +291,11 @@ Tk_NameOfJoinStyle(join)
*/
int
-Tk_GetCapStyle(interp, string, capPtr)
- Tcl_Interp *interp; /* Use this for error reporting. */
- CONST char *string; /* String describing a justification style. */
- int *capPtr; /* Where to store cap style corresponding
- * to string. */
+Tk_GetCapStyle(
+ Tcl_Interp *interp, /* Use this for error reporting. */
+ CONST char *string, /* String describing a justification style. */
+ int *capPtr) /* Where to store cap style corresponding to
+ * string. */
{
int c;
size_t length;
@@ -327,8 +317,7 @@ Tk_GetCapStyle(interp, string, capPtr)
}
Tcl_AppendResult(interp, "bad cap style \"", string,
- "\": must be butt, projecting, or round",
- (char *) NULL);
+ "\": must be butt, projecting, or round", NULL);
return TCL_ERROR;
}
@@ -337,8 +326,7 @@ Tk_GetCapStyle(interp, string, capPtr)
*
* Tk_NameOfCapStyle --
*
- * Given a Tk CapStyle, return the string that corresponds
- * to it.
+ * Given a Tk CapStyle, return the string that corresponds to it.
*
* Results:
* None.
@@ -350,14 +338,14 @@ Tk_GetCapStyle(interp, string, capPtr)
*/
CONST char *
-Tk_NameOfCapStyle(cap)
- int cap; /* Cap style for which identifying string
- * is desired. */
+Tk_NameOfCapStyle(
+ int cap) /* Cap style for which identifying string is
+ * desired. */
{
switch (cap) {
- case CapButt: return "butt";
- case CapProjecting: return "projecting";
- case CapRound: return "round";
+ case CapButt: return "butt";
+ case CapProjecting: return "projecting";
+ case CapRound: return "round";
}
return "unknown cap style";
}
@@ -381,11 +369,11 @@ Tk_NameOfCapStyle(cap)
*/
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
+Tk_GetJustifyFromObj(
+ 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. */
{
@@ -407,11 +395,10 @@ Tk_GetJustifyFromObj(interp, objPtr, justifyPtr)
* Given a string, return the corresponding Tk_Justify.
*
* Results:
- * The return value is a standard Tcl return result. If
- * 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
- * the interp's result.
+ * The return value is a standard Tcl return result. If 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 the interp's result.
*
* Side effects:
* None.
@@ -420,11 +407,11 @@ Tk_GetJustifyFromObj(interp, objPtr, justifyPtr)
*/
int
-Tk_GetJustify(interp, string, justifyPtr)
- Tcl_Interp *interp; /* Use this for error reporting. */
- CONST char *string; /* String describing a justification style. */
- Tk_Justify *justifyPtr; /* Where to store Tk_Justify corresponding
- * to string. */
+Tk_GetJustify(
+ Tcl_Interp *interp, /* Use this for error reporting. */
+ CONST char *string, /* String describing a justification style. */
+ Tk_Justify *justifyPtr) /* Where to store Tk_Justify corresponding to
+ * string. */
{
int c;
size_t length;
@@ -446,8 +433,7 @@ Tk_GetJustify(interp, string, justifyPtr)
}
Tcl_AppendResult(interp, "bad justification \"", string,
- "\": must be left, right, or center",
- (char *) NULL);
+ "\": must be left, right, or center", NULL);
return TCL_ERROR;
}
@@ -469,14 +455,14 @@ Tk_GetJustify(interp, string, justifyPtr)
*/
CONST char *
-Tk_NameOfJustify(justify)
- Tk_Justify justify; /* Justification style for which
- * identifying string is desired. */
+Tk_NameOfJustify(
+ Tk_Justify justify) /* Justification style for which identifying
+ * string is desired. */
{
switch (justify) {
- case TK_JUSTIFY_LEFT: return "left";
- case TK_JUSTIFY_RIGHT: return "right";
- case TK_JUSTIFY_CENTER: return "center";
+ case TK_JUSTIFY_LEFT: return "left";
+ case TK_JUSTIFY_RIGHT: return "right";
+ case TK_JUSTIFY_CENTER: return "center";
}
return "unknown justification style";
}
@@ -498,10 +484,10 @@ Tk_NameOfJustify(justify)
*/
static void
-FreeUidThreadExitProc(clientData)
- ClientData clientData; /* Not used. */
+FreeUidThreadExitProc(
+ ClientData clientData) /* Not used. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Tcl_DeleteHashTable(&tsdPtr->uidTable);
tsdPtr->initialized = 0;
@@ -512,17 +498,16 @@ FreeUidThreadExitProc(clientData)
*
* Tk_GetUid --
*
- * Given a string, this procedure returns a unique identifier
- * for the string.
+ * Given a string, this function returns a unique identifier for the
+ * string.
*
* Results:
- * This procedure returns a Tk_Uid corresponding to the "string"
- * argument. The Tk_Uid has a string value identical to string
- * (strcmp will return 0), but it's guaranteed that any other
- * calls to this procedure with a string equal to "string" will
- * return exactly the same result (i.e. can compare Tk_Uid
- * *values* directly, without having to call strcmp on what they
- * point to).
+ * This function returns a Tk_Uid corresponding to the "string" argument.
+ * The Tk_Uid has a string value identical to string (strcmp will return
+ * 0), but it's guaranteed that any other calls to this function with a
+ * string equal to "string" will return exactly the same result (i.e. can
+ * compare Tk_Uid *values* directly, without having to call strcmp on
+ * what they point to).
*
* Side effects:
* New information may be entered into the identifier table.
@@ -531,11 +516,11 @@ FreeUidThreadExitProc(clientData)
*/
Tk_Uid
-Tk_GetUid(string)
- CONST char *string; /* String to convert. */
+Tk_GetUid(
+ CONST char *string) /* String to convert. */
{
int dummy;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Tcl_HashTable *tablePtr = &tsdPtr->uidTable;
@@ -553,15 +538,14 @@ Tk_GetUid(string)
*
* Tk_GetScreenMM --
*
- * Given a string, returns the number of screen millimeters
- * corresponding to that string.
+ * Given a string, returns the number of screen millimeters corresponding
+ * to that string.
*
* Results:
- * The return value is a standard Tcl return result. If
- * 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
- * the interp's result.
+ * The return value is a standard Tcl return result. If 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 the interp's result.
*
* Side effects:
* None.
@@ -570,13 +554,13 @@ Tk_GetUid(string)
*/
int
-Tk_GetScreenMM(interp, tkwin, string, doublePtr)
- Tcl_Interp *interp; /* Use this for error reporting. */
- Tk_Window tkwin; /* Window whose screen determines conversion
+Tk_GetScreenMM(
+ Tcl_Interp *interp, /* Use this for error reporting. */
+ Tk_Window tkwin, /* Window whose screen determines conversion
* from centimeters and other absolute
* units. */
- CONST char *string; /* String describing a screen distance. */
- double *doublePtr; /* Place to store converted result. */
+ CONST char *string, /* String describing a screen distance. */
+ double *doublePtr) /* Place to store converted result. */
{
char *end;
double d;
@@ -584,35 +568,34 @@ Tk_GetScreenMM(interp, tkwin, string, doublePtr)
d = strtod(string, &end);
if (end == string) {
error:
- Tcl_AppendResult(interp, "bad screen distance \"", string,
- "\"", (char *) NULL);
+ Tcl_AppendResult(interp, "bad screen distance \"", string, "\"", NULL);
return TCL_ERROR;
}
while ((*end != '\0') && isspace(UCHAR(*end))) {
end++;
}
switch (*end) {
- case 0:
- d /= WidthOfScreen(Tk_Screen(tkwin));
- d *= WidthMMOfScreen(Tk_Screen(tkwin));
- break;
- case 'c':
- d *= 10;
- end++;
- break;
- case 'i':
- d *= 25.4;
- end++;
- break;
- case 'm':
- end++;
- break;
- case 'p':
- d *= 25.4/72.0;
- end++;
- break;
- default:
- goto error;
+ case 0:
+ d /= WidthOfScreen(Tk_Screen(tkwin));
+ d *= WidthMMOfScreen(Tk_Screen(tkwin));
+ break;
+ case 'c':
+ d *= 10;
+ end++;
+ break;
+ case 'i':
+ d *= 25.4;
+ end++;
+ break;
+ case 'm':
+ end++;
+ break;
+ case 'p':
+ d *= 25.4/72.0;
+ end++;
+ break;
+ default:
+ goto error;
}
while ((*end != '\0') && isspace(UCHAR(*end))) {
end++;
@@ -629,15 +612,14 @@ Tk_GetScreenMM(interp, tkwin, string, doublePtr)
*
* Tk_GetPixels --
*
- * Given a string, returns the number of pixels corresponding
- * to that string.
+ * Given a string, returns the number of pixels corresponding to that
+ * string.
*
* Results:
- * The return value is a standard Tcl return result. If
- * 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
- * the interp's result.
+ * The return value is a standard Tcl return result. If 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 the interp's result.
*
* Side effects:
* None.
@@ -646,13 +628,13 @@ Tk_GetScreenMM(interp, tkwin, string, doublePtr)
*/
int
-Tk_GetPixels(interp, tkwin, string, intPtr)
- Tcl_Interp *interp; /* Use this for error reporting. */
- Tk_Window tkwin; /* Window whose screen determines conversion
+Tk_GetPixels(
+ Tcl_Interp *interp, /* Use this for error reporting. */
+ Tk_Window tkwin, /* Window whose screen determines conversion
* from centimeters and other absolute
* units. */
- CONST char *string; /* String describing a number of pixels. */
- int *intPtr; /* Place to store converted result. */
+ CONST char *string, /* String describing a number of pixels. */
+ int *intPtr) /* Place to store converted result. */
{
double d;
@@ -672,15 +654,15 @@ Tk_GetPixels(interp, tkwin, string, intPtr)
*
* TkGetDoublePixels --
*
- * Given a string, returns the number of pixels corresponding
- * to that string.
+ * Given a string, returns the number of pixels corresponding to that
+ * string.
*
* Results:
- * The return value is a standard Tcl return result. If
- * TCL_OK is returned, then everything went well and the
- * pixel distance is stored at *doublePtr; 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 pixel distance is stored
+ * at *doublePtr; otherwise TCL_ERROR is returned and an error message is
+ * left in interp->result.
*
* Side effects:
* None.
@@ -689,52 +671,51 @@ Tk_GetPixels(interp, tkwin, string, intPtr)
*/
int
-TkGetDoublePixels(interp, tkwin, string, doublePtr)
- Tcl_Interp *interp; /* Use this for error reporting. */
- Tk_Window tkwin; /* Window whose screen determines conversion
+TkGetDoublePixels(
+ Tcl_Interp *interp, /* Use this for error reporting. */
+ Tk_Window tkwin, /* Window whose screen determines conversion
* from centimeters and other absolute
* units. */
- CONST char *string; /* String describing a number of pixels. */
- double *doublePtr; /* Place to store converted result. */
+ CONST char *string, /* String describing a number of pixels. */
+ double *doublePtr) /* Place to store converted result. */
{
char *end;
double d;
d = strtod((char *) string, &end);
if (end == string) {
- error:
- Tcl_AppendResult(interp, "bad screen distance \"", string,
- "\"", (char *) NULL);
+ error:
+ Tcl_AppendResult(interp, "bad screen distance \"", string, "\"", NULL);
return TCL_ERROR;
}
while ((*end != '\0') && isspace(UCHAR(*end))) {
end++;
}
switch (*end) {
- case 0:
- break;
- case 'c':
- d *= 10*WidthOfScreen(Tk_Screen(tkwin));
- d /= WidthMMOfScreen(Tk_Screen(tkwin));
- end++;
- break;
- case 'i':
- d *= 25.4*WidthOfScreen(Tk_Screen(tkwin));
- d /= WidthMMOfScreen(Tk_Screen(tkwin));
- end++;
- break;
- case 'm':
- d *= WidthOfScreen(Tk_Screen(tkwin));
- d /= WidthMMOfScreen(Tk_Screen(tkwin));
- end++;
- break;
- case 'p':
- d *= (25.4/72.0)*WidthOfScreen(Tk_Screen(tkwin));
- d /= WidthMMOfScreen(Tk_Screen(tkwin));
- end++;
- break;
- default:
- goto error;
+ case 0:
+ break;
+ case 'c':
+ d *= 10*WidthOfScreen(Tk_Screen(tkwin));
+ d /= WidthMMOfScreen(Tk_Screen(tkwin));
+ end++;
+ break;
+ case 'i':
+ d *= 25.4*WidthOfScreen(Tk_Screen(tkwin));
+ d /= WidthMMOfScreen(Tk_Screen(tkwin));
+ end++;
+ break;
+ case 'm':
+ d *= WidthOfScreen(Tk_Screen(tkwin));
+ d /= WidthMMOfScreen(Tk_Screen(tkwin));
+ end++;
+ break;
+ case 'p':
+ d *= (25.4/72.0)*WidthOfScreen(Tk_Screen(tkwin));
+ d /= WidthMMOfScreen(Tk_Screen(tkwin));
+ end++;
+ break;
+ default:
+ goto error;
}
while ((*end != '\0') && isspace(UCHAR(*end))) {
end++;
@@ -745,5 +726,11 @@ TkGetDoublePixels(interp, tkwin, string, doublePtr)
*doublePtr = d;
return TCL_OK;
}
-
-
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkGrab.c b/generic/tkGrab.c
index 4fa7393..44a4f8c 100644
--- a/generic/tkGrab.c
+++ b/generic/tkGrab.c
@@ -1,45 +1,44 @@
-/*
+/*
* tkGrab.c --
*
- * This file provides procedures that implement grabs for Tk.
+ * This file provides functions that implement grabs for Tk.
*
* Copyright (c) 1992-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
+#ifdef __WIN32__
+#include "tkWinInt.h"
+#elif !(defined(__WIN32__) || defined(MAC_OSX_TK))
#include "tkUnixInt.h"
#endif
/*
- * The grab state machine has four states: ungrabbed, button pressed,
- * grabbed, and button pressed while grabbed. In addition, there are
- * three pieces of grab state information: the current grab window,
- * the current restrict window, and whether the mouse is captured.
- *
- * The current grab window specifies the point in the Tk window
- * heirarchy above which pointer events will not be reported. Any
- * window within the subtree below the grab window will continue to
- * receive events as normal. Events outside of the grab tree will be
- * reported to the grab window.
- *
- * If the current restrict window is set, then all pointer events will
- * be reported only to the restrict window. The restrict window is
- * normally set during an automatic button grab.
- *
- * The mouse capture state specifies whether the window system will
- * report mouse events outside of any Tk toplevels. This is set
- * during a global grab or an automatic button grab.
- *
- * The transitions between different states is given in the following
- * table:
- *
+ * The grab state machine has four states: ungrabbed, button pressed, grabbed,
+ * and button pressed while grabbed. In addition, there are three pieces of
+ * grab state information: the current grab window, the current restrict
+ * window, and whether the mouse is captured.
+ *
+ * The current grab window specifies the point in the Tk window heirarchy
+ * above which pointer events will not be reported. Any window within the
+ * subtree below the grab window will continue to receive events as normal.
+ * Events outside of the grab tree will be reported to the grab window.
+ *
+ * If the current restrict window is set, then all pointer events will be
+ * reported only to the restrict window. The restrict window is normally set
+ * during an automatic button grab.
+ *
+ * The mouse capture state specifies whether the window system will report
+ * mouse events outside of any Tk toplevels. This is set during a global grab
+ * or an automatic button grab.
+ *
+ * The transitions between different states is given in the following table:
+ *
* Event\State U B G GB
* ----------- -- -- -- --
* FirstPress B B GB GB
@@ -60,15 +59,14 @@
* Grabbed 1 0 b/g
* Grab and Button 1 1 1
*
- * Note: 0 means variable is set to NULL, 1 means variable is set to
- * some window, b/g means the variable is set to a window if a button
- * is currently down or a global grab is in effect.
+ * Note: 0 means variable is set to NULL, 1 means variable is set to some
+ * window, b/g means the variable is set to a window if a button is currently
+ * down or a global grab is in effect.
*
- * The final complication to all of this is enter and leave events.
- * In order to correctly handle all of the various cases, Tk cannot
- * rely on X enter/leave events in all situations. The following
- * describes the correct sequence of enter and leave events that
- * should be observed by Tk scripts:
+ * The final complication to all of this is enter and leave events. In order
+ * to correctly handle all of the various cases, Tk cannot rely on X
+ * enter/leave events in all situations. The following describes the correct
+ * sequence of enter and leave events that should be observed by Tk scripts:
*
* Event(state) Enter/Leave From -> To
* ------------ ----------------------
@@ -80,13 +78,13 @@
* Ungrab(G): anc(grab window, event window) -> event window
* Ungrab(GB): restrict window -> event window
*
- * Note: anc(x,y) returns the least ancestor of y that is in the tree
- * of x, terminating at toplevels.
+ * Note: anc(x,y) returns the least ancestor of y that is in the tree of x,
+ * terminating at toplevels.
*/
/*
- * The following structure is used to pass information to
- * GrabRestrictProc from EatGrabEvents.
+ * The following structure is used to pass information to GrabRestrictProc
+ * from EatGrabEvents.
*/
typedef struct {
@@ -99,47 +97,46 @@ typedef struct {
*
* GRAB_GLOBAL 1 means this is a global grab (we grabbed via
* the server so all applications are locked out).
- * 0 means this is a local grab that affects
- * only this application.
+ * 0 means this is a local grab that affects only
+ * this application.
* GRAB_TEMP_GLOBAL 1 means we've temporarily grabbed via the
- * server because a button is down and we want
- * to make sure that we get the button-up
- * event. The grab will be released when the
- * last mouse button goes up.
+ * server because a button is down and we want to
+ * make sure that we get the button-up event. The
+ * grab will be released when the last mouse
+ * button goes up.
*/
#define GRAB_GLOBAL 1
#define GRAB_TEMP_GLOBAL 4
/*
- * The following structure is a Tcl_Event that triggers a change in
- * the grabWinPtr field of a display. This event guarantees that
- * the change occurs in the proper order relative to enter and leave
- * events.
+ * The following structure is a Tcl_Event that triggers a change in the
+ * grabWinPtr field of a display. This event guarantees that the change occurs
+ * in the proper order relative to enter and leave events.
*/
typedef struct NewGrabWinEvent {
Tcl_Event header; /* Standard information for all Tcl events. */
TkDisplay *dispPtr; /* Display whose grab window is to change. */
- Window grabWindow; /* New grab window for display. This is
+ Window grabWindow; /* New grab window for display. This is
* recorded instead of a (TkWindow *) because
- * it will allow us to detect cases where
- * the window is destroyed before this event
- * is processed. */
+ * it will allow us to detect cases where the
+ * window is destroyed before this event is
+ * processed. */
} NewGrabWinEvent;
/*
* The following magic value is stored in the "send_event" field of
- * EnterNotify and LeaveNotify events that are generated in this
- * file. This allows us to separate "real" events coming from the
- * server from those that we generated.
+ * EnterNotify and LeaveNotify events that are generated in this file. This
+ * allows us to separate "real" events coming from the server from those that
+ * we generated.
*/
#define GENERATED_EVENT_MAGIC ((Bool) 0x147321ac)
/*
- * Mask that selects any of the state bits corresponding to buttons,
- * plus masks that select individual buttons' bits:
+ * Mask that selects any of the state bits corresponding to buttons, plus
+ * masks that select individual buttons' bits:
*/
#define ALL_BUTTONS \
@@ -149,32 +146,27 @@ static unsigned int buttonStates[] = {
};
/*
- * Forward declarations for procedures declared later in this file:
+ * Forward declarations for functions declared later in this file:
*/
-static void EatGrabEvents _ANSI_ARGS_((TkDisplay *dispPtr,
- unsigned int serial));
-static TkWindow * FindCommonAncestor _ANSI_ARGS_((TkWindow *winPtr1,
- TkWindow *winPtr2, int *countPtr1,
- int *countPtr2));
-static Tk_RestrictAction GrabRestrictProc _ANSI_ARGS_((ClientData arg,
- XEvent *eventPtr));
-static int GrabWinEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
- int flags));
-static void MovePointer2 _ANSI_ARGS_((TkWindow *sourcePtr,
- TkWindow *destPtr, int mode, int leaveEvents,
- int EnterEvents));
-static void QueueGrabWindowChange _ANSI_ARGS_((TkDisplay *dispPtr,
- TkWindow *grabWinPtr));
-static void ReleaseButtonGrab _ANSI_ARGS_((TkDisplay *dispPtr));
+static void EatGrabEvents(TkDisplay *dispPtr, unsigned int serial);
+static TkWindow * FindCommonAncestor(TkWindow *winPtr1,
+ TkWindow *winPtr2, int *countPtr1, int *countPtr2);
+static Tk_RestrictAction GrabRestrictProc(ClientData arg, XEvent *eventPtr);
+static int GrabWinEventProc(Tcl_Event *evPtr, int flags);
+static void MovePointer2(TkWindow *sourcePtr, TkWindow *destPtr,
+ int mode, int leaveEvents, int EnterEvents);
+static void QueueGrabWindowChange(TkDisplay *dispPtr,
+ TkWindow *grabWinPtr);
+static void ReleaseButtonGrab(TkDisplay *dispPtr);
/*
*----------------------------------------------------------------------
*
* Tk_GrabObjCmd --
*
- * This procedure is invoked to process the "grab" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "grab" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -187,12 +179,11 @@ static void ReleaseButtonGrab _ANSI_ARGS_((TkDisplay *dispPtr));
/* ARGSUSED */
int
-Tk_GrabObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_GrabObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
int globalGrab;
Tk_Window tkwin;
@@ -200,14 +191,16 @@ Tk_GrabObjCmd(clientData, interp, objc, objv)
char *arg;
int index;
int len;
- static CONST char *optionStrings[] = { "current", "release",
- "set", "status", (char *) NULL };
-
- static CONST char *flagStrings[] = { "-global", (char *) NULL };
-
- enum options { GRABCMD_CURRENT, GRABCMD_RELEASE,
- GRABCMD_SET, GRABCMD_STATUS };
-
+ static CONST char *optionStrings[] = {
+ "current", "release", "set", "status", NULL
+ };
+ static CONST char *flagStrings[] = {
+ "-global", NULL
+ };
+ enum options {
+ GRABCMD_CURRENT, GRABCMD_RELEASE, GRABCMD_SET, GRABCMD_STATUS
+ };
+
if (objc < 2) {
/*
* Can't use Tcl_WrongNumArgs here because we want the message to
@@ -221,8 +214,7 @@ Tk_GrabObjCmd(clientData, interp, objc, objv)
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "wrong # args: should be \"",
Tcl_GetString(objv[0]), " ?-global? window\" or \"",
- Tcl_GetString(objv[0]), " option ?arg arg ...?\"",
- (char *) NULL);
+ Tcl_GetString(objv[0]), " option ?arg arg ...?\"", NULL);
return TCL_ERROR;
}
@@ -262,115 +254,114 @@ Tk_GrabObjCmd(clientData, interp, objc, objv)
}
/*
- * First argument is not a window name and not "-global", find out
- * which option it is.
+ * First argument is not a window name and not "-global", find out which
+ * option it is.
*/
if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
&index) != TCL_OK) {
return TCL_ERROR;
}
-
+
switch ((enum options) index) {
- case GRABCMD_CURRENT: {
- /* [grab current ?window?] */
- if (objc > 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "current ?window?");
+ case GRABCMD_CURRENT:
+ /* [grab current ?window?] */
+ if (objc > 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "current ?window?");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
+ (Tk_Window) clientData);
+ if (tkwin == NULL) {
return TCL_ERROR;
}
- if (objc == 3) {
- tkwin = Tk_NameToWindow(interp,
- Tcl_GetString(objv[2]), (Tk_Window) clientData);
- if (tkwin == NULL) {
- return TCL_ERROR;
- }
- dispPtr = ((TkWindow *) tkwin)->dispPtr;
+ dispPtr = ((TkWindow *) tkwin)->dispPtr;
+ if (dispPtr->eventualGrabWinPtr != NULL) {
+ Tcl_SetResult(interp, dispPtr->eventualGrabWinPtr->pathName,
+ TCL_STATIC);
+ }
+ } else {
+ for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
+ dispPtr = dispPtr->nextPtr) {
if (dispPtr->eventualGrabWinPtr != NULL) {
- Tcl_SetResult(interp,
- dispPtr->eventualGrabWinPtr->pathName, TCL_STATIC);
- }
- } else {
- for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
- dispPtr = dispPtr->nextPtr) {
- if (dispPtr->eventualGrabWinPtr != NULL) {
- Tcl_AppendElement(interp,
- dispPtr->eventualGrabWinPtr->pathName);
- }
+ Tcl_AppendElement(interp,
+ dispPtr->eventualGrabWinPtr->pathName);
}
}
- return TCL_OK;
}
+ return TCL_OK;
- case GRABCMD_RELEASE: {
- /* [grab release window] */
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "release window");
- return TCL_ERROR;
- }
- tkwin = Tk_NameToWindow(interp,
- Tcl_GetString(objv[2]), (Tk_Window) clientData);
- if (tkwin == NULL) {
- Tcl_ResetResult(interp);
- } else {
- Tk_Ungrab(tkwin);
- }
- break;
+ case GRABCMD_RELEASE:
+ /* [grab release window] */
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "release window");
+ return TCL_ERROR;
}
-
- case GRABCMD_SET: {
- /* [grab set ?-global? window] */
- if ((objc != 3) && (objc != 4)) {
- Tcl_WrongNumArgs(interp, 1, objv, "set ?-global? window");
- return TCL_ERROR;
- }
- if (objc == 3) {
- globalGrab = 0;
- tkwin = Tk_NameToWindow(interp,
- Tcl_GetString(objv[2]), (Tk_Window) clientData);
- } else {
- globalGrab = 1;
- /*
- * We could just test the argument by hand instead of using
- * Tcl_GetIndexFromObj; the benefit of using the function is
- * that it sets up the error message for us, so we are
- * certain to be consistant with the rest of Tcl.
- */
- if (Tcl_GetIndexFromObj(interp, objv[2], flagStrings, "option",
- 0, &index) != TCL_OK) {
- return TCL_ERROR;
- }
- tkwin = Tk_NameToWindow(interp,
- Tcl_GetString(objv[3]), (Tk_Window) clientData);
- }
- if (tkwin == NULL) {
- return TCL_ERROR;
- }
- return Tk_Grab(interp, tkwin, globalGrab);
+ tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
+ (Tk_Window) clientData);
+ if (tkwin == NULL) {
+ Tcl_ResetResult(interp);
+ } else {
+ Tk_Ungrab(tkwin);
}
+ break;
- case GRABCMD_STATUS: {
- /* [grab status window] */
- TkWindow *winPtr;
+ case GRABCMD_SET:
+ /* [grab set ?-global? window] */
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 1, objv, "set ?-global? window");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ globalGrab = 0;
+ tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
+ (Tk_Window) clientData);
+ } else {
+ globalGrab = 1;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "status window");
- return TCL_ERROR;
- }
- winPtr = (TkWindow *) Tk_NameToWindow(interp,
- Tcl_GetString(objv[2]), (Tk_Window) clientData);
- if (winPtr == NULL) {
+ /*
+ * We could just test the argument by hand instead of using
+ * Tcl_GetIndexFromObj; the benefit of using the function is that
+ * it sets up the error message for us, so we are certain to be
+ * consistant with the rest of Tcl.
+ */
+
+ if (Tcl_GetIndexFromObj(interp, objv[2], flagStrings, "option",
+ 0, &index) != TCL_OK) {
return TCL_ERROR;
}
- dispPtr = winPtr->dispPtr;
- if (dispPtr->eventualGrabWinPtr != winPtr) {
- Tcl_SetResult(interp, "none", TCL_STATIC);
- } else if (dispPtr->grabFlags & GRAB_GLOBAL) {
- Tcl_SetResult(interp, "global", TCL_STATIC);
- } else {
- Tcl_SetResult(interp, "local", TCL_STATIC);
- }
- break;
+ tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[3]),
+ (Tk_Window) clientData);
+ }
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+ return Tk_Grab(interp, tkwin, globalGrab);
+
+ case GRABCMD_STATUS: {
+ /* [grab status window] */
+ TkWindow *winPtr;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "status window");
+ return TCL_ERROR;
+ }
+ winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
+ (Tk_Window) clientData);
+ if (winPtr == NULL) {
+ return TCL_ERROR;
+ }
+ dispPtr = winPtr->dispPtr;
+ if (dispPtr->eventualGrabWinPtr != winPtr) {
+ Tcl_SetResult(interp, "none", TCL_STATIC);
+ } else if (dispPtr->grabFlags & GRAB_GLOBAL) {
+ Tcl_SetResult(interp, "global", TCL_STATIC);
+ } else {
+ Tcl_SetResult(interp, "local", TCL_STATIC);
}
+ break;
+ }
}
return TCL_OK;
@@ -381,34 +372,32 @@ Tk_GrabObjCmd(clientData, interp, objc, objv)
*
* Tk_Grab --
*
- * Grabs the pointer and keyboard, so that mouse-related events are
- * only reported relative to a given window and its descendants.
+ * Grabs the pointer and keyboard, so that mouse-related events are only
+ * reported relative to a given window and its descendants.
*
* 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 the interp's result will hold an error message.
+ * 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 the
+ * interp's result will hold an error message.
*
* Side effects:
- * Once this call completes successfully, no window outside the
- * tree rooted at tkwin will receive pointer- or keyboard-related
- * events until the next call to Tk_Ungrab. If a previous grab was
- * in effect within this application, then it is replaced with a new
- * one.
+ * Once this call completes successfully, no window outside the tree
+ * rooted at tkwin will receive pointer- or keyboard-related events until
+ * the next call to Tk_Ungrab. If a previous grab was in effect within
+ * this application, then it is replaced with a new one.
*
*----------------------------------------------------------------------
*/
int
-Tk_Grab(interp, tkwin, grabGlobal)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Window tkwin; /* Window on whose behalf the pointer
- * is to be grabbed. */
- int grabGlobal; /* Non-zero means issue a grab to the
- * server so that no other application
- * gets mouse or keyboard events.
- * Zero means the grab only applies
- * within this application. */
+Tk_Grab(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_Window tkwin, /* Window on whose behalf the pointer is to be
+ * grabbed. */
+ int grabGlobal) /* Non-zero means issue a grab to the server
+ * so that no other application gets mouse or
+ * keyboard events. Zero means the grab only
+ * applies within this application. */
{
int grabResult, numTries;
TkWindow *winPtr = (TkWindow *) tkwin;
@@ -423,7 +412,7 @@ Tk_Grab(interp, tkwin, grabGlobal)
return TCL_OK;
}
if (dispPtr->eventualGrabWinPtr->mainPtr != winPtr->mainPtr) {
- alreadyGrabbed:
+ alreadyGrabbed:
Tcl_SetResult(interp, "grab failed: another application has grab",
TCL_STATIC);
return TCL_ERROR;
@@ -438,11 +427,11 @@ Tk_Grab(interp, tkwin, grabGlobal)
unsigned int state;
/*
- * Local grab. However, if any mouse buttons are down, turn
- * it into a global grab temporarily, until the last button
- * goes up. This does two things: (a) it makes sure that we
- * see the button-up event; and (b) it allows us to track mouse
- * motion among all of the windows of this application.
+ * Local grab. However, if any mouse buttons are down, turn it into a
+ * global grab temporarily, until the last button goes up. This does
+ * two things: (a) it makes sure that we see the button-up event; and
+ * (b) it allows us to track mouse motion among all of the windows of
+ * this application.
*/
dispPtr->grabFlags &= ~(GRAB_GLOBAL|GRAB_TEMP_GLOBAL);
@@ -454,30 +443,28 @@ Tk_Grab(interp, tkwin, grabGlobal)
}
} else {
dispPtr->grabFlags |= GRAB_GLOBAL;
- setGlobalGrab:
+ setGlobalGrab:
/*
- * Tricky point: must ungrab before grabbing. This is needed
- * in case there is a button auto-grab already in effect. If
- * there is, and the mouse has moved to a different window, X
- * won't generate enter and leave events to move the mouse if
- * we grab without ungrabbing.
+ * Tricky point: must ungrab before grabbing. This is needed in case
+ * there is a button auto-grab already in effect. If there is, and the
+ * mouse has moved to a different window, X won't generate enter and
+ * leave events to move the mouse if we grab without ungrabbing.
*/
XUngrabPointer(dispPtr->display, CurrentTime);
serial = NextRequest(dispPtr->display);
/*
- * Another tricky point: there are races with some window
- * managers that can cause grabs to fail because the window
- * manager hasn't released its grab quickly enough. To work
- * around this problem, retry a few times after AlreadyGrabbed
- * errors to give the grab release enough time to register with
- * the server.
+ * Another tricky point: there are races with some window managers
+ * that can cause grabs to fail because the window manager hasn't
+ * released its grab quickly enough. To work around this problem,
+ * retry a few times after AlreadyGrabbed errors to give the grab
+ * release enough time to register with the server.
*/
- grabResult = 0; /* Needed only to prevent gcc
- * compiler warnings. */
+ grabResult = 0; /* Needed only to prevent gcc compiler
+ * warnings. */
for (numTries = 0; numTries < 10; numTries++) {
grabResult = XGrabPointer(dispPtr->display, winPtr->window,
True, ButtonPressMask|ButtonReleaseMask|ButtonMotionMask
@@ -489,7 +476,7 @@ Tk_Grab(interp, tkwin, grabGlobal)
Tcl_Sleep(100);
}
if (grabResult != 0) {
- grabError:
+ grabError:
if (grabResult == GrabNotViewable) {
Tcl_SetResult(interp, "grab failed: window not viewable",
TCL_STATIC);
@@ -503,10 +490,10 @@ Tk_Grab(interp, tkwin, grabGlobal)
TCL_STATIC);
} else {
char msg[64 + TCL_INTEGER_SPACE];
-
+
sprintf(msg, "grab failed for unknown reason (code %d)",
grabResult);
- Tcl_AppendResult(interp, msg, (char *) NULL);
+ Tcl_AppendResult(interp, msg, NULL);
}
return TCL_ERROR;
}
@@ -519,13 +506,13 @@ Tk_Grab(interp, tkwin, grabGlobal)
/*
* Eat up any grab-related events generated by the server for the
- * grab. There are several reasons for doing this:
+ * grab. There are several reasons for doing this:
*
* 1. We have to synthesize the events for local grabs anyway, since
* the server doesn't participate in them.
* 2. The server doesn't always generate the right events for global
- * grabs (e.g. it generates events even if the current window is
- * in the grab tree, which we don't want).
+ * grabs (e.g. it generates events even if the current window is in
+ * the grab tree, which we don't want).
* 3. We want all the grab-related events to be processed immediately
* (before other events that are already queued); events coming
* from the server will be in the wrong place, but events we
@@ -536,8 +523,8 @@ Tk_Grab(interp, tkwin, grabGlobal)
}
/*
- * Synthesize leave events to move the pointer from its current window
- * up to the lowest ancestor that it has in common with the grab window.
+ * Synthesize leave events to move the pointer from its current window up
+ * to the lowest ancestor that it has in common with the grab window.
* However, only do this if the pointer is outside the grab window's
* subtree but inside the grab window's application.
*/
@@ -563,8 +550,8 @@ Tk_Grab(interp, tkwin, grabGlobal)
*
* Tk_Ungrab --
*
- * Releases a grab on the mouse pointer and keyboard, if there
- * is one set on the specified window.
+ * Releases a grab on the mouse pointer and keyboard, if there is one set
+ * on the specified window.
*
* Results:
* None.
@@ -577,9 +564,8 @@ Tk_Grab(interp, tkwin, grabGlobal)
*/
void
-Tk_Ungrab(tkwin)
- Tk_Window tkwin; /* Window whose grab should be
- * released. */
+Tk_Ungrab(
+ Tk_Window tkwin) /* Window whose grab should be released. */
{
TkDisplay *dispPtr;
TkWindow *grabWinPtr, *winPtr;
@@ -591,7 +577,7 @@ Tk_Ungrab(tkwin)
return;
}
ReleaseButtonGrab(dispPtr);
- QueueGrabWindowChange(dispPtr, (TkWindow *) NULL);
+ QueueGrabWindowChange(dispPtr, NULL);
if (dispPtr->grabFlags & (GRAB_GLOBAL|GRAB_TEMP_GLOBAL)) {
dispPtr->grabFlags &= ~(GRAB_GLOBAL|GRAB_TEMP_GLOBAL);
serial = NextRequest(dispPtr->display);
@@ -601,17 +587,17 @@ Tk_Ungrab(tkwin)
}
/*
- * Generate events to move the pointer back to the window where it
- * really is. Some notes:
- * 1. As with grabs, only do this if the "real" window is not a
- * descendant of the grab window, since in this case the pointer
- * is already where it's supposed to be.
+ * Generate events to move the pointer back to the window where it really
+ * is. Some notes:
+ * 1. As with grabs, only do this if the "real" window is not a descendant
+ * of the grab window, since in this case the pointer is already where
+ * it's supposed to be.
* 2. If the "real" window is in some other application then don't
- * generate any events at all, since everything's already been
- * reported correctly.
- * 3. Only generate enter events. Don't generate leave events,
- * because we never told the lower-level windows that they
- * had the pointer in the first place.
+ * generate any events at all, since everything's already been reported
+ * correctly.
+ * 3. Only generate enter events. Don't generate leave events, because we
+ * never told the lower-level windows that they had the pointer in the
+ * first place.
*/
for (winPtr = dispPtr->serverWinPtr; ; winPtr = winPtr->parentPtr) {
@@ -634,26 +620,26 @@ Tk_Ungrab(tkwin)
*
* ReleaseButtonGrab --
*
- * This procedure is called to release a simulated button grab, if
- * there is one in effect. A button grab is present whenever
- * dispPtr->buttonWinPtr is non-NULL or when the GRAB_TEMP_GLOBAL
- * flag is set.
+ * This function is called to release a simulated button grab, if there
+ * is one in effect. A button grab is present whenever
+ * dispPtr->buttonWinPtr is non-NULL or when the GRAB_TEMP_GLOBAL flag is
+ * set.
*
* Results:
* None.
*
* Side effects:
- * DispPtr->buttonWinPtr is reset to NULL, and enter and leave
- * events are generated if necessary to move the pointer from
- * the button grab window to its current window.
+ * DispPtr->buttonWinPtr is reset to NULL, and enter and leave events are
+ * generated if necessary to move the pointer from the button grab window
+ * to its current window.
*
*----------------------------------------------------------------------
*/
static void
-ReleaseButtonGrab(dispPtr)
- register TkDisplay *dispPtr; /* Display whose button grab is to be
- * released. */
+ReleaseButtonGrab(
+ register TkDisplay *dispPtr)/* Display whose button grab is to be
+ * released. */
{
unsigned int serial;
@@ -678,64 +664,64 @@ ReleaseButtonGrab(dispPtr)
*
* TkPointerEvent --
*
- * This procedure is called for each pointer-related event, before
- * the event has been processed. It does various things to make
- * grabs work correctly.
+ * This function is called for each pointer-related event, before the
+ * event has been processed. It does various things to make grabs work
+ * correctly.
*
* Results:
- * If the return value is 1 it means the event should be processed
- * (event handlers should be invoked). If the return value is 0
- * it means the event should be ignored in order to make grabs
- * work correctly. In some cases this procedure modifies the event.
+ * If the return value is 1 it means the event should be processed (event
+ * handlers should be invoked). If the return value is 0 it means the
+ * event should be ignored in order to make grabs work correctly. In some
+ * cases this function modifies the event.
*
* Side effects:
- * Grab state information may be updated. New events may also be
- * pushed back onto the event queue to replace or augment the
- * one passed in here.
+ * Grab state information may be updated. New events may also be pushed
+ * back onto the event queue to replace or augment the one passed in
+ * here.
*
*----------------------------------------------------------------------
*/
int
-TkPointerEvent(eventPtr, winPtr)
- register XEvent *eventPtr; /* Pointer to the event. */
- TkWindow *winPtr; /* Tk's information for window
- * where event was reported. */
+TkPointerEvent(
+ register XEvent *eventPtr, /* Pointer to the event. */
+ TkWindow *winPtr) /* Tk's information for window where event was
+ * reported. */
{
register TkWindow *winPtr2;
TkDisplay *dispPtr = winPtr->dispPtr;
unsigned int serial;
int outsideGrabTree = 0;
int ancestorOfGrab = 0;
- int appGrabbed = 0; /* Non-zero means event is being
- * reported to an application that is
- * affected by the grab. */
+ int appGrabbed = 0; /* Non-zero means event is being reported to
+ * an application that is affected by the
+ * grab. */
/*
* Collect information about the grab (if any).
*/
switch (TkGrabState(winPtr)) {
- case TK_GRAB_IN_TREE:
- appGrabbed = 1;
- break;
- case TK_GRAB_ANCESTOR:
- appGrabbed = 1;
- outsideGrabTree = 1;
- ancestorOfGrab = 1;
- break;
- case TK_GRAB_EXCLUDED:
- appGrabbed = 1;
- outsideGrabTree = 1;
- break;
+ case TK_GRAB_IN_TREE:
+ appGrabbed = 1;
+ break;
+ case TK_GRAB_ANCESTOR:
+ appGrabbed = 1;
+ outsideGrabTree = 1;
+ ancestorOfGrab = 1;
+ break;
+ case TK_GRAB_EXCLUDED:
+ appGrabbed = 1;
+ outsideGrabTree = 1;
+ break;
}
if ((eventPtr->type == EnterNotify) || (eventPtr->type == LeaveNotify)) {
/*
- * Keep track of what window the mouse is *really* over.
- * Any events that we generate have a special send_event value,
- * which is detected below and used to ignore the event for
- * purposes of setting serverWinPtr.
+ * Keep track of what window the mouse is *really* over. Any events
+ * that we generate have a special send_event value, which is detected
+ * below and used to ignore the event for purposes of setting
+ * serverWinPtr.
*/
if (eventPtr->xcrossing.send_event != GENERATED_EVENT_MAGIC) {
@@ -748,13 +734,13 @@ TkPointerEvent(eventPtr, winPtr)
}
/*
- * When a grab is active, X continues to report enter and leave
- * events for windows outside the tree of the grab window:
- * 1. Detect these events and ignore them except for
- * windows above the grab window.
- * 2. Allow Enter and Leave events to pass through the
- * windows above the grab window, but never let them
- * end up with the pointer *in* one of those windows.
+ * When a grab is active, X continues to report enter and leave events
+ * for windows outside the tree of the grab window:
+ * 1. Detect these events and ignore them except for windows above the
+ * grab window.
+ * 2. Allow Enter and Leave events to pass through the windows above
+ * the grab window, but never let them end up with the pointer *in*
+ * one of those windows.
*/
if (dispPtr->grabWinPtr != NULL) {
@@ -763,22 +749,21 @@ TkPointerEvent(eventPtr, winPtr)
return 0;
}
switch (eventPtr->xcrossing.detail) {
- case NotifyInferior:
- return 0;
- case NotifyAncestor:
- eventPtr->xcrossing.detail = NotifyVirtual;
- break;
- case NotifyNonlinear:
- eventPtr->xcrossing.detail = NotifyNonlinearVirtual;
- break;
+ case NotifyInferior:
+ return 0;
+ case NotifyAncestor:
+ eventPtr->xcrossing.detail = NotifyVirtual;
+ break;
+ case NotifyNonlinear:
+ eventPtr->xcrossing.detail = NotifyNonlinearVirtual;
+ break;
}
}
/*
- * Make buttons have the same grab-like behavior inside a grab
- * as they do outside a grab: do this by ignoring enter and
- * leave events except for the window in which the button was
- * pressed.
+ * Make buttons have the same grab-like behavior inside a grab as
+ * they do outside a grab: do this by ignoring enter and leave
+ * events except for the window in which the button was pressed.
*/
if ((dispPtr->buttonWinPtr != NULL)
@@ -796,12 +781,12 @@ TkPointerEvent(eventPtr, winPtr)
if (eventPtr->type == MotionNotify) {
/*
* When grabs are active, X reports motion events relative to the
- * window under the pointer. Instead, it should report the events
+ * window under the pointer. Instead, it should report the events
* relative to the window the button went down in, if there is a
- * button down. Otherwise, if the pointer window is outside the
- * subtree of the grab window, the events should be reported
- * relative to the grab window. Otherwise, the event should be
- * reported to the pointer window.
+ * button down. Otherwise, if the pointer window is outside the
+ * subtree of the grab window, the events should be reported relative
+ * to the grab window. Otherwise, the event should be reported to the
+ * pointer window.
*/
winPtr2 = winPtr;
@@ -820,32 +805,32 @@ TkPointerEvent(eventPtr, winPtr)
/*
* Process ButtonPress and ButtonRelease events:
- * 1. Keep track of whether a button is down and what window it
- * went down in.
- * 2. If the first button goes down outside the grab tree, pretend
- * it went down in the grab window. Note: it's important to
- * redirect events to the grab window like this in order to make
- * things like menus work, where button presses outside the
- * grabbed menu need to be seen. An application can always
- * ignore the events if they occur outside its window.
- * 3. If a button press or release occurs outside the window where
- * the first button was pressed, retarget the event so it's reported
- * to the window where the first button was pressed.
- * 4. If the last button is released in a window different than where
- * the first button was pressed, generate Enter/Leave events to
- * move the mouse from the button window to its current window.
- * 5. If the grab is set at a time when a button is already down, or
- * if the window where the button was pressed was deleted, then
- * dispPtr->buttonWinPtr will stay NULL. Just forget about the
- * auto-grab for the button press; events will go to whatever
- * window contains the pointer. If this window isn't in the grab
- * tree then redirect events to the grab window.
- * 6. When a button is pressed during a local grab, the X server sets
- * a grab of its own, since it doesn't even know about our local
- * grab. This causes enter and leave events no longer to be
- * generated in the same way as for global grabs. To eliminate this
- * problem, set a temporary global grab when the first button goes
- * down and release it when the last button comes up.
+ * 1. Keep track of whether a button is down and what window it went down
+ * in.
+ * 2. If the first button goes down outside the grab tree, pretend it went
+ * down in the grab window. Note: it's important to redirect events to
+ * the grab window like this in order to make things like menus work,
+ * where button presses outside the grabbed menu need to be seen. An
+ * application can always ignore the events if they occur outside its
+ * window.
+ * 3. If a button press or release occurs outside the window where the
+ * first button was pressed, retarget the event so it's reported to the
+ * window where the first button was pressed.
+ * 4. If the last button is released in a window different than where the
+ * first button was pressed, generate Enter/Leave events to move the
+ * mouse from the button window to its current window.
+ * 5. If the grab is set at a time when a button is already down, or if
+ * the window where the button was pressed was deleted, then
+ * dispPtr->buttonWinPtr will stay NULL. Just forget about the
+ * auto-grab for the button press; events will go to whatever window
+ * contains the pointer. If this window isn't in the grab tree then
+ * redirect events to the grab window.
+ * 6. When a button is pressed during a local grab, the X server sets a
+ * grab of its own, since it doesn't even know about our local grab.
+ * This causes enter and leave events no longer to be generated in the
+ * same way as for global grabs. To eliminate this problem, set a
+ * temporary global grab when the first button goes down and release it
+ * when the last button comes up.
*/
if ((eventPtr->type == ButtonPress) || (eventPtr->type == ButtonRelease)) {
@@ -906,12 +891,12 @@ TkPointerEvent(eventPtr, winPtr)
* TkChangeEventWindow --
*
* Given an event and a new window to which the event should be
- * retargeted, modify fields of the event so that the event is
- * properly retargeted to the new window.
+ * retargeted, modify fields of the event so that the event is properly
+ * retargeted to the new window.
*
* Results:
- * The following fields of eventPtr are modified: window,
- * subwindow, x, y, same_screen.
+ * The following fields of eventPtr are modified: window, subwindow, x,
+ * y, same_screen.
*
* Side effects:
* None.
@@ -920,12 +905,12 @@ TkPointerEvent(eventPtr, winPtr)
*/
void
-TkChangeEventWindow(eventPtr, winPtr)
- register XEvent *eventPtr; /* Event to retarget. Must have
- * type ButtonPress, ButtonRelease, KeyPress,
- * KeyRelease, MotionNotify, EnterNotify,
- * or LeaveNotify. */
- TkWindow *winPtr; /* New target window for event. */
+TkChangeEventWindow(
+ register XEvent *eventPtr, /* Event to retarget. Must have type
+ * ButtonPress, ButtonRelease, KeyPress,
+ * KeyRelease, MotionNotify, EnterNotify, or
+ * LeaveNotify. */
+ TkWindow *winPtr) /* New target window for event. */
{
int x, y, sameScreen, bd;
register TkWindow *childPtr;
@@ -970,44 +955,44 @@ TkChangeEventWindow(eventPtr, winPtr)
*
* TkInOutEvents --
*
- * This procedure synthesizes EnterNotify and LeaveNotify events
- * to correctly transfer the pointer from one window to another.
- * It can also be used to generate FocusIn and FocusOut events
- * to move the input focus.
+ * This function synthesizes EnterNotify and LeaveNotify events to
+ * correctly transfer the pointer from one window to another. It can also
+ * be used to generate FocusIn and FocusOut events to move the input
+ * focus.
*
* Results:
* None.
*
* Side effects:
- * Synthesized events may be pushed back onto the event queue.
- * The event pointed to by eventPtr is modified.
+ * Synthesized events may be pushed back onto the event queue. The event
+ * pointed to by eventPtr is modified.
*
*----------------------------------------------------------------------
*/
void
-TkInOutEvents(eventPtr, sourcePtr, destPtr, leaveType, enterType, position)
- XEvent *eventPtr; /* A template X event. Must have all fields
+TkInOutEvents(
+ XEvent *eventPtr, /* A template X event. Must have all fields
* properly set except for type, window,
- * subwindow, x, y, detail, and same_screen
+ * subwindow, x, y, detail, and same_screen.
* (Not all of these fields are valid for
- * FocusIn/FocusOut events; x_root and y_root
+ * FocusIn/FocusOut events; x_root and y_root
* must be valid for Enter/Leave events, even
* though x and y needn't be valid). */
- TkWindow *sourcePtr; /* Window that used to have the pointer or
+ TkWindow *sourcePtr, /* Window that used to have the pointer or
* focus (NULL means it was not in a window
* managed by this process). */
- TkWindow *destPtr; /* Window that is to end up with the pointer
+ TkWindow *destPtr, /* Window that is to end up with the pointer
* or focus (NULL means it's not one managed
* by this process). */
- int leaveType; /* Type of events to generate for windows
- * being left (LeaveNotify or FocusOut). 0
+ int leaveType, /* Type of events to generate for windows
+ * being left (LeaveNotify or FocusOut). 0
* means don't generate leave events. */
- int enterType; /* Type of events to generate for windows
- * being entered (EnterNotify or FocusIn). 0
+ int enterType, /* Type of events to generate for windows
+ * being entered (EnterNotify or FocusIn). 0
* means don't generate enter events. */
- Tcl_QueuePosition position; /* Position at which events are added to
- * the system event queue. */
+ Tcl_QueuePosition position) /* Position at which events are added to the
+ * system event queue. */
{
register TkWindow *winPtr;
int upLevels, downLevels, i, j, focus;
@@ -1015,17 +1000,15 @@ TkInOutEvents(eventPtr, sourcePtr, destPtr, leaveType, enterType, position)
/*
* There are four possible cases to deal with:
*
- * 1. SourcePtr and destPtr are the same. There's nothing to do in
- * this case.
- * 2. SourcePtr is an ancestor of destPtr in the same top-level
- * window. Must generate events down the window tree from source
- * to dest.
- * 3. DestPtr is an ancestor of sourcePtr in the same top-level
- * window. Must generate events up the window tree from sourcePtr
- * to destPtr.
- * 4. All other cases. Must first generate events up the window tree
- * from sourcePtr to its top-level, then down from destPtr's
- * top-level to destPtr. This form is called "non-linear."
+ * 1. SourcePtr and destPtr are the same. There's nothing to do in this
+ * case.
+ * 2. SourcePtr is an ancestor of destPtr in the same top-level window.
+ * Must generate events down the window tree from source to dest.
+ * 3. DestPtr is an ancestor of sourcePtr in the same top-level window.
+ * Must generate events up the window tree from sourcePtr to destPtr.
+ * 4. All other cases. Must first generate events up the window tree from
+ * sourcePtr to its top-level, then down from destPtr's top-level to
+ * destPtr. This form is called "non-linear."
*
* The call to FindCommonAncestor separates these four cases and decides
* how many levels up and down events have to be generated for.
@@ -1045,7 +1028,6 @@ TkInOutEvents(eventPtr, sourcePtr, destPtr, leaveType, enterType, position)
* Generate enter/leave events and add them to the grab event queue.
*/
-
#define QUEUE(w, t, d) \
if (w->window != None) { \
eventPtr->type = t; \
@@ -1060,7 +1042,6 @@ TkInOutEvents(eventPtr, sourcePtr, destPtr, leaveType, enterType, position)
}
if (downLevels == 0) {
-
/*
* SourcePtr is an inferior of destPtr.
*/
@@ -1076,7 +1057,6 @@ TkInOutEvents(eventPtr, sourcePtr, destPtr, leaveType, enterType, position)
QUEUE(destPtr, enterType, NotifyInferior);
}
} else if (upLevels == 0) {
-
/*
* DestPtr is an inferior of sourcePtr.
*/
@@ -1088,6 +1068,7 @@ TkInOutEvents(eventPtr, sourcePtr, destPtr, leaveType, enterType, position)
for (i = downLevels-1; i > 0; i--) {
for (winPtr = destPtr->parentPtr, j = 1; j < i;
winPtr = winPtr->parentPtr, j++) {
+ /* empty */
}
QUEUE(winPtr, enterType, NotifyVirtual);
}
@@ -1096,9 +1077,8 @@ TkInOutEvents(eventPtr, sourcePtr, destPtr, leaveType, enterType, position)
}
}
} else {
-
/*
- * Non-linear: neither window is an inferior of the other.
+ * Non-linear: neither window is an inferior of the other.
*/
if (leaveType != 0) {
@@ -1127,11 +1107,11 @@ TkInOutEvents(eventPtr, sourcePtr, destPtr, leaveType, enterType, position)
*
* MovePointer2 --
*
- * This procedure synthesizes EnterNotify and LeaveNotify events
- * to correctly transfer the pointer from one window to another.
- * It is different from TkInOutEvents in that no template X event
- * needs to be supplied; this procedure generates the template
- * event and calls TkInOutEvents.
+ * This function synthesizes EnterNotify and LeaveNotify events to
+ * correctly transfer the pointer from one window to another. It is
+ * different from TkInOutEvents in that no template X event needs to be
+ * supplied; this function generates the template event and calls
+ * TkInOutEvents.
*
* Results:
* None.
@@ -1143,20 +1123,20 @@ TkInOutEvents(eventPtr, sourcePtr, destPtr, leaveType, enterType, position)
*/
static void
-MovePointer2(sourcePtr, destPtr, mode, leaveEvents, enterEvents)
- TkWindow *sourcePtr; /* Window currently containing pointer (NULL
+MovePointer2(
+ TkWindow *sourcePtr, /* Window currently containing pointer (NULL
* means it's not one managed by this
* process). */
- TkWindow *destPtr; /* Window that is to end up containing the
- * pointer (NULL means it's not one managed
- * by this process). */
- int mode; /* Mode for enter/leave events, such as
+ TkWindow *destPtr, /* Window that is to end up containing the
+ * pointer (NULL means it's not one managed by
+ * this process). */
+ int mode, /* Mode for enter/leave events, such as
* NotifyNormal or NotifyUngrab. */
- int leaveEvents; /* Non-zero means generate leave events for the
- * windows being left. Zero means don't
+ int leaveEvents, /* Non-zero means generate leave events for
+ * the windows being left. Zero means don't
* generate leave events. */
- int enterEvents; /* Non-zero means generate enter events for the
- * windows being entered. Zero means don't
+ int enterEvents) /* Non-zero means generate enter events for
+ * the windows being entered. Zero means don't
* generate enter events. */
{
XEvent event;
@@ -1172,12 +1152,10 @@ MovePointer2(sourcePtr, destPtr, mode, leaveEvents, enterEvents)
}
}
- event.xcrossing.serial = LastKnownRequestProcessed(
- winPtr->display);
+ event.xcrossing.serial = LastKnownRequestProcessed(winPtr->display);
event.xcrossing.send_event = GENERATED_EVENT_MAGIC;
event.xcrossing.display = winPtr->display;
- event.xcrossing.root = RootWindow(winPtr->display,
- winPtr->screenNum);
+ event.xcrossing.root = RootWindow(winPtr->display, winPtr->screenNum);
event.xcrossing.time = TkCurrentTime(winPtr->dispPtr);
XQueryPointer(winPtr->display, winPtr->window, &dummy1, &dummy2,
&event.xcrossing.x_root, &event.xcrossing.y_root,
@@ -1193,30 +1171,30 @@ MovePointer2(sourcePtr, destPtr, mode, leaveEvents, enterEvents)
*
* TkGrabDeadWindow --
*
- * This procedure is invoked whenever a window is deleted, so that
+ * This function is invoked whenever a window is deleted, so that
* grab-related cleanup can be performed.
*
* Results:
* None.
*
* Side effects:
- * Various cleanups happen, such as generating events to move the
- * pointer back to its "natural" window as if an ungrab had been
- * done. See the code.
+ * Various cleanups happen, such as generating events to move the pointer
+ * back to its "natural" window as if an ungrab had been done. See the
+ * code.
*
*----------------------------------------------------------------------
*/
void
-TkGrabDeadWindow(winPtr)
- register TkWindow *winPtr; /* Window that is in the process
- * of being deleted. */
+TkGrabDeadWindow(
+ register TkWindow *winPtr) /* Window that is in the process of being
+ * deleted. */
{
TkDisplay *dispPtr = winPtr->dispPtr;
if (dispPtr->eventualGrabWinPtr == winPtr) {
/*
- * Grab window was deleted. Release the grab.
+ * Grab window was deleted. Release the grab.
*/
Tk_Ungrab((Tk_Window) dispPtr->eventualGrabWinPtr);
@@ -1240,26 +1218,25 @@ TkGrabDeadWindow(winPtr)
*
* EatGrabEvents --
*
- * This procedure is called to eliminate any Enter, Leave,
- * FocusIn, or FocusOut events in the event queue for a
- * display that have mode NotifyGrab or NotifyUngrab and
- * have a serial number no less than a given value and are not
- * generated by the grab module.
+ * This function is called to eliminate any Enter, Leave, FocusIn, or
+ * FocusOut events in the event queue for a display that have mode
+ * NotifyGrab or NotifyUngrab and have a serial number no less than a
+ * given value and are not generated by the grab module.
*
* Results:
* None.
*
* Side effects:
- * DispPtr's display gets sync-ed, and some of the events get
- * removed from the Tk event queue.
+ * DispPtr's display gets sync-ed, and some of the events get removed
+ * from the Tk event queue.
*
*----------------------------------------------------------------------
*/
static void
-EatGrabEvents(dispPtr, serial)
- TkDisplay *dispPtr; /* Display from which to consume events. */
- unsigned int serial; /* Only discard events that have a serial
+EatGrabEvents(
+ TkDisplay *dispPtr, /* Display from which to consume events. */
+ unsigned int serial) /* Only discard events that have a serial
* number at least this great. */
{
Tk_RestrictProc *oldProc;
@@ -1280,10 +1257,10 @@ EatGrabEvents(dispPtr, serial)
*
* GrabRestrictProc --
*
- * A Tk_RestrictProc used by EatGrabEvents to eliminate any
- * Enter, Leave, FocusIn, or FocusOut events in the event queue
- * for a display that has mode NotifyGrab or NotifyUngrab and
- * have a serial number no less than a given value.
+ * A Tk_RestrictProc used by EatGrabEvents to eliminate any Enter, Leave,
+ * FocusIn, or FocusOut events in the event queue for a display that has
+ * mode NotifyGrab or NotifyUngrab and have a serial number no less than
+ * a given value.
*
* Results:
* Returns either TK_DISCARD_EVENT or TK_DEFER_EVENT.
@@ -1295,17 +1272,17 @@ EatGrabEvents(dispPtr, serial)
*/
static Tk_RestrictAction
-GrabRestrictProc(arg, eventPtr)
- ClientData arg;
- XEvent *eventPtr;
+GrabRestrictProc(
+ ClientData arg,
+ XEvent *eventPtr)
{
GrabInfo *info = (GrabInfo *) arg;
int mode, diff;
/*
- * The diff caculation is trickier than it may seem. Don't forget
- * that serial numbers can wrap around, so can't compare the two
- * serial numbers directly.
+ * The diff caculation is trickier than it may seem. Don't forget that
+ * serial numbers can wrap around, so can't compare the two serial numbers
+ * directly.
*/
diff = eventPtr->xany.serial - info->serial;
@@ -1331,29 +1308,28 @@ GrabRestrictProc(arg, eventPtr)
*
* QueueGrabWindowChange --
*
- * This procedure queues a special event in the Tcl event queue,
- * which will cause the "grabWinPtr" field for the display to get
- * modified when the event is processed. This is needed to make
- * sure that the grab window changes at the proper time relative
- * to grab-related enter and leave events that are also in the
- * queue. In particular, this approach works even when multiple
- * grabs and ungrabs happen back-to-back.
+ * This function queues a special event in the Tcl event queue, which
+ * will cause the "grabWinPtr" field for the display to get modified when
+ * the event is processed. This is needed to make sure that the grab
+ * window changes at the proper time relative to grab-related enter and
+ * leave events that are also in the queue. In particular, this approach
+ * works even when multiple grabs and ungrabs happen back-to-back.
*
* Results:
* None.
*
* Side effects:
- * DispPtr->grabWinPtr will be modified later (by GrabWinEventProc)
- * when the event is removed from the grab event queue.
+ * DispPtr->grabWinPtr will be modified later (by GrabWinEventProc) when
+ * the event is removed from the grab event queue.
*
*----------------------------------------------------------------------
*/
static void
-QueueGrabWindowChange(dispPtr, grabWinPtr)
- TkDisplay *dispPtr; /* Display on which to change the grab
+QueueGrabWindowChange(
+ TkDisplay *dispPtr, /* Display on which to change the grab
* window. */
- TkWindow *grabWinPtr; /* Window that is to become the new grab
+ TkWindow *grabWinPtr) /* Window that is to become the new grab
* window (may be NULL). */
{
NewGrabWinEvent *grabEvPtr;
@@ -1375,25 +1351,25 @@ QueueGrabWindowChange(dispPtr, grabWinPtr)
*
* GrabWinEventProc --
*
- * This procedure is invoked as a handler for Tcl_Events of type
- * NewGrabWinEvent. It updates the current grab window field in
- * a display.
+ * This function is invoked as a handler for Tcl_Events of type
+ * NewGrabWinEvent. It updates the current grab window field in a
+ * display.
*
* Results:
- * Returns 1 if the event was processed, 0 if it should be deferred
- * for processing later.
+ * Returns 1 if the event was processed, 0 if it should be deferred for
+ * processing later.
*
* Side effects:
- * The grabWinPtr field is modified in the display associated with
- * the event.
+ * The grabWinPtr field is modified in the display associated with the
+ * event.
*
*----------------------------------------------------------------------
*/
static int
-GrabWinEventProc(evPtr, flags)
- Tcl_Event *evPtr; /* Event of type NewGrabWinEvent. */
- int flags; /* Flags argument to Tk_DoOneEvent: indicates
+GrabWinEventProc(
+ Tcl_Event *evPtr, /* Event of type NewGrabWinEvent. */
+ int flags) /* Flags argument to Tk_DoOneEvent: indicates
* what kinds of events are being processed
* right now. */
{
@@ -1409,19 +1385,19 @@ GrabWinEventProc(evPtr, flags)
*
* FindCommonAncestor --
*
- * Given two windows, this procedure finds their least common
- * ancestor and also computes how many levels up this ancestor
- * is from each of the original windows.
+ * Given two windows, this function finds their least common ancestor and
+ * also computes how many levels up this ancestor is from each of the
+ * original windows.
*
* Results:
- * If the windows are in different applications or top-level
- * windows, then NULL is returned and *countPtr1 and *countPtr2
- * are set to the depths of the two windows in their respective
- * top-level windows (1 means the window is a top-level, 2 means
- * its parent is a top-level, and so on). Otherwise, the return
- * value is a pointer to the common ancestor and the counts are
- * set to the distance of winPtr1 and winPtr2 from this ancestor
- * (1 means they're children, 2 means grand-children, etc.).
+ * If the windows are in different applications or top-level windows,
+ * then NULL is returned and *countPtr1 and *countPtr2 are set to the
+ * depths of the two windows in their respective top-level windows (1
+ * means the window is a top-level, 2 means its parent is a top-level,
+ * and so on). Otherwise, the return value is a pointer to the common
+ * ancestor and the counts are set to the distance of winPtr1 and winPtr2
+ * from this ancestor (1 means they're children, 2 means grand-children,
+ * etc.).
*
* Side effects:
* None.
@@ -1430,12 +1406,12 @@ GrabWinEventProc(evPtr, flags)
*/
static TkWindow *
-FindCommonAncestor(winPtr1, winPtr2, countPtr1, countPtr2)
- TkWindow *winPtr1; /* First window. May be NULL. */
- TkWindow *winPtr2; /* Second window. May be NULL. */
- int *countPtr1; /* Store nesting level of winPtr1 within
+FindCommonAncestor(
+ TkWindow *winPtr1, /* First window. May be NULL. */
+ TkWindow *winPtr2, /* Second window. May be NULL. */
+ int *countPtr1, /* Store nesting level of winPtr1 within
* common ancestor here. */
- int *countPtr2; /* Store nesting level of winPtr2 within
+ int *countPtr2) /* Store nesting level of winPtr2 within
* common ancestor here. */
{
register TkWindow *winPtr;
@@ -1456,8 +1432,8 @@ FindCommonAncestor(winPtr1, winPtr2, countPtr1, countPtr2)
}
/*
- * Search upwards from winPtr2 until an ancestor of winPtr1 is
- * found or a top-level window is reached.
+ * Search upwards from winPtr2 until an ancestor of winPtr1 is found or a
+ * top-level window is reached.
*/
winPtr = winPtr2;
@@ -1510,15 +1486,13 @@ FindCommonAncestor(winPtr1, winPtr2, countPtr1, countPtr2)
*
* TkPositionInTree --
*
- * Compute where the given window is relative to a particular
- * subtree of the window hierarchy.
+ * Compute where the given window is relative to a particular subtree of
+ * the window hierarchy.
*
* Results:
- *
- * Returns TK_GRAB_IN_TREE if the window is contained in the
- * subtree. Returns TK_GRAB_ANCESTOR if the window is an
- * ancestor of the subtree, in the same toplevel. Otherwise
- * it returns TK_GRAB_EXCLUDED.
+ * Returns TK_GRAB_IN_TREE if the window is contained in the subtree.
+ * Returns TK_GRAB_ANCESTOR if the window is an ancestor of the subtree,
+ * in the same toplevel. Otherwise it returns TK_GRAB_EXCLUDED.
*
* Side effects:
* None.
@@ -1527,9 +1501,9 @@ FindCommonAncestor(winPtr1, winPtr2, countPtr1, countPtr2)
*/
int
-TkPositionInTree(winPtr, treePtr)
- TkWindow *winPtr; /* Window to be checked. */
- TkWindow *treePtr; /* Root of tree to compare against. */
+TkPositionInTree(
+ TkWindow *winPtr, /* Window to be checked. */
+ TkWindow *treePtr) /* Root of tree to compare against. */
{
TkWindow *winPtr2;
@@ -1556,21 +1530,20 @@ TkPositionInTree(winPtr, treePtr)
*
* TkGrabState --
*
- * Given a window, this procedure returns a value that indicates
- * the grab state of the application relative to the window.
+ * Given a window, this function returns a value that indicates the grab
+ * state of the application relative to the window.
*
* Results:
* The return value is one of three things:
* TK_GRAB_NONE - no grab is in effect.
- * TK_GRAB_IN_TREE - there is a grab in effect, and winPtr
- * is in the grabbed subtree.
- * TK_GRAB_ANCESTOR - there is a grab in effect; winPtr is
- * an ancestor of the grabbed window, in
- * the same toplevel.
- * TK_GRAB_EXCLUDED - there is a grab in effect; winPtr is
- * outside the tree of the grab and is not
- * an ancestor of the grabbed window in the
- * same toplevel.
+ * TK_GRAB_IN_TREE - there is a grab in effect, and winPtr is in
+ * the grabbed subtree.
+ * TK_GRAB_ANCESTOR - there is a grab in effect; winPtr is an
+ * ancestor of the grabbed window, in the same
+ * toplevel.
+ * TK_GRAB_EXCLUDED - there is a grab in effect; winPtr is outside
+ * the tree of the grab and is not an ancestor of
+ * the grabbed window in the same toplevel.
*
* Side effects:
* None.
@@ -1579,8 +1552,8 @@ TkPositionInTree(winPtr, treePtr)
*/
int
-TkGrabState(winPtr)
- TkWindow *winPtr; /* Window for which grab information is
+TkGrabState(
+ TkWindow *winPtr) /* Window for which grab information is
* needed. */
{
TkWindow *grabWinPtr = winPtr->dispPtr->grabWinPtr;
@@ -1595,3 +1568,11 @@ TkGrabState(winPtr)
return TkPositionInTree(winPtr, grabWinPtr);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkGrid.c b/generic/tkGrid.c
index 008e321..c6a00d5 100644
--- a/generic/tkGrid.c
+++ b/generic/tkGrid.c
@@ -5,8 +5,8 @@
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
@@ -19,26 +19,22 @@
# undef MAX
#endif
#define MAX(x,y) ((x) > (y) ? (x) : (y))
-#ifdef MIN
-# undef MIN
-#endif
-#define MIN(x,y) ((x) > (y) ? (y) : (x))
-#define COLUMN (1) /* working on column offsets */
-#define ROW (2) /* working on row offsets */
+#define COLUMN (1) /* Working on column offsets. */
+#define ROW (2) /* Working on row offsets. */
-#define CHECK_ONLY (1) /* check max slot constraint */
-#define CHECK_SPACE (2) /* alloc more space, don't change max */
+#define CHECK_ONLY (1) /* Check max slot constraint. */
+#define CHECK_SPACE (2) /* Alloc more space, don't change max. */
/*
- * Pre-allocate enough row and column slots for "typical" sized tables
- * this value should be chosen so by the time the extra malloc's are
- * required, the layout calculations overwehlm them. [A "slot" contains
- * information for either a row or column, depending upon the context.]
+ * Pre-allocate enough row and column slots for "typical" sized tables this
+ * value should be chosen so by the time the extra malloc's are required, the
+ * layout calculations overwehlm them. [A "slot" contains information for
+ * either a row or column, depending upon the context.]
*/
-#define TYPICAL_SIZE 25 /* (arbitrary guess) */
-#define PREALLOC 10 /* extra slots to allocate */
+#define TYPICAL_SIZE 25 /* (Arbitrary guess) */
+#define PREALLOC 10 /* Extra slots to allocate. */
/*
* Pre-allocate room for uniform groups during layout.
@@ -46,10 +42,10 @@
#define UNIFORM_PREALLOC 10
-/*
- * Data structures are allocated dynamically to support arbitrary sized tables.
- * However, the space is proportional to the highest numbered slot with
- * some non-default property. This limit is used to head off mistakes and
+/*
+ * Data structures are allocated dynamically to support arbitrary sized
+ * tables. However, the space is proportional to the highest numbered slot
+ * with some non-default property. This limit is used to head off mistakes and
* denial of service attacks by limiting the amount of storage required.
*/
@@ -64,63 +60,67 @@
#define REL_VERT '^' /* Extend widget from row above. */
/*
- * Structure to hold information for grid masters. A slot is either
- * a row or column.
+ * Default value for 'grid anchor'.
+ */
+
+#define GRID_DEFAULT_ANCHOR TK_ANCHOR_NW
+
+/*
+ * Structure to hold information for grid masters. A slot is either a row or
+ * column.
*/
typedef struct SlotInfo {
- int minSize; /* The minimum size of this slot (in pixels).
+ int minSize; /* The minimum size of this slot (in pixels).
* It is set via the rowconfigure or
* columnconfigure commands. */
- int weight; /* The resize weight of this slot. (0) means
+ int weight; /* The resize weight of this slot. (0) means
* this slot doesn't resize. Extra space in
* the layout is given distributed among slots
* inproportion to their weights. */
- int pad; /* Extra padding, in pixels, required for
- * this slot. This amount is "added" to the
- * largest slave in the slot. */
- Tk_Uid uniform; /* Value of -uniform option. It is used to
+ int pad; /* Extra padding, in pixels, required for this
+ * slot. This amount is "added" to the largest
+ * slave in the slot. */
+ Tk_Uid uniform; /* Value of -uniform option. It is used to
* group slots that should have the same
* size. */
- int offset; /* This is a cached value used for
- * introspection. It is the pixel
- * offset of the right or bottom edge
- * of this slot from the beginning of the
- * layout. */
- int temp; /* This is a temporary value used for
- * calculating adjusted weights when
- * shrinking the layout below its
- * nominal size. */
+ int offset; /* This is a cached value used for
+ * introspection. It is the pixel offset of
+ * the right or bottom edge of this slot from
+ * the beginning of the layout. */
+ int temp; /* This is a temporary value used for
+ * calculating adjusted weights when shrinking
+ * the layout below its nominal size. */
} SlotInfo;
/*
- * Structure to hold information during layout calculations. There
- * is one of these for each slot, an array for each of the rows or columns.
+ * Structure to hold information during layout calculations. There is one of
+ * these for each slot, an array for each of the rows or columns.
*/
typedef struct GridLayout {
- struct Gridder *binNextPtr; /* The next slave window in this bin.
- * Each bin contains a list of all
- * slaves whose spans are >1 and whose
- * right edges fall in this slot. */
- int minSize; /* Minimum size needed for this slot,
- * in pixels. This is the space required
- * to hold any slaves contained entirely
- * in this slot, adjusted for any slot
- * constrants, such as size or padding. */
+ struct Gridder *binNextPtr; /* The next slave window in this bin. Each bin
+ * contains a list of all slaves whose spans
+ * are >1 and whose right edges fall in this
+ * slot. */
+ int minSize; /* Minimum size needed for this slot, in
+ * pixels. This is the space required to hold
+ * any slaves contained entirely in this slot,
+ * adjusted for any slot constrants, such as
+ * size or padding. */
int pad; /* Padding needed for this slot */
int weight; /* Slot weight, controls resizing. */
- Tk_Uid uniform; /* Value of -uniform option. It is used to
+ Tk_Uid uniform; /* Value of -uniform option. It is used to
* group slots that should have the same
* size. */
- int minOffset; /* The minimum offset, in pixels, from
- * the beginning of the layout to the
- * right/bottom edge of the slot calculated
- * from top/left to bottom/right. */
- int maxOffset; /* The maximum offset, in pixels, from
- * the beginning of the layout to the
- * right-or-bottom edge of the slot calculated
- * from bottom-or-right to top-or-left. */
+ int minOffset; /* The minimum offset, in pixels, from the
+ * beginning of the layout to the bottom/right
+ * edge of the slot calculated from top/left
+ * to bottom/right. */
+ int maxOffset; /* The maximum offset, in pixels, from the
+ * beginning of the layout to the bottom/right
+ * edge of the slot calculated from
+ * bottom/right to top/left. */
} GridLayout;
/*
@@ -136,81 +136,84 @@ typedef struct {
* column constraints. */
int rowEnd; /* The last row occupied by any slave. */
int rowMax; /* The number of rows with constraints. */
- int rowSpace; /* The number of slots currently allocated
- * for row constraints. */
+ int rowSpace; /* The number of slots currently allocated for
+ * row constraints. */
int startX; /* Pixel offset of this layout within its
- * parent. */
+ * master. */
int startY; /* Pixel offset of this layout within its
- * parent. */
+ * master. */
+ Tk_Anchor anchor; /* Value of anchor option: specifies where a
+ * grid without weight should be placed. */
} GridMaster;
/*
- * For each window that the grid cares about (either because
- * the window is managed by the grid or because the window
- * has slaves that are managed by the grid), there is a
- * structure of the following type:
+ * For each window that the grid cares about (either because the window is
+ * managed by the grid or because the window has slaves that are managed by
+ * the grid), there is a structure of the following type:
*/
typedef struct Gridder {
- Tk_Window tkwin; /* Tk token for window. NULL means that
- * the window has been deleted, but the
- * gridder hasn't had a chance to clean up
- * yet because the structure is still in
- * use. */
- struct Gridder *masterPtr; /* Master window within which this window
- * is managed (NULL means this window
- * isn't managed by the gridder). */
- struct Gridder *nextPtr; /* Next window managed within same
- * parent. List order doesn't matter. */
- struct Gridder *slavePtr; /* First in list of slaves managed
- * inside this window (NULL means
- * no grid slaves). */
+ Tk_Window tkwin; /* Tk token for window. NULL means that the
+ * window has been deleted, but the gridder
+ * hasn't had a chance to clean up yet because
+ * the structure is still in use. */
+ struct Gridder *masterPtr; /* Master window within which this window is
+ * managed (NULL means this window isn't
+ * managed by the gridder). */
+ struct Gridder *nextPtr; /* Next window managed within same master.
+ * List order doesn't matter. */
+ struct Gridder *slavePtr; /* First in list of slaves managed inside this
+ * window (NULL means no grid slaves). */
GridMaster *masterDataPtr; /* Additional data for geometry master. */
- int column, row; /* Location in the grid (starting
- * from zero). */
+ Tcl_Obj *in; /* Store master name when removed. */
+ int column, row; /* Location in the grid (starting from
+ * zero). */
int numCols, numRows; /* Number of columns or rows this slave spans.
* Should be at least 1. */
int padX, padY; /* Total additional pixels to leave around the
- * window. Some is of this space is on each
- * side. This is space *outside* the window:
+ * window. Some is of this space is on each
+ * side. This is space *outside* the window:
* we'll allocate extra space in frame but
* won't enlarge window). */
- int padLeft, padTop; /* The part of padX or padY to use on the
- * left or top of the widget, respectively.
- * By default, this is half of padX or padY. */
+ int padLeft, padTop; /* The part of padX or padY to use on the left
+ * or top of the widget, respectively. By
+ * default, this is half of padX or padY. */
int iPadX, iPadY; /* Total extra pixels to allocate inside the
* window (half this amount will appear on
* each side). */
int sticky; /* which sides of its cavity this window
* sticks to. See below for definitions */
- int doubleBw; /* Twice the window's last known border
- * width. If this changes, the window
- * must be re-arranged within its parent. */
- int *abortPtr; /* If non-NULL, it means that there is a nested
- * call to ArrangeGrid already working on
- * this window. *abortPtr may be set to 1 to
- * abort that nested call. This happens, for
- * example, if tkwin or any of its slaves
+ int doubleBw; /* Twice the window's last known border width.
+ * If this changes, the window must be
+ * re-arranged within its master. */
+ int *abortPtr; /* If non-NULL, it means that there is a
+ * nested call to ArrangeGrid already working
+ * on this window. *abortPtr may be set to 1
+ * to abort that nested call. This happens,
+ * for example, if tkwin or any of its slaves
* is deleted. */
- int flags; /* Miscellaneous flags; see below
- * for definitions. */
+ int flags; /* Miscellaneous flags; see below for
+ * definitions. */
/*
* These fields are used temporarily for layout calculations only.
*/
struct Gridder *binNextPtr; /* Link to next span>1 slave in this bin. */
- int size; /* Nominal size (width or height) in pixels
- * of the slave. This includes the padding. */
+ int size; /* Nominal size (width or height) in pixels of
+ * the slave. This includes the padding. */
} Gridder;
-/* Flag values for "sticky"ness The 16 combinations subsume the packer's
+/*
+ * Flag values for "sticky"ness. The 16 combinations subsume the packer's
* notion of anchor and fill.
*
- * STICK_NORTH This window sticks to the top of its cavity.
- * STICK_EAST This window sticks to the right edge of its cavity.
- * STICK_SOUTH This window sticks to the bottom of its cavity.
- * STICK_WEST This window sticks to the left edge of its cavity.
+ * STICK_NORTH This window sticks to the top of its cavity.
+ * STICK_EAST This window sticks to the right edge of its
+ * cavity.
+ * STICK_SOUTH This window sticks to the bottom of its cavity.
+ * STICK_WEST This window sticks to the left edge of its
+ * cavity.
*/
#define STICK_NORTH 1
@@ -231,14 +234,13 @@ typedef struct UniformGroup {
/*
* Flag values for Grid structures:
*
- * REQUESTED_RELAYOUT: 1 means a Tcl_DoWhenIdle request
- * has already been made to re-arrange
- * all the slaves of this window.
- *
- * DONT_PROPAGATE: 1 means don't set this window's requested
- * size. 0 means if this window is a master
- * then Tk will set its requested size to fit
- * the needs of its slaves.
+ * REQUESTED_RELAYOUT 1 means a Tcl_DoWhenIdle request has already
+ * been made to re-arrange all the slaves of this
+ * window.
+ * DONT_PROPAGATE 1 means don't set this window's requested
+ * size. 0 means if this window is a master then
+ * Tk will set its requested size to fit the
+ * needs of its slaves.
*/
#define REQUESTED_RELAYOUT 1
@@ -248,66 +250,71 @@ typedef struct UniformGroup {
* Prototypes for procedures used only in this file:
*/
-static void AdjustForSticky _ANSI_ARGS_((Gridder *slavePtr, int *xPtr,
- int *yPtr, int *widthPtr, int *heightPtr));
-static int AdjustOffsets _ANSI_ARGS_((int width,
- int elements, SlotInfo *slotPtr));
-static void ArrangeGrid _ANSI_ARGS_((ClientData clientData));
-static int CheckSlotData _ANSI_ARGS_((Gridder *masterPtr, int slot,
- int slotType, int checkOnly));
-static int ConfigureSlaves _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, int objc, Tcl_Obj *CONST objv[]));
-static void DestroyGrid _ANSI_ARGS_((char *memPtr));
-static Gridder *GetGrid _ANSI_ARGS_((Tk_Window tkwin));
-static int GridBboxCommand _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
-static int GridForgetRemoveCommand _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
-static int GridInfoCommand _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
-static int GridLocationCommand _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
-static int GridPropagateCommand _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
-static int GridRowColumnConfigureCommand _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
-static int GridSizeCommand _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
-static int GridSlavesCommand _ANSI_ARGS_((Tk_Window tkwin,
- Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
-static void GridStructureProc _ANSI_ARGS_((
- ClientData clientData, XEvent *eventPtr));
-static void GridLostSlaveProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin));
-static void GridReqProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin));
-static void InitMasterData _ANSI_ARGS_((Gridder *masterPtr));
-static Tcl_Obj *NewPairObj _ANSI_ARGS_((Tcl_Interp*, int, int));
-static Tcl_Obj *NewQuadObj _ANSI_ARGS_((Tcl_Interp*, int, int, int, int));
-static int ResolveConstraints _ANSI_ARGS_((Gridder *gridPtr,
- int rowOrColumn, int maxOffset));
-static void SetGridSize _ANSI_ARGS_((Gridder *gridPtr));
-static int SetSlaveColumn _ANSI_ARGS_((Tcl_Interp *interp,
- Gridder *slavePtr, int column, int numCols));
-static int SetSlaveRow _ANSI_ARGS_((Tcl_Interp *interp,
- Gridder *slavePtr, int row, int numRows));
-static void StickyToString _ANSI_ARGS_((int flags, char *result));
-static int StringToSticky _ANSI_ARGS_((char *string));
-static void Unlink _ANSI_ARGS_((Gridder *gridPtr));
-
-static Tk_GeomMgr gridMgrType = {
+static void AdjustForSticky(Gridder *slavePtr, int *xPtr,
+ int *yPtr, int *widthPtr, int *heightPtr);
+static int AdjustOffsets(int width, int elements,
+ SlotInfo *slotPtr);
+static void ArrangeGrid(ClientData clientData);
+static int CheckSlotData(Gridder *masterPtr, int slot,
+ int slotType, int checkOnly);
+static int ConfigureSlaves(Tcl_Interp *interp, Tk_Window tkwin,
+ int objc, Tcl_Obj *CONST objv[]);
+static void DestroyGrid(char *memPtr);
+static Gridder * GetGrid(Tk_Window tkwin);
+static int GridAnchorCommand(Tk_Window tkwin, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int GridBboxCommand(Tk_Window tkwin, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int GridForgetRemoveCommand(Tk_Window tkwin,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]);
+static int GridInfoCommand(Tk_Window tkwin, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int GridLocationCommand(Tk_Window tkwin,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]);
+static int GridPropagateCommand(Tk_Window tkwin,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]);
+static int GridRowColumnConfigureCommand(Tk_Window tkwin,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]);
+static int GridSizeCommand(Tk_Window tkwin, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int GridSlavesCommand(Tk_Window tkwin, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static void GridStructureProc(ClientData clientData,
+ XEvent *eventPtr);
+static void GridLostSlaveProc(ClientData clientData,
+ Tk_Window tkwin);
+static void GridReqProc(ClientData clientData, Tk_Window tkwin);
+static void InitMasterData(Gridder *masterPtr);
+static Tcl_Obj * NewPairObj(int, int);
+static Tcl_Obj * NewQuadObj(int, int, int, int);
+static int ResolveConstraints(Gridder *gridPtr, int rowOrColumn,
+ int maxOffset);
+static void SetGridSize(Gridder *gridPtr);
+static int SetSlaveColumn(Tcl_Interp *interp, Gridder *slavePtr,
+ int column, int numCols);
+static int SetSlaveRow(Tcl_Interp *interp, Gridder *slavePtr,
+ int row, int numRows);
+static void StickyToString(int flags, char *result);
+static int StringToSticky(char *string);
+static void Unlink(Gridder *gridPtr);
+
+static const Tk_GeomMgr gridMgrType = {
"grid", /* name */
GridReqProc, /* requestProc */
GridLostSlaveProc, /* lostSlaveProc */
};
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* Tk_GridCmd --
*
- * This procedure is invoked to process the "grid" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "grid" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -315,31 +322,32 @@ static Tk_GeomMgr gridMgrType = {
* Side effects:
* See the user documentation.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
int
-Tk_GridObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_GridObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tk_Window tkwin = (Tk_Window) clientData;
static CONST char *optionStrings[] = {
- "bbox", "columnconfigure", "configure", "forget",
- "info", "location", "propagate", "remove",
- "rowconfigure", "size", "slaves", (char *) NULL };
+ "anchor", "bbox", "columnconfigure", "configure",
+ "forget", "info", "location", "propagate", "remove",
+ "rowconfigure", "size", "slaves", NULL
+ };
enum options {
- GRID_BBOX, GRID_COLUMNCONFIGURE, GRID_CONFIGURE, GRID_FORGET,
- GRID_INFO, GRID_LOCATION, GRID_PROPAGATE, GRID_REMOVE,
- GRID_ROWCONFIGURE, GRID_SIZE, GRID_SLAVES };
+ GRID_ANCHOR, GRID_BBOX, GRID_COLUMNCONFIGURE, GRID_CONFIGURE,
+ GRID_FORGET, GRID_INFO, GRID_LOCATION, GRID_PROPAGATE, GRID_REMOVE,
+ GRID_ROWCONFIGURE, GRID_SIZE, GRID_SLAVES
+ };
int index;
-
-
+
if (objc >= 2) {
char *argv1 = Tcl_GetString(objv[1]);
+
if ((argv1[0] == '.') || (argv1[0] == REL_SKIP) ||
(argv1[0] == REL_VERT)) {
return ConfigureSlaves(interp, tkwin, objc-1, objv+1);
@@ -356,22 +364,24 @@ Tk_GridObjCmd(clientData, interp, objc, objv)
}
switch ((enum options) index) {
- case GRID_BBOX:
+ case GRID_ANCHOR:
+ return GridAnchorCommand(tkwin, interp, objc, objv);
+ case GRID_BBOX:
return GridBboxCommand(tkwin, interp, objc, objv);
- case GRID_CONFIGURE:
+ case GRID_CONFIGURE:
return ConfigureSlaves(interp, tkwin, objc-2, objv+2);
- case GRID_FORGET:
- case GRID_REMOVE:
+ case GRID_FORGET:
+ case GRID_REMOVE:
return GridForgetRemoveCommand(tkwin, interp, objc, objv);
- case GRID_INFO:
+ case GRID_INFO:
return GridInfoCommand(tkwin, interp, objc, objv);
- case GRID_LOCATION:
+ case GRID_LOCATION:
return GridLocationCommand(tkwin, interp, objc, objv);
- case GRID_PROPAGATE:
+ case GRID_PROPAGATE:
return GridPropagateCommand(tkwin, interp, objc, objv);
- case GRID_SIZE:
+ case GRID_SIZE:
return GridSizeCommand(tkwin, interp, objc, objv);
- case GRID_SLAVES:
+ case GRID_SLAVES:
return GridSlavesCommand(tkwin, interp, objc, objv);
/*
@@ -383,8 +393,8 @@ Tk_GridObjCmd(clientData, interp, objc, objv)
* grid rowconfigure <master> <index> -option value -option value.
*/
- case GRID_COLUMNCONFIGURE:
- case GRID_ROWCONFIGURE:
+ case GRID_COLUMNCONFIGURE:
+ case GRID_ROWCONFIGURE:
return GridRowColumnConfigureCommand(tkwin, interp, objc, objv);
}
@@ -396,6 +406,75 @@ Tk_GridObjCmd(clientData, interp, objc, objv)
/*
*----------------------------------------------------------------------
*
+ * GridAnchorCommand --
+ *
+ * Implementation of the [grid anchor] subcommand. See the user
+ * documentation for details on what it does.
+ *
+ * Results:
+ * Standard Tcl result.
+ *
+ * Side effects:
+ * May recompute grid geometry.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GridAnchorCommand(
+ Tk_Window tkwin, /* Main window of the application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
+{
+ Tk_Window master;
+ Gridder *masterPtr;
+ GridMaster *gridPtr;
+ Tk_Anchor old;
+
+ if (objc > 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?anchor?");
+ return TCL_ERROR;
+ }
+
+ if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ masterPtr = GetGrid(master);
+
+ if (objc == 3) {
+ gridPtr = masterPtr->masterDataPtr;
+ Tcl_SetResult(interp, (char *) Tk_NameOfAnchor(gridPtr == NULL ?
+ GRID_DEFAULT_ANCHOR : gridPtr->anchor), TCL_VOLATILE);
+ return TCL_OK;
+ }
+
+ InitMasterData(masterPtr);
+ gridPtr = masterPtr->masterDataPtr;
+ old = gridPtr->anchor;
+ if (Tk_GetAnchorFromObj(interp, objv[3], &gridPtr->anchor) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Only request a relayout if the anchor changes.
+ */
+
+ if (old != gridPtr->anchor) {
+ if (masterPtr->abortPtr != NULL) {
+ *masterPtr->abortPtr = 1;
+ }
+ if (!(masterPtr->flags & REQUESTED_RELAYOUT)) {
+ masterPtr->flags |= REQUESTED_RELAYOUT;
+ Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr);
+ }
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* GridBboxCommand --
*
* Implementation of the [grid bbox] subcommand.
@@ -410,11 +489,11 @@ Tk_GridObjCmd(clientData, interp, objc, objv)
*/
static int
-GridBboxCommand(tkwin, interp, objc, objv)
- Tk_Window tkwin; /* Main window of the application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+GridBboxCommand(
+ Tk_Window tkwin, /* Main window of the application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tk_Window master;
Gridder *masterPtr; /* master grid record */
@@ -424,17 +503,17 @@ GridBboxCommand(tkwin, interp, objc, objv)
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 */
-
+
if (objc!=3 && objc != 5 && objc != 7) {
Tcl_WrongNumArgs(interp, 2, objv, "master ?column row ?column row??");
return TCL_ERROR;
}
-
+
if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
return TCL_ERROR;
}
masterPtr = GetGrid(master);
-
+
if (objc >= 5) {
if (Tcl_GetIntFromObj(interp, objv[3], &column) != TCL_OK) {
return TCL_ERROR;
@@ -445,7 +524,7 @@ GridBboxCommand(tkwin, interp, objc, objv)
column2 = column;
row2 = row;
}
-
+
if (objc == 7) {
if (Tcl_GetIntFromObj(interp, objv[5], &column2) != TCL_OK) {
return TCL_ERROR;
@@ -454,65 +533,70 @@ GridBboxCommand(tkwin, interp, objc, objv)
return TCL_ERROR;
}
}
-
+
gridPtr = masterPtr->masterDataPtr;
if (gridPtr == NULL) {
- Tcl_SetObjResult(interp, NewQuadObj(interp, 0, 0, 0, 0));
+ Tcl_SetObjResult(interp, NewQuadObj(0, 0, 0, 0));
return TCL_OK;
}
-
+
SetGridSize(masterPtr);
endX = MAX(gridPtr->columnEnd, gridPtr->columnMax);
endY = MAX(gridPtr->rowEnd, gridPtr->rowMax);
-
+
if ((endX == 0) || (endY == 0)) {
- Tcl_SetObjResult(interp, NewQuadObj(interp, 0, 0, 0, 0));
+ Tcl_SetObjResult(interp, NewQuadObj(0, 0, 0, 0));
return TCL_OK;
}
if (objc == 3) {
- row = column = 0;
+ row = 0;
+ column = 0;
row2 = endY;
column2 = endX;
}
-
+
if (column > column2) {
int temp = column;
- column = column2, column2 = temp;
+
+ column = column2;
+ column2 = temp;
}
if (row > row2) {
int temp = row;
- row = row2, row2 = temp;
+
+ row = row2;
+ row2 = temp;
}
-
+
if (column > 0 && column < endX) {
x = gridPtr->columnPtr[column-1].offset;
- } else if (column > 0) {
+ } else if (column > 0) {
x = gridPtr->columnPtr[endX-1].offset;
}
-
+
if (row > 0 && row < endY) {
y = gridPtr->rowPtr[row-1].offset;
} else if (row > 0) {
y = gridPtr->rowPtr[endY-1].offset;
}
-
+
if (column2 < 0) {
width = 0;
} else if (column2 >= endX) {
width = gridPtr->columnPtr[endX-1].offset - x;
} else {
width = gridPtr->columnPtr[column2].offset - x;
- }
-
+ }
+
if (row2 < 0) {
height = 0;
} else if (row2 >= endY) {
height = gridPtr->rowPtr[endY-1].offset - y;
} else {
height = gridPtr->rowPtr[row2].offset - y;
- }
-
- Tcl_SetObjResult(interp, NewQuadObj(interp,
+ }
+
+ Tcl_SetObjResult(interp, NewQuadObj(
x + gridPtr->startX, y + gridPtr->startY, width, height));
return TCL_OK;
}
@@ -522,8 +606,8 @@ GridBboxCommand(tkwin, interp, objc, objv)
*
* GridForgetRemoveCommand --
*
- * Implementation of the [grid forget]/[grid remove] subcommands.
- * See the user documentation for details on what these do.
+ * Implementation of the [grid forget]/[grid remove] subcommands. See the
+ * user documentation for details on what these do.
*
* Results:
* Standard Tcl result.
@@ -535,18 +619,18 @@ GridBboxCommand(tkwin, interp, objc, objv)
*/
static int
-GridForgetRemoveCommand(tkwin, interp, objc, objv)
- Tk_Window tkwin; /* Main window of the application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+GridForgetRemoveCommand(
+ Tk_Window tkwin, /* Main window of the application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tk_Window slave;
Gridder *slavePtr;
int i;
char *string = Tcl_GetString(objv[1]);
char c = string[0];
-
+
for (i = 2; i < objc; i++) {
if (TkGetWindowFromObj(interp, tkwin, objv[i], &slave) != TCL_OK) {
return TCL_ERROR;
@@ -554,27 +638,48 @@ GridForgetRemoveCommand(tkwin, interp, objc, objv)
slavePtr = GetGrid(slave);
if (slavePtr->masterPtr != NULL) {
-
/*
* For "forget", reset all the settings to their defaults
*/
-
+
if (c == 'f') {
- slavePtr->column = slavePtr->row = -1;
+ slavePtr->column = -1;
+ slavePtr->row = -1;
slavePtr->numCols = 1;
slavePtr->numRows = 1;
- slavePtr->padX = slavePtr->padY = 0;
- slavePtr->padLeft = slavePtr->padTop = 0;
- slavePtr->iPadX = slavePtr->iPadY = 0;
+ slavePtr->padX = 0;
+ slavePtr->padY = 0;
+ slavePtr->padLeft = 0;
+ slavePtr->padTop = 0;
+ slavePtr->iPadX = 0;
+ slavePtr->iPadY = 0;
+ if (slavePtr->in != NULL) {
+ Tcl_DecrRefCount(slavePtr->in);
+ slavePtr->in = NULL;
+ }
slavePtr->doubleBw = 2*Tk_Changes(tkwin)->border_width;
if (slavePtr->flags & REQUESTED_RELAYOUT) {
Tcl_CancelIdleCall(ArrangeGrid, (ClientData) slavePtr);
}
slavePtr->flags = 0;
slavePtr->sticky = 0;
+ } else {
+ /*
+ * When removing, store name of master to be able to
+ * restore it later, even if the master is recreated.
+ */
+
+ if (slavePtr->in != NULL) {
+ Tcl_DecrRefCount(slavePtr->in);
+ slavePtr->in = NULL;
+ }
+ if (slavePtr->masterPtr != NULL) {
+ slavePtr->in = Tcl_NewStringObj(
+ Tk_PathName(slavePtr->masterPtr->tkwin), -1);
+ Tcl_IncrRefCount(slavePtr->in);
+ }
}
- Tk_ManageGeometry(slave, (Tk_GeomMgr *) NULL,
- (ClientData) NULL);
+ Tk_ManageGeometry(slave, NULL, (ClientData) NULL);
if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
Tk_UnmaintainGeometry(slavePtr->tkwin,
slavePtr->masterPtr->tkwin);
@@ -591,7 +696,7 @@ GridForgetRemoveCommand(tkwin, interp, objc, objv)
*
* GridInfoCommand --
*
- * Implementation of the [grid info] subcommand. See the user
+ * Implementation of the [grid info] subcommand. See the user
* documentation for details on what it does.
*
* Results:
@@ -604,16 +709,16 @@ GridForgetRemoveCommand(tkwin, interp, objc, objv)
*/
static int
-GridInfoCommand(tkwin, interp, objc, objv)
- Tk_Window tkwin; /* Main window of the application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+GridInfoCommand(
+ Tk_Window tkwin, /* Main window of the application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
register Gridder *slavePtr;
Tk_Window slave;
char buffer[64 + TCL_INTEGER_SPACE * 4];
-
+
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "window");
return TCL_ERROR;
@@ -626,19 +731,19 @@ GridInfoCommand(tkwin, interp, objc, objv)
Tcl_ResetResult(interp);
return TCL_OK;
}
-
+
Tcl_AppendElement(interp, "-in");
Tcl_AppendElement(interp, Tk_PathName(slavePtr->masterPtr->tkwin));
sprintf(buffer, " -column %d -row %d -columnspan %d -rowspan %d",
slavePtr->column, slavePtr->row,
slavePtr->numCols, slavePtr->numRows);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
TkPrintPadAmount(interp, "ipadx", slavePtr->iPadX/2, slavePtr->iPadX);
TkPrintPadAmount(interp, "ipady", slavePtr->iPadY/2, slavePtr->iPadY);
TkPrintPadAmount(interp, "padx", slavePtr->padLeft, slavePtr->padX);
TkPrintPadAmount(interp, "pady", slavePtr->padTop, slavePtr->padY);
StickyToString(slavePtr->sticky, buffer);
- Tcl_AppendResult(interp, " -sticky ", buffer, (char *) NULL);
+ Tcl_AppendResult(interp, " -sticky ", buffer, NULL);
return TCL_OK;
}
@@ -647,7 +752,7 @@ GridInfoCommand(tkwin, interp, objc, objv)
*
* GridLocationCommand --
*
- * Implementation of the [grid location] subcommand. See the user
+ * Implementation of the [grid location] subcommand. See the user
* documentation for details on what it does.
*
* Results:
@@ -660,58 +765,58 @@ GridInfoCommand(tkwin, interp, objc, objv)
*/
static int
-GridLocationCommand(tkwin, interp, objc, objv)
- Tk_Window tkwin; /* Main window of the application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+GridLocationCommand(
+ Tk_Window tkwin, /* Main window of the application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tk_Window master;
- Gridder *masterPtr; /* master grid record */
- GridMaster *gridPtr; /* pointer to grid data */
+ Gridder *masterPtr; /* Master grid record. */
+ GridMaster *gridPtr; /* Pointer to grid data. */
register SlotInfo *slotPtr;
- int x, y; /* Offset in pixels, from edge of parent. */
- int i, j; /* Corresponding column and row indeces. */
- int endX, endY; /* end of grid */
-
+ int x, y; /* Offset in pixels, from edge of master. */
+ int i, j; /* Corresponding column and row indeces. */
+ int endX, endY; /* End of grid. */
+
if (objc != 5) {
Tcl_WrongNumArgs(interp, 2, objv, "master x y");
return TCL_ERROR;
}
-
+
if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) {
return TCL_ERROR;
}
-
+
if (Tk_GetPixelsFromObj(interp, master, objv[3], &x) != TCL_OK) {
return TCL_ERROR;
}
if (Tk_GetPixelsFromObj(interp, master, objv[4], &y) != TCL_OK) {
return TCL_ERROR;
}
-
+
masterPtr = GetGrid(master);
if (masterPtr->masterDataPtr == NULL) {
- Tcl_SetObjResult(interp, NewPairObj(interp, -1, -1));
+ Tcl_SetObjResult(interp, NewPairObj(-1, -1));
return TCL_OK;
}
gridPtr = masterPtr->masterDataPtr;
-
- /*
- * Update any pending requests. This is not always the
- * steady state value, as more configure events could be in
- * the pipeline, but its as close as its easy to get.
+
+ /*
+ * Update any pending requests. This is not always the steady state value,
+ * as more configure events could be in the pipeline, but its as close as
+ * its easy to get.
*/
-
+
while (masterPtr->flags & REQUESTED_RELAYOUT) {
Tcl_CancelIdleCall(ArrangeGrid, (ClientData) masterPtr);
- ArrangeGrid ((ClientData) masterPtr);
+ ArrangeGrid((ClientData) masterPtr);
}
SetGridSize(masterPtr);
endX = MAX(gridPtr->columnEnd, gridPtr->columnMax);
endY = MAX(gridPtr->rowEnd, gridPtr->rowMax);
-
- slotPtr = masterPtr->masterDataPtr->columnPtr;
+
+ slotPtr = masterPtr->masterDataPtr->columnPtr;
if (x < masterPtr->masterDataPtr->startX) {
i = -1;
} else {
@@ -720,8 +825,8 @@ GridLocationCommand(tkwin, interp, objc, objv)
/* null body */
}
}
-
- slotPtr = masterPtr->masterDataPtr->rowPtr;
+
+ slotPtr = masterPtr->masterDataPtr->rowPtr;
if (y < masterPtr->masterDataPtr->startY) {
j = -1;
} else {
@@ -730,8 +835,8 @@ GridLocationCommand(tkwin, interp, objc, objv)
/* null body */
}
}
-
- Tcl_SetObjResult(interp, NewPairObj(interp, i, j));
+
+ Tcl_SetObjResult(interp, NewPairObj(i, j));
return TCL_OK;
}
@@ -740,7 +845,7 @@ GridLocationCommand(tkwin, interp, objc, objv)
*
* GridPropagateCommand --
*
- * Implementation of the [grid propagate] subcommand. See the user
+ * Implementation of the [grid propagate] subcommand. See the user
* documentation for details on what it does.
*
* Results:
@@ -753,16 +858,16 @@ GridLocationCommand(tkwin, interp, objc, objv)
*/
static int
-GridPropagateCommand(tkwin, interp, objc, objv)
- Tk_Window tkwin; /* Main window of the application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+GridPropagateCommand(
+ Tk_Window tkwin, /* Main window of the application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tk_Window master;
Gridder *masterPtr;
int propagate, old;
-
+
if (objc > 4) {
Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
return TCL_ERROR;
@@ -780,9 +885,11 @@ GridPropagateCommand(tkwin, interp, objc, objv)
if (Tcl_GetBooleanFromObj(interp, objv[3], &propagate) != TCL_OK) {
return TCL_ERROR;
}
-
- /* Only request a relayout if the propagation bit changes */
-
+
+ /*
+ * Only request a relayout if the propagation bit changes.
+ */
+
old = !(masterPtr->flags & DONT_PROPAGATE);
if (propagate != old) {
if (propagate) {
@@ -790,12 +897,12 @@ GridPropagateCommand(tkwin, interp, objc, objv)
} else {
masterPtr->flags |= DONT_PROPAGATE;
}
-
+
/*
* Re-arrange the master to allow new geometry information to
* propagate upwards to the master's master.
*/
-
+
if (masterPtr->abortPtr != NULL) {
*masterPtr->abortPtr = 1;
}
@@ -813,8 +920,7 @@ GridPropagateCommand(tkwin, interp, objc, objv)
* GridRowColumnConfigureCommand --
*
* Implementation of the [grid rowconfigure] and [grid columnconfigure]
- * subcommands. See the user documentation for details on what these
- * do.
+ * subcommands. See the user documentation for details on what these do.
*
* Results:
* Standard Tcl result.
@@ -826,27 +932,29 @@ GridPropagateCommand(tkwin, interp, objc, objv)
*/
static int
-GridRowColumnConfigureCommand(tkwin, interp, objc, objv)
- Tk_Window tkwin; /* Main window of the application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+GridRowColumnConfigureCommand(
+ Tk_Window tkwin, /* Main window of the application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- Tk_Window master;
- Gridder *masterPtr;
+ Tk_Window master, slave;
+ Gridder *masterPtr, *slavePtr;
SlotInfo *slotPtr = NULL;
int slot; /* the column or row number */
int slotType; /* COLUMN or ROW */
int size; /* the configuration value */
- int checkOnly; /* check the size only */
int lObjc; /* Number of items in index list */
Tcl_Obj **lObjv; /* array of indices */
int ok; /* temporary TCL result code */
- int i, j;
+ int i, j, first, last;
char *string;
static CONST char *optionStrings[] = {
- "-minsize", "-pad", "-uniform", "-weight", (char *) NULL };
- enum options { ROWCOL_MINSIZE, ROWCOL_PAD, ROWCOL_UNIFORM, ROWCOL_WEIGHT };
+ "-minsize", "-pad", "-uniform", "-weight", NULL
+ };
+ enum options {
+ ROWCOL_MINSIZE, ROWCOL_PAD, ROWCOL_UNIFORM, ROWCOL_WEIGHT
+ };
int index;
Tcl_Obj *listCopy;
@@ -871,41 +979,40 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv)
if (lObjc == 0) {
Tcl_AppendResult(interp, "no ",
(slotType == COLUMN) ? "column" : "row",
- " indices specified", (char *) NULL);
+ " indices specified", NULL);
Tcl_DecrRefCount(listCopy);
return TCL_ERROR;
}
- checkOnly = ((objc == 4) || (objc == 5));
masterPtr = GetGrid(master);
- if (checkOnly && (lObjc > 1)) {
- Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ",
- Tcl_GetString(objv[1]),
- ": must specify a single element on retrieval", (char *) NULL);
- Tcl_DecrRefCount(listCopy);
- return TCL_ERROR;
- }
- for (j = 0; j < lObjc; j++) {
- if (Tcl_GetIntFromObj(interp, lObjv[j], &slot) != TCL_OK) {
+ first = 0; /* lint */
+ last = 0; /* lint */
+
+ if ((objc == 4) || (objc == 5)) {
+ if (lObjc != 1) {
+ Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ",
+ Tcl_GetString(objv[1]),
+ ": must specify a single element on retrieval", NULL);
Tcl_DecrRefCount(listCopy);
return TCL_ERROR;
}
- ok = CheckSlotData(masterPtr, slot, slotType, checkOnly);
- if ((ok != TCL_OK) && ((objc < 4) || (objc > 5))) {
- Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ",
- Tcl_GetString(objv[1]), ": \"", Tcl_GetString(lObjv[j]),
- "\" is out of range", (char *) NULL);
+ if (Tcl_GetIntFromObj(interp, lObjv[0], &slot) != TCL_OK) {
+ Tcl_AppendResult(interp,
+ " (when retreiving options only integer indices are "
+ "allowed)", NULL);
Tcl_DecrRefCount(listCopy);
return TCL_ERROR;
- } else if (ok == TCL_OK) {
+ }
+ ok = CheckSlotData(masterPtr, slot, slotType, /* checkOnly */ 1);
+ if (ok == TCL_OK) {
slotPtr = (slotType == COLUMN) ?
masterPtr->masterDataPtr->columnPtr :
masterPtr->masterDataPtr->rowPtr;
}
/*
- * Return all of the options for this row or column. If the
- * request is out of range, return all 0's.
+ * Return all of the options for this row or column. If the request is
+ * out of range, return all 0's.
*/
if (objc == 4) {
@@ -939,116 +1046,200 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv)
}
/*
- * Loop through each option value pair, setting the values as
- * required. If only one option is given, with no value, the
- * current value is returned.
+ * If only one option is given, with no value, the current value is
+ * returned.
*/
- for (i = 4; i < objc; i += 2) {
- if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option",
- 0, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObj(interp, objv[4], optionStrings, "option", 0,
+ &index) != TCL_OK) {
+ Tcl_DecrRefCount(listCopy);
+ return TCL_ERROR;
+ }
+ if (index == ROWCOL_MINSIZE) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewIntObj((ok == TCL_OK) ? slotPtr[slot].minSize : 0));
+ } else if (index == ROWCOL_WEIGHT) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewIntObj((ok == TCL_OK) ? slotPtr[slot].weight : 0));
+ } else if (index == ROWCOL_UNIFORM) {
+ Tk_Uid value = (ok == TCL_OK) ? slotPtr[slot].uniform : "";
+
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj(value == NULL ? "" : value, -1));
+ } else if (index == ROWCOL_PAD) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewIntObj((ok == TCL_OK) ? slotPtr[slot].pad : 0));
+ }
+ Tcl_DecrRefCount(listCopy);
+ return TCL_OK;
+ }
+
+ for (j = 0; j < lObjc; j++) {
+ int allSlaves = 0;
+
+ if (Tcl_GetIntFromObj(NULL, lObjv[j], &slot) == TCL_OK) {
+ first = slot;
+ last = slot;
+ slavePtr = NULL;
+ } else if (strcmp(Tcl_GetString(lObjv[j]), "all") == 0) {
+ /*
+ * Make sure master is initialised.
+ */
+
+ InitMasterData(masterPtr);
+
+ slavePtr = masterPtr->slavePtr;
+ if (slavePtr == NULL) {
+ continue;
+ }
+ allSlaves = 1;
+ } else if (TkGetWindowFromObj(NULL, tkwin, lObjv[j], &slave)
+ == TCL_OK) {
+ /*
+ * Is it gridded in this master?
+ */
+
+ slavePtr = GetGrid(slave);
+ if (slavePtr->masterPtr != masterPtr) {
+ Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ",
+ Tcl_GetString(objv[1]), ": the window \"",
+ Tcl_GetString(lObjv[j]), "\" is not managed by \"",
+ Tcl_GetString(objv[2]), "\"", NULL);
Tcl_DecrRefCount(listCopy);
return TCL_ERROR;
}
- if (index == ROWCOL_MINSIZE) {
- if (objc == 5) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(
- (ok == TCL_OK) ? slotPtr[slot].minSize : 0));
- } else if (Tk_GetPixelsFromObj(interp, master, objv[i+1], &size)
- != TCL_OK) {
- Tcl_DecrRefCount(listCopy);
- return TCL_ERROR;
- } else {
- slotPtr[slot].minSize = size;
- }
- } else if (index == ROWCOL_WEIGHT) {
- int wt;
- if (objc == 5) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(
- (ok == TCL_OK) ? slotPtr[slot].weight : 0));
- } else if (Tcl_GetIntFromObj(interp, objv[i+1], &wt)
- != TCL_OK) {
- Tcl_DecrRefCount(listCopy);
- return TCL_ERROR;
- } else if (wt < 0) {
- Tcl_AppendResult(interp, "invalid arg \"",
- Tcl_GetString(objv[i]),
- "\": should be non-negative", (char *) NULL);
- Tcl_DecrRefCount(listCopy);
+ } else {
+ Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ",
+ Tcl_GetString(objv[1]), ": illegal index \"",
+ Tcl_GetString(lObjv[j]), "\"", NULL);
+ Tcl_DecrRefCount(listCopy);
+ return TCL_ERROR;
+ }
+
+ /*
+ * The outer loop is only to handle "all".
+ */
+
+ do {
+ if (slavePtr != NULL) {
+ first = (slotType == COLUMN) ?
+ slavePtr->column : slavePtr->row;
+ last = first - 1 + ((slotType == COLUMN) ?
+ slavePtr->numCols : slavePtr->numRows);
+ }
+
+ for (slot = first; slot <= last; slot++) {
+ ok = CheckSlotData(masterPtr, slot, slotType, /*checkOnly*/ 0);
+ if (ok != TCL_OK) {
+ Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ",
+ Tcl_GetString(objv[1]), ": \"",
+ Tcl_GetString(lObjv[j]),
+ "\" is out of range", NULL);
+ Tcl_DecrRefCount(listCopy);
return TCL_ERROR;
- } else {
- slotPtr[slot].weight = wt;
}
- } else if (index == ROWCOL_UNIFORM) {
- if (objc == 5) {
- Tk_Uid value;
- value = (ok == TCL_OK) ? slotPtr[slot].uniform : "";
- if (value == NULL) {
- value = "";
+ slotPtr = (slotType == COLUMN) ?
+ masterPtr->masterDataPtr->columnPtr :
+ masterPtr->masterDataPtr->rowPtr;
+
+ /*
+ * Loop through each option value pair, setting the values as
+ * required.
+ */
+
+ for (i = 4; i < objc; i += 2) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings,
+ "option", 0, &index) != TCL_OK) {
+ Tcl_DecrRefCount(listCopy);
+ return TCL_ERROR;
}
- Tcl_SetObjResult(interp, Tcl_NewStringObj(value, -1));
- } else {
- slotPtr[slot].uniform = Tk_GetUid(Tcl_GetString(objv[i+1]));
- if (slotPtr[slot].uniform != NULL &&
- slotPtr[slot].uniform[0] == 0) {
- slotPtr[slot].uniform = NULL;
+ if (index == ROWCOL_MINSIZE) {
+ if (Tk_GetPixelsFromObj(interp, master, objv[i+1],
+ &size) != TCL_OK) {
+ Tcl_DecrRefCount(listCopy);
+ return TCL_ERROR;
+ } else {
+ slotPtr[slot].minSize = size;
+ }
+ } else if (index == ROWCOL_WEIGHT) {
+ int wt;
+
+ if (Tcl_GetIntFromObj(interp,objv[i+1],&wt)!=TCL_OK) {
+ Tcl_DecrRefCount(listCopy);
+ return TCL_ERROR;
+ } else if (wt < 0) {
+ Tcl_AppendResult(interp, "invalid arg \"",
+ Tcl_GetString(objv[i]),
+ "\": should be non-negative", NULL);
+ Tcl_DecrRefCount(listCopy);
+ return TCL_ERROR;
+ } else {
+ slotPtr[slot].weight = wt;
+ }
+ } else if (index == ROWCOL_UNIFORM) {
+ slotPtr[slot].uniform =
+ Tk_GetUid(Tcl_GetString(objv[i+1]));
+ if (slotPtr[slot].uniform != NULL &&
+ slotPtr[slot].uniform[0] == 0) {
+ slotPtr[slot].uniform = NULL;
+ }
+ } else if (index == ROWCOL_PAD) {
+ if (Tk_GetPixelsFromObj(interp, master, objv[i+1],
+ &size) != TCL_OK) {
+ Tcl_DecrRefCount(listCopy);
+ return TCL_ERROR;
+ } else if (size < 0) {
+ Tcl_AppendResult(interp, "invalid arg \"",
+ Tcl_GetString(objv[i]),
+ "\": should be non-negative", NULL);
+ Tcl_DecrRefCount(listCopy);
+ return TCL_ERROR;
+ } else {
+ slotPtr[slot].pad = size;
+ }
}
}
- } else if (index == ROWCOL_PAD) {
- if (objc == 5) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(
- (ok == TCL_OK) ? slotPtr[slot].pad : 0));
- } else if (Tk_GetPixelsFromObj(interp, master, objv[i+1], &size)
- != TCL_OK) {
- Tcl_DecrRefCount(listCopy);
- return TCL_ERROR;
- } else if (size < 0) {
- Tcl_AppendResult(interp, "invalid arg \"",
- Tcl_GetString(objv[i]),
- "\": should be non-negative", (char *) NULL);
- Tcl_DecrRefCount(listCopy);
- return TCL_ERROR;
- } else {
- slotPtr[slot].pad = size;
- }
}
- }
+ if (slavePtr != NULL) {
+ slavePtr = slavePtr->nextPtr;
+ }
+ } while ((allSlaves == 1) && (slavePtr != NULL));
}
Tcl_DecrRefCount(listCopy);
/*
- * If we changed a property, re-arrange the table,
- * and check for constraint shrinkage.
+ * We changed a property, re-arrange the table, and check for constraint
+ * shrinkage. A null slotPtr will occur for 'all' checks.
*/
- if (objc != 5) {
+ if (slotPtr != NULL) {
if (slotType == ROW) {
int last = masterPtr->masterDataPtr->rowMax - 1;
+
while ((last >= 0) && (slotPtr[last].weight == 0)
- && (slotPtr[last].pad == 0)
- && (slotPtr[last].minSize == 0)
+ && (slotPtr[last].pad == 0) && (slotPtr[last].minSize == 0)
&& (slotPtr[last].uniform == NULL)) {
last--;
}
masterPtr->masterDataPtr->rowMax = last+1;
} else {
int last = masterPtr->masterDataPtr->columnMax - 1;
+
while ((last >= 0) && (slotPtr[last].weight == 0)
- && (slotPtr[last].pad == 0)
- && (slotPtr[last].minSize == 0)
+ && (slotPtr[last].pad == 0) && (slotPtr[last].minSize == 0)
&& (slotPtr[last].uniform == NULL)) {
last--;
}
masterPtr->masterDataPtr->columnMax = last + 1;
}
+ }
- if (masterPtr->abortPtr != NULL) {
- *masterPtr->abortPtr = 1;
- }
- if (!(masterPtr->flags & REQUESTED_RELAYOUT)) {
- masterPtr->flags |= REQUESTED_RELAYOUT;
- Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr);
- }
+ if (masterPtr->abortPtr != NULL) {
+ *masterPtr->abortPtr = 1;
+ }
+ if (!(masterPtr->flags & REQUESTED_RELAYOUT)) {
+ masterPtr->flags |= REQUESTED_RELAYOUT;
+ Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr);
}
return TCL_OK;
}
@@ -1058,7 +1249,7 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv)
*
* GridSizeCommand --
*
- * Implementation of the [grid size] subcommand. See the user
+ * Implementation of the [grid size] subcommand. See the user
* documentation for details on what it does.
*
* Results:
@@ -1071,16 +1262,16 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv)
*/
static int
-GridSizeCommand(tkwin, interp, objc, objv)
- Tk_Window tkwin; /* Main window of the application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+GridSizeCommand(
+ Tk_Window tkwin, /* Main window of the application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tk_Window master;
Gridder *masterPtr;
GridMaster *gridPtr; /* pointer to grid data */
-
+
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "window");
return TCL_ERROR;
@@ -1090,15 +1281,15 @@ GridSizeCommand(tkwin, interp, objc, objv)
return TCL_ERROR;
}
masterPtr = GetGrid(master);
-
+
if (masterPtr->masterDataPtr != NULL) {
SetGridSize(masterPtr);
gridPtr = masterPtr->masterDataPtr;
- Tcl_SetObjResult(interp, NewPairObj(interp,
+ Tcl_SetObjResult(interp, NewPairObj(
MAX(gridPtr->columnEnd, gridPtr->columnMax),
MAX(gridPtr->rowEnd, gridPtr->rowMax)));
} else {
- Tcl_SetObjResult(interp, NewPairObj(interp, 0, 0));
+ Tcl_SetObjResult(interp, NewPairObj(0, 0));
}
return TCL_OK;
}
@@ -1108,42 +1299,42 @@ GridSizeCommand(tkwin, interp, objc, objv)
*
* GridSlavesCommand --
*
- * Implementation of the [grid slaves] subcommand. See the user
+ * Implementation of the [grid slaves] subcommand. See the user
* documentation for details on what it does.
*
* Results:
* Standard Tcl result.
*
* Side effects:
- * Places a list of slaves of the specified window in the
- * interpreter's result field.
+ * Places a list of slaves of the specified window in the interpreter's
+ * result field.
*
*----------------------------------------------------------------------
*/
static int
-GridSlavesCommand(tkwin, interp, objc, objv)
- Tk_Window tkwin; /* Main window of the application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+GridSlavesCommand(
+ Tk_Window tkwin, /* Main window of the application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tk_Window master;
Gridder *masterPtr; /* master grid record */
Gridder *slavePtr;
- int i, value;
+ int i, value, index;
int row = -1, column = -1;
static CONST char *optionStrings[] = {
- "-column", "-row", (char *) NULL };
+ "-column", "-row", NULL
+ };
enum options { SLAVES_COLUMN, SLAVES_ROW };
- int index;
Tcl_Obj *res;
-
+
if ((objc < 3) || ((objc % 2) == 0)) {
Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value...?");
return TCL_ERROR;
}
-
+
for (i = 3; i < objc; i += 2) {
if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0,
&index) != TCL_OK) {
@@ -1154,8 +1345,7 @@ GridSlavesCommand(tkwin, interp, objc, objv)
}
if (value < 0) {
Tcl_AppendResult(interp, Tcl_GetString(objv[i]),
- " is an invalid value: should NOT be < 0",
- (char *) NULL);
+ " is an invalid value: should NOT be < 0", NULL);
return TCL_ERROR;
}
if (index == SLAVES_COLUMN) {
@@ -1172,7 +1362,7 @@ GridSlavesCommand(tkwin, interp, objc, objv)
res = Tcl_NewListObj(0, NULL);
for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
- slavePtr = slavePtr->nextPtr) {
+ slavePtr = slavePtr->nextPtr) {
if (column>=0 && (slavePtr->column > column
|| slavePtr->column+slavePtr->numCols-1 < column)) {
continue;
@@ -1189,30 +1379,29 @@ GridSlavesCommand(tkwin, interp, objc, objv)
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* GridReqProc --
*
- * This procedure is invoked by Tk_GeometryRequest for
- * windows managed by the grid.
+ * This procedure is invoked by Tk_GeometryRequest for windows managed by
+ * the grid.
*
* Results:
* None.
*
* Side effects:
- * Arranges for tkwin, and all its managed siblings, to
- * be re-arranged at the next idle point.
+ * Arranges for tkwin, and all its managed siblings, to be re-arranged at
+ * the next idle point.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static void
-GridReqProc(clientData, tkwin)
- ClientData clientData; /* Grid's information about
- * window that got new preferred
- * geometry. */
- Tk_Window tkwin; /* Other Tk-related information
- * about the window. */
+GridReqProc(
+ ClientData clientData, /* Grid's information about window that got
+ * new preferred geometry. */
+ Tk_Window tkwin) /* Other Tk-related information about the
+ * window. */
{
register Gridder *gridPtr = (Gridder *) clientData;
@@ -1224,12 +1413,12 @@ GridReqProc(clientData, tkwin)
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* GridLostSlaveProc --
*
- * This procedure is invoked by Tk whenever some other geometry
- * claims control over a slave that used to be managed by us.
+ * This procedure is invoked by Tk whenever some other geometry claims
+ * control over a slave that used to be managed by us.
*
* Results:
* None.
@@ -1237,14 +1426,14 @@ GridReqProc(clientData, tkwin)
* Side effects:
* Forgets all grid-related information about the slave.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static void
-GridLostSlaveProc(clientData, tkwin)
- ClientData clientData; /* Grid structure for slave window that
- * was stolen away. */
- Tk_Window tkwin; /* Tk's handle for the slave window. */
+GridLostSlaveProc(
+ ClientData clientData, /* Grid structure for slave window that was
+ * stolen away. */
+ Tk_Window tkwin) /* Tk's handle for the slave window. */
{
register Gridder *slavePtr = (Gridder *) clientData;
@@ -1256,39 +1445,38 @@ GridLostSlaveProc(clientData, tkwin)
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* AdjustOffsets --
*
- * This procedure adjusts the size of the layout to fit in the
- * space provided. If it needs more space, the extra is added
- * according to the weights. If it needs less, the space is removed
- * according to the weights, but at no time does the size drop below
- * the minsize specified for that slot.
+ * This procedure adjusts the size of the layout to fit in the space
+ * provided. If it needs more space, the extra is added according to the
+ * weights. If it needs less, the space is removed according to the
+ * weights, but at no time does the size drop below the minsize specified
+ * for that slot.
*
* Results:
- * The initial offset of the layout,
- * if all the weights are zero, else 0.
+ * The size used by the layout.
*
* Side effects:
* The slot offsets are modified to shrink the layout.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static int
-AdjustOffsets(size, slots, slotPtr)
- int size; /* The total layout size (in pixels). */
- int slots; /* Number of slots. */
- register SlotInfo *slotPtr; /* Pointer to slot array. */
+AdjustOffsets(
+ int size, /* The total layout size (in pixels). */
+ int slots, /* Number of slots. */
+ register SlotInfo *slotPtr) /* Pointer to slot array. */
{
register int slot; /* Current slot. */
int diff; /* Extra pixels needed to add to the layout. */
- int totalWeight = 0; /* Sum of the weights for all the slots. */
- int weight = 0; /* Sum of the weights so far. */
+ int totalWeight; /* Sum of the weights for all the slots. */
+ int weight; /* Sum of the weights so far. */
int minSize; /* Minimum possible layout size. */
- int newDiff; /* The most pixels that can be added on
- * the current pass. */
+ int newDiff; /* The most pixels that can be added on the
+ * current pass. */
diff = size - slotPtr[slots-1].offset;
@@ -1297,24 +1485,24 @@ AdjustOffsets(size, slots, slotPtr)
*/
if (diff == 0) {
- return(0);
+ return size;
}
/*
- * If all the weights are zero, center the layout in its parent if
- * there is extra space, else clip on the bottom/right.
+ * If all the weights are zero, there is nothing more to do.
*/
+ totalWeight = 0;
for (slot = 0; slot < slots; slot++) {
totalWeight += slotPtr[slot].weight;
}
- if (totalWeight == 0 ) {
- return(diff > 0 ? diff/2 : 0);
+ if (totalWeight == 0) {
+ return slotPtr[slots-1].offset;
}
/*
- * Add extra space according to the slot weights. This is done
+ * Add extra space according to the slot weights. This is done
* cumulatively to prevent round-off error accumulation.
*/
@@ -1324,13 +1512,13 @@ AdjustOffsets(size, slots, slotPtr)
weight += slotPtr[slot].weight;
slotPtr[slot].offset += diff * weight / totalWeight;
}
- return(0);
+ return size;
}
/*
- * The layout must shrink below its requested size. Compute the
- * minimum possible size by looking at the slot minSizes.
- * Store each slot's minimum size in temp.
+ * The layout must shrink below its requested size. Compute the minimum
+ * possible size by looking at the slot minSizes. Store each slot's
+ * minimum size in temp.
*/
minSize = 0;
@@ -1346,34 +1534,35 @@ AdjustOffsets(size, slots, slotPtr)
}
/*
- * If the requested size is less than the minimum required size,
- * set the slot sizes to their minimum values, then clip on the
- * bottom/right.
+ * If the requested size is less than the minimum required size, set the
+ * slot sizes to their minimum values.
*/
if (size <= minSize) {
int offset = 0;
+
for (slot = 0; slot < slots; slot++) {
offset += slotPtr[slot].temp;
slotPtr[slot].offset = offset;
}
- return(0);
+ return minSize;
}
/*
- * Remove space from slots according to their weights. The weights
- * get renormalized anytime a slot shrinks to its minimum size.
+ * Remove space from slots according to their weights. The weights get
+ * renormalized anytime a slot shrinks to its minimum size.
*/
while (diff < 0) {
-
/*
* Find the total weight for the shrinkable slots.
*/
- for (totalWeight=slot=0; slot < slots; slot++) {
+ totalWeight = 0;
+ for (slot = 0; slot < slots; slot++) {
int current = (slot == 0) ? slotPtr[slot].offset :
slotPtr[slot].offset - slotPtr[slot-1].offset;
+
if (current > slotPtr[slot].minSize) {
totalWeight += slotPtr[slot].weight;
slotPtr[slot].temp = slotPtr[slot].weight;
@@ -1391,9 +1580,10 @@ AdjustOffsets(size, slots, slotPtr)
newDiff = diff;
for (slot = 0; slot < slots; slot++) {
- int current; /* current size of this slot */
- int maxDiff; /* max diff that would cause
- * this slot to equal its minsize */
+ int current; /* Current size of this slot. */
+ int maxDiff; /* Maximum diff that would cause this slot to
+ * equal its minsize. */
+
if (slotPtr[slot].temp == 0) {
continue;
}
@@ -1410,43 +1600,44 @@ AdjustOffsets(size, slots, slotPtr)
* Now distribute the space.
*/
- for (weight=slot=0; slot < slots; slot++) {
+ weight = 0;
+ for (slot = 0; slot < slots; slot++) {
weight += slotPtr[slot].temp;
slotPtr[slot].offset += newDiff * weight / totalWeight;
}
diff -= newDiff;
}
- return(0);
+ return size;
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* AdjustForSticky --
*
- * This procedure adjusts the size of a slave in its cavity based
- * on its "sticky" flags.
+ * This procedure adjusts the size of a slave in its cavity based on its
+ * "sticky" flags.
*
* Results:
- * The input x, y, width, and height are changed to represent the
- * desired coordinates of the slave.
+ * The input x, y, width, and height are changed to represent the desired
+ * coordinates of the slave.
*
* Side effects:
* None.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static void
-AdjustForSticky(slavePtr, xPtr, yPtr, widthPtr, heightPtr)
- Gridder *slavePtr; /* Slave window to arrange in its cavity. */
- int *xPtr; /* Pixel location of the left edge of the cavity. */
- int *yPtr; /* Pixel location of the top edge of the cavity. */
- int *widthPtr; /* Width of the cavity (in pixels). */
- int *heightPtr; /* Height of the cavity (in pixels). */
+AdjustForSticky(
+ Gridder *slavePtr, /* Slave window to arrange in its cavity. */
+ int *xPtr, /* Pixel location of the left edge of the cavity. */
+ int *yPtr, /* Pixel location of the top edge of the cavity. */
+ int *widthPtr, /* Width of the cavity (in pixels). */
+ int *heightPtr) /* Height of the cavity (in pixels). */
{
- int diffx=0; /* Cavity width - slave width. */
- int diffy=0; /* Cavity hight - slave height. */
+ int diffx = 0; /* Cavity width - slave width. */
+ int diffy = 0; /* Cavity hight - slave height. */
int sticky = slavePtr->sticky;
*xPtr += slavePtr->padLeft;
@@ -1479,14 +1670,13 @@ AdjustForSticky(slavePtr, xPtr, yPtr, widthPtr, heightPtr)
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* ArrangeGrid --
*
- * This procedure is invoked (using the Tcl_DoWhenIdle
- * mechanism) to re-layout a set of windows managed by
- * the grid. It is invoked at idle time so that a
- * series of grid requests can be merged into a single
+ * This procedure is invoked (using the Tcl_DoWhenIdle mechanism) to
+ * re-layout a set of windows managed by the grid. It is invoked at idle
+ * time so that a series of grid requests can be merged into a single
* layout operation.
*
* Results:
@@ -1495,28 +1685,29 @@ AdjustForSticky(slavePtr, xPtr, yPtr, widthPtr, heightPtr)
* Side effects:
* The slaves of masterPtr may get resized or moved.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static void
-ArrangeGrid(clientData)
- ClientData clientData; /* Structure describing parent whose slaves
+ArrangeGrid(
+ ClientData clientData) /* Structure describing master whose slaves
* are to be re-layed out. */
{
register Gridder *masterPtr = (Gridder *) clientData;
- register Gridder *slavePtr;
+ register Gridder *slavePtr;
GridMaster *slotPtr = masterPtr->masterDataPtr;
int abort;
- int width, height; /* requested size of layout, in pixels */
- int realWidth, realHeight; /* actual size layout should take-up */
+ int width, height; /* Requested size of layout, in pixels. */
+ int realWidth, realHeight; /* Actual size layout should take-up. */
+ int usedX, usedY;
masterPtr->flags &= ~REQUESTED_RELAYOUT;
/*
- * If the parent has no slaves anymore, then don't do anything
- * at all: just leave the parent's size as-is. Otherwise there is
- * no way to "relinquish" control over the parent so another geometry
- * manager can take over.
+ * If the master has no slaves anymore, then don't do anything at all:
+ * just leave the master's size as-is. Otherwise there is no way to
+ * "relinquish" control over the master so another geometry manager can
+ * take over.
*/
if (masterPtr->slavePtr == NULL) {
@@ -1528,9 +1719,9 @@ ArrangeGrid(clientData)
}
/*
- * Abort any nested call to ArrangeGrid for this window, since
- * we'll do everything necessary here, and set up so this call
- * can be aborted if necessary.
+ * Abort any nested call to ArrangeGrid for this window, since we'll do
+ * everything necessary here, and set up so this call can be aborted if
+ * necessary.
*/
if (masterPtr->abortPtr != NULL) {
@@ -1545,13 +1736,13 @@ ArrangeGrid(clientData)
*/
SetGridSize(masterPtr);
- width = ResolveConstraints(masterPtr, COLUMN, 0);
+ width = ResolveConstraints(masterPtr, COLUMN, 0);
height = ResolveConstraints(masterPtr, ROW, 0);
width += Tk_InternalBorderLeft(masterPtr->tkwin) +
Tk_InternalBorderRight(masterPtr->tkwin);
height += Tk_InternalBorderTop(masterPtr->tkwin) +
Tk_InternalBorderBottom(masterPtr->tkwin);
-
+
if (width < Tk_MinReqWidth(masterPtr->tkwin)) {
width = Tk_MinReqWidth(masterPtr->tkwin);
}
@@ -1569,15 +1760,14 @@ ArrangeGrid(clientData)
}
masterPtr->abortPtr = NULL;
Tcl_Release((ClientData) masterPtr);
- return;
+ return;
}
/*
- * If the currently requested layout size doesn't match the parent's
- * window size, then adjust the slot offsets according to the
- * weights. If all of the weights are zero, center the layout in
- * its parent. I haven't decided what to do if the parent is smaller
- * than the requested size.
+ * If the currently requested layout size doesn't match the master's
+ * window size, then adjust the slot offsets according to the weights. If
+ * all of the weights are zero, place the layout according to the anchor
+ * value.
*/
realWidth = Tk_Width(masterPtr->tkwin) -
@@ -1586,23 +1776,22 @@ ArrangeGrid(clientData)
realHeight = Tk_Height(masterPtr->tkwin) -
Tk_InternalBorderTop(masterPtr->tkwin) -
Tk_InternalBorderBottom(masterPtr->tkwin);
- slotPtr->startX = AdjustOffsets(realWidth,
- MAX(slotPtr->columnEnd,slotPtr->columnMax), slotPtr->columnPtr);
- slotPtr->startY = AdjustOffsets(realHeight,
- MAX(slotPtr->rowEnd,slotPtr->rowMax), slotPtr->rowPtr);
- slotPtr->startX += Tk_InternalBorderLeft(masterPtr->tkwin);
- slotPtr->startY += Tk_InternalBorderTop(masterPtr->tkwin);
+ usedX = AdjustOffsets(realWidth,
+ MAX(slotPtr->columnEnd, slotPtr->columnMax), slotPtr->columnPtr);
+ usedY = AdjustOffsets(realHeight, MAX(slotPtr->rowEnd, slotPtr->rowMax),
+ slotPtr->rowPtr);
+ TkComputeAnchor(masterPtr->masterDataPtr->anchor, masterPtr->tkwin,
+ 0, 0, usedX, usedY, &slotPtr->startX, &slotPtr->startY);
/*
- * Now adjust the actual size of the slave to its cavity by
- * computing the cavity size, and adjusting the widget according
- * to its stickyness.
+ * Now adjust the actual size of the slave to its cavity by computing the
+ * cavity size, and adjusting the widget according to its stickyness.
*/
for (slavePtr = masterPtr->slavePtr; slavePtr != NULL && !abort;
slavePtr = slavePtr->nextPtr) {
- int x, y; /* top left coordinate */
- int width, height; /* slot or slave size */
+ int x, y; /* Top left coordinate */
+ int width, height; /* Slot or slave size */
int col = slavePtr->column;
int row = slavePtr->row;
@@ -1612,49 +1801,47 @@ ArrangeGrid(clientData)
width = slotPtr->columnPtr[slavePtr->numCols+col-1].offset - x;
height = slotPtr->rowPtr[slavePtr->numRows+row-1].offset - y;
- x += slotPtr->startX;
- y += slotPtr->startY;
+ x += slotPtr->startX;
+ y += slotPtr->startY;
AdjustForSticky(slavePtr, &x, &y, &width, &height);
/*
- * Now put the window in the proper spot. (This was taken directly
- * from tkPack.c.) If the slave is a child of the master, then
- * do this here. Otherwise let Tk_MaintainGeometry do the work.
- */
-
- if (masterPtr->tkwin == Tk_Parent(slavePtr->tkwin)) {
- if ((width <= 0) || (height <= 0)) {
- Tk_UnmapWindow(slavePtr->tkwin);
- } else {
- if ((x != Tk_X(slavePtr->tkwin))
- || (y != Tk_Y(slavePtr->tkwin))
- || (width != Tk_Width(slavePtr->tkwin))
- || (height != Tk_Height(slavePtr->tkwin))) {
- Tk_MoveResizeWindow(slavePtr->tkwin, x, y, width, height);
- }
- if (abort) {
- break;
- }
-
- /*
- * Don't map the slave if the master isn't mapped: wait
- * until the master gets mapped later.
- */
-
- if (Tk_IsMapped(masterPtr->tkwin)) {
- Tk_MapWindow(slavePtr->tkwin);
- }
- }
- } else {
- if ((width <= 0) || (height <= 0)) {
- Tk_UnmaintainGeometry(slavePtr->tkwin, masterPtr->tkwin);
- Tk_UnmapWindow(slavePtr->tkwin);
- } else {
- Tk_MaintainGeometry(slavePtr->tkwin, masterPtr->tkwin,
- x, y, width, height);
- }
- }
+ * Now put the window in the proper spot. (This was taken directly
+ * from tkPack.c.) If the slave is a child of the master, then do this
+ * here. Otherwise let Tk_MaintainGeometry do the work.
+ */
+
+ if (masterPtr->tkwin == Tk_Parent(slavePtr->tkwin)) {
+ if ((width <= 0) || (height <= 0)) {
+ Tk_UnmapWindow(slavePtr->tkwin);
+ } else {
+ if ((x != Tk_X(slavePtr->tkwin))
+ || (y != Tk_Y(slavePtr->tkwin))
+ || (width != Tk_Width(slavePtr->tkwin))
+ || (height != Tk_Height(slavePtr->tkwin))) {
+ Tk_MoveResizeWindow(slavePtr->tkwin, x, y, width, height);
+ }
+ if (abort) {
+ break;
+ }
+
+ /*
+ * Don't map the slave if the master isn't mapped: wait until
+ * the master gets mapped later.
+ */
+
+ if (Tk_IsMapped(masterPtr->tkwin)) {
+ Tk_MapWindow(slavePtr->tkwin);
+ }
+ }
+ } else if ((width <= 0) || (height <= 0)) {
+ Tk_UnmaintainGeometry(slavePtr->tkwin, masterPtr->tkwin);
+ Tk_UnmapWindow(slavePtr->tkwin);
+ } else {
+ Tk_MaintainGeometry(slavePtr->tkwin, masterPtr->tkwin, x, y,
+ width, height);
+ }
}
masterPtr->abortPtr = NULL;
@@ -1662,13 +1849,13 @@ ArrangeGrid(clientData)
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* ResolveConstraints --
*
- * Resolve all of the column and row boundaries. Most of
- * the calculations are identical for rows and columns, so this procedure
- * is called twice, once for rows, and again for columns.
+ * Resolve all of the column and row boundaries. Most of the calculations
+ * are identical for rows and columns, so this procedure is called twice,
+ * once for rows, and again for columns.
*
* Results:
* The offset (in pixels) from the left/top edge of this layout is
@@ -1678,34 +1865,34 @@ ArrangeGrid(clientData)
* The slot offsets are copied into the SlotInfo structure for the
* geometry master.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static int
-ResolveConstraints(masterPtr, slotType, maxOffset)
- Gridder *masterPtr; /* The geometry master for this grid. */
- int slotType; /* Either ROW or COLUMN. */
- int maxOffset; /* The actual maximum size of this layout
- * in pixels, or 0 (not currently used). */
+ResolveConstraints(
+ Gridder *masterPtr, /* The geometry master for this grid. */
+ int slotType, /* Either ROW or COLUMN. */
+ int maxOffset) /* The actual maximum size of this layout in
+ * pixels, or 0 (not currently used). */
{
register SlotInfo *slotPtr; /* Pointer to row/col constraints. */
register Gridder *slavePtr; /* List of slave windows in this grid. */
int constraintCount; /* Count of rows or columns that have
- * constraints. */
+ * constraints. */
int slotCount; /* Last occupied row or column. */
- int gridCount; /* The larger of slotCount and constraintCount.
- */
+ int gridCount; /* The larger of slotCount and
+ * constraintCount. */
GridLayout *layoutPtr; /* Temporary layout structure. */
int requiredSize; /* The natural size of the grid (pixels).
* This is the minimum size needed to
* accomodate all of the slaves at their
* requested sizes. */
int offset; /* The pixel offset of the right edge of the
- * current slot from the beginning of the
- * layout. */
+ * current slot from the beginning of the
+ * layout. */
int slot; /* The current slot. */
int start; /* The first slot of a contiguous set whose
- * constraints are not yet fully resolved. */
+ * constraints are not yet fully resolved. */
int end; /* The Last slot of a contiguous set whose
* constraints are not yet fully resolved. */
UniformGroup uniformPre[UNIFORM_PREALLOC];
@@ -1713,13 +1900,14 @@ ResolveConstraints(masterPtr, slotType, maxOffset)
UniformGroup *uniformGroupPtr;
/* Uniform groups data. */
int uniformGroups; /* Number of currently used uniform groups. */
- int uniformGroupsAlloced; /* Size of allocated space for uniform groups.
- */
+ int uniformGroupsAlloced; /* Size of allocated space for uniform
+ * groups. */
int weight, minSize;
+ int prevGrow, accWeight, grow;
/*
- * For typical sized tables, we'll use stack space for the layout data
- * to avoid the overhead of a malloc and free for every layout.
+ * For typical sized tables, we'll use stack space for the layout data to
+ * avoid the overhead of a malloc and free for every layout.
*/
GridLayout layoutData[TYPICAL_SIZE + 1];
@@ -1727,30 +1915,32 @@ ResolveConstraints(masterPtr, slotType, maxOffset)
if (slotType == COLUMN) {
constraintCount = masterPtr->masterDataPtr->columnMax;
slotCount = masterPtr->masterDataPtr->columnEnd;
- slotPtr = masterPtr->masterDataPtr->columnPtr;
+ slotPtr = masterPtr->masterDataPtr->columnPtr;
} else {
constraintCount = masterPtr->masterDataPtr->rowMax;
slotCount = masterPtr->masterDataPtr->rowEnd;
- slotPtr = masterPtr->masterDataPtr->rowPtr;
+ slotPtr = masterPtr->masterDataPtr->rowPtr;
}
/*
* Make sure there is enough memory for the layout.
*/
- gridCount = MAX(constraintCount,slotCount);
+ gridCount = MAX(constraintCount, slotCount);
if (gridCount >= TYPICAL_SIZE) {
- layoutPtr = (GridLayout *) ckalloc(sizeof(GridLayout) * (1+gridCount));
+ layoutPtr = (GridLayout *)
+ ckalloc(sizeof(GridLayout) * (1+gridCount));
} else {
layoutPtr = layoutData;
}
/*
- * Allocate an extra layout slot to represent the left/top edge of
- * the 0th slot to make it easier to calculate slot widths from
- * offsets without special case code.
- * Initialize the "dummy" slot to the left/top of the table.
- * This slot avoids special casing the first slot.
+ * Allocate an extra layout slot to represent the left/top edge of the 0th
+ * slot to make it easier to calculate slot widths from offsets without
+ * special case code.
+ *
+ * Initialize the "dummy" slot to the left/top of the table. This slot
+ * avoids special casing the first slot.
*/
layoutPtr->minOffset = 0;
@@ -1759,74 +1949,77 @@ ResolveConstraints(masterPtr, slotType, maxOffset)
/*
* Step 1.
- * Copy the slot constraints into the layout structure,
- * and initialize the rest of the fields.
+ * Copy the slot constraints into the layout structure, and initialize the
+ * rest of the fields.
*/
for (slot=0; slot < constraintCount; slot++) {
- layoutPtr[slot].minSize = slotPtr[slot].minSize;
- layoutPtr[slot].weight = slotPtr[slot].weight;
- layoutPtr[slot].uniform = slotPtr[slot].uniform;
- layoutPtr[slot].pad = slotPtr[slot].pad;
- layoutPtr[slot].binNextPtr = NULL;
+ layoutPtr[slot].minSize = slotPtr[slot].minSize;
+ layoutPtr[slot].weight = slotPtr[slot].weight;
+ layoutPtr[slot].uniform = slotPtr[slot].uniform;
+ layoutPtr[slot].pad = slotPtr[slot].pad;
+ layoutPtr[slot].binNextPtr = NULL;
}
- for(;slot<gridCount;slot++) {
- layoutPtr[slot].minSize = 0;
- layoutPtr[slot].weight = 0;
- layoutPtr[slot].uniform = NULL;
- layoutPtr[slot].pad = 0;
- layoutPtr[slot].binNextPtr = NULL;
+ for (; slot<gridCount; slot++) {
+ layoutPtr[slot].minSize = 0;
+ layoutPtr[slot].weight = 0;
+ layoutPtr[slot].uniform = NULL;
+ layoutPtr[slot].pad = 0;
+ layoutPtr[slot].binNextPtr = NULL;
}
/*
* Step 2.
- * Slaves with a span of 1 are used to determine the minimum size of
- * each slot. Slaves whose span is two or more slots don't
- * contribute to the minimum size of each slot directly, but can cause
- * slots to grow if their size exceeds the the sizes of the slots they
- * span.
- *
- * Bin all slaves whose spans are > 1 by their right edges. This
- * allows the computation on minimum and maximum possible layout
- * sizes at each slot boundary, without the need to re-sort the slaves.
+ * Slaves with a span of 1 are used to determine the minimum size of each
+ * slot. Slaves whose span is two or more slots don't contribute to the
+ * minimum size of each slot directly, but can cause slots to grow if
+ * their size exceeds the the sizes of the slots they span.
+ *
+ * Bin all slaves whose spans are > 1 by their right edges. This allows
+ * the computation on minimum and maximum possible layout sizes at each
+ * slot boundary, without the need to re-sort the slaves.
*/
-
+
switch (slotType) {
- case COLUMN:
- for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
- slavePtr = slavePtr->nextPtr) {
- int rightEdge = slavePtr->column + slavePtr->numCols - 1;
- slavePtr->size = Tk_ReqWidth(slavePtr->tkwin) +
- slavePtr->padX + slavePtr->iPadX + slavePtr->doubleBw;
- if (slavePtr->numCols > 1) {
- slavePtr->binNextPtr = layoutPtr[rightEdge].binNextPtr;
- layoutPtr[rightEdge].binNextPtr = slavePtr;
- } else {
- int size = slavePtr->size + layoutPtr[rightEdge].pad;
- if (size > layoutPtr[rightEdge].minSize) {
- layoutPtr[rightEdge].minSize = size;
- }
+ case COLUMN:
+ for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
+ slavePtr = slavePtr->nextPtr) {
+ int rightEdge = slavePtr->column + slavePtr->numCols - 1;
+
+ slavePtr->size = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->padX
+ + slavePtr->iPadX + slavePtr->doubleBw;
+ if (slavePtr->numCols > 1) {
+ slavePtr->binNextPtr = layoutPtr[rightEdge].binNextPtr;
+ layoutPtr[rightEdge].binNextPtr = slavePtr;
+ } else {
+ int size = slavePtr->size + layoutPtr[rightEdge].pad;
+
+ if (size > layoutPtr[rightEdge].minSize) {
+ layoutPtr[rightEdge].minSize = size;
}
}
- break;
- case ROW:
- for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
- slavePtr = slavePtr->nextPtr) {
- int rightEdge = slavePtr->row + slavePtr->numRows - 1;
- slavePtr->size = Tk_ReqHeight(slavePtr->tkwin) +
- slavePtr->padY + slavePtr->iPadY + slavePtr->doubleBw;
- if (slavePtr->numRows > 1) {
- slavePtr->binNextPtr = layoutPtr[rightEdge].binNextPtr;
- layoutPtr[rightEdge].binNextPtr = slavePtr;
- } else {
- int size = slavePtr->size + layoutPtr[rightEdge].pad;
- if (size > layoutPtr[rightEdge].minSize) {
- layoutPtr[rightEdge].minSize = size;
- }
+ }
+ break;
+ case ROW:
+ for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
+ slavePtr = slavePtr->nextPtr) {
+ int rightEdge = slavePtr->row + slavePtr->numRows - 1;
+
+ slavePtr->size = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->padY
+ + slavePtr->iPadY + slavePtr->doubleBw;
+ if (slavePtr->numRows > 1) {
+ slavePtr->binNextPtr = layoutPtr[rightEdge].binNextPtr;
+ layoutPtr[rightEdge].binNextPtr = slavePtr;
+ } else {
+ int size = slavePtr->size + layoutPtr[rightEdge].pad;
+
+ if (size > layoutPtr[rightEdge].minSize) {
+ layoutPtr[rightEdge].minSize = size;
}
}
- break;
}
+ break;
+ }
/*
* Step 2b.
@@ -1858,13 +2051,14 @@ ResolveConstraints(masterPtr, slotType, maxOffset)
* sizeof(UniformGroup);
size_t newSize = (uniformGroupsAlloced + UNIFORM_PREALLOC)
* sizeof(UniformGroup);
- UniformGroup *new = (UniformGroup *) ckalloc(newSize);
- UniformGroup *old = uniformGroupPtr;
- memcpy((VOID *) new, (VOID *) old, oldSize);
- if (old != uniformPre) {
- ckfree((char *) old);
+ UniformGroup *newUG = (UniformGroup *) ckalloc(newSize);
+ UniformGroup *oldUG = uniformGroupPtr;
+
+ memcpy(newUG, oldUG, oldSize);
+ if (oldUG != uniformPre) {
+ ckfree((char *) oldUG);
}
- uniformGroupPtr = new;
+ uniformGroupPtr = newUG;
uniformGroupsAlloced += UNIFORM_PREALLOC;
}
uniformGroups++;
@@ -1907,54 +2101,58 @@ ResolveConstraints(masterPtr, slotType, maxOffset)
/*
* Step 3.
- * Determine the minimum slot offsets going from left to right
- * that would fit all of the slaves. This determines the minimum
+ * Determine the minimum slot offsets going from left to right that would
+ * fit all of the slaves. This determines the minimum
*/
- for (offset=slot=0; slot < gridCount; slot++) {
- layoutPtr[slot].minOffset = layoutPtr[slot].minSize + offset;
- for (slavePtr = layoutPtr[slot].binNextPtr; slavePtr != NULL;
- slavePtr = slavePtr->binNextPtr) {
- int span = (slotType == COLUMN) ? slavePtr->numCols : slavePtr->numRows;
- int required = slavePtr->size + layoutPtr[slot - span].minOffset;
- if (required > layoutPtr[slot].minOffset) {
- layoutPtr[slot].minOffset = required;
- }
- }
- offset = layoutPtr[slot].minOffset;
+ for (offset=0,slot=0; slot < gridCount; slot++) {
+ layoutPtr[slot].minOffset = layoutPtr[slot].minSize + offset;
+ for (slavePtr = layoutPtr[slot].binNextPtr; slavePtr != NULL;
+ slavePtr = slavePtr->binNextPtr) {
+ int span = (slotType == COLUMN) ?
+ slavePtr->numCols : slavePtr->numRows;
+ int required = slavePtr->size + layoutPtr[slot - span].minOffset;
+
+ if (required > layoutPtr[slot].minOffset) {
+ layoutPtr[slot].minOffset = required;
+ }
+ }
+ offset = layoutPtr[slot].minOffset;
}
/*
* At this point, we know the minimum required size of the entire layout.
- * It might be prudent to stop here if our "master" will resize itself
- * to this size.
+ * It might be prudent to stop here if our "master" will resize itself to
+ * this size.
*/
requiredSize = offset;
if (maxOffset > offset) {
- offset=maxOffset;
+ offset=maxOffset;
}
/*
* Step 4.
- * Determine the minimum slot offsets going from right to left,
- * bounding the pixel range of each slot boundary.
- * Pre-fill all of the right offsets with the actual size of the table;
- * they will be reduced as required.
+ * Determine the minimum slot offsets going from right to left, bounding
+ * the pixel range of each slot boundary. Pre-fill all of the right
+ * offsets with the actual size of the table; they will be reduced as
+ * required.
*/
for (slot=0; slot < gridCount; slot++) {
- layoutPtr[slot].maxOffset = offset;
+ layoutPtr[slot].maxOffset = offset;
}
for (slot=gridCount-1; slot > 0;) {
- for (slavePtr = layoutPtr[slot].binNextPtr; slavePtr != NULL;
- slavePtr = slavePtr->binNextPtr) {
- int span = (slotType == COLUMN) ? slavePtr->numCols : slavePtr->numRows;
- int require = offset - slavePtr->size;
- int startSlot = slot - span;
- if (startSlot >=0 && require < layoutPtr[startSlot].maxOffset) {
- layoutPtr[startSlot].maxOffset = require;
- }
+ for (slavePtr = layoutPtr[slot].binNextPtr; slavePtr != NULL;
+ slavePtr = slavePtr->binNextPtr) {
+ int span = (slotType == COLUMN) ?
+ slavePtr->numCols : slavePtr->numRows;
+ int require = offset - slavePtr->size;
+ int startSlot = slot - span;
+
+ if (startSlot >=0 && require < layoutPtr[startSlot].maxOffset) {
+ layoutPtr[startSlot].maxOffset = require;
+ }
}
offset -= layoutPtr[slot].minSize;
slot--;
@@ -1967,58 +2165,56 @@ ResolveConstraints(masterPtr, slotType, maxOffset)
/*
* Step 5.
- * At this point, each slot boundary has a range of values that
- * will satisfy the overall layout size.
- * Make repeated passes over the layout structure looking for
- * spans of slot boundaries where the minOffsets are less than
- * the maxOffsets, and adjust the offsets according to the slot
- * weights. At each pass, at least one slot boundary will have
- * its range of possible values fixed at a single value.
+ * At this point, each slot boundary has a range of values that will
+ * satisfy the overall layout size. Make repeated passes over the layout
+ * structure looking for spans of slot boundaries where the minOffsets are
+ * less than the maxOffsets, and adjust the offsets according to the slot
+ * weights. At each pass, at least one slot boundary will have its range
+ * of possible values fixed at a single value.
*/
- for (start=0; start < gridCount;) {
- int totalWeight = 0; /* Sum of the weights for all of the
- * slots in this span. */
- int need = 0; /* The minimum space needed to layout
- * this span. */
- int have; /* The actual amount of space that will
- * be taken up by this span. */
- int weight; /* Cumulative weights of the columns in
- * this span. */
- int noWeights = 0; /* True if the span has no weights. */
-
- /*
- * Find a span by identifying ranges of slots whose edges are
- * already constrained at fixed offsets, but whose internal
- * slot boundaries have a range of possible positions.
- */
-
- if (layoutPtr[start].minOffset == layoutPtr[start].maxOffset) {
+ for (start = 0; start < gridCount;) {
+ int totalWeight = 0; /* Sum of the weights for all of the slots in
+ * this span. */
+ int need = 0; /* The minimum space needed to layout this
+ * span. */
+ int have; /* The actual amount of space that will be
+ * taken up by this span. */
+ int weight; /* Cumulative weights of the columns in this
+ * span. */
+ int noWeights = 0; /* True if the span has no weights. */
+
+ /*
+ * Find a span by identifying ranges of slots whose edges are already
+ * constrained at fixed offsets, but whose internal slot boundaries
+ * have a range of possible positions.
+ */
+
+ if (layoutPtr[start].minOffset == layoutPtr[start].maxOffset) {
start++;
continue;
}
- for (end=start+1; end<gridCount; end++) {
+ for (end = start + 1; end < gridCount; end++) {
if (layoutPtr[end].minOffset == layoutPtr[end].maxOffset) {
break;
}
}
/*
- * We found a span. Compute the total weight, minumum space required,
- * for this span, and the actual amount of space the span should
- * use.
+ * We found a span. Compute the total weight, minumum space required,
+ * for this span, and the actual amount of space the span should use.
*/
- for (slot=start; slot<=end; slot++) {
+ for (slot = start; slot <= end; slot++) {
totalWeight += layoutPtr[slot].weight;
need += layoutPtr[slot].minSize;
}
have = layoutPtr[end].maxOffset - layoutPtr[start-1].minOffset;
/*
- * If all the weights in the span are zero, then distribute the
- * extra space evenly.
+ * If all the weights in the span are zero, then distribute the extra
+ * space evenly.
*/
if (totalWeight == 0) {
@@ -2028,100 +2224,180 @@ ResolveConstraints(masterPtr, slotType, maxOffset)
/*
* It might not be possible to give the span all of the space
- * available on this pass without violating the size constraints
- * of one or more of the internal slot boundaries.
- * Determine the maximum amount of space that when added to the
- * entire span, would cause a slot boundary to have its possible
- * range reduced to one value, and reduce the amount of extra
- * space allocated on this pass accordingly.
- *
- * The calculation is done cumulatively to avoid accumulating
- * roundoff errors.
+ * available on this pass without violating the size constraints of
+ * one or more of the internal slot boundaries. Try to determine the
+ * maximum amount of space that when added to the entire span, would
+ * cause a slot boundary to have its possible range reduced to one
+ * value, and reduce the amount of extra space allocated on this pass
+ * accordingly.
+ *
+ * The calculation is done cumulatively to avoid accumulating roundoff
+ * errors.
*/
- for (weight=0,slot=start; slot<end; slot++) {
- int diff = layoutPtr[slot].maxOffset - layoutPtr[slot].minOffset;
- weight += noWeights ? 1 : layoutPtr[slot].weight;
- if ((noWeights || layoutPtr[slot].weight>0) &&
- (diff*totalWeight/weight) < (have-need)) {
- have = diff * totalWeight / weight + need;
+ do {
+ int prevMinOffset = layoutPtr[start - 1].minOffset;
+
+ prevGrow = 0;
+ accWeight = 0;
+ for (slot = start; slot <= end; slot++) {
+ weight = noWeights ? 1 : layoutPtr[slot].weight;
+ accWeight += weight;
+ grow = (have - need) * accWeight / totalWeight - prevGrow;
+ prevGrow += grow;
+
+ if ((weight > 0) &&
+ ((prevMinOffset + layoutPtr[slot].minSize + grow)
+ > layoutPtr[slot].maxOffset)) {
+ int newHave;
+
+ /*
+ * There is not enough room to grow that much. Calculate
+ * how much this slot can grow and how much "have" that
+ * corresponds to.
+ */
+
+ grow = layoutPtr[slot].maxOffset -
+ layoutPtr[slot].minSize - prevMinOffset;
+ newHave = grow * totalWeight / weight;
+ if (newHave > totalWeight) {
+ /*
+ * By distributing multiples of totalWeight we
+ * minimize rounding errors since they will only
+ * happen in the last loop(s).
+ */
+
+ newHave = newHave / totalWeight * totalWeight;
+ }
+ if (newHave <= 0) {
+ /*
+ * We can end up with a "have" of 0 here if the
+ * previous slots have taken all the space. In that
+ * case we cannot guess an appropriate "have" so we
+ * just try some lower "have" that is >= 1, to make
+ * sure this terminates.
+ */
+
+ newHave = (have - need) - 1;
+ if (newHave > (3 * totalWeight)) {
+ /*
+ * Go down 25% for large values.
+ */
+ newHave = newHave * 3 / 4;
+ }
+
+ if (newHave > totalWeight) {
+ /*
+ * Round down to a multiple of totalWeight.
+ */
+ newHave = newHave / totalWeight * totalWeight;
+ }
+
+ if (newHave <= 0) {
+ newHave = 1;
+ }
+ }
+ have = newHave + need;
+
+ /*
+ * Restart loop to check if the new "have" will fit.
+ */
+
+ break;
+ }
+ prevMinOffset += layoutPtr[slot].minSize + grow;
+ if (prevMinOffset < layoutPtr[slot].minOffset) {
+ prevMinOffset = layoutPtr[slot].minOffset;
+ }
}
- }
+
+ /*
+ * Quit the outer loop if the inner loop ran all the way.
+ */
+ } while (slot <= end);
/*
- * Now distribute the extra space among the slots by
- * adjusting the minSizes and minOffsets.
+ * Now distribute the extra space among the slots by adjusting the
+ * minSizes and minOffsets.
*/
- for (weight=0,slot=start; slot<end; slot++) {
- weight += noWeights ? 1 : layoutPtr[slot].weight;
- layoutPtr[slot].minOffset +=
- (int)((double) (have-need) * weight/totalWeight + 0.5);
- layoutPtr[slot].minSize = layoutPtr[slot].minOffset
- - layoutPtr[slot-1].minOffset;
+ prevGrow = 0;
+ accWeight = 0;
+ for (slot = start; slot <= end; slot++) {
+ accWeight += noWeights ? 1 : layoutPtr[slot].weight;
+ grow = (have - need) * accWeight / totalWeight - prevGrow;
+ prevGrow += grow;
+ layoutPtr[slot].minSize += grow;
+ if ((layoutPtr[slot-1].minOffset + layoutPtr[slot].minSize)
+ > layoutPtr[slot].minOffset) {
+ layoutPtr[slot].minOffset = layoutPtr[slot-1].minOffset +
+ layoutPtr[slot].minSize;
+ }
}
- layoutPtr[slot].minSize = layoutPtr[slot].minOffset
- - layoutPtr[slot-1].minOffset;
/*
- * Having pushed the top/left boundaries of the slots to
- * take up extra space, the bottom/right space is recalculated
- * to propagate the new space allocation.
+ * Having pushed the top/left boundaries of the slots to take up extra
+ * space, the bottom/right space is recalculated to propagate the new
+ * space allocation.
*/
- for (slot=end; slot > start; slot--) {
- layoutPtr[slot-1].maxOffset =
- layoutPtr[slot].maxOffset-layoutPtr[slot].minSize;
+ for (slot = end; slot > start; slot--) {
+ /*
+ * maxOffset may not go up.
+ */
+
+ if ((layoutPtr[slot].maxOffset-layoutPtr[slot].minSize)
+ < layoutPtr[slot-1].maxOffset) {
+ layoutPtr[slot-1].maxOffset =
+ layoutPtr[slot].maxOffset-layoutPtr[slot].minSize;
+ }
}
}
-
/*
* Step 6.
- * All of the space has been apportioned; copy the
- * layout information back into the master.
+ * All of the space has been apportioned; copy the layout information back
+ * into the master.
*/
for (slot=0; slot < gridCount; slot++) {
- slotPtr[slot].offset = layoutPtr[slot].minOffset;
+ slotPtr[slot].offset = layoutPtr[slot].minOffset;
}
--layoutPtr;
if (layoutPtr != layoutData) {
- ckfree((char *)layoutPtr);
+ ckfree((char *) layoutPtr);
}
return requiredSize;
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* GetGrid --
*
- * This internal procedure is used to locate a Grid
- * structure for a given window, creating one if one
- * doesn't exist already.
+ * This internal procedure is used to locate a Grid structure for a given
+ * window, creating one if one doesn't exist already.
*
* Results:
- * The return value is a pointer to the Grid structure
- * corresponding to tkwin.
+ * The return value is a pointer to the Grid structure corresponding to
+ * tkwin.
*
* Side effects:
- * A new grid structure may be created. If so, then
- * a callback is set up to clean things up when the
- * window is deleted.
+ * A new grid structure may be created. If so, then a callback is set up
+ * to clean things up when the window is deleted.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static Gridder *
-GetGrid(tkwin)
- Tk_Window tkwin; /* Token for window for which
- * grid structure is desired. */
+GetGrid(
+ Tk_Window tkwin) /* Token for window for which grid structure
+ * is desired. */
{
register Gridder *gridPtr;
Tcl_HashEntry *hPtr;
- int new;
+ int isNew;
TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
if (!dispPtr->gridInit) {
@@ -2130,12 +2406,12 @@ GetGrid(tkwin)
}
/*
- * See if there's already grid for this window. If not,
- * then create a new one.
+ * See if there's already grid for this window. If not, then create a new
+ * one.
*/
- hPtr = Tcl_CreateHashEntry(&dispPtr->gridHashTable, (char *) tkwin, &new);
- if (!new) {
+ hPtr = Tcl_CreateHashEntry(&dispPtr->gridHashTable, (char*) tkwin, &isNew);
+ if (!isNew) {
return (Gridder *) Tcl_GetHashValue(hPtr);
}
gridPtr = (Gridder *) ckalloc(sizeof(Gridder));
@@ -2146,18 +2422,23 @@ GetGrid(tkwin)
gridPtr->slavePtr = NULL;
gridPtr->binNextPtr = NULL;
- gridPtr->column = gridPtr->row = -1;
+ gridPtr->column = -1;
+ gridPtr->row = -1;
gridPtr->numCols = 1;
gridPtr->numRows = 1;
- gridPtr->padX = gridPtr->padY = 0;
- gridPtr->padLeft = gridPtr->padTop = 0;
- gridPtr->iPadX = gridPtr->iPadY = 0;
+ gridPtr->padX = 0;
+ gridPtr->padY = 0;
+ gridPtr->padLeft = 0;
+ gridPtr->padTop = 0;
+ gridPtr->iPadX = 0;
+ gridPtr->iPadY = 0;
gridPtr->doubleBw = 2*Tk_Changes(tkwin)->border_width;
gridPtr->abortPtr = NULL;
gridPtr->flags = 0;
gridPtr->sticky = 0;
gridPtr->size = 0;
+ gridPtr->in = NULL;
gridPtr->masterDataPtr = NULL;
Tcl_SetHashValue(hPtr, gridPtr);
Tk_CreateEventHandler(tkwin, StructureNotifyMask,
@@ -2166,35 +2447,34 @@ GetGrid(tkwin)
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* SetGridSize --
*
- * This internal procedure sets the size of the grid occupied
- * by slaves.
+ * This internal procedure sets the size of the grid occupied by slaves.
*
* Results:
- * none
+ * None
*
* Side effects:
- * The width and height arguments are filled in the master data structure.
- * Additional space is allocated for the constraints to accomodate
- * the offsets.
+ * The width and height arguments are filled in the master data
+ * structure. Additional space is allocated for the constraints to
+ * accomodate the offsets.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static void
-SetGridSize(masterPtr)
- Gridder *masterPtr; /* The geometry master for this grid. */
+SetGridSize(
+ Gridder *masterPtr) /* The geometry master for this grid. */
{
- register Gridder *slavePtr; /* Current slave window. */
+ register Gridder *slavePtr; /* Current slave window. */
int maxX = 0, maxY = 0;
for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
- slavePtr = slavePtr->nextPtr) {
- maxX = MAX(maxX,slavePtr->numCols + slavePtr->column);
- maxY = MAX(maxY,slavePtr->numRows + slavePtr->row);
+ slavePtr = slavePtr->nextPtr) {
+ maxX = MAX(maxX, slavePtr->numCols + slavePtr->column);
+ maxY = MAX(maxY, slavePtr->numRows + slavePtr->row);
}
masterPtr->masterDataPtr->columnEnd = maxX;
masterPtr->masterDataPtr->rowEnd = maxY;
@@ -2207,37 +2487,37 @@ SetGridSize(masterPtr)
*
* SetSlaveColumn --
*
- * Update column data for a slave, checking that MAX_ELEMENT bound
+ * Update column data for a slave, checking that MAX_ELEMENT bound
* is not passed.
*
* Results:
- * TCL_ERROR if out of bounds, TCL_OK otherwise
+ * TCL_ERROR if out of bounds, TCL_OK otherwise
*
* Side effects:
- * Slave fields are updated.
+ * Slave fields are updated.
*
*----------------------------------------------------------------------
*/
static int
SetSlaveColumn(
- Tcl_Interp *interp, /* Interp for error message */
- Gridder *slavePtr, /* Slave to be updated */
- int column, /* New column or -1 to be unchanged */
- int numCols) /* New columnspan or -1 to be unchanged */
+ Tcl_Interp *interp, /* Interp for error message. */
+ Gridder *slavePtr, /* Slave to be updated. */
+ int column, /* New column or -1 to be unchanged. */
+ int numCols) /* New columnspan or -1 to be unchanged. */
{
int newColumn, newNumCols, lastCol;
- newColumn = (column >= 0) ? column : slavePtr->column;
+ newColumn = (column >= 0) ? column : slavePtr->column;
newNumCols = (numCols >= 1) ? numCols : slavePtr->numCols;
- lastCol = ((newColumn >= 0) ? newColumn : 0) + newNumCols;
+ lastCol = ((newColumn >= 0) ? newColumn : 0) + newNumCols;
if (lastCol >= MAX_ELEMENT) {
- Tcl_SetResult(interp, "Column out of bounds", TCL_STATIC);
- return TCL_ERROR;
+ Tcl_SetResult(interp, "Column out of bounds", TCL_STATIC);
+ return TCL_ERROR;
}
- slavePtr->column = newColumn;
+ slavePtr->column = newColumn;
slavePtr->numCols = newNumCols;
return TCL_OK;
}
@@ -2247,70 +2527,70 @@ SetSlaveColumn(
*
* SetSlaveRow --
*
- * Update row data for a slave, checking that MAX_ELEMENT bound
+ * Update row data for a slave, checking that MAX_ELEMENT bound
* is not passed.
*
* Results:
- * TCL_ERROR if out of bounds, TCL_OK otherwise
+ * TCL_ERROR if out of bounds, TCL_OK otherwise
*
* Side effects:
- * Slave fields are updated.
+ * Slave fields are updated.
*
*----------------------------------------------------------------------
*/
static int
SetSlaveRow(
- Tcl_Interp *interp, /* Interp for error message */
- Gridder *slavePtr, /* Slave to be updated */
- int row, /* New row or -1 to be unchanged */
- int numRows) /* New rowspan or -1 to be unchanged */
+ Tcl_Interp *interp, /* Interp for error message. */
+ Gridder *slavePtr, /* Slave to be updated. */
+ int row, /* New row or -1 to be unchanged. */
+ int numRows) /* New rowspan or -1 to be unchanged. */
{
int newRow, newNumRows, lastRow;
- newRow = (row >= 0) ? row : slavePtr->row;
+ newRow = (row >= 0) ? row : slavePtr->row;
newNumRows = (numRows >= 1) ? numRows : slavePtr->numRows;
- lastRow = ((newRow >= 0) ? newRow : 0) + newNumRows;
+ lastRow = ((newRow >= 0) ? newRow : 0) + newNumRows;
if (lastRow >= MAX_ELEMENT) {
- Tcl_SetResult(interp, "Row out of bounds", TCL_STATIC);
- return TCL_ERROR;
+ Tcl_SetResult(interp, "Row out of bounds", TCL_STATIC);
+ return TCL_ERROR;
}
- slavePtr->row = newRow;
+ slavePtr->row = newRow;
slavePtr->numRows = newNumRows;
return TCL_OK;
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* CheckSlotData --
*
- * This internal procedure is used to manage the storage for
- * row and column (slot) constraints.
+ * This internal procedure is used to manage the storage for row and
+ * column (slot) constraints.
*
* Results:
* TRUE if the index is OK, False otherwise.
*
* Side effects:
- * A new master grid structure may be created. If so, then
- * it is initialized. In addition, additional storage for
- * a row or column constraints may be allocated, and the constraint
- * maximums are adjusted.
+ * A new master grid structure may be created. If so, then it is
+ * initialized. In addition, additional storage for a row or column
+ * constraints may be allocated, and the constraint maximums are
+ * adjusted.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static int
-CheckSlotData(masterPtr, slot, slotType, checkOnly)
- Gridder *masterPtr; /* the geometry master for this grid */
- int slot; /* which slot to look at */
- int slotType; /* ROW or COLUMN */
- int checkOnly; /* don't allocate new space if true */
+CheckSlotData(
+ Gridder *masterPtr, /* The geometry master for this grid. */
+ int slot, /* Which slot to look at. */
+ int slotType, /* ROW or COLUMN. */
+ int checkOnly) /* Don't allocate new space if true. */
{
- int numSlot; /* number of slots already allocated (Space) */
- int end; /* last used constraint */
+ int numSlot; /* Number of slots already allocated (Space) */
+ int end; /* Last used constraint. */
/*
* If slot is out of bounds, return immediately.
@@ -2326,35 +2606,36 @@ CheckSlotData(masterPtr, slot, slotType, checkOnly)
/*
* If we need to allocate more space, allocate a little extra to avoid
- * repeated re-alloc's for large tables. We need enough space to
- * hold all of the offsets as well.
+ * repeated re-alloc's for large tables. We need enough space to hold all
+ * of the offsets as well.
*/
InitMasterData(masterPtr);
end = (slotType == ROW) ? masterPtr->masterDataPtr->rowMax :
masterPtr->masterDataPtr->columnMax;
if (checkOnly == CHECK_ONLY) {
- return (end < slot) ? TCL_ERROR : TCL_OK;
+ return ((end < slot) ? TCL_ERROR : TCL_OK);
} else {
- numSlot = (slotType == ROW) ? masterPtr->masterDataPtr->rowSpace
- : masterPtr->masterDataPtr->columnSpace;
+ numSlot = (slotType == ROW) ? masterPtr->masterDataPtr->rowSpace
+ : masterPtr->masterDataPtr->columnSpace;
if (slot >= numSlot) {
- int newNumSlot = slot + PREALLOC ;
- size_t oldSize = numSlot * sizeof(SlotInfo) ;
- size_t newSize = newNumSlot * sizeof(SlotInfo) ;
- SlotInfo *new = (SlotInfo *) ckalloc(newSize);
- SlotInfo *old = (slotType == ROW) ?
- masterPtr->masterDataPtr->rowPtr :
- masterPtr->masterDataPtr->columnPtr;
- memcpy((VOID *) new, (VOID *) old, oldSize );
- memset((VOID *) (new+numSlot), 0, newSize - oldSize );
- ckfree((char *) old);
+ int newNumSlot = slot + PREALLOC;
+ size_t oldSize = numSlot * sizeof(SlotInfo);
+ size_t newSize = newNumSlot * sizeof(SlotInfo);
+ SlotInfo *newSI = (SlotInfo *) ckalloc(newSize);
+ SlotInfo *oldSI = (slotType == ROW)
+ ? masterPtr->masterDataPtr->rowPtr
+ : masterPtr->masterDataPtr->columnPtr;
+
+ memcpy(newSI, oldSI, oldSize);
+ memset(newSI+numSlot, 0, newSize - oldSize);
+ ckfree((char *) oldSI);
if (slotType == ROW) {
- masterPtr->masterDataPtr->rowPtr = new ;
- masterPtr->masterDataPtr->rowSpace = newNumSlot ;
+ masterPtr->masterDataPtr->rowPtr = newSI;
+ masterPtr->masterDataPtr->rowSpace = newNumSlot;
} else {
- masterPtr->masterDataPtr->columnPtr = new;
- masterPtr->masterDataPtr->columnSpace = newNumSlot ;
+ masterPtr->masterDataPtr->columnPtr = newSI;
+ masterPtr->masterDataPtr->columnSpace = newNumSlot;
}
}
if (slot >= end && checkOnly != CHECK_SPACE) {
@@ -2369,33 +2650,31 @@ CheckSlotData(masterPtr, slot, slotType, checkOnly)
}
/*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* InitMasterData --
*
- * This internal procedure is used to allocate and initialize
- * the data for a geometry master, if the data
- * doesn't exist already.
+ * This internal procedure is used to allocate and initialize the data
+ * for a geometry master, if the data doesn't exist already.
*
* Results:
* none
*
* Side effects:
- * A new master grid structure may be created. If so, then
- * it is initialized.
+ * A new master grid structure may be created. If so, then it is
+ * initialized.
*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static void
-InitMasterData(masterPtr)
- Gridder *masterPtr;
+InitMasterData(
+ Gridder *masterPtr)
{
- size_t size;
if (masterPtr->masterDataPtr == NULL) {
- GridMaster *gridPtr = masterPtr->masterDataPtr =
- (GridMaster *) ckalloc(sizeof(GridMaster));
- size = sizeof(SlotInfo) * TYPICAL_SIZE;
+ GridMaster *gridPtr = masterPtr->masterDataPtr = (GridMaster *)
+ ckalloc(sizeof(GridMaster));
+ size_t size = sizeof(SlotInfo) * TYPICAL_SIZE;
gridPtr->columnEnd = 0;
gridPtr->columnMax = 0;
@@ -2407,9 +2686,10 @@ InitMasterData(masterPtr)
gridPtr->rowSpace = TYPICAL_SIZE;
gridPtr->startX = 0;
gridPtr->startY = 0;
+ gridPtr->anchor = GRID_DEFAULT_ANCHOR;
- memset((VOID *) gridPtr->columnPtr, 0, size);
- memset((VOID *) gridPtr->rowPtr, 0, size);
+ memset(gridPtr->columnPtr, 0, size);
+ memset(gridPtr->rowPtr, 0, size);
}
}
@@ -2418,21 +2698,21 @@ InitMasterData(masterPtr)
*
* Unlink --
*
- * Remove a grid from its parent's list of slaves.
+ * Remove a grid from its master's list of slaves.
*
* Results:
* None.
*
* Side effects:
- * The parent will be scheduled for re-arranging, and the size of the
+ * The master will be scheduled for re-arranging, and the size of the
* grid will be adjusted accordingly
*
*----------------------------------------------------------------------
*/
static void
-Unlink(slavePtr)
- register Gridder *slavePtr; /* Window to unlink. */
+Unlink(
+ register Gridder *slavePtr) /* Window to unlink. */
{
register Gridder *masterPtr, *slavePtr2;
@@ -2444,9 +2724,9 @@ Unlink(slavePtr)
if (masterPtr->slavePtr == slavePtr) {
masterPtr->slavePtr = slavePtr->nextPtr;
} else {
- for (slavePtr2 = masterPtr->slavePtr; ; slavePtr2 = slavePtr2->nextPtr) {
+ for (slavePtr2=masterPtr->slavePtr ; ; slavePtr2=slavePtr2->nextPtr) {
if (slavePtr2 == NULL) {
- panic("Unlink couldn't find previous window");
+ Tcl_Panic("Unlink couldn't find previous window");
}
if (slavePtr2->nextPtr == slavePtr) {
slavePtr2->nextPtr = slavePtr->nextPtr;
@@ -2471,11 +2751,11 @@ Unlink(slavePtr)
*
* DestroyGrid --
*
- * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release
- * to clean up the internal structure of a grid at a safe time
- * (when no-one is using it anymore). Cleaning up the grid involves
- * freeing the main structure for all windows. and the master structure
- * for geometry managers.
+ * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to
+ * clean up the internal structure of a grid at a safe time (when no-one
+ * is using it anymore). Cleaning up the grid involves freeing the main
+ * structure for all windows and the master structure for geometry
+ * managers.
*
* Results:
* None.
@@ -2487,8 +2767,8 @@ Unlink(slavePtr)
*/
static void
-DestroyGrid(memPtr)
- char *memPtr; /* Info about window that is now dead. */
+DestroyGrid(
+ char *memPtr) /* Info about window that is now dead. */
{
register Gridder *gridPtr = (Gridder *) memPtr;
@@ -2501,6 +2781,9 @@ DestroyGrid(memPtr)
}
ckfree((char *) gridPtr->masterDataPtr);
}
+ if (gridPtr->in != NULL) {
+ Tcl_DecrRefCount(gridPtr->in);
+ }
ckfree((char *) gridPtr);
}
@@ -2509,37 +2792,37 @@ DestroyGrid(memPtr)
*
* GridStructureProc --
*
- * This procedure is invoked by the Tk event dispatcher in response
- * to StructureNotify events.
+ * This procedure is invoked by the Tk event dispatcher in response to
+ * StructureNotify events.
*
* Results:
* None.
*
* Side effects:
* If a window was just deleted, clean up all its grid-related
- * information. If it was just resized, re-configure its slaves, if
- * any.
+ * information. If it was just resized, re-configure its slaves, if any.
*
*----------------------------------------------------------------------
*/
static void
-GridStructureProc(clientData, eventPtr)
- ClientData clientData; /* Our information about window
- * referred to by eventPtr. */
- XEvent *eventPtr; /* Describes what just happened. */
+GridStructureProc(
+ ClientData clientData, /* Our information about window referred to by
+ * 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)) {
+ if ((gridPtr->slavePtr != NULL)
+ && !(gridPtr->flags & REQUESTED_RELAYOUT)) {
gridPtr->flags |= REQUESTED_RELAYOUT;
Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr);
}
- if (gridPtr->doubleBw != 2*Tk_Changes(gridPtr->tkwin)->border_width) {
- if ((gridPtr->masterPtr != NULL) &&
- !(gridPtr->masterPtr->flags & REQUESTED_RELAYOUT)) {
+ if ((gridPtr->masterPtr != NULL) &&
+ (gridPtr->doubleBw != 2*Tk_Changes(gridPtr->tkwin)->border_width)) {
+ if (!(gridPtr->masterPtr->flags & REQUESTED_RELAYOUT)) {
gridPtr->doubleBw = 2*Tk_Changes(gridPtr->tkwin)->border_width;
gridPtr->masterPtr->flags |= REQUESTED_RELAYOUT;
Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr->masterPtr);
@@ -2552,7 +2835,7 @@ GridStructureProc(clientData, eventPtr)
Unlink(gridPtr);
}
for (gridPtr2 = gridPtr->slavePtr; gridPtr2 != NULL;
- gridPtr2 = nextPtr) {
+ gridPtr2 = nextPtr) {
Tk_UnmapWindow(gridPtr2->tkwin);
gridPtr2->masterPtr = NULL;
nextPtr = gridPtr2->nextPtr;
@@ -2566,7 +2849,8 @@ GridStructureProc(clientData, eventPtr)
gridPtr->tkwin = NULL;
Tcl_EventuallyFree((ClientData) gridPtr, DestroyGrid);
} else if (eventPtr->type == MapNotify) {
- if (!(gridPtr->flags & REQUESTED_RELAYOUT)) {
+ if ((gridPtr->slavePtr != NULL)
+ && !(gridPtr->flags & REQUESTED_RELAYOUT)) {
gridPtr->flags |= REQUESTED_RELAYOUT;
Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr);
}
@@ -2574,7 +2858,7 @@ GridStructureProc(clientData, eventPtr)
register Gridder *gridPtr2;
for (gridPtr2 = gridPtr->slavePtr; gridPtr2 != NULL;
- gridPtr2 = gridPtr2->nextPtr) {
+ gridPtr2 = gridPtr2->nextPtr) {
Tk_UnmapWindow(gridPtr2->tkwin);
}
}
@@ -2585,15 +2869,14 @@ GridStructureProc(clientData, eventPtr)
*
* ConfigureSlaves --
*
- * This implements the guts of the "grid configure" command. Given
- * a list of slaves and configuration options, it arranges for the
- * grid to manage the slaves and sets the specified options.
- * arguments consist of windows or window shortcuts followed by
- * "-option value" pairs.
+ * This implements the guts of the "grid configure" command. Given a list
+ * of slaves and configuration options, it arranges for the grid to
+ * manage the slaves and sets the specified options. Arguments consist
+ * of windows or window shortcuts followed by "-option value" pairs.
*
* Results:
- * TCL_OK is returned if all went well. Otherwise, TCL_ERROR is
- * returned and the interp's result is set to contain an error message.
+ * TCL_OK is returned if all went well. Otherwise, TCL_ERROR is returned
+ * and the interp's result is set to contain an error message.
*
* Side effects:
* Slave windows get taken over by the grid.
@@ -2602,57 +2885,90 @@ GridStructureProc(clientData, eventPtr)
*/
static int
-ConfigureSlaves(interp, tkwin, objc, objv)
- Tcl_Interp *interp; /* Interpreter for error reporting. */
- Tk_Window tkwin; /* Any window in application containing
- * slaves. Used to look up slave names. */
- int objc; /* Number of elements in argv. */
- Tcl_Obj *CONST objv[]; /* Argument objects: contains one or more
- * window names followed by any number
- * of "option value" pairs. Caller must
- * make sure that there is at least one
- * window name. */
+ConfigureSlaves(
+ Tcl_Interp *interp, /* Interpreter for error reporting. */
+ Tk_Window tkwin, /* Any window in application containing
+ * slaves. Used to look up slave names. */
+ int objc, /* Number of elements in argv. */
+ Tcl_Obj *CONST objv[]) /* Argument objects: contains one or more
+ * window names followed by any number of
+ * "option value" pairs. Caller must make sure
+ * that there is at least one window name. */
{
- Gridder *masterPtr;
+ Gridder *masterPtr = NULL;
Gridder *slavePtr;
Tk_Window other, slave, parent, ancestor;
int i, j, tmp;
- int length;
int numWindows;
int width;
- int defaultColumn = 0; /* default column number */
- int defaultColumnSpan = 1; /* default number of columns */
- char *lastWindow; /* use this window to base current
- * Row/col on */
- int numSkip; /* number of 'x' found */
+ int defaultRow = -1;
+ int defaultColumn = 0; /* Default column number */
+ int defaultColumnSpan = 1; /* Default number of columns */
+ char *lastWindow; /* Use this window to base current row/col
+ * on */
+ int numSkip; /* Number of 'x' found */
static CONST char *optionStrings[] = {
"-column", "-columnspan", "-in", "-ipadx", "-ipady",
- "-padx", "-pady", "-row", "-rowspan", "-sticky",
- (char *) NULL };
+ "-padx", "-pady", "-row", "-rowspan", "-sticky", NULL
+ };
enum options {
CONF_COLUMN, CONF_COLUMNSPAN, CONF_IN, CONF_IPADX, CONF_IPADY,
CONF_PADX, CONF_PADY, CONF_ROW, CONF_ROWSPAN, CONF_STICKY };
int index;
char *string;
- char firstChar, prevChar;
+ char firstChar;
+ int positionGiven;
/*
* Count the number of windows, or window short-cuts.
*/
firstChar = 0;
- for (numWindows = i = 0; i < objc; i++) {
- prevChar = firstChar;
+ for (numWindows=0, i=0; i < objc; i++) {
+ int length;
+ char prevChar = firstChar;
+
string = Tcl_GetStringFromObj(objv[i], &length);
firstChar = string[0];
-
+
if (firstChar == '.') {
+ /*
+ * Check that windows are valid, and locate the first slave's
+ * parent window (default for -in).
+ */
+
+ if (TkGetWindowFromObj(interp, tkwin, objv[i], &slave) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (masterPtr == NULL) {
+ /*
+ * Is there any saved -in from a removed slave?
+ * If there is, it becomes default for -in.
+ * If the stored master does not exist, just ignore it.
+ */
+
+ struct Gridder *slavePtr = GetGrid(slave);
+ if (slavePtr->in != NULL) {
+ if (TkGetWindowFromObj(interp, slave, slavePtr->in, &parent)
+ == TCL_OK) {
+ masterPtr = GetGrid(parent);
+ InitMasterData(masterPtr);
+ }
+ }
+ }
+ if (masterPtr == NULL) {
+ parent = Tk_Parent(slave);
+ if (parent != NULL) {
+ masterPtr = GetGrid(parent);
+ InitMasterData(masterPtr);
+ }
+ }
numWindows++;
continue;
}
if (length > 1 && i == 0) {
Tcl_AppendResult(interp, "bad argument \"", string,
- "\": must be name of window", (char *) NULL);
+ "\": must be name of window", NULL);
return TCL_ERROR;
}
if (length > 1 && firstChar == '-') {
@@ -2661,15 +2977,14 @@ ConfigureSlaves(interp, tkwin, objc, objv)
if (length > 1) {
Tcl_AppendResult(interp, "unexpected parameter, \"",
string, "\", in configure list. ",
- "Should be window name or option", (char *) NULL);
+ "Should be window name or option", NULL);
return TCL_ERROR;
}
if ((firstChar == REL_HORIZ) && ((numWindows == 0) ||
(prevChar == REL_SKIP) || (prevChar == REL_VERT))) {
Tcl_AppendResult(interp,
- "Must specify window before shortcut '-'.",
- (char *) NULL);
+ "Must specify window before shortcut '-'.", NULL);
return TCL_ERROR;
}
@@ -2679,36 +2994,79 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
Tcl_AppendResult(interp, "invalid window shortcut, \"",
- string, "\" should be '-', 'x', or '^'", (char *) NULL);
+ string, "\" should be '-', 'x', or '^'", NULL);
return TCL_ERROR;
}
numWindows = i;
if ((objc - numWindows) & 1) {
- Tcl_AppendResult(interp, "extra option or",
- " option with no value", (char *) NULL);
+ Tcl_AppendResult(interp, "extra option or option with no value", NULL);
return TCL_ERROR;
}
/*
- * Iterate over all of the slave windows and short-cuts, parsing
- * options for each slave. It's a bit wasteful to re-parse the
- * options for each slave, but things get too messy if we try to
- * parse the arguments just once at the beginning. For example,
- * if a slave already is managed we want to just change a few
- * existing values without resetting everything. If there are
- * multiple windows, the -in option only gets processed for the
- * first window.
+ * Go through all options looking for -in and -row, which are needed to be
+ * found first to handle the special case where ^ is used on a row without
+ * windows names, but with an -in option. Since all options are checked
+ * here, we do not need to handle the error case again later.
+ */
+
+ for (i = numWindows; i < objc; i += 2) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (index == CONF_IN) {
+ if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other) !=
+ TCL_OK) {
+ return TCL_ERROR;
+ }
+ masterPtr = GetGrid(other);
+ InitMasterData(masterPtr);
+ } else if (index == CONF_ROW) {
+ if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK
+ || tmp < 0) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "bad row value \"",
+ Tcl_GetString(objv[i+1]), "\": must be ",
+ "a non-negative integer", NULL);
+ return TCL_ERROR;
+ }
+ defaultRow = tmp;
+ }
+ }
+
+ /*
+ * If no -row is given, use the first unoccupied row of the master.
+ */
+
+ if (defaultRow < 0) {
+ if (masterPtr != NULL && masterPtr->masterDataPtr != NULL) {
+ SetGridSize(masterPtr);
+ defaultRow = masterPtr->masterDataPtr->rowEnd;
+ } else {
+ defaultRow = 0;
+ }
+ }
+
+ /*
+ * Iterate over all of the slave windows and short-cuts, parsing options
+ * for each slave. It's a bit wasteful to re-parse the options for each
+ * slave, but things get too messy if we try to parse the arguments just
+ * once at the beginning. For example, if a slave already is managed we
+ * want to just change a few existing values without resetting everything.
+ * If there are multiple windows, the -in option only gets processed for
+ * the first window.
*/
- masterPtr = NULL;
+ positionGiven = 0;
for (j = 0; j < numWindows; j++) {
string = Tcl_GetString(objv[j]);
firstChar = string[0];
/*
- * '^' and 'x' cause us to skip a column. '-' is processed
- * as part of its preceeding slave.
+ * '^' and 'x' cause us to skip a column. '-' is processed as part of
+ * its preceeding slave.
*/
if ((firstChar == REL_VERT) || (firstChar == REL_SKIP)) {
@@ -2722,6 +3080,7 @@ ConfigureSlaves(interp, tkwin, objc, objv)
for (defaultColumnSpan = 1; j + defaultColumnSpan < numWindows;
defaultColumnSpan++) {
char *string = Tcl_GetString(objv[j + defaultColumnSpan]);
+
if (*string != REL_HORIZ) {
break;
}
@@ -2733,7 +3092,7 @@ ConfigureSlaves(interp, tkwin, objc, objv)
if (Tk_TopWinHierarchy(slave)) {
Tcl_AppendResult(interp, "can't manage \"", Tcl_GetString(objv[j]),
- "\": it's a top-level window", (char *) NULL);
+ "\": it's a top-level window", NULL);
return TCL_ERROR;
}
slavePtr = GetGrid(slave);
@@ -2742,49 +3101,48 @@ ConfigureSlaves(interp, tkwin, objc, objv)
* The following statement is taken from tkPack.c:
*
* "If the slave isn't currently managed, reset all of its
- * configuration information to default values (there could
- * be old values left from a previous packer)."
+ * configuration information to default values (there could be old
+ * values left from a previous packer)."
*
- * I [D.S.] disagree with this statement. If a slave is disabled (using
- * "forget") and then re-enabled, I submit that 90% of the time the
- * programmer will want it to retain its old configuration information.
- * If the programmer doesn't want this behavior, then the
+ * I [D.S.] disagree with this statement. If a slave is disabled
+ * (using "forget") and then re-enabled, I submit that 90% of the time
+ * the programmer will want it to retain its old configuration
+ * information. If the programmer doesn't want this behavior, then the
* defaults can be reestablished by hand, without having to worry
- * about keeping track of the old state.
+ * about keeping track of the old state.
*/
for (i = numWindows; i < objc; i += 2) {
- if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0,
- &index) != TCL_OK) {
- return TCL_ERROR;
- }
- if (index == CONF_COLUMN) {
- if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK ||
- tmp < 0) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad column value \"",
- Tcl_GetString(objv[i+1]),
- "\": must be a non-negative integer", (char *)NULL);
+ Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0,
+ &index);
+ switch ((enum options) index) {
+ case CONF_COLUMN:
+ if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK
+ || tmp < 0) {
+ Tcl_AppendResult(interp, "bad column value \"",
+ Tcl_GetString(objv[i+1]), "\": must be ",
+ "a non-negative integer", NULL);
return TCL_ERROR;
}
if (SetSlaveColumn(interp, slavePtr, tmp, -1) != TCL_OK) {
return TCL_ERROR;
}
- } else if (index == CONF_COLUMNSPAN) {
- if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK ||
- tmp <= 0) {
- Tcl_ResetResult(interp);
+ break;
+ case CONF_COLUMNSPAN:
+ if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK
+ || tmp <= 0) {
Tcl_AppendResult(interp, "bad columnspan value \"",
- Tcl_GetString(objv[i+1]),
- "\": must be a positive integer", (char *)NULL);
+ Tcl_GetString(objv[i+1]), "\": must be ",
+ "a positive integer", NULL);
return TCL_ERROR;
}
if (SetSlaveColumn(interp, slavePtr, -1, tmp) != TCL_OK) {
return TCL_ERROR;
}
- } else if (index == CONF_IN) {
- if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other) !=
- TCL_OK) {
+ break;
+ case CONF_IN:
+ if (TkGetWindowFromObj(interp, tkwin, objv[i+1],
+ &other) != TCL_OK) {
return TCL_ERROR;
}
if (other == slave) {
@@ -2792,89 +3150,106 @@ ConfigureSlaves(interp, tkwin, objc, objv)
TCL_STATIC);
return TCL_ERROR;
}
+ positionGiven = 1;
masterPtr = GetGrid(other);
InitMasterData(masterPtr);
- } else if (index == CONF_IPADX) {
- if ((Tk_GetPixelsFromObj(interp, slave, objv[i+1], &tmp)
- != TCL_OK)
- || (tmp < 0)) {
- Tcl_ResetResult(interp);
+ break;
+ case CONF_STICKY: {
+ int sticky = StringToSticky(Tcl_GetString(objv[i+1]));
+
+ if (sticky == -1) {
+ Tcl_AppendResult(interp, "bad stickyness value \"",
+ Tcl_GetString(objv[i+1]), "\": must be ",
+ "a string containing n, e, s, and/or w", NULL);
+ return TCL_ERROR;
+ }
+ slavePtr->sticky = sticky;
+ break;
+ }
+ case CONF_IPADX:
+ if ((Tk_GetPixelsFromObj(NULL, slave, objv[i+1],
+ &tmp) != TCL_OK) || (tmp < 0)) {
Tcl_AppendResult(interp, "bad ipadx value \"",
- Tcl_GetString(objv[i+1]),
- "\": must be positive screen distance",
- (char *) NULL);
+ Tcl_GetString(objv[i+1]), "\": must be ",
+ "positive screen distance", NULL);
return TCL_ERROR;
}
slavePtr->iPadX = tmp*2;
- } else if (index == CONF_IPADY) {
- if ((Tk_GetPixelsFromObj(interp, slave, objv[i+1], &tmp)
- != TCL_OK)
- || (tmp < 0)) {
- Tcl_ResetResult(interp);
+ break;
+ case CONF_IPADY:
+ if ((Tk_GetPixelsFromObj(NULL, slave, objv[i+1],
+ &tmp) != TCL_OK) || (tmp < 0)) {
Tcl_AppendResult(interp, "bad ipady value \"",
- Tcl_GetString(objv[i+1]),
- "\": must be positive screen distance",
- (char *) NULL);
+ Tcl_GetString(objv[i+1]), "\": must be ",
+ "positive screen distance", NULL);
return TCL_ERROR;
}
slavePtr->iPadY = tmp*2;
- } else if (index == CONF_PADX) {
+ break;
+ case CONF_PADX:
if (TkParsePadAmount(interp, tkwin, objv[i+1],
&slavePtr->padLeft, &slavePtr->padX) != TCL_OK) {
return TCL_ERROR;
}
- } else if (index == CONF_PADY) {
+ break;
+ case CONF_PADY:
if (TkParsePadAmount(interp, tkwin, objv[i+1],
&slavePtr->padTop, &slavePtr->padY) != TCL_OK) {
return TCL_ERROR;
}
- } else if (index == CONF_ROW) {
- if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK
+ break;
+ case CONF_ROW:
+ if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK
|| tmp < 0) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad grid value \"",
+ Tcl_AppendResult(interp, "bad row value \"",
Tcl_GetString(objv[i+1]),
- "\": must be a non-negative integer", (char *)NULL);
+ "\": must be a non-negative integer", NULL);
return TCL_ERROR;
}
if (SetSlaveRow(interp, slavePtr, tmp, -1) != TCL_OK) {
return TCL_ERROR;
}
- } else if (index == CONF_ROWSPAN) {
- if ((Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK)
+ break;
+ case CONF_ROWSPAN:
+ if ((Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK)
|| tmp <= 0) {
- Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "bad rowspan value \"",
Tcl_GetString(objv[i+1]),
- "\": must be a positive integer", (char *)NULL);
+ "\": must be a positive integer", NULL);
return TCL_ERROR;
}
if (SetSlaveRow(interp, slavePtr, -1, tmp) != TCL_OK) {
return TCL_ERROR;
}
- } else if (index == CONF_STICKY) {
- int sticky = StringToSticky(Tcl_GetString(objv[i+1]));
- if (sticky == -1) {
- Tcl_AppendResult(interp, "bad stickyness value \"",
- Tcl_GetString(objv[i+1]),
- "\": must be a string containing n, e, s, and/or w",
- (char *)NULL);
- return TCL_ERROR;
- }
- slavePtr->sticky = sticky;
+ break;
}
}
/*
- * Make sure we have a geometry master. We look at:
- * 1) the -in flag
- * 2) the geometry master of the first slave (if specified)
- * 3) the parent of the first slave.
+ * If no position was specified via -in and the slave is already
+ * packed, then leave it in its current location.
*/
-
- if (masterPtr == NULL) {
+
+ if (!positionGiven && (slavePtr->masterPtr != NULL)) {
masterPtr = slavePtr->masterPtr;
+ goto scheduleLayout;
}
+
+ /*
+ * If the same -in window is passed in again, then just leave it in
+ * its current location.
+ */
+
+ if (positionGiven && (masterPtr == slavePtr->masterPtr)) {
+ goto scheduleLayout;
+ }
+
+ /*
+ * Make sure we have a geometry master. We look at:
+ * 1) the -in flag
+ * 2) the parent of the first slave.
+ */
+
parent = Tk_Parent(slave);
if (masterPtr == NULL) {
masterPtr = GetGrid(parent);
@@ -2888,15 +3263,16 @@ ConfigureSlaves(interp, tkwin, objc, objv)
if (slavePtr->masterPtr == NULL) {
Gridder *tempPtr = masterPtr->slavePtr;
+
slavePtr->masterPtr = masterPtr;
masterPtr->slavePtr = slavePtr;
slavePtr->nextPtr = tempPtr;
}
/*
- * Make sure that the slave's parent is either the master or
- * an ancestor of the master, and that the master and slave
- * aren't the same.
+ * Make sure that the slave's parent is either the master or an
+ * ancestor of the master, and that the master and slave aren't the
+ * same.
*/
for (ancestor = masterPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
@@ -2905,8 +3281,7 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
if (Tk_TopWinHierarchy(ancestor)) {
Tcl_AppendResult(interp, "can't put ", Tcl_GetString(objv[j]),
- " inside ", Tk_PathName(masterPtr->tkwin),
- (char *) NULL);
+ " inside ", Tk_PathName(masterPtr->tkwin), NULL);
Unlink(slavePtr);
return TCL_ERROR;
}
@@ -2919,8 +3294,7 @@ ConfigureSlaves(interp, tkwin, objc, objv)
if (masterPtr->masterPtr == slavePtr) {
Tcl_AppendResult(interp, "can't put ", Tcl_GetString(objv[j]),
" inside ", Tk_PathName(masterPtr->tkwin),
- ", would cause management loop.",
- (char *) NULL);
+ ", would cause management loop.", NULL);
Unlink(slavePtr);
return TCL_ERROR;
}
@@ -2932,7 +3306,7 @@ ConfigureSlaves(interp, tkwin, objc, objv)
*/
if (slavePtr->column == -1) {
- if (SetSlaveColumn(interp, slavePtr, defaultColumn, -1) != TCL_OK) {
+ if (SetSlaveColumn(interp, slavePtr, defaultColumn,-1) != TCL_OK){
return TCL_ERROR;
}
}
@@ -2941,23 +3315,18 @@ ConfigureSlaves(interp, tkwin, objc, objv)
return TCL_ERROR;
}
if (slavePtr->row == -1) {
- if (masterPtr->masterDataPtr == NULL) {
- slavePtr->row = 0;
- } else {
- if (SetSlaveRow(interp, slavePtr,
- masterPtr->masterDataPtr->rowEnd, -1) != TCL_OK) {
- return TCL_ERROR;
- }
+ if (SetSlaveRow(interp, slavePtr, defaultRow, -1) != TCL_OK) {
+ return TCL_ERROR;
}
}
defaultColumn += slavePtr->numCols;
defaultColumnSpan = 1;
/*
- * Arrange for the parent to be re-arranged at the first
- * idle moment.
+ * Arrange for the master to be re-arranged at the first idle moment.
*/
+ scheduleLayout:
if (masterPtr->abortPtr != NULL) {
*masterPtr->abortPtr = 1;
}
@@ -2967,14 +3336,16 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
}
- /* Now look for all the "^"'s. */
+ /*
+ * Now look for all the "^"'s.
+ */
lastWindow = NULL;
numSkip = 0;
for (j = 0; j < numWindows; j++) {
struct Gridder *otherPtr;
- int match; /* found a match for the ^ */
- int lastRow, lastColumn; /* implied end of table */
+ int match; /* Found a match for the ^ */
+ int lastRow, lastColumn; /* Implied end of table. */
string = Tcl_GetString(objv[j]);
firstChar = string[0];
@@ -2991,28 +3362,28 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
if (masterPtr == NULL) {
- Tcl_AppendResult(interp, "can't use '^', cant find master",
- (char *) NULL);
+ Tcl_AppendResult(interp, "can't use '^', cant find master", NULL);
return TCL_ERROR;
}
- /* Count the number of consecutive ^'s starting from this position */
+ /*
+ * Count the number of consecutive ^'s starting from this position.
+ */
+
for (width = 1; width + j < numWindows; width++) {
char *string = Tcl_GetString(objv[j+width]);
- if (*string != REL_VERT) break;
+
+ if (*string != REL_VERT) {
+ break;
+ }
}
/*
* Find the implied grid location of the ^
*/
- if (lastWindow == NULL) {
- if (masterPtr->masterDataPtr != NULL) {
- SetGridSize(masterPtr);
- lastRow = masterPtr->masterDataPtr->rowEnd - 2;
- } else {
- lastRow = 0;
- }
+ if (lastWindow == NULL) {
+ lastRow = defaultRow - 1;
lastColumn = 0;
} else {
other = Tk_NameToWindow(interp, lastWindow, tkwin);
@@ -3023,13 +3394,13 @@ ConfigureSlaves(interp, tkwin, objc, objv)
lastColumn += numSkip;
- for (match=0, slavePtr = masterPtr->slavePtr; slavePtr != NULL;
- slavePtr = slavePtr->nextPtr) {
+ match = 0;
+ for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
+ slavePtr = slavePtr->nextPtr) {
if (slavePtr->column == lastColumn
&& slavePtr->row + slavePtr->numRows - 1 == lastRow) {
if (slavePtr->numCols <= width) {
-
if (SetSlaveRow(interp, slavePtr, -1,
slavePtr->numRows + 1) != TCL_OK) {
return TCL_ERROR;
@@ -3044,14 +3415,13 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
if (!match) {
Tcl_AppendResult(interp, "can't find slave to extend with \"^\".",
- (char *) NULL);
+ NULL);
return TCL_ERROR;
}
}
if (masterPtr == NULL) {
- Tcl_AppendResult(interp, "can't determine master window",
- (char *) NULL);
+ Tcl_AppendResult(interp, "can't determine master window", NULL);
return TCL_ERROR;
}
SetGridSize(masterPtr);
@@ -3063,8 +3433,8 @@ ConfigureSlaves(interp, tkwin, objc, objv)
*
* StickyToString
*
- * Converts the internal boolean combination of "sticky" bits onto
- * a TCL list element containing zero or mor of n, s, e, or w.
+ * Converts the internal boolean combination of "sticky" bits onto a Tcl
+ * list element containing zero or more of n, s, e, or w.
*
* Results:
* A string is placed into the "result" pointer.
@@ -3076,9 +3446,9 @@ ConfigureSlaves(interp, tkwin, objc, objv)
*/
static void
-StickyToString(flags, result)
- int flags; /* the sticky flags */
- char *result; /* where to put the result */
+StickyToString(
+ int flags, /* The sticky flags. */
+ char *result) /* Where to put the result. */
{
int count = 0;
if (flags&STICK_NORTH) {
@@ -3096,7 +3466,7 @@ StickyToString(flags, result)
if (count) {
result[count] = '\0';
} else {
- sprintf(result,"{}");
+ sprintf(result, "{}");
}
}
@@ -3105,12 +3475,12 @@ StickyToString(flags, result)
*
* StringToSticky --
*
- * Converts an ascii string representing a widgets stickyness
- * into the boolean result.
+ * Converts an ascii string representing a widgets stickyness into the
+ * boolean result.
*
* Results:
- * The boolean combination of the "sticky" bits is retuned. If an
- * error occurs, such as an invalid character, -1 is returned instead.
+ * The boolean combination of the "sticky" bits is retuned. If an error
+ * occurs, such as an invalid character, -1 is returned instead.
*
* Side effects:
* none
@@ -3119,20 +3489,30 @@ StickyToString(flags, result)
*/
static int
-StringToSticky(string)
- char *string;
+StringToSticky(
+ char *string)
{
int sticky = 0;
char c;
while ((c = *string++) != '\0') {
switch (c) {
- case 'n': case 'N': sticky |= STICK_NORTH; break;
- case 'e': case 'E': sticky |= STICK_EAST; break;
- case 's': case 'S': sticky |= STICK_SOUTH; break;
- case 'w': case 'W': sticky |= STICK_WEST; break;
- case ' ': case ',': case '\t': case '\r': case '\n': break;
- default: return -1;
+ case 'n': case 'N':
+ sticky |= STICK_NORTH;
+ break;
+ case 'e': case 'E':
+ sticky |= STICK_EAST;
+ break;
+ case 's': case 'S':
+ sticky |= STICK_SOUTH;
+ break;
+ case 'w': case 'W':
+ sticky |= STICK_WEST;
+ break;
+ case ' ': case ',': case '\t': case '\r': case '\n':
+ break;
+ default:
+ return -1;
}
}
return sticky;
@@ -3155,14 +3535,14 @@ StringToSticky(string)
*/
static Tcl_Obj *
-NewPairObj(interp, val1, val2)
- Tcl_Interp *interp; /* Current interpreter. */
- int val1, val2;
+NewPairObj(
+ int val1, int val2)
{
- Tcl_Obj *res = Tcl_NewListObj(0, NULL);
- Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(val1));
- Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(val2));
- return res;
+ Tcl_Obj *ary[2];
+
+ ary[0] = Tcl_NewIntObj(val1);
+ ary[1] = Tcl_NewIntObj(val2);
+ return Tcl_NewListObj(2, ary);
}
/*
@@ -3182,14 +3562,22 @@ NewPairObj(interp, val1, val2)
*/
static Tcl_Obj *
-NewQuadObj(interp, val1, val2, val3, val4)
- Tcl_Interp *interp; /* Current interpreter. */
- int val1, val2, val3, val4;
+NewQuadObj(
+ int val1, int val2, int val3, int val4)
{
- Tcl_Obj *res = Tcl_NewListObj(0, NULL);
- Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(val1));
- Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(val2));
- Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(val3));
- Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(val4));
- return res;
+ Tcl_Obj *ary[4];
+
+ ary[0] = Tcl_NewIntObj(val1);
+ ary[1] = Tcl_NewIntObj(val2);
+ ary[2] = Tcl_NewIntObj(val3);
+ ary[3] = Tcl_NewIntObj(val4);
+ return Tcl_NewListObj(4, ary);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkImage.c b/generic/tkImage.c
index 35f013f..6c7c9cd 100644
--- a/generic/tkImage.c
+++ b/generic/tkImage.c
@@ -1,19 +1,17 @@
-/*
+/*
* tkImage.c --
*
- * This module implements the image protocol, which allows lots
- * of different kinds of images to be used in lots of different
- * widgets.
+ * This module implements the image protocol, which allows lots of
+ * different kinds of images to be used in lots of different widgets.
*
* Copyright (c) 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
-#include "tkPort.h"
/*
* Each call to Tk_GetImage returns a pointer to one of the following
@@ -25,114 +23,162 @@ typedef struct Image {
Tk_Window tkwin; /* Window passed to Tk_GetImage (needed to
* "re-get" the image later if the manager
* changes). */
- Display *display; /* Display for tkwin. Needed because when
- * the image is eventually freed tkwin may
- * not exist anymore. */
+ Display *display; /* Display for tkwin. Needed because when the
+ * image is eventually freed tkwin may not
+ * exist anymore. */
struct ImageMaster *masterPtr;
/* Master for this image (identifiers image
* manager, for example). */
- ClientData instanceData;
- /* One word argument to pass to image manager
+ ClientData instanceData; /* One word argument to pass to image manager
* when dealing with this image instance. */
Tk_ImageChangedProc *changeProc;
/* Code in widget to call when image changes
* in a way that affects redisplay. */
- ClientData widgetClientData;
- /* Argument to pass to changeProc. */
+ ClientData widgetClientData;/* Argument to pass to changeProc. */
struct Image *nextPtr; /* Next in list of all image instances
* associated with the same name. */
-
} Image;
/*
- * For each image master there is one of the following structures,
- * which represents a name in the image table and all of the images
- * instantiated from it. Entries in mainPtr->imageTable point to
- * these structures.
+ * For each image master there is one of the following structures, which
+ * represents a name in the image table and all of the images instantiated
+ * from it. Entries in mainPtr->imageTable point to these structures.
*/
typedef struct ImageMaster {
- Tk_ImageType *typePtr; /* Information about image type. NULL means
- * that no image manager owns this image: the
+ Tk_ImageType *typePtr; /* Information about image type. NULL means
+ * that no image manager owns this image: the
* image was deleted. */
- ClientData masterData; /* One-word argument to pass to image mgr
- * when dealing with the master, as opposed
- * to instances. */
+ ClientData masterData; /* One-word argument to pass to image mgr when
+ * dealing with the master, as opposed to
+ * instances. */
int width, height; /* Last known dimensions for image. */
- Tcl_HashTable *tablePtr; /* Pointer to hash table containing image
- * (the imageTable field in some TkMainInfo
+ Tcl_HashTable *tablePtr; /* Pointer to hash table containing image (the
+ * imageTable field in some TkMainInfo
* structure). */
- Tcl_HashEntry *hPtr; /* Hash entry in mainPtr->imageTable for
- * this structure (used to delete the hash
+ Tcl_HashEntry *hPtr; /* Hash entry in mainPtr->imageTable for this
+ * structure (used to delete the hash
* entry). */
Image *instancePtr; /* Pointer to first in list of instances
* derived from this name. */
int deleted; /* Flag set when image is being deleted. */
- TkWindow *winPtr; /* Main window of interpreter (used to
- * detect when the world is falling apart.) */
+ TkWindow *winPtr; /* Main window of interpreter (used to detect
+ * when the world is falling apart.) */
} ImageMaster;
typedef struct ThreadSpecificData {
- Tk_ImageType *imageTypeList;/* First in a list of all known image
- * types. */
- Tk_ImageType *oldImageTypeList;/* First in a list of all known old-style image
- * types. */
-} ThreadSpecificData;
+ Tk_ImageType *imageTypeList;/* First in a list of all known image
+ * types. */
+ Tk_ImageType *oldImageTypeList;
+ /* First in a list of all known old-style
+ * image types. */
+ int initialized; /* Set to 1 if we've initialized the
+ * structure. */
+} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
/*
- * Prototypes for local procedures:
+ * Prototypes for local functions:
*/
-static void DeleteImage _ANSI_ARGS_((ImageMaster *masterPtr));
-static void EventuallyDeleteImage _ANSI_ARGS_((ImageMaster *masterPtr,
- int forgetHashEntryNow));
+static void ImageTypeThreadExitProc(ClientData clientData);
+static void DeleteImage(ImageMaster *masterPtr);
+static void EventuallyDeleteImage(ImageMaster *masterPtr,
+ int forgetImageHashNow);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ImageTypeThreadExitProc --
+ *
+ * Clean up the registered list of image types.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The thread's linked lists of photo image formats is deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ImageTypeThreadExitProc(
+ ClientData clientData) /* not used */
+{
+ Tk_ImageType *freePtr;
+ ThreadSpecificData *tsdPtr =
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
+ while (tsdPtr->oldImageTypeList != NULL) {
+ freePtr = tsdPtr->oldImageTypeList;
+ tsdPtr->oldImageTypeList = tsdPtr->oldImageTypeList->nextPtr;
+ ckfree((char *) freePtr);
+ }
+ while (tsdPtr->imageTypeList != NULL) {
+ freePtr = tsdPtr->imageTypeList;
+ tsdPtr->imageTypeList = tsdPtr->imageTypeList->nextPtr;
+ ckfree((char *) freePtr);
+ }
+}
/*
*----------------------------------------------------------------------
*
* Tk_CreateOldImageType, Tk_CreateImageType --
*
- * This procedure is invoked by an image manager to tell Tk about
- * a new kind of image and the procedures that manage the new type.
- * The procedure is typically invoked during Tcl_AppInit.
+ * This function is invoked by an image manager to tell Tk about a new
+ * kind of image and the functions that manage the new type. The function
+ * is typically invoked during Tcl_AppInit.
*
* Results:
* None.
*
* Side effects:
- * The new image type is entered into a table used in the "image
- * create" command.
+ * The new image type is entered into a table used in the "image create"
+ * command.
*
*----------------------------------------------------------------------
*/
void
-Tk_CreateOldImageType(typePtr)
- Tk_ImageType *typePtr; /* Structure describing the type. All of
- * the fields except "nextPtr" must be filled
- * in by caller. Must not have been passed
- * to Tk_CreateImageType previously. */
+Tk_CreateOldImageType(
+ Tk_ImageType *typePtr) /* Structure describing the type. All of the
+ * fields except "nextPtr" must be filled in
+ * by caller. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tk_ImageType *copyPtr;
+ ThreadSpecificData *tsdPtr =
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- typePtr->nextPtr = tsdPtr->oldImageTypeList;
- tsdPtr->oldImageTypeList = typePtr;
+ if (!tsdPtr->initialized) {
+ tsdPtr->initialized = 1;
+ Tcl_CreateThreadExitHandler(ImageTypeThreadExitProc, NULL);
+ }
+ copyPtr = (Tk_ImageType *) ckalloc(sizeof(Tk_ImageType));
+ *copyPtr = *typePtr;
+ copyPtr->nextPtr = tsdPtr->oldImageTypeList;
+ tsdPtr->oldImageTypeList = copyPtr;
}
void
-Tk_CreateImageType(typePtr)
- Tk_ImageType *typePtr; /* Structure describing the type. All of
- * the fields except "nextPtr" must be filled
- * in by caller. Must not have been passed
- * to Tk_CreateImageType previously. */
+Tk_CreateImageType(
+ Tk_ImageType *typePtr) /* Structure describing the type. All of the
+ * fields except "nextPtr" must be filled in
+ * by caller. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tk_ImageType *copyPtr;
+ ThreadSpecificData *tsdPtr =
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- typePtr->nextPtr = tsdPtr->imageTypeList;
- tsdPtr->imageTypeList = typePtr;
+ if (!tsdPtr->initialized) {
+ tsdPtr->initialized = 1;
+ Tcl_CreateThreadExitHandler(ImageTypeThreadExitProc, NULL);
+ }
+ copyPtr = (Tk_ImageType *) ckalloc(sizeof(Tk_ImageType));
+ *copyPtr = *typePtr;
+ copyPtr->nextPtr = tsdPtr->imageTypeList;
+ tsdPtr->imageTypeList = copyPtr;
}
/*
@@ -140,8 +186,8 @@ Tk_CreateImageType(typePtr)
*
* Tk_ImageObjCmd --
*
- * This procedure is invoked to process the "image" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "image" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -153,30 +199,31 @@ Tk_CreateImageType(typePtr)
*/
int
-Tk_ImageObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument strings. */
+Tk_ImageObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument strings. */
{
static CONST char *imageOptions[] = {
"create", "delete", "height", "inuse", "names", "type", "types",
- "width", (char *) NULL
+ "width", NULL
};
enum options {
IMAGE_CREATE, IMAGE_DELETE, IMAGE_HEIGHT, IMAGE_INUSE, IMAGE_NAMES,
IMAGE_TYPE, IMAGE_TYPES, IMAGE_WIDTH
};
TkWindow *winPtr = (TkWindow *) clientData;
- int i, new, firstOption, index;
+ int i, isNew, firstOption, index;
Tk_ImageType *typePtr;
ImageMaster *masterPtr;
Image *imagePtr;
Tcl_HashEntry *hPtr;
Tcl_HashSearch search;
- char idString[16 + TCL_INTEGER_SPACE], *name;
+ char idString[16 + TCL_INTEGER_SPACE];
TkDisplay *dispPtr = winPtr->dispPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ char *arg, *name;
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (objc < 2) {
@@ -189,276 +236,256 @@ Tk_ImageObjCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
switch ((enum options) index) {
- case IMAGE_CREATE: {
- char *arg;
- Tcl_Obj **args;
- int oldimage = 0;
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "type ?name? ?options?");
- return TCL_ERROR;
- }
+ case IMAGE_CREATE: {
+ Tcl_Obj **args;
+ int oldimage = 0;
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "type ?name? ?options?");
+ return TCL_ERROR;
+ }
- /*
- * Look up the image type.
- */
+ /*
+ * Look up the image type.
+ */
- arg = Tcl_GetString(objv[2]);
- for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
- typePtr = typePtr->nextPtr) {
+ arg = Tcl_GetString(objv[2]);
+ for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
+ typePtr = typePtr->nextPtr) {
+ if ((*arg == typePtr->name[0])
+ && (strcmp(arg, typePtr->name) == 0)) {
+ break;
+ }
+ }
+ if (typePtr == NULL) {
+ oldimage = 1;
+ for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
+ typePtr = typePtr->nextPtr) {
if ((*arg == typePtr->name[0])
&& (strcmp(arg, typePtr->name) == 0)) {
break;
}
}
- if (typePtr == NULL) {
- oldimage = 1;
- for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
- typePtr = typePtr->nextPtr) {
- if ((*arg == typePtr->name[0])
- && (strcmp(arg, typePtr->name) == 0)) {
- break;
- }
- }
- }
- if (typePtr == NULL) {
- Tcl_AppendResult(interp, "image type \"", arg,
- "\" doesn't exist", (char *) NULL);
- return TCL_ERROR;
- }
+ }
+ if (typePtr == NULL) {
+ Tcl_AppendResult(interp, "image type \"", arg, "\" doesn't exist",
+ NULL);
+ return TCL_ERROR;
+ }
- /*
- * Figure out a name to use for the new image.
- */
+ /*
+ * Figure out a name to use for the new image.
+ */
- if ((objc == 3) || (*(arg = Tcl_GetString(objv[3])) == '-')) {
- Tcl_CmdInfo dummy;
- do {
- dispPtr->imageId++;
- sprintf(idString, "image%d", dispPtr->imageId);
- name = idString;
- } while (Tcl_GetCommandInfo(interp, name, &dummy) != 0);
- firstOption = 3;
- } else {
- TkWindow *topWin;
-
- name = arg;
- firstOption = 4;
- /*
- * Need to check if the _command_ that we are about to
- * create is the name of the current master widget
- * command (normally "." but could have been renamed)
- * and fail in that case before a really nasty and
- * hard to stop crash happens.
- */
- topWin = (TkWindow *) TkToplevelWindowForCommand(interp, name);
- if (topWin != NULL && winPtr->mainPtr->winPtr == topWin) {
- Tcl_AppendResult(interp, "images may not be named the ",
- "same as the main window", (char *) NULL);
- return TCL_ERROR;
- }
- }
+ if ((objc == 3) || (*(arg = Tcl_GetString(objv[3])) == '-')) {
+ Tcl_CmdInfo dummy;
+ do {
+ dispPtr->imageId++;
+ sprintf(idString, "image%d", dispPtr->imageId);
+ name = idString;
+ } while (Tcl_GetCommandInfo(interp, name, &dummy) != 0);
+ firstOption = 3;
+ } else {
+ TkWindow *topWin;
+
+ name = arg;
+ firstOption = 4;
/*
- * Create the data structure for the new image.
+ * Need to check if the _command_ that we are about to create is
+ * the name of the current master widget command (normally "." but
+ * could have been renamed) and fail in that case before a really
+ * nasty and hard to stop crash happens.
*/
- hPtr = Tcl_CreateHashEntry(&winPtr->mainPtr->imageTable,
- name, &new);
- if (new) {
- masterPtr = (ImageMaster *) ckalloc(sizeof(ImageMaster));
- masterPtr->typePtr = NULL;
- masterPtr->masterData = NULL;
- masterPtr->width = masterPtr->height = 1;
- masterPtr->tablePtr = &winPtr->mainPtr->imageTable;
- masterPtr->hPtr = hPtr;
- masterPtr->instancePtr = NULL;
- masterPtr->deleted = 0;
- masterPtr->winPtr = winPtr->mainPtr->winPtr;
- Tcl_Preserve((ClientData) masterPtr->winPtr);
- Tcl_SetHashValue(hPtr, masterPtr);
- } else {
- /*
- * An image already exists by this name. Disconnect the
- * instances from the master.
- */
-
- masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
- if (masterPtr->typePtr != NULL) {
- for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
- imagePtr = imagePtr->nextPtr) {
- (*masterPtr->typePtr->freeProc)(
- imagePtr->instanceData, imagePtr->display);
- (*imagePtr->changeProc)(imagePtr->widgetClientData,
- 0, 0, masterPtr->width, masterPtr->height,
- masterPtr->width, masterPtr->height);
- }
- (*masterPtr->typePtr->deleteProc)(masterPtr->masterData);
- masterPtr->typePtr = NULL;
- }
+ topWin = (TkWindow *) TkToplevelWindowForCommand(interp, name);
+ if (topWin != NULL && winPtr->mainPtr->winPtr == topWin) {
+ Tcl_AppendResult(interp, "images may not be named the ",
+ "same as the main window", NULL);
+ return TCL_ERROR;
}
+ }
+ /*
+ * Create the data structure for the new image.
+ */
+
+ hPtr = Tcl_CreateHashEntry(&winPtr->mainPtr->imageTable, name, &isNew);
+ if (isNew) {
+ masterPtr = (ImageMaster *) ckalloc(sizeof(ImageMaster));
+ masterPtr->typePtr = NULL;
+ masterPtr->masterData = NULL;
+ masterPtr->width = masterPtr->height = 1;
+ masterPtr->tablePtr = &winPtr->mainPtr->imageTable;
+ masterPtr->hPtr = hPtr;
+ masterPtr->instancePtr = NULL;
+ masterPtr->deleted = 0;
+ masterPtr->winPtr = winPtr->mainPtr->winPtr;
+ Tcl_Preserve((ClientData) masterPtr->winPtr);
+ Tcl_SetHashValue(hPtr, masterPtr);
+ } else {
/*
- * Call the image type manager so that it can perform its own
- * initialization, then re-"get" for any existing instances of
- * the image.
+ * An image already exists by this name. Disconnect the instances
+ * from the master.
*/
- objv += firstOption;
- objc -= firstOption;
- args = (Tcl_Obj **) objv;
- if (oldimage) {
- int i;
- args = (Tcl_Obj **) ckalloc((objc+1) * sizeof(char *));
- for (i = 0; i < objc; i++) {
- args[i] = (Tcl_Obj *) Tcl_GetString(objv[i]);
+ masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
+ if (masterPtr->typePtr != NULL) {
+ for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
+ imagePtr = imagePtr->nextPtr) {
+ (*masterPtr->typePtr->freeProc)(imagePtr->instanceData,
+ imagePtr->display);
+ (*imagePtr->changeProc)(imagePtr->widgetClientData,
+ 0, 0, masterPtr->width, masterPtr->height,
+ masterPtr->width, masterPtr->height);
}
- args[objc] = NULL;
+ (*masterPtr->typePtr->deleteProc)(masterPtr->masterData);
+ masterPtr->typePtr = NULL;
}
- Tcl_Preserve((ClientData) masterPtr);
- if ((*typePtr->createProc)(interp, name, objc,
- args, typePtr, (Tk_ImageMaster) masterPtr,
- &masterPtr->masterData) != TCL_OK) {
- EventuallyDeleteImage(masterPtr, 0);
- Tcl_Release((ClientData) masterPtr);
- if (oldimage) {
- ckfree((char *) args);
- }
- return TCL_ERROR;
+ masterPtr->deleted = 0;
+ }
+
+ /*
+ * Call the image type manager so that it can perform its own
+ * initialization, then re-"get" for any existing instances of the
+ * image.
+ */
+
+ objv += firstOption;
+ objc -= firstOption;
+ args = (Tcl_Obj **) objv;
+ if (oldimage) {
+ int i;
+
+ args = (Tcl_Obj **) ckalloc((objc+1) * sizeof(char *));
+ for (i = 0; i < objc; i++) {
+ args[i] = (Tcl_Obj *) Tcl_GetString(objv[i]);
}
+ args[objc] = NULL;
+ }
+ Tcl_Preserve((ClientData) masterPtr);
+ if ((*typePtr->createProc)(interp, name, objc, args, typePtr,
+ (Tk_ImageMaster)masterPtr, &masterPtr->masterData) != TCL_OK) {
+ EventuallyDeleteImage(masterPtr, 0);
Tcl_Release((ClientData) masterPtr);
if (oldimage) {
ckfree((char *) args);
}
- masterPtr->typePtr = typePtr;
- for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
- imagePtr = imagePtr->nextPtr) {
- imagePtr->instanceData = (*typePtr->getProc)(
- imagePtr->tkwin, masterPtr->masterData);
- }
- Tcl_SetResult(interp,
- Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr),
- TCL_STATIC);
- break;
+ return TCL_ERROR;
}
- case IMAGE_DELETE: {
- for (i = 2; i < objc; i++) {
- char *arg = Tcl_GetString(objv[i]);
- hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
- if (hPtr == NULL) {
- Tcl_AppendResult(interp, "image \"", arg,
- "\" doesn't exist", (char *) NULL);
- return TCL_ERROR;
- }
- DeleteImage((ImageMaster *) Tcl_GetHashValue(hPtr));
- }
- break;
+ Tcl_Release((ClientData) masterPtr);
+ if (oldimage) {
+ ckfree((char *) args);
}
- case IMAGE_HEIGHT: {
- char *arg;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "name");
- return TCL_ERROR;
- }
- arg = Tcl_GetString(objv[2]);
- hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
- if (hPtr == NULL) {
- Tcl_AppendResult(interp, "image \"", arg,
- "\" doesn't exist", (char *) NULL);
- return TCL_ERROR;
- }
- masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
- Tcl_SetIntObj(Tcl_GetObjResult(interp), masterPtr->height);
- break;
+ masterPtr->typePtr = typePtr;
+ for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
+ imagePtr = imagePtr->nextPtr) {
+ imagePtr->instanceData = (*typePtr->getProc)(imagePtr->tkwin,
+ masterPtr->masterData);
}
-
- case IMAGE_INUSE: {
- int count = 0;
- char *arg;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "name");
- return TCL_ERROR;
- }
- arg = Tcl_GetString(objv[2]);
+ Tcl_SetResult(interp,
+ Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr),
+ TCL_STATIC);
+ break;
+ }
+ case IMAGE_DELETE:
+ for (i = 2; i < objc; i++) {
+ arg = Tcl_GetString(objv[i]);
hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
if (hPtr == NULL) {
- Tcl_AppendResult(interp, "image \"", arg,
- "\" doesn't exist", (char *) NULL);
- return TCL_ERROR;
+ goto alreadyDeleted;
}
masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
- if (masterPtr->typePtr != NULL && masterPtr->instancePtr != NULL) {
- count = 1;
+ if (masterPtr->deleted) {
+ goto alreadyDeleted;
}
- Tcl_SetBooleanObj(Tcl_GetObjResult(interp), count);
- break;
+ DeleteImage(masterPtr);
}
-
- case IMAGE_NAMES: {
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
+ break;
+ case IMAGE_NAMES:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ hPtr = Tcl_FirstHashEntry(&winPtr->mainPtr->imageTable, &search);
+ for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+ masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
+ if (masterPtr->deleted) {
+ continue;
}
- hPtr = Tcl_FirstHashEntry(&winPtr->mainPtr->imageTable, &search);
- for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- Tcl_AppendElement(interp, Tcl_GetHashKey(
+ Tcl_AppendElement(interp, Tcl_GetHashKey(
&winPtr->mainPtr->imageTable, hPtr));
- }
- break;
}
-
- case IMAGE_TYPE: {
- char *arg;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "name");
- return TCL_ERROR;
- }
- arg = Tcl_GetString(objv[2]);
- hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
- if (hPtr == NULL) {
- Tcl_AppendResult(interp, "image \"", arg,
- "\" doesn't exist", (char *) NULL);
- return TCL_ERROR;
- }
- masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
+ break;
+ case IMAGE_TYPES:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
+ typePtr = typePtr->nextPtr) {
+ Tcl_AppendElement(interp, typePtr->name);
+ }
+ for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
+ typePtr = typePtr->nextPtr) {
+ Tcl_AppendElement(interp, typePtr->name);
+ }
+ break;
+
+ case IMAGE_HEIGHT:
+ case IMAGE_INUSE:
+ case IMAGE_TYPE:
+ case IMAGE_WIDTH:
+ /*
+ * These operations all parse virtually identically. First check to
+ * see if three args are given. Then get a non-deleted master from the
+ * third arg.
+ */
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name");
+ return TCL_ERROR;
+ }
+
+ arg = Tcl_GetString(objv[2]);
+ hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
+ if (hPtr == NULL) {
+ goto alreadyDeleted;
+ }
+ masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
+ if (masterPtr->deleted) {
+ goto alreadyDeleted;
+ }
+
+ /*
+ * Now we read off the specific piece of data we were asked for.
+ */
+
+ switch ((enum options) index) {
+ case IMAGE_HEIGHT:
+ Tcl_SetIntObj(Tcl_GetObjResult(interp), masterPtr->height);
+ break;
+ case IMAGE_INUSE:
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
+ masterPtr->typePtr!=NULL && masterPtr->instancePtr!=NULL);
+ break;
+ case IMAGE_TYPE:
if (masterPtr->typePtr != NULL) {
Tcl_SetResult(interp, masterPtr->typePtr->name, TCL_STATIC);
}
break;
- }
- case IMAGE_TYPES: {
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
- }
- for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
- typePtr = typePtr->nextPtr) {
- Tcl_AppendElement(interp, typePtr->name);
- }
- for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
- typePtr = typePtr->nextPtr) {
- Tcl_AppendElement(interp, typePtr->name);
- }
- break;
- }
- case IMAGE_WIDTH: {
- char *arg;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "name");
- return TCL_ERROR;
- }
- arg = Tcl_GetString(objv[2]);
- hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg);
- if (hPtr == NULL) {
- Tcl_AppendResult(interp, "image \"", arg,
- "\" doesn't exist", (char *) NULL);
- return TCL_ERROR;
- }
- masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
+ case IMAGE_WIDTH:
Tcl_SetIntObj(Tcl_GetObjResult(interp), masterPtr->width);
break;
+ default:
+ Tcl_Panic("can't happen");
}
+ break;
}
return TCL_OK;
+
+ alreadyDeleted:
+ Tcl_AppendResult(interp, "image \"", arg, "\" doesn't exist", NULL);
+ return TCL_ERROR;
}
/*
@@ -466,33 +493,32 @@ Tk_ImageObjCmd(clientData, interp, objc, objv)
*
* Tk_ImageChanged --
*
- * This procedure is called by an image manager whenever something
- * has happened that requires the image to be redrawn (some of its
- * pixels have changed, or its size has changed).
+ * This function is called by an image manager whenever something has
+ * happened that requires the image to be redrawn (some of its pixels
+ * have changed, or its size has changed).
*
* Results:
* None.
*
* Side effects:
- * Any widgets that display the image are notified so that they
- * can redisplay themselves as appropriate.
+ * Any widgets that display the image are notified so that they can
+ * redisplay themselves as appropriate.
*
*----------------------------------------------------------------------
*/
void
-Tk_ImageChanged(imageMaster, x, y, width, height, imageWidth,
- imageHeight)
- Tk_ImageMaster imageMaster; /* Image that needs redisplay. */
- int x, y; /* Coordinates of upper-left pixel of
- * region of image that needs to be
- * redrawn. */
- int width, height; /* Dimensions (in pixels) of region of
- * image to redraw. If either dimension
- * is zero then the image doesn't need to
- * be redrawn (perhaps all that happened is
- * that its size changed). */
- int imageWidth, imageHeight;/* New dimensions of image. */
+Tk_ImageChanged(
+ Tk_ImageMaster imageMaster, /* Image that needs redisplay. */
+ int x, int y, /* Coordinates of upper-left pixel of region
+ * of image that needs to be redrawn. */
+ int width, int height, /* Dimensions (in pixels) of region of image
+ * to redraw. If either dimension is zero then
+ * the image doesn't need to be redrawn
+ * (perhaps all that happened is that its size
+ * changed). */
+ int imageWidth, int imageHeight)
+ /* New dimensions of image. */
{
ImageMaster *masterPtr = (ImageMaster *) imageMaster;
Image *imagePtr;
@@ -500,7 +526,7 @@ Tk_ImageChanged(imageMaster, x, y, width, height, imageWidth,
masterPtr->width = imageWidth;
masterPtr->height = imageHeight;
for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
- imagePtr = imagePtr->nextPtr) {
+ imagePtr = imagePtr->nextPtr) {
(*imagePtr->changeProc)(imagePtr->widgetClientData, x, y,
width, height, imageWidth, imageHeight);
}
@@ -511,8 +537,8 @@ Tk_ImageChanged(imageMaster, x, y, width, height, imageWidth,
*
* Tk_NameOfImage --
*
- * Given a token for an image master, this procedure returns
- * the name of the image.
+ * Given a token for an image master, this function returns the name of
+ * the image.
*
* Results:
* The return value is the string name for imageMaster.
@@ -524,8 +550,8 @@ Tk_ImageChanged(imageMaster, x, y, width, height, imageWidth,
*/
CONST char *
-Tk_NameOfImage(imageMaster)
- Tk_ImageMaster imageMaster; /* Token for image. */
+Tk_NameOfImage(
+ Tk_ImageMaster imageMaster) /* Token for image. */
{
ImageMaster *masterPtr = (ImageMaster *) imageMaster;
@@ -540,36 +566,34 @@ Tk_NameOfImage(imageMaster)
*
* Tk_GetImage --
*
- * This procedure is invoked by a widget when it wants to use
- * a particular image in a particular window.
+ * This function is invoked by a widget when it wants to use a particular
+ * image in a particular window.
*
* 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 the interp's result.
+ * 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 the
+ * interp's result.
*
* Side effects:
- * Tk records the fact that the widget is using the image, and
- * it will invoke changeProc later if the widget needs redisplay
- * (i.e. its size changes or some of its pixels change). The
- * caller must eventually invoke Tk_FreeImage when it no longer
- * needs the image.
+ * Tk records the fact that the widget is using the image, and it will
+ * invoke changeProc later if the widget needs redisplay (i.e. its size
+ * changes or some of its pixels change). The caller must eventually
+ * invoke Tk_FreeImage when it no longer needs the image.
*
*----------------------------------------------------------------------
*/
Tk_Image
-Tk_GetImage(interp, tkwin, name, changeProc, clientData)
- Tcl_Interp *interp; /* Place to leave error message if image
- * can't be found. */
- Tk_Window tkwin; /* Token for window in which image will
- * be used. */
- CONST char *name; /* Name of desired image. */
- Tk_ImageChangedProc *changeProc;
- /* Procedure to invoke when redisplay is
- * needed because image's pixels or size
- * changed. */
- ClientData clientData; /* One-word argument to pass to damageProc. */
+Tk_GetImage(
+ Tcl_Interp *interp, /* Place to leave error message if image can't
+ * be found. */
+ Tk_Window tkwin, /* Token for window in which image will be
+ * used. */
+ CONST char *name, /* Name of desired image. */
+ Tk_ImageChangedProc *changeProc,
+ /* Function to invoke when redisplay is needed
+ * because image's pixels or size changed. */
+ ClientData clientData) /* One-word argument to pass to damageProc. */
{
Tcl_HashEntry *hPtr;
ImageMaster *masterPtr;
@@ -583,6 +607,9 @@ Tk_GetImage(interp, tkwin, name, changeProc, clientData)
if (masterPtr->typePtr == NULL) {
goto noSuchImage;
}
+ if (masterPtr->deleted) {
+ goto noSuchImage;
+ }
imagePtr = (Image *) ckalloc(sizeof(Image));
imagePtr->tkwin = tkwin;
imagePtr->display = Tk_Display(tkwin);
@@ -595,9 +622,10 @@ Tk_GetImage(interp, tkwin, name, changeProc, clientData)
masterPtr->instancePtr = imagePtr;
return (Tk_Image) imagePtr;
- noSuchImage:
- Tcl_AppendResult(interp, "image \"", name, "\" doesn't exist",
- (char *) NULL);
+ noSuchImage:
+ if (interp) {
+ Tcl_AppendResult(interp, "image \"", name, "\" doesn't exist", NULL);
+ }
return NULL;
}
@@ -606,9 +634,9 @@ Tk_GetImage(interp, tkwin, name, changeProc, clientData)
*
* Tk_FreeImage --
*
- * This procedure is invoked by a widget when it no longer needs
- * an image acquired by a previous call to Tk_GetImage. For each
- * call to Tk_GetImage there must be exactly one call to Tk_FreeImage.
+ * This function is invoked by a widget when it no longer needs an image
+ * acquired by a previous call to Tk_GetImage. For each call to
+ * Tk_GetImage there must be exactly one call to Tk_FreeImage.
*
* Results:
* None.
@@ -620,9 +648,9 @@ Tk_GetImage(interp, tkwin, name, changeProc, clientData)
*/
void
-Tk_FreeImage(image)
- Tk_Image image; /* Token for image that is no longer
- * needed by a widget. */
+Tk_FreeImage(
+ Tk_Image image) /* Token for image that is no longer needed by
+ * a widget. */
{
Image *imagePtr = (Image *) image;
ImageMaster *masterPtr = imagePtr->masterPtr;
@@ -647,16 +675,16 @@ Tk_FreeImage(image)
}
ckfree((char *) imagePtr);
- /*
- * If there are no more instances left for the master, and if the
- * master image has been deleted, then delete the master too.
+ /*
+ * If there are no more instances left for the master, and if the master
+ * image has been deleted, then delete the master too.
*/
if ((masterPtr->typePtr == NULL) && (masterPtr->instancePtr == NULL)) {
if (masterPtr->hPtr != NULL) {
Tcl_DeleteHashEntry(masterPtr->hPtr);
}
- Tcl_Release(masterPtr->winPtr);
+ Tcl_Release((ClientData) masterPtr->winPtr);
ckfree((char *) masterPtr);
}
}
@@ -666,29 +694,29 @@ Tk_FreeImage(image)
*
* Tk_PostscriptImage --
*
- * This procedure is called by widgets that contain images in order
- * to redisplay an image on the screen or an off-screen pixmap.
+ * This function is called by widgets that contain images in order to
+ * redisplay an image on the screen or an off-screen pixmap.
*
* Results:
* None.
*
* Side effects:
- * The image's manager is notified, and it redraws the desired
- * portion of the image before returning.
+ * The image's manager is notified, and it redraws the desired portion of
+ * the image before returning.
*
*----------------------------------------------------------------------
*/
int
-Tk_PostscriptImage(image, interp, tkwin, psinfo, x, y, width, height, prepass)
- Tk_Image image; /* Token for image to redisplay. */
- Tcl_Interp *interp;
- Tk_Window tkwin;
- Tk_PostscriptInfo psinfo; /* postscript info */
- int x, y; /* Upper-left pixel of region in image that
+Tk_PostscriptImage(
+ Tk_Image image, /* Token for image to redisplay. */
+ Tcl_Interp *interp,
+ Tk_Window tkwin,
+ Tk_PostscriptInfo psinfo, /* postscript info */
+ int x, int y, /* Upper-left pixel of region in image that
* needs to be redisplayed. */
- int width, height; /* Dimensions of region to redraw. */
- int prepass;
+ int width, int height, /* Dimensions of region to redraw. */
+ int prepass)
{
Image *imagePtr = (Image *) image;
int result;
@@ -701,12 +729,13 @@ Tk_PostscriptImage(image, interp, tkwin, psinfo, x, y, width, height, prepass)
/*
* No master for image, so nothing to display on postscript.
*/
+
return TCL_OK;
}
/*
- * Check if an image specific postscript-generation function
- * exists; otherwise go on with generic code.
+ * Check if an image specific postscript-generation function exists;
+ * otherwise go on with generic code.
*/
if (imagePtr->masterPtr->typePtr->postscriptProc != NULL) {
@@ -721,12 +750,12 @@ Tk_PostscriptImage(image, interp, tkwin, psinfo, x, y, width, height, prepass)
/*
* Create a Pixmap, tell the image to redraw itself there, and then
- * generate an XImage from the Pixmap. We can then read pixel
- * values out of the XImage.
+ * generate an XImage from the Pixmap. We can then read pixel values out
+ * of the XImage.
*/
- pmap = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin),
- width, height, Tk_Depth(tkwin));
+ pmap = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin), width, height,
+ Tk_Depth(tkwin));
gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin));
newGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
@@ -742,11 +771,13 @@ Tk_PostscriptImage(image, interp, tkwin, psinfo, x, y, width, height, prepass)
(unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap);
Tk_FreePixmap(Tk_Display(tkwin), pmap);
-
+
if (ximage == NULL) {
- /* The XGetImage() function is apparently not
- * implemented on this system. Just ignore it.
+ /*
+ * The XGetImage() function is apparently not implemented on this
+ * system. Just ignore it.
*/
+
return TCL_OK;
}
result = TkPostscriptImage(interp, tkwin, psinfo, ximage, x, y,
@@ -755,39 +786,38 @@ Tk_PostscriptImage(image, interp, tkwin, psinfo, x, y, width, height, prepass)
XDestroyImage(ximage);
return result;
}
-
+
/*
*----------------------------------------------------------------------
*
* Tk_RedrawImage --
*
- * This procedure is called by widgets that contain images in order
- * to redisplay an image on the screen or an off-screen pixmap.
+ * This function is called by widgets that contain images in order to
+ * redisplay an image on the screen or an off-screen pixmap.
*
* Results:
* None.
*
* Side effects:
- * The image's manager is notified, and it redraws the desired
- * portion of the image before returning.
+ * The image's manager is notified, and it redraws the desired portion of
+ * the image before returning.
*
*----------------------------------------------------------------------
*/
void
-Tk_RedrawImage(image, imageX, imageY, width, height, drawable,
- drawableX, drawableY)
- Tk_Image image; /* Token for image to redisplay. */
- int imageX, imageY; /* Upper-left pixel of region in image that
+Tk_RedrawImage(
+ Tk_Image image, /* Token for image to redisplay. */
+ int imageX, int imageY, /* Upper-left pixel of region in image that
* needs to be redisplayed. */
- int width, height; /* Dimensions of region to redraw. */
- Drawable drawable; /* Drawable in which to display image
- * (window or pixmap). If this is a pixmap,
- * it must have the same depth as the window
- * used in the Tk_GetImage call for the
- * image. */
- int drawableX, drawableY; /* Coordinates in drawable that correspond
- * to imageX and imageY. */
+ int width, int height, /* Dimensions of region to redraw. */
+ Drawable drawable, /* Drawable in which to display image (window
+ * or pixmap). If this is a pixmap, it must
+ * have the same depth as the window used in
+ * the Tk_GetImage call for the image. */
+ int drawableX, int drawableY)
+ /* Coordinates in drawable that correspond to
+ * imageX and imageY. */
{
Image *imagePtr = (Image *) image;
@@ -829,11 +859,11 @@ Tk_RedrawImage(image, imageX, imageY, width, height, drawable,
*
* Tk_SizeOfImage --
*
- * This procedure returns the current dimensions of an image.
+ * This function returns the current dimensions of an image.
*
* Results:
- * The width and height of the image are returned in *widthPtr
- * and *heightPtr.
+ * The width and height of the image are returned in *widthPtr and
+ * *heightPtr.
*
* Side effects:
* None.
@@ -842,10 +872,10 @@ Tk_RedrawImage(image, imageX, imageY, width, height, drawable,
*/
void
-Tk_SizeOfImage(image, widthPtr, heightPtr)
- Tk_Image image; /* Token for image whose size is wanted. */
- int *widthPtr; /* Return width of image here. */
- int *heightPtr; /* Return height of image here. */
+Tk_SizeOfImage(
+ Tk_Image image, /* Token for image whose size is wanted. */
+ int *widthPtr, /* Return width of image here. */
+ int *heightPtr) /* Return height of image here. */
{
Image *imagePtr = (Image *) image;
@@ -858,25 +888,23 @@ Tk_SizeOfImage(image, widthPtr, heightPtr)
*
* Tk_DeleteImage --
*
- * Given the name of an image, this procedure destroys the
- * image.
+ * Given the name of an image, this function destroys the image.
*
* Results:
* None.
*
* Side effects:
- * The image is destroyed; existing instances will display as
- * blank areas. If no such image exists then the procedure does
- * nothing.
+ * The image is destroyed; existing instances will display as blank
+ * areas. If no such image exists then the function does nothing.
*
*----------------------------------------------------------------------
*/
void
-Tk_DeleteImage(interp, name)
- Tcl_Interp *interp; /* Interpreter in which the image was
+Tk_DeleteImage(
+ Tcl_Interp *interp, /* Interpreter in which the image was
* created. */
- CONST char *name; /* Name of image. */
+ CONST char *name) /* Name of image. */
{
Tcl_HashEntry *hPtr;
TkWindow *winPtr;
@@ -897,22 +925,22 @@ Tk_DeleteImage(interp, name)
*
* DeleteImage --
*
- * This procedure is responsible for deleting an image.
+ * This function is responsible for deleting an image.
*
* Results:
* None.
*
* Side effects:
- * The connection is dropped between instances of this image and
- * an image master. Image instances will redisplay themselves
- * as empty areas, but existing instances will not be deleted.
+ * The connection is dropped between instances of this image and an image
+ * master. Image instances will redisplay themselves as empty areas, but
+ * existing instances will not be deleted.
*
*----------------------------------------------------------------------
*/
static void
-DeleteImage(masterPtr)
- ImageMaster *masterPtr; /* Pointer to main data structure for image. */
+DeleteImage(
+ ImageMaster *masterPtr) /* Pointer to main data structure for image. */
{
Image *imagePtr;
Tk_ImageType *typePtr;
@@ -922,9 +950,9 @@ DeleteImage(masterPtr)
if (typePtr != NULL) {
for (imagePtr = masterPtr->instancePtr; imagePtr != NULL;
imagePtr = imagePtr->nextPtr) {
- (*typePtr->freeProc)(imagePtr->instanceData,
- imagePtr->display);
- (*imagePtr->changeProc)(imagePtr->widgetClientData, 0, 0,
+ (*typePtr->freeProc)(imagePtr->instanceData,
+ imagePtr->display);
+ (*imagePtr->changeProc)(imagePtr->widgetClientData, 0, 0,
masterPtr->width, masterPtr->height, masterPtr->width,
masterPtr->height);
}
@@ -936,6 +964,8 @@ DeleteImage(masterPtr)
}
Tcl_Release((ClientData) masterPtr->winPtr);
ckfree((char *) masterPtr);
+ } else {
+ masterPtr->deleted = 1;
}
}
@@ -950,19 +980,20 @@ DeleteImage(masterPtr)
* None.
*
* Side effects:
- * Image will get freed, though not until it is no longer
- * Tcl_Preserve()d by anything. May be called multiple times on
- * the same image without ill effects.
+ * Image will get freed, though not until it is no longer Tcl_Preserve()d
+ * by anything. May be called multiple times on the same image without
+ * ill effects.
*
*----------------------------------------------------------------------
*/
static void
-EventuallyDeleteImage(masterPtr, forgetHashEntryNow)
- ImageMaster *masterPtr; /* Pointer to main data structure for image. */
- int forgetHashEntryNow;
+EventuallyDeleteImage(
+ ImageMaster *masterPtr, /* Pointer to main data structure for image. */
+ int forgetImageHashNow) /* Flag to say whether the hash table is about
+ * to vanish. */
{
- if (forgetHashEntryNow) {
+ if (forgetImageHashNow) {
masterPtr->hPtr = NULL;
}
if (!masterPtr->deleted) {
@@ -977,10 +1008,9 @@ EventuallyDeleteImage(masterPtr, forgetHashEntryNow)
*
* TkDeleteAllImages --
*
- * This procedure is called when an application is deleted. It
- * calls back all of the managers for all images so that they
- * can cleanup, then it deletes all of Tk's internal information
- * about images.
+ * This function is called when an application is deleted. It calls back
+ * all of the managers for all images so that they can cleanup, then it
+ * deletes all of Tk's internal information about images.
*
* Results:
* None.
@@ -992,8 +1022,8 @@ EventuallyDeleteImage(masterPtr, forgetHashEntryNow)
*/
void
-TkDeleteAllImages(mainPtr)
- TkMainInfo *mainPtr; /* Structure describing application that is
+TkDeleteAllImages(
+ TkMainInfo *mainPtr) /* Structure describing application that is
* going away. */
{
Tcl_HashSearch search;
@@ -1011,15 +1041,14 @@ TkDeleteAllImages(mainPtr)
*
* Tk_GetImageMasterData --
*
- * Given the name of an image, this procedure returns the type
- * of the image and the clientData associated with its master.
+ * Given the name of an image, this function returns the type of the
+ * image and the clientData associated with its master.
*
* Results:
- * If there is no image by the given name, then NULL is returned
- * and a NULL value is stored at *typePtrPtr. Otherwise the return
- * value is the clientData returned by the createProc when the
- * image was created and a pointer to the type structure for the
- * image is stored at *typePtrPtr.
+ * If there is no image by the given name, then NULL is returned and a
+ * NULL value is stored at *typePtrPtr. Otherwise the return value is the
+ * clientData returned by the createProc when the image was created and a
+ * pointer to the type structure for the image is stored at *typePtrPtr.
*
* Side effects:
* None.
@@ -1028,12 +1057,12 @@ TkDeleteAllImages(mainPtr)
*/
ClientData
-Tk_GetImageMasterData(interp, name, typePtrPtr)
- Tcl_Interp *interp; /* Interpreter in which the image was
+Tk_GetImageMasterData(
+ Tcl_Interp *interp, /* Interpreter in which the image was
* created. */
- CONST char *name; /* Name of image. */
- Tk_ImageType **typePtrPtr; /* Points to location to fill in with
- * pointer to type information for image. */
+ CONST char *name, /* Name of image. */
+ Tk_ImageType **typePtrPtr) /* Points to location to fill in with pointer
+ * to type information for image. */
{
Tcl_HashEntry *hPtr;
TkWindow *winPtr;
@@ -1046,36 +1075,41 @@ Tk_GetImageMasterData(interp, name, typePtrPtr)
return NULL;
}
masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr);
+ if (masterPtr->deleted) {
+ *typePtrPtr = NULL;
+ return NULL;
+ }
*typePtrPtr = masterPtr->typePtr;
return masterPtr->masterData;
}
-
+
/*
*----------------------------------------------------------------------
*
* Tk_SetTSOrigin --
*
- * Set the pattern origin of the tile to a common point (i.e. the
- * origin (0,0) of the top level window) so that tiles from two
- * different widgets will match up. This done by setting the
- * GCTileStipOrigin field is set to the translated origin of the
- * toplevel window in the hierarchy.
+ * Set the pattern origin of the tile to a common point (i.e. the origin
+ * (0,0) of the top level window) so that tiles from two different
+ * widgets will match up. This done by setting the GCTileStipOrigin field
+ * is set to the translated origin of the toplevel window in the
+ * hierarchy.
*
* Results:
* None.
*
* Side Effects:
- * The GCTileStipOrigin is reset in the GC. This will cause the
- * tile origin to change when the GC is used for drawing.
+ * The GCTileStipOrigin is reset in the GC. This will cause the tile
+ * origin to change when the GC is used for drawing.
*
*----------------------------------------------------------------------
*/
+
/*ARGSUSED*/
void
-Tk_SetTSOrigin(tkwin, gc, x, y)
- Tk_Window tkwin;
- GC gc;
- int x, y;
+Tk_SetTSOrigin(
+ Tk_Window tkwin,
+ GC gc,
+ int x, int y)
{
while (!Tk_TopWinHierarchy(tkwin)) {
x -= Tk_X(tkwin) + Tk_Changes(tkwin)->border_width;
@@ -1084,4 +1118,11 @@ Tk_SetTSOrigin(tkwin, gc, x, y)
}
XSetTSOrigin(Tk_Display(tkwin), gc, x, y);
}
-
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkImgBmap.c b/generic/tkImgBmap.c
index 2542697..4f5c6ac 100644
--- a/generic/tkImgBmap.c
+++ b/generic/tkImgBmap.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkImgBmap.c --
*
* This procedure implements images of type "bitmap" for Tk.
@@ -12,7 +12,6 @@
*/
#include "tkInt.h"
-#include "tkPort.h"
/*
* The following data structure represents the master for a bitmap
@@ -20,21 +19,19 @@
*/
typedef struct BitmapMaster {
- Tk_ImageMaster tkMaster; /* Tk's token for image master. NULL means
- * the image is being deleted. */
- Tcl_Interp *interp; /* Interpreter for application that is
- * using image. */
- Tcl_Command imageCmd; /* Token for image command (used to delete
- * it when the image goes away). NULL means
- * the image command has already been
- * deleted. */
+ Tk_ImageMaster tkMaster; /* Tk's token for image master. NULL means the
+ * image is being deleted. */
+ Tcl_Interp *interp; /* Interpreter for application that is using
+ * image. */
+ Tcl_Command imageCmd; /* Token for image command (used to delete it
+ * when the image goes away). NULL means the
+ * image command has already been deleted. */
int width, height; /* Dimensions of image. */
- char *data; /* Data comprising bitmap (suitable for
- * input to XCreateBitmapFromData). May
- * be NULL if no data. Malloc'ed. */
- char *maskData; /* Data for bitmap's mask (suitable for
- * input to XCreateBitmapFromData).
- * Malloc'ed. */
+ char *data; /* Data comprising bitmap (suitable for input
+ * to XCreateBitmapFromData). May be NULL if
+ * no data. Malloc'ed. */
+ char *maskData; /* Data for bitmap's mask (suitable for input
+ * to XCreateBitmapFromData). Malloc'ed. */
Tk_Uid fgUid; /* Value of -foreground option (malloc'ed). */
Tk_Uid bgUid; /* Value of -background option (malloc'ed). */
char *fileString; /* Value of -file option (malloc'ed). */
@@ -47,13 +44,13 @@ typedef struct BitmapMaster {
} BitmapMaster;
/*
- * The following data structure represents all of the instances of an
- * image that lie within a particular window:
+ * The following data structure represents all of the instances of an image
+ * that lie within a particular window:
*/
typedef struct BitmapInstance {
- int refCount; /* Number of instances that share this
- * data structure. */
+ int refCount; /* Number of instances that share this data
+ * structure. */
BitmapMaster *masterPtr; /* Pointer to master for image. */
Tk_Window tkwin; /* Window in which the instances will be
* displayed. */
@@ -63,37 +60,35 @@ typedef struct BitmapInstance {
Pixmap mask; /* Mask: only display bitmap pixels where
* there are 1's here. */
GC gc; /* Graphics context for displaying bitmap.
- * None means there was an error while
- * setting up the instance, so it cannot
- * be displayed. */
+ * None means there was an error while setting
+ * up the instance, so it cannot be
+ * displayed. */
struct BitmapInstance *nextPtr;
/* Next in list of all instance structures
- * associated with masterPtr (NULL means
- * end of list). */
+ * associated with masterPtr (NULL means end
+ * of list). */
} BitmapInstance;
/*
* The type record for bitmap images:
*/
-static int GetByte _ANSI_ARGS_((Tcl_Channel chan));
-static int ImgBmapCreate _ANSI_ARGS_((Tcl_Interp *interp,
+static int GetByte(Tcl_Channel chan);
+static int ImgBmapCreate(Tcl_Interp *interp,
char *name, int argc, Tcl_Obj *CONST objv[],
Tk_ImageType *typePtr, Tk_ImageMaster master,
- ClientData *clientDataPtr));
-static ClientData ImgBmapGet _ANSI_ARGS_((Tk_Window tkwin,
- ClientData clientData));
-static void ImgBmapDisplay _ANSI_ARGS_((ClientData clientData,
- Display *display, Drawable drawable,
+ ClientData *clientDataPtr);
+static ClientData ImgBmapGet(Tk_Window tkwin, ClientData clientData);
+static void ImgBmapDisplay(ClientData clientData,
+ Display *display, Drawable drawable,
int imageX, int imageY, int width, int height,
- int drawableX, int drawableY));
-static void ImgBmapFree _ANSI_ARGS_((ClientData clientData,
- Display *display));
-static void ImgBmapDelete _ANSI_ARGS_((ClientData clientData));
-static int ImgBmapPostscript _ANSI_ARGS_((ClientData clientData,
+ int drawableX, int drawableY);
+static void ImgBmapFree(ClientData clientData, Display *display);
+static void ImgBmapDelete(ClientData clientData);
+static int ImgBmapPostscript(ClientData clientData,
Tcl_Interp *interp, Tk_Window tkwin,
Tk_PostscriptInfo psinfo, int x, int y,
- int width, int height, int prepass));
+ int width, int height, int prepass);
Tk_ImageType tkBitmapImageType = {
"bitmap", /* name */
@@ -103,7 +98,7 @@ Tk_ImageType tkBitmapImageType = {
ImgBmapFree, /* freeProc */
ImgBmapDelete, /* deleteProc */
ImgBmapPostscript, /* postscriptProc */
- (Tk_ImageType *) NULL /* nextPtr */
+ NULL /* nextPtr */
};
/*
@@ -111,28 +106,25 @@ Tk_ImageType tkBitmapImageType = {
*/
static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_UID, "-background", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_UID, "-background", NULL, NULL,
"", Tk_Offset(BitmapMaster, bgUid), 0},
- {TK_CONFIG_STRING, "-data", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(BitmapMaster, dataString), TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-file", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(BitmapMaster, fileString), TK_CONFIG_NULL_OK},
- {TK_CONFIG_UID, "-foreground", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_STRING, "-data", NULL, NULL,
+ NULL, Tk_Offset(BitmapMaster, dataString), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_STRING, "-file", NULL, NULL,
+ NULL, Tk_Offset(BitmapMaster, fileString), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_UID, "-foreground", NULL, NULL,
"#000000", Tk_Offset(BitmapMaster, fgUid), 0},
- {TK_CONFIG_STRING, "-maskdata", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(BitmapMaster, maskDataString),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-maskfile", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(BitmapMaster, maskFileString),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+ {TK_CONFIG_STRING, "-maskdata", NULL, NULL,
+ NULL, Tk_Offset(BitmapMaster, maskDataString), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_STRING, "-maskfile", NULL, NULL,
+ NULL, Tk_Offset(BitmapMaster, maskFileString), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};
/*
- * The following data structure is used to describe the state of
- * parsing a bitmap file or string. It is used for communication
- * between TkGetBitmapData and NextBitmapWord.
+ * The following data structure is used to describe the state of parsing a
+ * bitmap file or string. It is used for communication between TkGetBitmapData
+ * and NextBitmapWord.
*/
#define MAX_WORD_LENGTH 100
@@ -140,8 +132,8 @@ typedef struct ParseInfo {
char *string; /* Next character of string data for bitmap,
* or NULL if bitmap is being read from
* file. */
- Tcl_Channel chan; /* File containing bitmap data, or NULL
- * if no file. */
+ Tcl_Channel chan; /* File containing bitmap data, or NULL if no
+ * file. */
char word[MAX_WORD_LENGTH+1];
/* Current word of bitmap data, NULL
* terminated. */
@@ -152,24 +144,20 @@ typedef struct ParseInfo {
* Prototypes for procedures used only locally in this file:
*/
-static int ImgBmapCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int argc, Tcl_Obj *CONST objv[]));
-static void ImgBmapCmdDeletedProc _ANSI_ARGS_((
- ClientData clientData));
-static void ImgBmapConfigureInstance _ANSI_ARGS_((
- BitmapInstance *instancePtr));
-static int ImgBmapConfigureMaster _ANSI_ARGS_((
- BitmapMaster *masterPtr, int argc, Tcl_Obj *CONST objv[],
- int flags));
-static int NextBitmapWord _ANSI_ARGS_((ParseInfo *parseInfoPtr));
+static int ImgBmapCmd(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *CONST objv[]);
+static void ImgBmapCmdDeletedProc(ClientData clientData);
+static void ImgBmapConfigureInstance(BitmapInstance *instancePtr);
+static int ImgBmapConfigureMaster(BitmapMaster *masterPtr,
+ int argc, Tcl_Obj *CONST objv[], int flags);
+static int NextBitmapWord(ParseInfo *parseInfoPtr);
/*
*----------------------------------------------------------------------
*
* ImgBmapCreate --
*
- * This procedure is called by the Tk image code to create "test"
- * images.
+ * This procedure is called by the Tk image code to create "test" images.
*
* Results:
* A standard Tcl result.
@@ -182,18 +170,18 @@ static int NextBitmapWord _ANSI_ARGS_((ParseInfo *parseInfoPtr));
/* ARGSUSED */
static int
-ImgBmapCreate(interp, name, argc, argv, typePtr, master, clientDataPtr)
- Tcl_Interp *interp; /* Interpreter for application containing
+ImgBmapCreate(
+ Tcl_Interp *interp, /* Interpreter for application containing
* image. */
- char *name; /* Name to use for image. */
- int argc; /* Number of arguments. */
- Tcl_Obj *CONST argv[]; /* Argument objects for options (doesn't
+ char *name, /* Name to use for image. */
+ int argc, /* Number of arguments. */
+ Tcl_Obj *CONST argv[], /* Argument objects for options (doesn't
* include image name or type). */
- Tk_ImageType *typePtr; /* Pointer to our type record (not used). */
- Tk_ImageMaster master; /* Token for image, to be used by us in
- * later callbacks. */
- ClientData *clientDataPtr; /* Store manager's token for image here;
- * it will be returned in later callbacks. */
+ Tk_ImageType *typePtr, /* Pointer to our type record (not used). */
+ Tk_ImageMaster master, /* Token for image, to be used by us in later
+ * callbacks. */
+ ClientData *clientDataPtr) /* Store manager's token for image here; it
+ * will be returned in later callbacks. */
{
BitmapMaster *masterPtr;
@@ -226,28 +214,28 @@ ImgBmapCreate(interp, name, argc, argv, typePtr, master, clientDataPtr)
* ImgBmapConfigureMaster --
*
* This procedure is called when a bitmap image is created or
- * reconfigured. It process configuration options and resets
- * any instances of the image.
+ * reconfigured. It process configuration options and resets any
+ * instances of the image.
*
* Results:
- * A standard Tcl return value. If TCL_ERROR is returned then
- * an error message is left in the masterPtr->interp's result.
+ * A standard Tcl return value. If TCL_ERROR is returned then an error
+ * message is left in the masterPtr->interp's result.
*
* Side effects:
- * Existing instances of the image will be redisplayed to match
- * the new configuration options.
+ * Existing instances of the image will be redisplayed to match the new
+ * configuration options.
*
*----------------------------------------------------------------------
*/
static int
-ImgBmapConfigureMaster(masterPtr, objc, objv, flags)
- BitmapMaster *masterPtr; /* Pointer to data structure describing
+ImgBmapConfigureMaster(
+ BitmapMaster *masterPtr, /* Pointer to data structure describing
* overall bitmap image to (reconfigure). */
- int objc; /* Number of entries in objv. */
- Tcl_Obj *CONST objv[]; /* Pairs of configuration options for image. */
- int flags; /* Flags to pass to Tk_ConfigureWidget,
- * such as TK_CONFIG_ARGV_ONLY. */
+ int objc, /* Number of entries in objv. */
+ Tcl_Obj *CONST objv[], /* Pairs of configuration options for image. */
+ int flags) /* Flags to pass to Tk_ConfigureWidget, such
+ * as TK_CONFIG_ARGV_ONLY. */
{
BitmapInstance *instancePtr;
int maskWidth, maskHeight, dummy1, dummy2;
@@ -267,8 +255,8 @@ ImgBmapConfigureMaster(masterPtr, objc, objv, flags)
ckfree((char *) argv);
/*
- * Parse the bitmap and/or mask to create binary data. Make sure that
- * the bitmap and mask have the same dimensions.
+ * Parse the bitmap and/or mask to create binary data. Make sure that the
+ * bitmap and mask have the same dimensions.
*/
if (masterPtr->data != NULL) {
@@ -311,9 +299,9 @@ ImgBmapConfigureMaster(masterPtr, objc, objv, flags)
}
/*
- * Cycle through all of the instances of this image, regenerating
- * the information for each instance. Then force the image to be
- * redisplayed everywhere that it is used.
+ * Cycle through all of the instances of this image, regenerating the
+ * information for each instance. Then force the image to be redisplayed
+ * everywhere that it is used.
*/
for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
@@ -330,24 +318,24 @@ ImgBmapConfigureMaster(masterPtr, objc, objv, flags)
*
* ImgBmapConfigureInstance --
*
- * This procedure is called to create displaying information for
- * a bitmap image instance based on the configuration information
- * in the master. It is invoked both when new instances are
- * created and when the master is reconfigured.
+ * This procedure is called to create displaying information for a bitmap
+ * image instance based on the configuration information in the master.
+ * It is invoked both when new instances are created and when the master
+ * is reconfigured.
*
* Results:
* None.
*
* Side effects:
- * Generates errors via Tcl_BackgroundError if there are problems
- * in setting up the instance.
+ * Generates errors via Tcl_BackgroundError if there are problems in
+ * setting up the instance.
*
*----------------------------------------------------------------------
*/
static void
-ImgBmapConfigureInstance(instancePtr)
- BitmapInstance *instancePtr; /* Instance to reconfigure. */
+ImgBmapConfigureInstance(
+ BitmapInstance *instancePtr)/* Instance to reconfigure. */
{
BitmapMaster *masterPtr = instancePtr->masterPtr;
XColor *colorPtr;
@@ -357,8 +345,8 @@ ImgBmapConfigureInstance(instancePtr)
Pixmap oldBitmap, oldMask;
/*
- * For each of the options in masterPtr, translate the string
- * form into an internal form appropriate for instancePtr.
+ * For each of the options in masterPtr, translate the string form into an
+ * internal form appropriate for instancePtr.
*/
if (*masterPtr->bgUid != 0) {
@@ -385,9 +373,6 @@ ImgBmapConfigureInstance(instancePtr)
}
instancePtr->fg = colorPtr;
- oldMask = instancePtr->mask;
- instancePtr->mask = None;
-
/*
* Careful: We have to allocate new Pixmaps before deleting the old ones.
* Otherwise, The XID allocator will always return the same XID for the
@@ -447,11 +432,10 @@ ImgBmapConfigureInstance(instancePtr)
instancePtr->gc = gc;
return;
- error:
+ error:
/*
- * An error occurred: clear the graphics context in the instance to
- * make it clear that this instance cannot be displayed. Then report
- * the error.
+ * An error occurred: clear the graphics context in the instance to make
+ * it clear that this instance cannot be displayed. Then report the error.
*/
if (instancePtr->gc != None) {
@@ -469,17 +453,16 @@ ImgBmapConfigureInstance(instancePtr)
*
* TkGetBitmapData --
*
- * Given a file name or ASCII string, this procedure parses the
- * file or string contents to produce binary data for a bitmap.
+ * Given a file name or ASCII string, this procedure parses the file or
+ * string contents to produce binary data for a bitmap.
*
* Results:
- * If the bitmap description was parsed successfully then the
- * return value is a malloc-ed array containing the bitmap data.
- * The dimensions of the data are stored in *widthPtr and
- * *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 the interp's result.
+ * If the bitmap description was parsed successfully then the return
+ * value is a malloc-ed array containing the bitmap data. The dimensions
+ * of the data are stored in *widthPtr and *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 the interp's result.
*
* Side effects:
* A bitmap is created.
@@ -488,18 +471,15 @@ ImgBmapConfigureInstance(instancePtr)
*/
char *
-TkGetBitmapData(interp, string, fileName, widthPtr, heightPtr,
- hotXPtr, hotYPtr)
- Tcl_Interp *interp; /* For reporting errors, or NULL. */
- char *string; /* String describing bitmap. May
- * be NULL. */
- char *fileName; /* Name of file containing bitmap
- * description. Used only if string
- * is NULL. Must not be NULL if
- * string is NULL. */
- int *widthPtr, *heightPtr; /* Dimensions of bitmap get returned
- * here. */
- int *hotXPtr, *hotYPtr; /* Position of hot spot or -1,-1. */
+TkGetBitmapData(
+ Tcl_Interp *interp, /* For reporting errors, or NULL. */
+ char *string, /* String describing bitmap. May be NULL. */
+ char *fileName, /* Name of file containing bitmap description.
+ * Used only if string is NULL. Must not be
+ * NULL if string is NULL. */
+ int *widthPtr, int *heightPtr,
+ /* Dimensions of bitmap get returned here. */
+ int *hotXPtr, int *hotYPtr) /* Position of hot spot or -1,-1. */
{
int width, height, numBytes, hotX, hotY;
CONST char *expandedFileName;
@@ -510,11 +490,11 @@ TkGetBitmapData(interp, string, fileName, widthPtr, heightPtr,
pi.string = string;
if (string == NULL) {
- if ((interp != NULL) && Tcl_IsSafe(interp)) {
- Tcl_AppendResult(interp, "can't get bitmap data from a file in a",
- " safe interpreter", (char *) NULL);
- return NULL;
- }
+ if ((interp != NULL) && Tcl_IsSafe(interp)) {
+ Tcl_AppendResult(interp, "can't get bitmap data from a file in a",
+ " safe interpreter", NULL);
+ return NULL;
+ }
expandedFileName = Tcl_TranslateFileName(interp, fileName, &buffer);
if (expandedFileName == NULL) {
return NULL;
@@ -525,29 +505,28 @@ TkGetBitmapData(interp, string, fileName, widthPtr, heightPtr,
if (interp != NULL) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "couldn't read bitmap file \"",
- fileName, "\": ", Tcl_PosixError(interp),
- (char *) NULL);
+ fileName, "\": ", Tcl_PosixError(interp), NULL);
}
return NULL;
}
-
- if (Tcl_SetChannelOption(interp, pi.chan, "-translation", "binary")
+
+ if (Tcl_SetChannelOption(interp, pi.chan, "-translation", "binary")
!= TCL_OK) {
- return NULL;
- }
- if (Tcl_SetChannelOption(interp, pi.chan, "-encoding", "binary")
+ return NULL;
+ }
+ if (Tcl_SetChannelOption(interp, pi.chan, "-encoding", "binary")
!= TCL_OK) {
- return NULL;
- }
+ return NULL;
+ }
} else {
pi.chan = NULL;
}
/*
- * Parse the lines that define the dimensions of the bitmap,
- * plus the first line that defines the bitmap data (it declares
- * the name of a data variable but doesn't include any actual
- * data). These lines look something like the following:
+ * Parse the lines that define the dimensions of the bitmap, plus the
+ * first line that defines the bitmap data (it declares the name of a data
+ * variable but doesn't include any actual data). These lines look
+ * something like the following:
*
* #define foo_width 16
* #define foo_height 16
@@ -555,9 +534,9 @@ TkGetBitmapData(interp, string, fileName, widthPtr, heightPtr,
* #define foo_y_hot 3
* static char foo_bits[] = {
*
- * The x_hot and y_hot lines may or may not be present. It's
- * important to check for "char" in the last line, in order to
- * reject old X10-style bitmaps that used shorts.
+ * The x_hot and y_hot lines may or may not be present. It's important to
+ * check for "char" in the last line, in order to reject old X10-style
+ * bitmaps that used shorts.
*/
width = 0;
@@ -616,19 +595,18 @@ TkGetBitmapData(interp, string, fileName, widthPtr, heightPtr,
} else if ((pi.word[0] == '{') && (pi.word[1] == 0)) {
if (interp != NULL) {
Tcl_AppendResult(interp, "format error in bitmap data; ",
- "looks like it's an obsolete X10 bitmap file",
- (char *) NULL);
+ "looks like it's an obsolete X10 bitmap file", NULL);
}
goto errorCleanup;
}
}
/*
- * Now we've read everything but the data. Allocate an array
- * and read in the data.
+ * Now we've read everything but the data. Allocate an array and read in
+ * the data.
*/
- getData:
+ getData:
if ((width <= 0) || (height <= 0)) {
goto error;
}
@@ -645,7 +623,7 @@ TkGetBitmapData(interp, string, fileName, widthPtr, heightPtr,
}
/*
- * All done. Clean up and return.
+ * All done. Clean up and return.
*/
if (pi.chan != NULL) {
@@ -657,12 +635,12 @@ TkGetBitmapData(interp, string, fileName, widthPtr, heightPtr,
*hotYPtr = hotY;
return data;
- error:
+ error:
if (interp != NULL) {
Tcl_SetResult(interp, "format error in bitmap data", TCL_STATIC);
}
-
- errorCleanup:
+
+ errorCleanup:
if (data != NULL) {
ckfree(data);
}
@@ -677,13 +655,13 @@ TkGetBitmapData(interp, string, fileName, widthPtr, heightPtr,
*
* NextBitmapWord --
*
- * This procedure retrieves the next word of information (stuff
- * between commas or white space) from a bitmap description.
+ * This procedure retrieves the next word of information (stuff between
+ * commas or white space) from a bitmap description.
*
* Results:
- * Returns TCL_OK if all went well. In this case the next word,
- * and its length, will be availble in *parseInfoPtr. If the end
- * of the bitmap description was reached then TCL_ERROR is returned.
+ * Returns TCL_OK if all went well. In this case the next word, and its
+ * length, will be availble in *parseInfoPtr. If the end of the bitmap
+ * description was reached then TCL_ERROR is returned.
*
* Side effects:
* None.
@@ -692,9 +670,9 @@ TkGetBitmapData(interp, string, fileName, widthPtr, heightPtr,
*/
static int
-NextBitmapWord(parseInfoPtr)
- ParseInfo *parseInfoPtr; /* Describes what we're reading
- * and where we are in it. */
+NextBitmapWord(
+ ParseInfo *parseInfoPtr) /* Describes what we're reading and where we
+ * are in it. */
{
char *src, *dst;
int c;
@@ -746,9 +724,9 @@ NextBitmapWord(parseInfoPtr)
*
* ImgBmapCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to an image managed by this module.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the Tcl command that corresponds
+ * to an image managed by this module. See the user documentation for
+ * details on what it does.
*
* Results:
* A standard Tcl result.
@@ -760,15 +738,15 @@ NextBitmapWord(parseInfoPtr)
*/
static int
-ImgBmapCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Information about the image master. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+ImgBmapCmd(
+ ClientData clientData, /* Information about the image master. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- static CONST char *bmapOptions[] = {"cget", "configure", (char *) NULL};
+ static CONST char *bmapOptions[] = {"cget", "configure", NULL};
BitmapMaster *masterPtr = (BitmapMaster *) clientData;
- int code, index;
+ int index;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
@@ -779,33 +757,29 @@ ImgBmapCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
switch (index) {
- case 0: {
+ case 0: /* cget */
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "option");
return TCL_ERROR;
}
return Tk_ConfigureValue(interp, Tk_MainWindow(interp), configSpecs,
(char *) masterPtr, Tcl_GetString(objv[2]), 0);
- }
- case 1: {
+ case 1: /* configure */
if (objc == 2) {
- code = Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
- configSpecs, (char *) masterPtr, (char *) NULL, 0);
+ return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
+ configSpecs, (char *) masterPtr, NULL, 0);
} else if (objc == 3) {
- code = Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
+ return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
configSpecs, (char *) masterPtr,
Tcl_GetString(objv[2]), 0);
} else {
- code = ImgBmapConfigureMaster(masterPtr, objc-2, objv+2,
+ return ImgBmapConfigureMaster(masterPtr, objc-2, objv+2,
TK_CONFIG_ARGV_ONLY);
}
- return code;
- }
- default: {
- panic("bad const entries to bmapOptions in ImgBmapCmd");
- }
+ default:
+ Tcl_Panic("bad const entries to bmapOptions in ImgBmapCmd");
+ return TCL_OK;
}
- return TCL_OK;
}
/*
@@ -813,33 +787,32 @@ ImgBmapCmd(clientData, interp, objc, objv)
*
* ImgBmapGet --
*
- * This procedure is called for each use of a bitmap image in a
- * widget.
+ * This procedure is called for each use of a bitmap image in a widget.
*
* Results:
- * The return value is a token for the instance, which is passed
- * back to us in calls to ImgBmapDisplay and ImgBmapFree.
+ * The return value is a token for the instance, which is passed back to
+ * us in calls to ImgBmapDisplay and ImgBmapFree.
*
* Side effects:
- * A data structure is set up for the instance (or, an existing
- * instance is re-used for the new one).
+ * A data structure is set up for the instance (or, an existing instance
+ * is re-used for the new one).
*
*----------------------------------------------------------------------
*/
static ClientData
-ImgBmapGet(tkwin, masterData)
- Tk_Window tkwin; /* Window in which the instance will be
+ImgBmapGet(
+ Tk_Window tkwin, /* Window in which the instance will be
* used. */
- ClientData masterData; /* Pointer to our master structure for the
+ ClientData masterData) /* Pointer to our master structure for the
* image. */
{
BitmapMaster *masterPtr = (BitmapMaster *) masterData;
BitmapInstance *instancePtr;
/*
- * See if there is already an instance for this window. If so
- * then just re-use it.
+ * See if there is already an instance for this window. If so then just
+ * re-use it.
*/
for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
@@ -851,8 +824,8 @@ ImgBmapGet(tkwin, masterData)
}
/*
- * The image isn't already in use in this window. Make a new
- * instance of the image.
+ * The image isn't already in use in this window. Make a new instance of
+ * the image.
*/
instancePtr = (BitmapInstance *) ckalloc(sizeof(BitmapInstance));
@@ -897,24 +870,24 @@ ImgBmapGet(tkwin, masterData)
*/
static void
-ImgBmapDisplay(clientData, display, drawable, imageX, imageY, width,
- height, drawableX, drawableY)
- ClientData clientData; /* Pointer to BitmapInstance structure for
- * for instance to be displayed. */
- Display *display; /* Display on which to draw image. */
- Drawable drawable; /* Pixmap or window in which to draw image. */
- int imageX, imageY; /* Upper-left corner of region within image
- * to draw. */
- int width, height; /* Dimensions of region within image to draw. */
- int drawableX, drawableY; /* Coordinates within drawable that
- * correspond to imageX and imageY. */
+ImgBmapDisplay(
+ ClientData clientData, /* Pointer to BitmapInstance structure for
+ * instance to be displayed. */
+ Display *display, /* Display on which to draw image. */
+ Drawable drawable, /* Pixmap or window in which to draw image. */
+ int imageX, int imageY, /* Upper-left corner of region within image to
+ * draw. */
+ int width, int height, /* Dimensions of region within image to draw. */
+ int drawableX, int drawableY)
+ /* Coordinates within drawable that correspond
+ * to imageX and imageY. */
{
BitmapInstance *instancePtr = (BitmapInstance *) clientData;
int masking;
/*
- * If there's no graphics context, it means that an error occurred
- * while creating the image instance so it can't be displayed.
+ * If there's no graphics context, it means that an error occurred while
+ * creating the image instance so it can't be displayed.
*/
if (instancePtr->gc == None) {
@@ -922,10 +895,9 @@ ImgBmapDisplay(clientData, display, drawable, imageX, imageY, width,
}
/*
- * If masking is in effect, must modify the mask origin within
- * the graphics context to line up with the image's origin.
- * Then draw the image and reset the clip origin, if there's
- * a mask.
+ * If masking is in effect, must modify the mask origin within the
+ * graphics context to line up with the image's origin. Then draw the
+ * image and reset the clip origin, if there's a mask.
*/
masking = (instancePtr->mask != None) || (instancePtr->bg == NULL);
@@ -946,8 +918,8 @@ ImgBmapDisplay(clientData, display, drawable, imageX, imageY, width,
*
* ImgBmapFree --
*
- * This procedure is called when a widget ceases to use a
- * particular instance of an image.
+ * This procedure is called when a widget ceases to use a particular
+ * instance of an image.
*
* Results:
* None.
@@ -959,10 +931,10 @@ ImgBmapDisplay(clientData, display, drawable, imageX, imageY, width,
*/
static void
-ImgBmapFree(clientData, display)
- ClientData clientData; /* Pointer to BitmapInstance structure for
- * for instance to be displayed. */
- Display *display; /* Display containing window that used image. */
+ImgBmapFree(
+ ClientData clientData, /* Pointer to BitmapInstance structure for
+ * instance to be displayed. */
+ Display *display) /* Display containing window that used image. */
{
BitmapInstance *instancePtr = (BitmapInstance *) clientData;
BitmapInstance *prevPtr;
@@ -973,8 +945,8 @@ ImgBmapFree(clientData, display)
}
/*
- * There are no more uses of the image within this widget. Free
- * the instance structure.
+ * There are no more uses of the image within this widget. Free the
+ * instance structure.
*/
if (instancePtr->fg != NULL) {
@@ -1009,8 +981,8 @@ ImgBmapFree(clientData, display)
*
* ImgBmapDelete --
*
- * This procedure is called by the image code to delete the
- * master structure for an image.
+ * This procedure is called by the image code to delete the master
+ * structure for an image.
*
* Results:
* None.
@@ -1022,14 +994,14 @@ ImgBmapFree(clientData, display)
*/
static void
-ImgBmapDelete(masterData)
- ClientData masterData; /* Pointer to BitmapMaster structure for
- * image. Must not have any more instances. */
+ImgBmapDelete(
+ ClientData masterData) /* Pointer to BitmapMaster structure for
+ * image. Must not have any more instances. */
{
BitmapMaster *masterPtr = (BitmapMaster *) masterData;
if (masterPtr->instancePtr != NULL) {
- panic("tried to delete bitmap image when instances still exist");
+ Tcl_Panic("tried to delete bitmap image when instances still exist");
}
masterPtr->tkMaster = NULL;
if (masterPtr->imageCmd != NULL) {
@@ -1041,7 +1013,7 @@ ImgBmapDelete(masterData)
if (masterPtr->maskData != NULL) {
ckfree(masterPtr->maskData);
}
- Tk_FreeOptions(configSpecs, (char *) masterPtr, (Display *) NULL, 0);
+ Tk_FreeOptions(configSpecs, (char *) masterPtr, NULL, 0);
ckfree((char *) masterPtr);
}
@@ -1050,8 +1022,8 @@ ImgBmapDelete(masterData)
*
* ImgBmapCmdDeletedProc --
*
- * This procedure is invoked when the image command for an image
- * is deleted. It deletes the image.
+ * This procedure is invoked when the image command for an image is
+ * deleted. It deletes the image.
*
* Results:
* None.
@@ -1063,8 +1035,8 @@ ImgBmapDelete(masterData)
*/
static void
-ImgBmapCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to BitmapMaster structure for
+ImgBmapCmdDeletedProc(
+ ClientData clientData) /* Pointer to BitmapMaster structure for
* image. */
{
BitmapMaster *masterPtr = (BitmapMaster *) clientData;
@@ -1092,8 +1064,8 @@ ImgBmapCmdDeletedProc(clientData)
*/
static int
-GetByte(chan)
- Tcl_Channel chan; /* The channel we read from. */
+GetByte(
+ Tcl_Channel chan) /* The channel we read from. */
{
char buffer;
int size;
@@ -1112,29 +1084,28 @@ GetByte(chan)
*
* ImgBmapPsImagemask --
*
- * This procedure generates postscript suitable for rendering a
- * single bitmap of an image. A single bitmap image might contain both
- * a foreground and a background bitmap. This routine is called once
- * for each such bitmap in a bitmap image.
+ * This procedure generates postscript suitable for rendering a single
+ * bitmap of an image. A single bitmap image might contain both a
+ * foreground and a background bitmap. This routine is called once for
+ * each such bitmap in a bitmap image.
*
- * Prior to invoking this routine, the following setup has occurred:
+ * Prior to invoking this routine, the following setup has occurred:
*
- * 1. The postscript foreground color has been set to the color
- * used to render the bitmap.
+ * 1. The postscript foreground color has been set to the color used
+ * to render the bitmap.
*
- * 2. The origin of the postscript coordinate system is set to
- * the lower left corner of the bitmap.
+ * 2. The origin of the postscript coordinate system is set to the
+ * lower left corner of the bitmap.
*
- * 3. The postscript coordinate system has been scaled so that
- * the entire bitmap is one unit squared.
+ * 3. The postscript coordinate system has been scaled so that the
+ * entire bitmap is one unit squared.
*
- * Some postscript implementations cannot handle bitmap strings
- * longer than about 60k characters. If the bitmap data is that big
- * or bigger, then we render it by splitting it into several smaller
- * bitmaps.
+ * Some postscript implementations cannot handle bitmap strings longer
+ * than about 60k characters. If the bitmap data is that big or bigger,
+ * then we render it by splitting it into several smaller bitmaps.
*
* Results:
- * Returns TCL_OK on success. Returns TCL_ERROR and leaves and error
+ * Returns TCL_OK on success. Returns TCL_ERROR and leaves and error
* message in interp->result if there is a problem.
*
* Side effects:
@@ -1144,22 +1115,23 @@ GetByte(chan)
*/
static int
-ImgBmapPsImagemask(interp, width, height, data)
- Tcl_Interp *interp; /* Append postscript to this interpreter */
- int width, height; /* Width and height of the bitmap in pixels */
- char *data; /* Data for the bitmap */
+ImgBmapPsImagemask(
+ Tcl_Interp *interp, /* Append postscript to this interpreter */
+ int width, int height, /* Width and height of the bitmap in pixels */
+ char *data) /* Data for the bitmap */
{
int i, j, nBytePerRow;
char buffer[200];
- /*
+ /*
* The bit order of bitmaps in Tk is the opposite of the bit order that
- * postscript uses. (In Tk, the least significant bit is on the right
- * side of the bitmap and in postscript the least significant bit is shown
- * on the left.) The following array is used to reverse the order of bits
+ * postscript uses. (In Tk, the least significant bit is on the right side
+ * of the bitmap and in postscript the least significant bit is shown on
+ * the left.) The following array is used to reverse the order of bits
* within a byte so that the bits will be in the order postscript expects.
*/
- static CONST unsigned char bit_reverse[] = {
+
+ static const unsigned char bit_reverse[] = {
0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240,
8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248,
4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,
@@ -1184,17 +1156,21 @@ ImgBmapPsImagemask(interp, width, height, data)
"larger than 60000 pixels", NULL);
return TCL_ERROR;
}
+
sprintf(buffer, "0 0 moveto %d %d true [%d 0 0 %d 0 %d] {<\n",
- width, height, width, -height, height);
+ width, height, width, -height, height);
Tcl_AppendResult(interp, buffer, NULL);
+
nBytePerRow = (width+7)/8;
for(i=0; i<height; i++){
- for(j=0; j<nBytePerRow; j++){
- sprintf(buffer, " %02x", bit_reverse[0xff & data[i*nBytePerRow + j]]);
- Tcl_AppendResult(interp, buffer, NULL);
- }
- Tcl_AppendResult(interp, "\n", NULL);
+ for(j=0; j<nBytePerRow; j++){
+ sprintf(buffer, " %02x",
+ bit_reverse[0xff & data[i*nBytePerRow + j]]);
+ Tcl_AppendResult(interp, buffer, NULL);
+ }
+ Tcl_AppendResult(interp, "\n", NULL);
}
+
Tcl_AppendResult(interp, ">} imagemask \n", NULL);
return TCL_OK;
}
@@ -1207,9 +1183,10 @@ ImgBmapPsImagemask(interp, width, height, data)
* This procedure generates postscript for rendering a bitmap image.
*
* Results:
+
* On success, this routine writes postscript code into interp->result
- * and returns TCL_OK TCL_ERROR is returned and an error
- * message is left in interp->result if anything goes wrong.
+ * and returns TCL_OK TCL_ERROR is returned and an error message is left
+ * in interp->result if anything goes wrong.
*
* Side effects:
* None.
@@ -1218,13 +1195,13 @@ ImgBmapPsImagemask(interp, width, height, data)
*/
static int
-ImgBmapPostscript(clientData, interp, tkwin, psinfo, x, y, width, height,
- prepass)
- ClientData clientData;
- Tcl_Interp *interp;
- Tk_Window tkwin;
- Tk_PostscriptInfo psinfo;
- int x, y, width, height, prepass;
+ImgBmapPostscript(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tk_Window tkwin,
+ Tk_PostscriptInfo psinfo,
+ int x, int y, int width, int height,
+ int prepass)
{
BitmapMaster *masterPtr = (BitmapMaster *) clientData;
char buffer[200];
@@ -1234,38 +1211,42 @@ ImgBmapPostscript(clientData, interp, tkwin, psinfo, x, y, width, height,
}
/*
- * There is nothing to do for bitmaps with zero width or height
+ * There is nothing to do for bitmaps with zero width or height.
*/
- if( width<=0 || height<=0 || masterPtr->width<=0 || masterPtr->height<=0 ){
+
+ if (width<=0 || height<=0 || masterPtr->width<=0 || masterPtr->height<= 0){
return TCL_OK;
}
/*
* Translate the origin of the coordinate system to be the lower-left
- * corner of the bitmap and adjust the scale of the coordinate system
- * so that entire bitmap covers one square unit of the page.
- * The calling function put a "gsave" into the postscript and
- * will add a "grestore" at after this routine returns, so it is safe
- * to make whatever changes are necessary here.
+ * corner of the bitmap and adjust the scale of the coordinate system so
+ * that entire bitmap covers one square unit of the page. The calling
+ * function put a "gsave" into the postscript and will add a "grestore" at
+ * after this routine returns, so it is safe to make whatever changes are
+ * necessary here.
*/
- if( x!=0 || y!=0 ){
+
+ if (x!=0 || y!=0) {
sprintf(buffer, "%d %d moveto\n", x, y);
Tcl_AppendResult(interp, buffer, NULL);
}
- if( width!=1 || height!=1 ){
+ if (width!=1 || height!=1) {
sprintf(buffer, "%d %d scale\n", width, height);
Tcl_AppendResult(interp, buffer, NULL);
}
/*
- * Color the background, if there is one. This step is skipped if the
- * background is transparent. If the background is not transparent and
+ * Color the background, if there is one. This step is skipped if the
+ * background is transparent. If the background is not transparent and
* there is no background mask, then color the complete rectangle that
- * encloses the bitmap. If there is a background mask, then only apply
+ * encloses the bitmap. If there is a background mask, then only apply
* color to the bits specified by the mask.
*/
+
if ((masterPtr->bgUid != NULL) && (masterPtr->bgUid[0] != '\000')) {
XColor color;
+
TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->bgUid,
&color);
if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) {
@@ -1273,10 +1254,10 @@ ImgBmapPostscript(clientData, interp, tkwin, psinfo, x, y, width, height,
}
if (masterPtr->maskData == NULL) {
Tcl_AppendResult(interp,
- "0 0 moveto 1 0 rlineto 0 1 rlineto -1 0 rlineto "
- "closepath fill\n", NULL);
+ "0 0 moveto 1 0 rlineto 0 1 rlineto -1 0 rlineto ",
+ "closepath fill\n", NULL);
} else if (ImgBmapPsImagemask(interp, masterPtr->width,
- masterPtr->height, masterPtr->maskData) != TCL_OK) {
+ masterPtr->height, masterPtr->maskData) != TCL_OK) {
return TCL_ERROR;
}
}
@@ -1284,8 +1265,10 @@ ImgBmapPostscript(clientData, interp, tkwin, psinfo, x, y, width, height,
/*
* Draw the bitmap foreground, assuming there is one.
*/
- if ( (masterPtr->fgUid != NULL) && (masterPtr->data != NULL) ) {
+
+ if ((masterPtr->fgUid != NULL) && (masterPtr->data != NULL)) {
XColor color;
+
TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->fgUid,
&color);
if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) {
@@ -1298,3 +1281,11 @@ ImgBmapPostscript(clientData, interp, tkwin, psinfo, x, y, width, height,
}
return TCL_OK;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkImgGIF.c b/generic/tkImgGIF.c
index d46f9f9..e576559 100644
--- a/generic/tkImgGIF.c
+++ b/generic/tkImgGIF.c
@@ -1,20 +1,20 @@
/*
* tkImgGIF.c --
*
- * A photo image file handler for GIF files. Reads 87a and 89a GIF
- * files. At present, there only is a file write function. GIF images
- * may be read using the -data option of the photo image. The data may be
- * given as a binary string in a Tcl_Obj or by representing
- * the data as BASE64 encoded ascii. Derived from the giftoppm code
- * found in the pbmplus package and tkImgFmtPPM.c in the tk4.0b2
- * distribution.
+ * A photo image file handler for GIF files. Reads 87a and 89a GIF files.
+ * At present, there only is a file write function. GIF images may be
+ * read using the -data option of the photo image. The data may be given
+ * as a binary string in a Tcl_Obj or by representing the data as BASE64
+ * encoded ascii. Derived from the giftoppm code found in the pbmplus
+ * package and tkImgFmtPPM.c in the tk4.0b2 distribution.
*
* Copyright (c) Reed Wade (wade@cs.utk.edu), University of Tennessee
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
* Copyright (c) 1997 Australian National University
+ * Copyright (c) 2005 Donal K. Fellows
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* This file also contains code from the giftoppm program, which is
* copyrighted as follows:
@@ -25,18 +25,22 @@
* | and its documentation for any purpose and without fee is hereby |
* | granted, provided that the above copyright notice appear in all |
* | copies and that both that copyright notice and this permission |
- * | notice appear in supporting documentation. This software is |
+ * | notice appear in supporting documentation. This software is |
* | provided "as is" without express or implied warranty. |
- * +-------------------------------------------------------------------+
+ * +--------------------------------------------------------------------+
+ *
+ * This file also contains code from miGIF. See lower down in file for the
+ * applicable copyright notice for that portion.
*/
+#include "tkInt.h"
+
/*
- * GIF's are represented as data in base64 format.
- * base64 strings consist of 4 6-bit characters -> 3 8 bit bytes.
- * A-Z, a-z, 0-9, + and / represent the 64 values (in order).
- * '=' is a trailing padding char when the un-encoded data is not a
- * multiple of 3 bytes. We'll ignore white space when encountered.
- * Any other invalid character is treated as an EOF
+ * GIF's are represented as data in either binary or base64 format. base64
+ * strings consist of 4 6-bit characters -> 3 8 bit bytes. A-Z, a-z, 0-9, +
+ * and / represent the 64 values (in order). '=' is a trailing padding char
+ * when the un-encoded data is not a multiple of 3 bytes. We'll ignore white
+ * space when encountered. Any other invalid character is treated as an EOF
*/
#define GIF_SPECIAL (256)
@@ -46,77 +50,86 @@
#define GIF_DONE (GIF_SPECIAL+4)
/*
- * structure to "mimic" FILE for Mread, so we can look like fread.
- * The decoder state keeps track of which byte we are about to read,
- * or EOF.
+ * structure to "mimic" FILE for Mread, so we can look like fread. The decoder
+ * state keeps track of which byte we are about to read, or EOF.
*/
typedef struct mFile {
unsigned char *data; /* mmencoded source string */
- int length; /* Length of string in bytes */
int c; /* bits left over from previous character */
int state; /* decoder state (0-4 or GIF_DONE) */
+ int length; /* Total amount of bytes in data */
} MFile;
-#include "tkInt.h"
-#include "tkPort.h"
-
/*
* Non-ASCII encoding support:
- * Most data in a GIF image is binary and is treated as such. However,
- * a few key bits are stashed in ASCII. If we try to compare those pieces
- * to the char they represent, it will fail on any non-ASCII (eg, EBCDIC)
- * system. To accomodate these systems, we test against the numeric value
- * of the ASCII characters instead of the characters themselves. This is
- * encoding independant.
+ * Most data in a GIF image is binary and is treated as such. However, a few
+ * key bits are stashed in ASCII. If we try to compare those pieces to the
+ * char they represent, it will fail on any non-ASCII (eg, EBCDIC) system. To
+ * accomodate these systems, we test against the numeric value of the ASCII
+ * characters instead of the characters themselves. This is encoding
+ * independant.
*/
-static CONST char GIF87a[] = { /* ASCII GIF87a */
+static const char GIF87a[] = { /* ASCII GIF87a */
0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x00
};
-static CONST char GIF89a[] = { /* ASCII GIF89a */
+static const char GIF89a[] = { /* ASCII GIF89a */
0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x00
};
-# define GIF_TERMINATOR 0x3b /* ASCII ; */
-# define GIF_EXTENSION 0x21 /* ASCII ! */
-# define GIF_START 0x2c /* ASCII , */
+#define GIF_TERMINATOR 0x3b /* ASCII ; */
+#define GIF_EXTENSION 0x21 /* ASCII ! */
+#define GIF_START 0x2c /* ASCII , */
/*
- * 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.
- * 0==from file; 1==from base64 encoded data; 2==from binary data
+ * Flags used to notify that we've got inline data instead of a file to read
+ * from. Note that we need to figure out which type of inline data we've got
+ * before handing off to the GIF reading code; this is done in StringReadGIF.
*/
-typedef struct ThreadSpecificData {
- int fromData;
-} ThreadSpecificData;
-static Tcl_ThreadDataKey dataKey;
+#define INLINE_DATA_BINARY ((const char *) 0x01)
+#define INLINE_DATA_BASE64 ((const char *) 0x02)
+
+/*
+ * 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. 0==from file;
+ * 1==from base64 encoded data; 2==from binary data
+ */
+
+typedef struct {
+ const char *fromData;
+ unsigned char workingBuffer[280];
+ struct {
+ int bytes;
+ int done;
+ unsigned int window;
+ int bitsInWindow;
+ unsigned char *c;
+ } reader;
+} GIFImageConfig;
/*
* The format record for the GIF file format:
*/
-static int FileMatchGIF _ANSI_ARGS_((Tcl_Channel chan, CONST char *fileName,
- Tcl_Obj *format, int *widthPtr, int *heightPtr,
- Tcl_Interp *interp));
-static int FileReadGIF _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Channel chan, CONST char *fileName, Tcl_Obj *format,
- Tk_PhotoHandle imageHandle, int destX, int destY,
- int width, int height, int srcX, int srcY));
-static int StringMatchGIF _ANSI_ARGS_(( Tcl_Obj *dataObj,
- Tcl_Obj *format, int *widthPtr, int *heightPtr,
- Tcl_Interp *interp));
-static int StringReadGIF _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *dataObj,
- Tcl_Obj *format, Tk_PhotoHandle imageHandle,
- int destX, int destY, int width, int height,
- int srcX, int srcY));
-static int FileWriteGIF _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *filename, Tcl_Obj *format,
- Tk_PhotoImageBlock *blockPtr));
-static int CommonWriteGIF _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Channel handle, Tcl_Obj *format,
- Tk_PhotoImageBlock *blockPtr));
+static int FileMatchGIF(Tcl_Channel chan, const char *fileName,
+ Tcl_Obj *format, int *widthPtr, int *heightPtr,
+ Tcl_Interp *interp);
+static int FileReadGIF(Tcl_Interp *interp, Tcl_Channel chan,
+ const char *fileName, Tcl_Obj *format,
+ Tk_PhotoHandle imageHandle, int destX, int destY,
+ int width, int height, int srcX, int srcY);
+static int StringMatchGIF(Tcl_Obj *dataObj, Tcl_Obj *format,
+ int *widthPtr, int *heightPtr, Tcl_Interp *interp);
+static int StringReadGIF(Tcl_Interp *interp, Tcl_Obj *dataObj,
+ Tcl_Obj *format, Tk_PhotoHandle imageHandle,
+ int destX, int destY, int width, int height,
+ int srcX, int srcY);
+static int FileWriteGIF(Tcl_Interp *interp, const char *filename,
+ Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr);
+static int CommonWriteGIF(Tcl_Interp *interp, Tcl_Channel handle,
+ Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr);
Tk_PhotoImageFormat tkImgFmtGIF = {
"gif", /* name */
@@ -138,54 +151,53 @@ Tk_PhotoImageFormat tkImgFmtGIF = {
#define CM_ALPHA 3
#define MAX_LWZ_BITS 12
#define LM_to_uint(a,b) (((b)<<8)|(a))
-#define ReadOK(file,buffer,len) (Fread(buffer, len, 1, file) != 0)
/*
- * Prototypes for local procedures defined in this file:
+ * Prototypes for local functions defined in this file:
*/
-static int DoExtension _ANSI_ARGS_((Tcl_Channel chan, int label,
- int *transparent));
-static int GetCode _ANSI_ARGS_((Tcl_Channel chan, int code_size,
- int flag));
-static int GetDataBlock _ANSI_ARGS_((Tcl_Channel chan,
- unsigned char *buf));
-static int ReadColorMap _ANSI_ARGS_((Tcl_Channel chan, int number,
- unsigned char buffer[MAXCOLORMAPSIZE][4]));
-static int ReadGIFHeader _ANSI_ARGS_((Tcl_Channel chan,
- int *widthPtr, int *heightPtr));
-static int ReadImage _ANSI_ARGS_((Tcl_Interp *interp,
- char *imagePtr, Tcl_Channel chan,
- int len, int rows,
- unsigned char cmap[MAXCOLORMAPSIZE][4],
- int width, int height, int srcX, int srcY,
- int interlace, int transparent));
+static int DoExtension(GIFImageConfig *gifConfPtr,
+ Tcl_Channel chan, int label, unsigned char *buffer,
+ int *transparent);
+static int GetCode(Tcl_Channel chan, int code_size, int flag,
+ GIFImageConfig *gifConfPtr);
+static int GetDataBlock(GIFImageConfig *gifConfPtr,
+ Tcl_Channel chan, unsigned char *buf);
+static int ReadColorMap(GIFImageConfig *gifConfPtr,
+ Tcl_Channel chan, int number,
+ unsigned char buffer[MAXCOLORMAPSIZE][4]);
+static int ReadGIFHeader(GIFImageConfig *gifConfPtr,
+ Tcl_Channel chan, int *widthPtr, int *heightPtr);
+static int ReadImage(GIFImageConfig *gifConfPtr,
+ Tcl_Interp *interp, unsigned char *imagePtr,
+ Tcl_Channel chan, int len, int rows,
+ unsigned char cmap[MAXCOLORMAPSIZE][4], int srcX,
+ int srcY, int interlace, int transparent);
/*
* these are for the BASE64 image reader code only
*/
-static int Fread _ANSI_ARGS_((unsigned char *dst, size_t size,
- size_t count, Tcl_Channel chan));
-static int Mread _ANSI_ARGS_((unsigned char *dst, size_t size,
- size_t count, MFile *handle));
-static int Mgetc _ANSI_ARGS_((MFile *handle));
-static int char64 _ANSI_ARGS_((int c));
-static void mInit _ANSI_ARGS_((unsigned char *string,
- int length, MFile *handle));
-
+static int Fread(GIFImageConfig *gifConfPtr, unsigned char *dst,
+ size_t size, size_t count, Tcl_Channel chan);
+static int Mread(unsigned char *dst, size_t size, size_t count,
+ MFile *handle);
+static int Mgetc(MFile *handle);
+static int char64(int c);
+static void mInit(unsigned char *string, MFile *handle,
+ int length);
/*
*----------------------------------------------------------------------
*
* FileMatchGIF --
*
- * This procedure is invoked by the photo image type to see if
- * a file contains image data in GIF format.
+ * This function is invoked by the photo image type to see if a file
+ * contains image data in GIF format.
*
* Results:
- * The return value is 1 if the first characters in file f look
- * like GIF data, and 0 otherwise.
+ * The return value is 1 if the first characters in file f look like GIF
+ * data, and 0 otherwise.
*
* Side effects:
* The access position in f may change.
@@ -194,16 +206,19 @@ static void mInit _ANSI_ARGS_((unsigned char *string,
*/
static int
-FileMatchGIF(chan, fileName, format, widthPtr, heightPtr, interp)
- Tcl_Channel chan; /* The image file, open for reading. */
- CONST char *fileName; /* The name of the image file. */
- Tcl_Obj *format; /* User-specified format object, or NULL. */
- int *widthPtr, *heightPtr; /* The dimensions of the image are
- * returned here if the file is a valid
- * raw GIF file. */
- Tcl_Interp *interp; /* not used */
+FileMatchGIF(
+ Tcl_Channel chan, /* The image file, open for reading. */
+ const char *fileName, /* The name of the image file. */
+ Tcl_Obj *format, /* User-specified format object, or NULL. */
+ int *widthPtr, int *heightPtr,
+ /* The dimensions of the image are returned
+ * here if the file is a valid raw GIF file. */
+ Tcl_Interp *interp) /* not used */
{
- return ReadGIFHeader(chan, widthPtr, heightPtr);
+ GIFImageConfig gifConf;
+
+ memset(&gifConf, 0, sizeof(GIFImageConfig));
+ return ReadGIFHeader(&gifConf, chan, widthPtr, heightPtr);
}
/*
@@ -211,88 +226,108 @@ FileMatchGIF(chan, fileName, format, widthPtr, heightPtr, interp)
*
* FileReadGIF --
*
- * This procedure is called by the photo image type to read
- * GIF format data from a file and write it into a given
- * photo image.
+ * This function is called by the photo image type to read GIF format
+ * data from a file and write it into a given photo image.
*
* Results:
- * A standard TCL completion code. If TCL_ERROR is returned
- * then an error message is left in the interp's result.
+ * A standard TCL completion code. If TCL_ERROR is returned 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
- * added to the image given by imageHandle.
+ * The access position in file f is changed, and new data is added to the
+ * image given by imageHandle.
*
*----------------------------------------------------------------------
*/
static int
-FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY,
- width, height, srcX, srcY)
- Tcl_Interp *interp; /* Interpreter to use for reporting errors. */
- Tcl_Channel chan; /* The image file, open for reading. */
- CONST char *fileName; /* The name of the image file. */
- Tcl_Obj *format; /* User-specified format object, or NULL. */
- Tk_PhotoHandle imageHandle; /* The photo image to write into. */
- int destX, destY; /* Coordinates of top-left pixel in
- * photo image to be written to. */
- int width, height; /* Dimensions of block of photo image to
- * be written to. */
- int srcX, srcY; /* Coordinates of top-left pixel to be used
- * in image being read. */
+FileReadGIF(
+ Tcl_Interp *interp, /* Interpreter to use for reporting errors. */
+ Tcl_Channel chan, /* The image file, open for reading. */
+ const char *fileName, /* The name of the image file. */
+ Tcl_Obj *format, /* User-specified format object, or NULL. */
+ Tk_PhotoHandle imageHandle, /* The photo image to write into. */
+ int destX, int destY, /* Coordinates of top-left pixel in photo
+ * image to be written to. */
+ int width, int height, /* Dimensions of block of photo image to be
+ * written to. */
+ int srcX, int srcY) /* Coordinates of top-left pixel to be used in
+ * image being read. */
{
int fileWidth, fileHeight, imageWidth, imageHeight;
- int nBytes, index = 0, argc = 0, i;
+ int nBytes, index = 0, argc = 0, i, result = TCL_ERROR;
Tcl_Obj **objv;
- Tk_PhotoImageBlock block;
unsigned char buf[100];
unsigned char *trashBuffer = NULL;
int bitPixel;
unsigned char colorMap[MAXCOLORMAPSIZE][4];
int transparent = -1;
- static CONST char *optionStrings[] = {
- "-index", NULL
+ static const char *optionStrings[] = {
+ "-index", NULL
};
+ GIFImageConfig gifConf, *gifConfPtr = &gifConf;
+
+ /*
+ * Decode the magic used to convey when we're sourcing data from a string
+ * source and not a file.
+ */
+
+ memset(gifConfPtr, 0, sizeof(GIFImageConfig));
+ if (fileName == INLINE_DATA_BINARY || fileName == INLINE_DATA_BASE64) {
+ gifConfPtr->fromData = fileName;
+ fileName = "inline data";
+ }
+
+ /*
+ * Parse the format string to get options.
+ */
if (format && Tcl_ListObjGetElements(interp, format,
&argc, &objv) != TCL_OK) {
return TCL_ERROR;
}
for (i = 1; i < argc; i++) {
- if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option name", 0,
- &nBytes) != TCL_OK) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option name",
+ 0, &nBytes) != TCL_OK) {
return TCL_ERROR;
}
if (i == (argc-1)) {
Tcl_AppendResult(interp, "no value given for \"",
- Tcl_GetStringFromObj(objv[i], NULL),
- "\" option", (char *) NULL);
+ Tcl_GetString(objv[i]), "\" option", NULL);
return TCL_ERROR;
}
if (Tcl_GetIntFromObj(interp, objv[++i], &index) != TCL_OK) {
return TCL_ERROR;
}
}
- if (!ReadGIFHeader(chan, &fileWidth, &fileHeight)) {
- Tcl_AppendResult(interp, "couldn't read GIF header from file \"",
+
+ /*
+ * Read the GIF file header and check for some sanity.
+ */
+
+ if (!ReadGIFHeader(gifConfPtr, chan, &fileWidth, &fileHeight)) {
+ Tcl_AppendResult(interp, "couldn't read GIF header from file \"",
fileName, "\"", NULL);
return TCL_ERROR;
}
if ((fileWidth <= 0) || (fileHeight <= 0)) {
Tcl_AppendResult(interp, "GIF image file \"", fileName,
- "\" has dimension(s) <= 0", (char *) NULL);
+ "\" has dimension(s) <= 0", NULL);
return TCL_ERROR;
}
- if (Fread(buf, 1, 3, chan) != 3) {
+ /*
+ * Get the general colormap information.
+ */
+
+ if (Fread(gifConfPtr, buf, 1, 3, chan) != 3) {
return TCL_OK;
}
- bitPixel = 2<<(buf[0]&0x07);
+ bitPixel = 2 << (buf[0] & 0x07);
if (BitSet(buf[0], LOCALCOLORMAP)) { /* Global Colormap */
- if (!ReadColorMap(chan, bitPixel, colorMap)) {
- Tcl_AppendResult(interp, "error reading color map",
- (char *) NULL);
+ if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
+ Tcl_AppendResult(interp, "error reading color map", NULL);
return TCL_ERROR;
}
}
@@ -308,85 +343,87 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY,
return TCL_OK;
}
- Tk_PhotoExpand(imageHandle, destX + width, destY + height);
+ /*
+ * Make sure we have enough space in the photo image to hold the data from
+ * the GIF.
+ */
+
+ if (Tk_PhotoExpand(interp, imageHandle,
+ destX + width, destY + height) != TCL_OK) {
+ return TCL_ERROR;
+ }
- block.width = width;
- block.height = height;
- block.pixelSize = 4;
- block.pitch = block.pixelSize * block.width;
- block.offset[0] = 0;
- block.offset[1] = 1;
- block.offset[2] = 2;
- block.offset[3] = 3;
- block.pixelPtr = NULL;
+ /*
+ * Search for the frame from the GIF to display.
+ */
while (1) {
- if (Fread(buf, 1, 1, chan) != 1) {
+ if (Fread(gifConfPtr, buf, 1, 1, chan) != 1) {
/*
* Premature end of image.
*/
- Tcl_AppendResult(interp,"premature end of image data for this index",
- (char *) NULL);
+ Tcl_AppendResult(interp,
+ "premature end of image data for this index", NULL);
goto error;
}
- if (buf[0] == GIF_TERMINATOR) {
- /*
- * GIF terminator.
- */
-
- Tcl_AppendResult(interp,"no image data for this index",
- (char *) NULL);
+ switch (buf[0]) {
+ case GIF_TERMINATOR:
+ Tcl_AppendResult(interp, "no image data for this index", NULL);
goto error;
- }
- if (buf[0] == GIF_EXTENSION) {
+ case GIF_EXTENSION:
/*
* This is a GIF extension.
*/
- if (Fread(buf, 1, 1, chan) != 1) {
+ if (Fread(gifConfPtr, buf, 1, 1, chan) != 1) {
Tcl_SetResult(interp,
"error reading extension function code in GIF image",
TCL_STATIC);
goto error;
}
- if (DoExtension(chan, buf[0], &transparent) < 0) {
+ if (DoExtension(gifConfPtr, chan, buf[0],
+ gifConfPtr->workingBuffer, &transparent) < 0) {
Tcl_SetResult(interp, "error reading extension in GIF image",
TCL_STATIC);
goto error;
}
continue;
- }
-
- if (buf[0] != GIF_START) {
+ case GIF_START:
+ if (Fread(gifConfPtr, buf, 1, 9, chan) != 9) {
+ Tcl_SetResult(interp,
+ "couldn't read left/top/width/height in GIF image",
+ TCL_STATIC);
+ goto error;
+ }
+ break;
+ default:
/*
* Not a valid start character; ignore it.
*/
- continue;
- }
- if (Fread(buf, 1, 9, chan) != 9) {
- Tcl_SetResult(interp,
- "couldn't read left/top/width/height in GIF image",
- TCL_STATIC);
- goto error;
+ continue;
}
- imageWidth = LM_to_uint(buf[4],buf[5]);
- imageHeight = LM_to_uint(buf[6],buf[7]);
+ /*
+ * We've read the header for a GIF frame. Work out what we are going
+ * to do about it.
+ */
- bitPixel = 1<<((buf[8]&0x07)+1);
+ imageWidth = LM_to_uint(buf[4], buf[5]);
+ imageHeight = LM_to_uint(buf[6], buf[7]);
+ bitPixel = 1 << ((buf[8] & 0x07) + 1);
if (index--) {
/*
- * This is not the image we want to read: skip it.
+ * This is not the GIF frame we want to read: skip it.
*/
+
if (BitSet(buf[8], LOCALCOLORMAP)) {
- if (!ReadColorMap(chan, bitPixel, colorMap)) {
- Tcl_AppendResult(interp,
- "error reading color map", (char *) NULL);
+ if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
+ Tcl_AppendResult(interp, "error reading color map", NULL);
goto error;
}
}
@@ -394,113 +431,126 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY,
/*
* If we've not yet allocated a trash buffer, do so now.
*/
+
if (trashBuffer == NULL) {
nBytes = fileWidth * fileHeight * 3;
- trashBuffer =
- (unsigned char *) ckalloc((unsigned int) nBytes);
+ trashBuffer = (unsigned char *) ckalloc((unsigned) nBytes);
}
/*
- * Slurp! Process the data for this image and stuff it in
- * a trash buffer.
+ * Slurp! Process the data for this image and stuff it in a trash
+ * buffer.
*
- * Yes, it might be more efficient here to *not* store the
- * data (we're just going to throw it away later).
- * However, I elected to implement it this way for good
- * reasons. First, I wanted to avoid duplicating the
- * (fairly complex) LWZ decoder in ReadImage. Fine, you
- * say, why didn't you just modify it to allow the use of
- * a NULL specifier for the output buffer? I tried that,
- * but it negatively impacted the performance of what I
- * think will be the common case: reading the first image
- * in the file. Rather than marginally improve the speed
- * of the less frequent case, I chose to maintain high
- * performance for the common case.
+ * Yes, it might be more efficient here to *not* store the data
+ * (we're just going to throw it away later). However, I elected
+ * to implement it this way for good reasons. First, I wanted to
+ * avoid duplicating the (fairly complex) LWZ decoder in
+ * ReadImage. Fine, you say, why didn't you just modify it to
+ * allow the use of a NULL specifier for the output buffer? I
+ * tried that, but it negatively impacted the performance of what
+ * I think will be the common case: reading the first image in the
+ * file. Rather than marginally improve the speed of the less
+ * frequent case, I chose to maintain high performance for the
+ * common case.
*/
- if (ReadImage(interp, (char *) trashBuffer, chan, imageWidth,
- imageHeight, colorMap, 0, 0, 0, 0, 0, -1) != TCL_OK) {
+
+ if (ReadImage(gifConfPtr, interp, trashBuffer, chan, imageWidth,
+ imageHeight, colorMap, 0, 0, 0, -1) != TCL_OK) {
goto error;
}
continue;
}
+ break;
+ }
- if (BitSet(buf[8], LOCALCOLORMAP)) {
- if (!ReadColorMap(chan, bitPixel, colorMap)) {
- Tcl_AppendResult(interp, "error reading color map",
- (char *) NULL);
- goto error;
- }
- }
+ /*
+ * Found the frame we want to read. Next, check for a local color map for
+ * this frame.
+ */
- index = LM_to_uint(buf[0],buf[1]);
- srcX -= index;
- if (srcX<0) {
- destX -= srcX; width += srcX;
- srcX = 0;
+ if (BitSet(buf[8], LOCALCOLORMAP)) {
+ if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
+ Tcl_AppendResult(interp, "error reading color map", NULL);
+ goto error;
}
+ }
- if (width > imageWidth) {
- width = imageWidth;
- }
+ /*
+ * Extract the location within the overall visible image to put the data
+ * in this frame, together with the size of this frame.
+ */
- index = LM_to_uint(buf[2],buf[3]);
- srcY -= index;
- if (index > srcY) {
- destY -= srcY; height += srcY;
- srcY = 0;
- }
- if (height > imageHeight) {
- height = imageHeight;
- }
+ index = LM_to_uint(buf[0], buf[1]);
+ srcX -= index;
+ if (srcX<0) {
+ destX -= srcX; width += srcX;
+ srcX = 0;
+ }
- if ((width <= 0) || (height <= 0)) {
- block.pixelPtr = 0;
- goto noerror;
- }
+ if (width > imageWidth) {
+ width = imageWidth;
+ }
+
+ index = LM_to_uint(buf[2], buf[3]);
+ srcY -= index;
+ if (index > srcY) {
+ destY -= srcY; height += srcY;
+ srcY = 0;
+ }
+ if (height > imageHeight) {
+ height = imageHeight;
+ }
+
+ if ((width > 0) && (height > 0)) {
+ Tk_PhotoImageBlock block;
+
+ /*
+ * Read the data and put it into the photo buffer for display by the
+ * general image machinery.
+ */
block.width = width;
block.height = height;
block.pixelSize = (transparent>=0) ? 4 : 3;
+ block.offset[0] = 0;
+ block.offset[1] = 1;
+ block.offset[2] = 2;
block.offset[3] = (transparent>=0) ? 3 : 0;
block.pitch = block.pixelSize * imageWidth;
nBytes = block.pitch * imageHeight;
block.pixelPtr = (unsigned char *) ckalloc((unsigned) nBytes);
- if (ReadImage(interp, (char *) block.pixelPtr, chan, imageWidth,
- imageHeight, colorMap, fileWidth, fileHeight, srcX, srcY,
- BitSet(buf[8], INTERLACE), transparent) != TCL_OK) {
+ if (ReadImage(gifConfPtr, interp, block.pixelPtr, chan, imageWidth,
+ imageHeight, colorMap, srcX, srcY, BitSet(buf[8],INTERLACE),
+ transparent) != TCL_OK) {
+ ckfree((char *) block.pixelPtr);
goto error;
}
- break;
+ if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
+ width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
+ ckfree((char *) block.pixelPtr);
+ goto error;
+ }
+ ckfree((char *) block.pixelPtr);
}
- Tk_PhotoPutBlock(imageHandle, &block, destX, destY, width, height,
- TK_PHOTO_COMPOSITE_SET);
-
- noerror:
/*
- * If a trash buffer has been allocated, free it now.
+ * We've successfully read the GIF frame (or there was nothing to read,
+ * which suits as well). We're done.
*/
- if (trashBuffer != NULL) {
- ckfree((char *)trashBuffer);
- }
- if (block.pixelPtr) {
- ckfree((char *) block.pixelPtr);
- }
- Tcl_AppendResult(interp, tkImgFmtGIF.name, (char *) NULL);
- return TCL_OK;
- error:
+ Tcl_AppendResult(interp, tkImgFmtGIF.name, NULL);
+ result = TCL_OK;
+
+ error:
/*
* If a trash buffer has been allocated, free it now.
*/
+
if (trashBuffer != NULL) {
- ckfree((char *)trashBuffer);
- }
- if (block.pixelPtr) {
- ckfree((char *) block.pixelPtr);
+ ckfree((char *) trashBuffer);
}
- return TCL_ERROR;
+ return result;
}
/*
@@ -508,26 +558,26 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY,
*
* StringMatchGIF --
*
- * This procedure is invoked by the photo image type to see if
- * an object contains image data in GIF format.
+ * This function is invoked by the photo image type to see if an object
+ * contains image data in GIF format.
*
* Results:
- * The return value is 1 if the first characters in the data are
- * like GIF data, and 0 otherwise.
+ * The return value is 1 if the first characters in the data are like GIF
+ * data, and 0 otherwise.
*
* Side effects:
- * the size of the image is placed in widthPre and heightPtr.
+ * The size of the image is placed in widthPtr and heightPtr.
*
*----------------------------------------------------------------------
*/
static int
-StringMatchGIF(dataObj, format, widthPtr, heightPtr, interp)
- Tcl_Obj *dataObj; /* the object containing the image data */
- Tcl_Obj *format; /* the image format object, or NULL */
- int *widthPtr; /* where to put the string width */
- int *heightPtr; /* where to put the string height */
- Tcl_Interp *interp; /* not used */
+StringMatchGIF(
+ Tcl_Obj *dataObj, /* the object containing the image data */
+ Tcl_Obj *format, /* the image format object, or NULL */
+ int *widthPtr, /* where to put the string width */
+ int *heightPtr, /* where to put the string height */
+ Tcl_Interp *interp) /* not used */
{
unsigned char *data, header[10];
int got, length;
@@ -538,6 +588,7 @@ StringMatchGIF(dataObj, format, widthPtr, heightPtr, interp)
/*
* Header is a minimum of 10 bytes.
*/
+
if (length < 10) {
return 0;
}
@@ -546,97 +597,99 @@ StringMatchGIF(dataObj, format, widthPtr, heightPtr, interp)
* Check whether the data is Base64 encoded.
*/
- if ((strncmp(GIF87a, (char *) data, 6) != 0) &&
+ if ((strncmp(GIF87a, (char *) data, 6) != 0) &&
(strncmp(GIF89a, (char *) data, 6) != 0)) {
/*
* Try interpreting the data as Base64 encoded
*/
- mInit((unsigned char *) data, length, &handle);
+
+ mInit((unsigned char *) data, &handle, length);
got = Mread(header, 10, 1, &handle);
- if (got != 10
- || ((strncmp(GIF87a, (char *) header, 6) != 0)
+ if (got != 10 ||
+ ((strncmp(GIF87a, (char *) header, 6) != 0)
&& (strncmp(GIF89a, (char *) header, 6) != 0))) {
return 0;
}
} else {
- memcpy((VOID *) header, (VOID *) data, 10);
+ memcpy(header, data, 10);
}
- *widthPtr = LM_to_uint(header[6],header[7]);
- *heightPtr = LM_to_uint(header[8],header[9]);
+ *widthPtr = LM_to_uint(header[6], header[7]);
+ *heightPtr = LM_to_uint(header[8], header[9]);
return 1;
}
/*
*----------------------------------------------------------------------
*
- * StringReadGif -- --
+ * StringReadGIF --
*
- * This procedure is called by the photo image type to read
- * GIF format data from an object, optionally base64 encoded,
- * and give it to the photo image.
+ * This function is called by the photo image type to read GIF format
+ * data from an object, optionally base64 encoded, and give it to the
+ * photo image.
*
* Results:
- * A standard TCL completion code. If TCL_ERROR is returned
- * then an error message is left in the interp's result.
+ * A standard TCL completion code. If TCL_ERROR is returned then an error
+ * message is left in the interp's result.
*
* Side effects:
- * new data is added to the image given by imageHandle. This
- * procedure calls FileReadGif by redefining the operation of
- * fprintf temporarily.
+ * New data is added to the image given by imageHandle. This function
+ * calls FileReadGIF by redefining the operation of fprintf temporarily.
*
*----------------------------------------------------------------------
*/
static int
-StringReadGIF(interp, dataObj, format, imageHandle,
- destX, destY, width, height, srcX, srcY)
- Tcl_Interp *interp; /* interpreter for reporting errors in */
- Tcl_Obj *dataObj; /* object containing the image */
- Tcl_Obj *format; /* format object, or NULL */
- Tk_PhotoHandle imageHandle; /* the image to write this data into */
- int destX, destY; /* The rectangular region of the */
- int width, height; /* image to copy */
- int srcX, srcY;
+StringReadGIF(
+ Tcl_Interp *interp, /* interpreter for reporting errors in */
+ Tcl_Obj *dataObj, /* object containing the image */
+ Tcl_Obj *format, /* format object, or NULL */
+ Tk_PhotoHandle imageHandle, /* the image to write this data into */
+ int destX, int destY, /* The rectangular region of the */
+ int width, int height, /* image to copy */
+ int srcX, int srcY)
{
- int result, length;
- MFile handle;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- Tcl_Channel dataSrc;
- char *data;
+ MFile handle, *hdlPtr = &handle;
+ int length;
+ const char *xferFormat;
+ unsigned char *data = Tcl_GetByteArrayFromObj(dataObj, &length);
+
+ mInit(data, hdlPtr, length);
/*
- * Check whether the data is Base64 encoded
+ * Check whether the data is Base64 encoded by doing a character-by-
+ * charcter comparison with the binary-format headers; BASE64-encoded
+ * never matches (matching the other way is harder because of potential
+ * padding of the BASE64 data).
*/
- data = (char *) Tcl_GetByteArrayFromObj(dataObj, &length);
- if ((strncmp(GIF87a, data, 6) != 0) && (strncmp(GIF89a, data, 6) != 0)) {
- mInit((unsigned char *)data, length, &handle);
- tsdPtr->fromData = 1;
- dataSrc = (Tcl_Channel) &handle;
+
+ if (strncmp(GIF87a, (char *) data, 6)
+ && strncmp(GIF89a, (char *) data, 6)) {
+ xferFormat = INLINE_DATA_BASE64;
} else {
- tsdPtr->fromData = 2;
- mInit((unsigned char *)data, length, &handle);
- dataSrc = (Tcl_Channel) &handle;
+ xferFormat = INLINE_DATA_BINARY;
}
- result = FileReadGIF(interp, dataSrc, "inline data",
- format, imageHandle, destX, destY, width, height, srcX, srcY);
- tsdPtr->fromData = 0;
- return result;
-}
+ /*
+ * Fall through to the file reader now that we have a correctly-configured
+ * pseudo-channel to pull the data from.
+ */
+
+ return FileReadGIF(interp, (Tcl_Channel) hdlPtr, xferFormat, format,
+ imageHandle, destX, destY, width, height, srcX, srcY);
+}
+
/*
*----------------------------------------------------------------------
*
* ReadGIFHeader --
*
- * This procedure reads the GIF header from the beginning of a
- * GIF file and returns the dimensions of the image.
+ * This function reads the GIF header from the beginning of a GIF file
+ * and returns the dimensions of the image.
*
* Results:
- * The return value is 1 if file "f" appears to start with
- * a valid GIF header, 0 otherwise. If the header is valid,
- * then *widthPtr and *heightPtr are modified to hold the
- * dimensions of the image.
+ * The return value is 1 if file "f" appears to start with a valid GIF
+ * header, 0 otherwise. If the header is valid, then *widthPtr and
+ * *heightPtr are modified to hold the dimensions of the image.
*
* Side effects:
* The access position in f advances.
@@ -645,68 +698,70 @@ StringReadGIF(interp, dataObj, format, imageHandle,
*/
static int
-ReadGIFHeader(chan, widthPtr, heightPtr)
- Tcl_Channel chan; /* Image file to read the header from */
- int *widthPtr, *heightPtr; /* The dimensions of the image are
- * returned here. */
+ReadGIFHeader(
+ GIFImageConfig *gifConfPtr,
+ Tcl_Channel chan, /* Image file to read the header from */
+ int *widthPtr, int *heightPtr)
+ /* The dimensions of the image are returned
+ * here. */
{
unsigned char buf[7];
- if ((Fread(buf, 1, 6, chan) != 6)
+ if ((Fread(gifConfPtr, buf, 1, 6, chan) != 6)
|| ((strncmp(GIF87a, (char *) buf, 6) != 0)
&& (strncmp(GIF89a, (char *) buf, 6) != 0))) {
return 0;
}
- if (Fread(buf, 1, 4, chan) != 4) {
+ if (Fread(gifConfPtr, buf, 1, 4, chan) != 4) {
return 0;
}
- *widthPtr = LM_to_uint(buf[0],buf[1]);
- *heightPtr = LM_to_uint(buf[2],buf[3]);
+ *widthPtr = LM_to_uint(buf[0], buf[1]);
+ *heightPtr = LM_to_uint(buf[2], buf[3]);
return 1;
}
-
+
/*
*-----------------------------------------------------------------
- * The code below is copied from the giftoppm program and modified
- * just slightly.
+ * The code below is copied from the giftoppm program and modified just
+ * slightly.
*-----------------------------------------------------------------
*/
static int
-ReadColorMap(chan, number, buffer)
- Tcl_Channel chan;
- int number;
- unsigned char buffer[MAXCOLORMAPSIZE][4];
+ReadColorMap(
+ GIFImageConfig *gifConfPtr,
+ Tcl_Channel chan,
+ int number,
+ unsigned char buffer[MAXCOLORMAPSIZE][4])
{
int i;
unsigned char rgb[3];
for (i = 0; i < number; ++i) {
- if (! ReadOK(chan, rgb, sizeof(rgb))) {
+ if (Fread(gifConfPtr, rgb, sizeof(rgb), 1, chan) <= 0) {
return 0;
}
if (buffer) {
- buffer[i][CM_RED] = rgb[0] ;
- buffer[i][CM_GREEN] = rgb[1] ;
- buffer[i][CM_BLUE] = rgb[2] ;
- buffer[i][CM_ALPHA] = 255 ;
+ buffer[i][CM_RED] = rgb[0];
+ buffer[i][CM_GREEN] = rgb[1];
+ buffer[i][CM_BLUE] = rgb[2];
+ buffer[i][CM_ALPHA] = 255;
}
}
return 1;
}
-
-
-
+
static int
-DoExtension(chan, label, transparent)
- Tcl_Channel chan;
- int label;
- int *transparent;
+DoExtension(
+ GIFImageConfig *gifConfPtr,
+ Tcl_Channel chan,
+ int label,
+ unsigned char *buf,
+ int *transparent)
{
- static unsigned char buf[256];
int count;
switch (label) {
@@ -718,12 +773,12 @@ DoExtension(chan, label, transparent)
case 0xfe: /* Comment Extension */
do {
- count = GetDataBlock(chan, (unsigned char*) buf);
+ count = GetDataBlock(gifConfPtr, chan, buf);
} while (count > 0);
return count;
case 0xf9: /* Graphic Control Extension */
- count = GetDataBlock(chan, (unsigned char*) buf);
+ count = GetDataBlock(gifConfPtr, chan, buf);
if (count < 0) {
return 1;
}
@@ -732,53 +787,52 @@ DoExtension(chan, label, transparent)
}
do {
- count = GetDataBlock(chan, (unsigned char*) buf);
+ count = GetDataBlock(gifConfPtr, chan, buf);
} while (count > 0);
return count;
}
do {
- count = GetDataBlock(chan, (unsigned char*) buf);
+ count = GetDataBlock(gifConfPtr, chan, buf);
} while (count > 0);
return count;
}
-
+
static int
-GetDataBlock(chan, buf)
- Tcl_Channel chan;
- unsigned char *buf;
+GetDataBlock(
+ GIFImageConfig *gifConfPtr,
+ Tcl_Channel chan,
+ unsigned char *buf)
{
unsigned char count;
- if (! ReadOK(chan, &count,1)) {
+ if (Fread(gifConfPtr, &count, 1, 1, chan) <= 0) {
return -1;
}
- if ((count != 0) && (! ReadOK(chan, buf, count))) {
+ if ((count != 0) && (Fread(gifConfPtr, buf, count, 1, chan) <= 0)) {
return -1;
}
return count;
}
-
-
/*
*----------------------------------------------------------------------
*
* ReadImage --
*
- * Process a GIF image from a given source, with a given height,
- * width, transparency, etc.
+ * Process a GIF image from a given source, with a given height, width,
+ * transparency, etc.
*
* This code is based on the code found in the ImageMagick GIF decoder,
* which is (c) 2000 ImageMagick Studio.
*
* Some thoughts on our implementation:
- * It sure would be nice if ReadImage didn't take 11 parameters! I think
+ * It sure would be nice if ReadImage didn't take 11 parameters! I think
* that if we were smarter, we could avoid doing that.
*
- * Possible further optimizations: we could pull the GetCode function
+ * Possible further optimizations: we could pull the GetCode function
* directly into ReadImage, which would improve our speed.
*
* Results:
@@ -791,37 +845,36 @@ GetDataBlock(chan, buf)
*/
static int
-ReadImage(interp, imagePtr, chan, len, rows, cmap,
- width, height, srcX, srcY, interlace, transparent)
- Tcl_Interp *interp;
- char *imagePtr;
- Tcl_Channel chan;
- int len, rows;
- unsigned char cmap[MAXCOLORMAPSIZE][4];
- int width, height;
- int srcX, srcY;
- int interlace;
- int transparent;
+ReadImage(
+ GIFImageConfig *gifConfPtr,
+ Tcl_Interp *interp,
+ unsigned char *imagePtr,
+ Tcl_Channel chan,
+ int len, int rows,
+ unsigned char cmap[MAXCOLORMAPSIZE][4],
+ int srcX, int srcY,
+ int interlace,
+ int transparent)
{
unsigned char initialCodeSize;
- int v;
int xpos = 0, ypos = 0, pass = 0, i;
- register char *pixelPtr;
- static CONST int interlaceStep[] = { 8, 8, 4, 2 };
- static CONST int interlaceStart[] = { 0, 4, 2, 1 };
+ register unsigned char *pixelPtr;
+ static const int interlaceStep[] = { 8, 8, 4, 2 };
+ static const int interlaceStart[] = { 0, 4, 2, 1 };
unsigned short prefix[(1 << MAX_LWZ_BITS)];
- unsigned char append[(1 << MAX_LWZ_BITS)];
- unsigned char stack[(1 << MAX_LWZ_BITS)*2];
+ unsigned char append[(1 << MAX_LWZ_BITS)];
+ unsigned char stack[(1 << MAX_LWZ_BITS)*2];
register unsigned char *top;
int codeSize, clearCode, inCode, endCode, oldCode, maxCode;
- int code, firstCode;
+ int code, firstCode, v;
/*
- * Initialize the decoder
+ * Initialize the decoder
*/
- if (! ReadOK(chan, &initialCodeSize, 1)) {
+
+ if (Fread(gifConfPtr, &initialCodeSize, 1, 1, chan) <= 0) {
Tcl_AppendResult(interp, "error reading GIF image: ",
- Tcl_PosixError(interp), (char *) NULL);
+ Tcl_PosixError(interp), NULL);
return TCL_ERROR;
}
@@ -848,46 +901,49 @@ ReadImage(interp, imagePtr, chan, len, rows, cmap,
* code size size of the next code to retrieve
* max code next available table position
*/
+
clearCode = 1 << (int) initialCodeSize;
endCode = clearCode + 1;
codeSize = (int) initialCodeSize + 1;
maxCode = clearCode + 2;
oldCode = -1;
firstCode = -1;
-
- memset((void *)prefix, 0, (1 << MAX_LWZ_BITS) * sizeof(short));
- memset((void *)append, 0, (1 << MAX_LWZ_BITS) * sizeof(char));
+
+ memset(prefix, 0, (1 << MAX_LWZ_BITS) * sizeof(short));
+ memset(append, 0, (1 << MAX_LWZ_BITS) * sizeof(char));
for (i = 0; i < clearCode; i++) {
append[i] = i;
}
top = stack;
- GetCode(chan, 0, 1);
+ GetCode(chan, 0, 1, gifConfPtr);
/*
* Read until we finish the image
*/
+
for (i = 0, ypos = 0; i < rows; i++) {
for (xpos = 0; xpos < len; ) {
-
if (top == stack) {
/*
- * Bummer -- our stack is empty. Now we have to work!
+ * Bummer - our stack is empty. Now we have to work!
*/
- code = GetCode(chan, codeSize, 0);
+
+ code = GetCode(chan, codeSize, 0, gifConfPtr);
if (code < 0) {
return TCL_OK;
}
if (code > maxCode || code == endCode) {
/*
- * If we're doing things right, we should never
- * receive a code that is greater than our current
- * maximum code. If we do, bail, because our decoder
- * does not yet have that code set up.
+ * If we're doing things right, we should never receive a
+ * code that is greater than our current maximum code. If
+ * we do, bail, because our decoder does not yet have that
+ * code set up.
*
* If the code is the magic endCode value, quit.
*/
+
return TCL_OK;
}
@@ -895,44 +951,48 @@ ReadImage(interp, imagePtr, chan, len, rows, cmap,
/*
* Reset the decoder.
*/
+
codeSize = initialCodeSize + 1;
maxCode = clearCode + 2;
oldCode = -1;
continue;
}
-
+
if (oldCode == -1) {
/*
- * Last pass reset the decoder, so the first code we
- * see must be a singleton. Seed the stack with it,
- * and set up the old/first code pointers for
- * insertion into the string table. We can't just
- * roll this into the clearCode test above, because
- * at that point we have not yet read the next code.
+ * Last pass reset the decoder, so the first code we see
+ * must be a singleton. Seed the stack with it, and set up
+ * the old/first code pointers for insertion into the
+ * string table. We can't just roll this into the
+ * clearCode test above, because at that point we have not
+ * yet read the next code.
*/
+
*top++ = append[code];
oldCode = code;
firstCode = code;
continue;
}
-
+
inCode = code;
if (code == maxCode) {
/*
* maxCode is always one bigger than our highest assigned
- * code. If the code we see is equal to maxCode, then
- * we are about to add a new string to the table. ???
+ * code. If the code we see is equal to maxCode, then we
+ * are about to add a new string to the table. ???
*/
+
*top++ = firstCode;
code = oldCode;
}
while (code > clearCode) {
/*
- * Populate the stack by tracing the string in the
- * string table from its tail to its head
+ * Populate the stack by tracing the string in the string
+ * table from its tail to its head
*/
+
*top++ = append[code];
code = prefix[code];
}
@@ -942,6 +1002,7 @@ ReadImage(interp, imagePtr, chan, len, rows, cmap,
* If there's no more room in our string table, quit.
* Otherwise, add a new string to the table
*/
+
if (maxCode >= (1 << MAX_LWZ_BITS)) {
return TCL_OK;
}
@@ -949,21 +1010,24 @@ ReadImage(interp, imagePtr, chan, len, rows, cmap,
/*
* Push the head of the string onto the stack.
*/
+
*top++ = firstCode;
/*
* Add a new string to the string table
*/
+
prefix[maxCode] = oldCode;
append[maxCode] = firstCode;
maxCode++;
/*
- * maxCode tells us the maximum code value we can accept.
- * If we see that we need more bits to represent it than
- * we are requesting from the unpacker, we need to increase
- * the number we ask for.
+ * maxCode tells us the maximum code value we can accept. If
+ * we see that we need more bits to represent it than we are
+ * requesting from the unpacker, we need to increase the
+ * number we ask for.
*/
+
if ((maxCode >= (1 << codeSize))
&& (maxCode < (1<<MAX_LWZ_BITS))) {
codeSize++;
@@ -974,16 +1038,18 @@ ReadImage(interp, imagePtr, chan, len, rows, cmap,
/*
* Pop the next color index off the stack.
*/
+
v = *(--top);
if (v < 0) {
return TCL_OK;
}
- /*
+ /*
* If pixelPtr is null, we're skipping this image (presumably
- * there are more in the file and we will be called to read
- * one of them later)
+ * there are more in the file and we will be called to read one of
+ * them later)
*/
+
*pixelPtr++ = cmap[v][CM_RED];
*pixelPtr++ = cmap[v][CM_GREEN];
*pixelPtr++ = cmap[v][CM_BLUE];
@@ -995,8 +1061,9 @@ ReadImage(interp, imagePtr, chan, len, rows, cmap,
}
/*
- * If interlacing, the next ypos is not just +1
+ * If interlacing, the next ypos is not just +1.
*/
+
if (interlace) {
ypos += interlaceStep[pass];
while (ypos >= rows) {
@@ -1013,27 +1080,25 @@ ReadImage(interp, imagePtr, chan, len, rows, cmap,
}
return TCL_OK;
}
-
/*
*----------------------------------------------------------------------
*
* GetCode --
*
- * Extract the next compression code from the file. In GIF's, the
- * compression codes are between 3 and 12 bits long and are then
- * packed into 8 bit bytes, left to right, for example:
+ * Extract the next compression code from the file. In GIF's, the
+ * compression codes are between 3 and 12 bits long and are then packed
+ * into 8 bit bytes, left to right, for example:
* bbbaaaaa
* dcccccbb
* eeeedddd
* ...
- * We use a byte buffer read from the file and a sliding window
- * to unpack the bytes. Thanks to ImageMagick for the sliding window
- * idea.
+ * We use a byte buffer read from the file and a sliding window to unpack
+ * the bytes. Thanks to ImageMagick for the sliding window idea.
* args: chan the channel to read from
* code_size size of the code to extract
- * flag boolean indicating whether the extractor
- * should be reset or not
+ * flag boolean indicating whether the extractor should be
+ * reset or not
*
* Results:
* code the next compression code
@@ -1045,69 +1110,72 @@ ReadImage(interp, imagePtr, chan, len, rows, cmap,
*/
static int
-GetCode(chan, code_size, flag)
- Tcl_Channel chan;
- int code_size;
- int flag;
+GetCode(
+ Tcl_Channel chan,
+ int code_size,
+ int flag,
+ GIFImageConfig *gifConfPtr)
{
- static unsigned char buf[280];
- static int bytes = 0, done;
- static unsigned char *c;
-
- static unsigned int window;
- static int bitsInWindow = 0;
int ret;
-
+
if (flag) {
/*
* Initialize the decoder.
*/
- bitsInWindow = 0;
- bytes = 0;
- window = 0;
- done = 0;
- c = NULL;
+
+ gifConfPtr->reader.bitsInWindow = 0;
+ gifConfPtr->reader.bytes = 0;
+ gifConfPtr->reader.window = 0;
+ gifConfPtr->reader.done = 0;
+ gifConfPtr->reader.c = NULL;
return 0;
}
- while (bitsInWindow < code_size) {
+ while (gifConfPtr->reader.bitsInWindow < code_size) {
/*
* Not enough bits in our window to cover the request.
*/
- if (done) {
+
+ if (gifConfPtr->reader.done) {
return -1;
}
- if (bytes == 0) {
+ if (gifConfPtr->reader.bytes == 0) {
/*
* Not enough bytes in our buffer to add to the window.
*/
- bytes = GetDataBlock(chan, buf);
- c = buf;
- if (bytes <= 0) {
- done = 1;
+
+ gifConfPtr->reader.bytes =
+ GetDataBlock(gifConfPtr, chan, gifConfPtr->workingBuffer);
+ gifConfPtr->reader.c = gifConfPtr->workingBuffer;
+ if (gifConfPtr->reader.bytes <= 0) {
+ gifConfPtr->reader.done = 1;
break;
}
}
+
/*
* Tack another byte onto the window, see if that's enough.
*/
- window += (*c) << bitsInWindow;
- c++;
- bitsInWindow += 8;
- bytes--;
- }
+ gifConfPtr->reader.window +=
+ (*gifConfPtr->reader.c) << gifConfPtr->reader.bitsInWindow;
+ gifConfPtr->reader.c++;
+ gifConfPtr->reader.bitsInWindow += 8;
+ gifConfPtr->reader.bytes--;
+ }
/*
* The next code will always be the last code_size bits of the window.
*/
- ret = window & ((1 << code_size) - 1);
-
+
+ ret = gifConfPtr->reader.window & ((1 << code_size) - 1);
+
/*
* Shift data in the window to put the next code at the end.
*/
- window >>= code_size;
- bitsInWindow -= code_size;
+
+ gifConfPtr->reader.window >>= code_size;
+ gifConfPtr->reader.bitsInWindow -= code_size;
return ret;
}
@@ -1116,27 +1184,27 @@ GetCode(chan, code_size, flag)
*
* Minit -- --
*
- * This procedure initializes a base64 decoder handle
+ * This function initializes a base64 decoder handle
*
* Results:
- * none
+ * None
*
* Side effects:
- * the base64 handle is initialized
+ * The base64 handle is initialized
*
*----------------------------------------------------------------------
*/
static void
-mInit(string, length, handle)
- unsigned char *string; /* string containing initial mmencoded data */
- int length; /* Length of string */
- MFile *handle; /* mmdecode "file" handle */
+mInit(
+ unsigned char *string, /* string containing initial mmencoded data */
+ MFile *handle, /* mmdecode "file" handle */
+ int length) /* Number of bytes in string */
{
handle->data = string;
- handle->length = length;
handle->state = 0;
handle->c = 0;
+ handle->length = length;
}
/*
@@ -1144,9 +1212,9 @@ mInit(string, length, handle)
*
* Mread --
*
- * This procedure is invoked by the GIF file reader as a
- * temporary replacement for "fread", to get GIF data out
- * of a string (using Mgetc).
+ * This function is invoked by the GIF file reader as a temporary
+ * replacement for "fread", to get GIF data out of a string (using
+ * Mgetc).
*
* Results:
* The return value is the number of characters "read"
@@ -1158,50 +1226,45 @@ mInit(string, length, handle)
*/
static int
-Mread(dst, chunkSize, numChunks, handle)
- unsigned char *dst; /* where to put the result */
- size_t chunkSize; /* size of each transfer */
- size_t numChunks; /* number of chunks */
- MFile *handle; /* mmdecode "file" handle */
+Mread(
+ unsigned char *dst, /* where to put the result */
+ size_t chunkSize, /* size of each transfer */
+ size_t numChunks, /* number of chunks */
+ MFile *handle) /* mmdecode "file" handle */
{
register int i, c;
int count = chunkSize * numChunks;
- for(i=0; i<count && (c=Mgetc(handle)) != GIF_DONE; i++) {
+ for (i=0; i<count && (c=Mgetc(handle)) != GIF_DONE; i++) {
*dst++ = c;
}
return i;
}
-
-/*
- * get the next decoded character from an mmencode handle
- * This causes at least 1 character to be "read" from the encoded string
- */
/*
*----------------------------------------------------------------------
*
* Mgetc --
*
- * This procedure decodes and returns the next byte from a base64
- * encoded string.
+ * This function gets the next decoded character from an mmencode handle.
+ * This causes at least 1 character to be "read" from the encoded string.
*
* Results:
- * The next byte (or GIF_DONE) is returned.
+ * The next byte (or GIF_DONE) is returned.
*
* Side effects:
- * The base64 handle will change state.
+ * The base64 handle will change state.
*
*----------------------------------------------------------------------
*/
static int
-Mgetc(handle)
- MFile *handle; /* Handle containing decoder data and state */
+Mgetc(
+ MFile *handle) /* Handle containing decoder data and state */
{
int c;
- int result = 0; /* Initialization needed only to prevent
- * gcc compiler warning. */
+ int result = 0; /* Initialization needed only to prevent gcc
+ * compiler warning. */
if (handle->state == GIF_DONE) {
return GIF_DONE;
@@ -1209,7 +1272,6 @@ Mgetc(handle)
do {
if (handle->length-- <= 0) {
- handle->state = GIF_DONE;
return GIF_DONE;
}
c = char64(*handle->data);
@@ -1247,21 +1309,22 @@ Mgetc(handle)
*
* char64 --
*
- * This procedure converts a base64 ascii character into its binary
- * equivalent. This code is a slightly modified version of the
- * char64 proc in N. Borenstein's metamail decoder.
+ * This function converts a base64 ascii character into its binary
+ * equivalent. This code is a slightly modified version of the char64
+ * function in N. Borenstein's metamail decoder.
*
* Results:
* The binary value, or an error code.
*
* Side effects:
* None.
+ *
*----------------------------------------------------------------------
*/
static int
-char64(c)
-int c;
+char64(
+ int c)
{
switch(c) {
case 'A': return 0; case 'B': return 1; case 'C': return 2;
@@ -1303,52 +1366,53 @@ int c;
*
* Fread --
*
- * This procedure calls either fread or Mread to read data
- * from a file or a base64 encoded string.
+ * This function calls either fread or Mread to read data from a file or
+ * a base64 encoded string.
*
- * Results: - same as fread
+ * Results: - same as POSIX fread() or Tcl Tcl_Read()
*
*----------------------------------------------------------------------
*/
static int
-Fread(dst, hunk, count, chan)
- unsigned char *dst; /* where to put the result */
- size_t hunk,count; /* how many */
- Tcl_Channel chan;
+Fread(
+ GIFImageConfig *gifConfPtr,
+ unsigned char *dst, /* where to put the result */
+ size_t hunk, size_t count, /* how many */
+ Tcl_Channel chan)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- MFile *handle;
-
- switch (tsdPtr->fromData) {
- case 1:
+ if (gifConfPtr->fromData == INLINE_DATA_BASE64) {
return Mread(dst, hunk, count, (MFile *) chan);
- case 2:
- handle = (MFile *) chan;
- if (handle->length <= 0 || (size_t)handle->length < (size_t) (hunk * count)) {
+ }
+
+ if (gifConfPtr->fromData == INLINE_DATA_BINARY) {
+ MFile *handle = (MFile *) chan;
+
+ if (handle->length <= 0 || (size_t) handle->length < hunk*count) {
return -1;
}
- memcpy((VOID *)dst, (VOID *) handle->data, (size_t) (hunk * count));
+ memcpy(dst, handle->data, (size_t) (hunk * count));
handle->data += hunk * count;
- handle->length -= hunk * count;
return (int)(hunk * count);
- default:
- return Tcl_Read(chan, (char *) dst, (int) (hunk * count));
}
-}
+ /*
+ * Otherwise we've got a real file to read.
+ */
+
+ return Tcl_Read(chan, (char *) dst, (int) (hunk * count));
+}
/*
* ChanWriteGIF - writes a image in GIF format.
*-------------------------------------------------------------------------
- * Author: Lolo
- * Engeneering Projects Area
- * Department of Mining
- * University of Oviedo
- * e-mail zz11425958@zeus.etsimo.uniovi.es
- * lolo@pcsig22.etsimo.uniovi.es
- * Date: Fri September 20 1996
+ * Author: Lolo
+ * Engeneering Projects Area
+ * Department of Mining
+ * University of Oviedo
+ * e-mail zz11425958@zeus.etsimo.uniovi.es
+ * lolo@pcsig22.etsimo.uniovi.es
+ * Date: Fri September 20 1996
*
* Modified for transparency handling (gif89a) and miGIF compression
* by Jan Nijtmans <j.nijtmans@chello.nl>
@@ -1356,60 +1420,65 @@ Fread(dst, hunk, count, chan)
*----------------------------------------------------------------------
* FileWriteGIF-
*
- * This procedure is called by the photo image type to write
- * GIF format data from a photo image into a given file
+ * This function is called by the photo image type to write GIF format
+ * data from a photo image into a given file
*
* Results:
- * A standard TCL completion code. If TCL_ERROR is returned
- * then an error message is left in interp->result.
+ * A standard TCL completion code. If TCL_ERROR is returned then an error
+ * message is left in interp->result.
*
*----------------------------------------------------------------------
*/
- /*
- * Types, defines and variables needed to write and compress a GIF.
- */
-
-typedef int (* ifunptr) _ANSI_ARGS_((void));
-
-#define LSB(a) ((unsigned char) (((short)(a)) & 0x00FF))
-#define MSB(a) ((unsigned char) (((short)(a)) >> 8))
-
-#define GIFBITS 12
-#define HSIZE 5003 /* 80% occupancy */
+/*
+ * Types, defines and variables needed to write and compress a GIF.
+ */
-static int ssize;
-static int csize;
-static int rsize;
-static unsigned char *pixelo;
-static int pixelSize;
-static int pixelPitch;
-static int greenOffset;
-static int blueOffset;
-static int alphaOffset;
-static int num;
-static unsigned char mapa[MAXCOLORMAPSIZE][3];
+typedef int (* ifunptr) (ClientData clientData);
+
+#define LSB(a) ((unsigned char) (((short)(a)) & 0x00FF))
+#define MSB(a) ((unsigned char) (((short)(a)) >> 8))
+
+#define GIFBITS 12
+#define HSIZE 5003 /* 80% occupancy */
+
+typedef struct {
+ int ssize;
+ int csize;
+ int rsize;
+ unsigned char *pixelo;
+ int pixelSize;
+ int pixelPitch;
+ int greenOffset;
+ int blueOffset;
+ int alphaOffset;
+ int num;
+ unsigned char mapa[MAXCOLORMAPSIZE][3];
+} GifWriterState;
/*
- * Definition of new functions to write GIFs
+ * Definition of new functions to write GIFs
*/
-static int color _ANSI_ARGS_((int red,int green, int blue,
- unsigned char mapa[MAXCOLORMAPSIZE][3]));
-static void compress _ANSI_ARGS_((int init_bits, Tcl_Channel handle,
- ifunptr readValue));
-static int nuevo _ANSI_ARGS_((int red, int green ,int blue,
- unsigned char mapa[MAXCOLORMAPSIZE][3]));
-static void savemap _ANSI_ARGS_((Tk_PhotoImageBlock *blockPtr,
- unsigned char mapa[MAXCOLORMAPSIZE][3]));
-static int ReadValue _ANSI_ARGS_((void));
-
+static int color(GifWriterState *statePtr,
+ int red, int green, int blue,
+ unsigned char mapa[MAXCOLORMAPSIZE][3]);
+static void compress(int initBits, Tcl_Channel handle,
+ ifunptr readValue, ClientData clientData);
+static int nuevo(GifWriterState *statePtr,
+ int red, int green, int blue,
+ unsigned char mapa[MAXCOLORMAPSIZE][3]);
+static void savemap(GifWriterState *statePtr,
+ Tk_PhotoImageBlock *blockPtr,
+ unsigned char mapa[MAXCOLORMAPSIZE][3]);
+static int ReadValue(ClientData clientData);
+
static int
-FileWriteGIF(interp, filename, format, blockPtr)
- Tcl_Interp *interp; /* Interpreter to use for reporting errors. */
- CONST char *filename;
- Tcl_Obj *format;
- Tk_PhotoImageBlock *blockPtr;
+FileWriteGIF(
+ Tcl_Interp *interp, /* Interpreter to use for reporting errors. */
+ const char *filename,
+ Tcl_Obj *format,
+ Tk_PhotoImageBlock *blockPtr)
{
Tcl_Channel chan = NULL;
int result;
@@ -1418,167 +1487,168 @@ FileWriteGIF(interp, filename, format, blockPtr)
if (!chan) {
return TCL_ERROR;
}
- if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") != TCL_OK) {
+ if (Tcl_SetChannelOption(interp, chan, "-translation",
+ "binary") != TCL_OK) {
Tcl_Close(NULL, chan);
return TCL_ERROR;
}
result = CommonWriteGIF(interp, chan, format, blockPtr);
+
if (Tcl_Close(interp, chan) == TCL_ERROR) {
return TCL_ERROR;
}
return result;
}
-
-#define Mputc(c,handle) Tcl_Write(handle,(char *) &c,1)
-
+
static int
-CommonWriteGIF(interp, handle, format, blockPtr)
- Tcl_Interp *interp;
- Tcl_Channel handle;
- Tcl_Obj *format;
- Tk_PhotoImageBlock *blockPtr;
+CommonWriteGIF(
+ Tcl_Interp *interp,
+ Tcl_Channel handle,
+ Tcl_Obj *format,
+ Tk_PhotoImageBlock *blockPtr)
{
- int resolution;
-
- long width,height,x;
+ GifWriterState state, *statePtr = &state;
+ int resolution;
+ long width, height, x;
unsigned char c;
- unsigned int top,left;
+ unsigned int top, left;
top = 0;
left = 0;
- pixelSize = blockPtr->pixelSize;
- greenOffset = blockPtr->offset[1]-blockPtr->offset[0];
- blueOffset = blockPtr->offset[2]-blockPtr->offset[0];
- alphaOffset = blockPtr->offset[0];
- if (alphaOffset < blockPtr->offset[2]) {
- alphaOffset = blockPtr->offset[2];
+ memset(statePtr, 0, sizeof(state));
+
+ statePtr->pixelSize = blockPtr->pixelSize;
+ statePtr->greenOffset = blockPtr->offset[1]-blockPtr->offset[0];
+ statePtr->blueOffset = blockPtr->offset[2]-blockPtr->offset[0];
+ statePtr->alphaOffset = blockPtr->offset[0];
+ if (statePtr->alphaOffset < blockPtr->offset[2]) {
+ statePtr->alphaOffset = blockPtr->offset[2];
}
- if (++alphaOffset < pixelSize) {
- alphaOffset -= blockPtr->offset[0];
+ if (++statePtr->alphaOffset < statePtr->pixelSize) {
+ statePtr->alphaOffset -= blockPtr->offset[0];
} else {
- alphaOffset = 0;
+ statePtr->alphaOffset = 0;
}
- Tcl_Write(handle, (char *) (alphaOffset ? GIF89a : GIF87a), 6);
+ Tcl_Write(handle, (char *) (statePtr->alphaOffset ? GIF89a : GIF87a), 6);
for (x=0 ; x<MAXCOLORMAPSIZE ; x++) {
- mapa[x][CM_RED] = 255;
- mapa[x][CM_GREEN] = 255;
- mapa[x][CM_BLUE] = 255;
+ statePtr->mapa[x][CM_RED] = 255;
+ statePtr->mapa[x][CM_GREEN] = 255;
+ statePtr->mapa[x][CM_BLUE] = 255;
}
-
width = blockPtr->width;
height = blockPtr->height;
- pixelo = blockPtr->pixelPtr + blockPtr->offset[0];
- pixelPitch = blockPtr->pitch;
- savemap(blockPtr,mapa);
- if (num >= MAXCOLORMAPSIZE) {
- Tcl_AppendResult(interp, "too many colors", (char *) NULL);
+ statePtr->pixelo = blockPtr->pixelPtr + blockPtr->offset[0];
+ statePtr->pixelPitch = blockPtr->pitch;
+ savemap(statePtr, blockPtr, statePtr->mapa);
+ if (statePtr->num >= MAXCOLORMAPSIZE) {
+ Tcl_AppendResult(interp, "too many colors", NULL);
return TCL_ERROR;
}
- if (num<2) {
- num = 2;
+ if (statePtr->num<2) {
+ statePtr->num = 2;
}
c = LSB(width);
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
c = MSB(width);
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
c = LSB(height);
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
c = MSB(height);
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
resolution = 0;
- while (num >> resolution) {
+ while (statePtr->num >> resolution) {
resolution++;
}
c = 111 + resolution * 17;
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
- num = 1 << resolution;
+ statePtr->num = 1 << resolution;
/*
- * background color
+ * Background color
*/
c = 0;
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
/*
- * zero for future expansion.
+ * Zero for future expansion.
*/
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
- for (x=0 ; x<num ; x++) {
- c = mapa[x][CM_RED];
- Mputc(c,handle);
- c = mapa[x][CM_GREEN];
- Mputc(c,handle);
- c = mapa[x][CM_BLUE];
- Mputc(c,handle);
+ for (x=0 ; x<statePtr->num ; x++) {
+ c = statePtr->mapa[x][CM_RED];
+ Tcl_Write(handle, (char *) &c, 1);
+ c = statePtr->mapa[x][CM_GREEN];
+ Tcl_Write(handle, (char *) &c, 1);
+ c = statePtr->mapa[x][CM_BLUE];
+ Tcl_Write(handle, (char *) &c, 1);
}
/*
* Write out extension for transparent colour index, if necessary.
*/
- if (alphaOffset) {
+ if (statePtr->alphaOffset) {
c = GIF_EXTENSION;
- Mputc(c, handle);
+ Tcl_Write(handle, (char *) &c, 1);
Tcl_Write(handle, "\371\4\1\0\0\0", 7);
}
c = GIF_START;
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
c = LSB(top);
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
c = MSB(top);
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
c = LSB(left);
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
c = MSB(left);
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
c = LSB(width);
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
c = MSB(width);
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
c = LSB(height);
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
c = MSB(height);
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
c = 0;
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
c = resolution;
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
- ssize = rsize = blockPtr->width;
- csize = blockPtr->height;
- compress(resolution+1, handle, ReadValue);
+ statePtr->ssize = statePtr->rsize = blockPtr->width;
+ statePtr->csize = blockPtr->height;
+ compress(resolution+1, handle, ReadValue, (ClientData) statePtr);
- c = 0;
- Mputc(c,handle);
+ c = 0;
+ Tcl_Write(handle, (char *) &c, 1);
c = GIF_TERMINATOR;
- Mputc(c,handle);
+ Tcl_Write(handle, (char *) &c, 1);
- return TCL_OK;
+ return TCL_OK;
}
-
+
static int
-color(red, green, blue, mapa)
- int red;
- int green;
- int blue;
- unsigned char mapa[MAXCOLORMAPSIZE][3];
+color(
+ GifWriterState *statePtr,
+ int red, int green, int blue,
+ unsigned char mapa[MAXCOLORMAPSIZE][3])
{
- int x;
- for (x=(alphaOffset != 0) ; x<=MAXCOLORMAPSIZE ; x++) {
+ int x = (statePtr->alphaOffset != 0);
+
+ for (; x<=MAXCOLORMAPSIZE ; x++) {
if ((mapa[x][CM_RED] == red) && (mapa[x][CM_GREEN] == green) &&
(mapa[x][CM_BLUE] == blue)) {
return x;
@@ -1586,15 +1656,16 @@ color(red, green, blue, mapa)
}
return -1;
}
-
static int
-nuevo(red, green, blue, mapa)
- int red,green,blue;
- unsigned char mapa[MAXCOLORMAPSIZE][3];
+nuevo(
+ GifWriterState *statePtr,
+ int red, int green, int blue,
+ unsigned char mapa[MAXCOLORMAPSIZE][3])
{
- int x = (alphaOffset != 0);
- for (; x<=num ; x++) {
+ int x = (statePtr->alphaOffset != 0);
+
+ for (; x<=statePtr->num ; x++) {
if ((mapa[x][CM_RED] == red) && (mapa[x][CM_GREEN] == green) &&
(mapa[x][CM_BLUE] == blue)) {
return 0;
@@ -1602,74 +1673,76 @@ nuevo(red, green, blue, mapa)
}
return 1;
}
-
+
static void
-savemap(blockPtr,mapa)
- Tk_PhotoImageBlock *blockPtr;
- unsigned char mapa[MAXCOLORMAPSIZE][3];
+savemap(
+ GifWriterState *statePtr,
+ Tk_PhotoImageBlock *blockPtr,
+ unsigned char mapa[MAXCOLORMAPSIZE][3])
{
unsigned char *colores;
- int x,y;
- unsigned char red,green,blue;
+ int x, y;
+ unsigned char red, green, blue;
- if (alphaOffset) {
- num = 0;
+ if (statePtr->alphaOffset) {
+ statePtr->num = 0;
mapa[0][CM_RED] = 0xd9;
mapa[0][CM_GREEN] = 0xd9;
mapa[0][CM_BLUE] = 0xd9;
} else {
- num = -1;
+ statePtr->num = -1;
}
- for(y=0 ; y<blockPtr->height ; y++) {
- colores = blockPtr->pixelPtr + blockPtr->offset[0]
- + y * blockPtr->pitch;
- for(x=0 ; x<blockPtr->width ; x++) {
- if (!alphaOffset || (colores[alphaOffset] != 0)) {
+ for (y=0 ; y<blockPtr->height ; y++) {
+ colores = blockPtr->pixelPtr + blockPtr->offset[0] + y*blockPtr->pitch;
+ for (x=0 ; x<blockPtr->width ; x++) {
+ if (!statePtr->alphaOffset || colores[statePtr->alphaOffset]!=0) {
red = colores[0];
- green = colores[greenOffset];
- blue = colores[blueOffset];
- if (nuevo(red,green,blue,mapa)) {
- num++;
- if (num >= MAXCOLORMAPSIZE) {
+ green = colores[statePtr->greenOffset];
+ blue = colores[statePtr->blueOffset];
+ if (nuevo(statePtr, red, green, blue, mapa)) {
+ statePtr->num++;
+ if (statePtr->num >= MAXCOLORMAPSIZE) {
return;
}
- mapa[num][CM_RED] = red;
- mapa[num][CM_GREEN] = green;
- mapa[num][CM_BLUE] = blue;
+ mapa[statePtr->num][CM_RED] = red;
+ mapa[statePtr->num][CM_GREEN] = green;
+ mapa[statePtr->num][CM_BLUE] = blue;
}
}
- colores += pixelSize;
+ colores += statePtr->pixelSize;
}
}
- return;
}
-
+
static int
-ReadValue()
+ReadValue(
+ ClientData clientData)
{
+ GifWriterState *statePtr = (GifWriterState *) clientData;
unsigned int col;
- if (csize == 0) {
+ if (statePtr->csize == 0) {
return EOF;
}
- if (alphaOffset && (pixelo[alphaOffset] == 0)) {
+ if (statePtr->alphaOffset && statePtr->pixelo[statePtr->alphaOffset]==0) {
col = 0;
} else {
- col = color(pixelo[0], pixelo[greenOffset], pixelo[blueOffset], mapa);
+ col = color(statePtr, statePtr->pixelo[0],
+ statePtr->pixelo[statePtr->greenOffset],
+ statePtr->pixelo[statePtr->blueOffset], statePtr->mapa);
}
- pixelo += pixelSize;
- if (--ssize <= 0) {
- ssize = rsize;
- csize--;
- pixelo += pixelPitch - (rsize * pixelSize);
+ statePtr->pixelo += statePtr->pixelSize;
+ if (--statePtr->ssize <= 0) {
+ statePtr->ssize = statePtr->rsize;
+ statePtr->csize--;
+ statePtr->pixelo += statePtr->pixelPitch
+ - (statePtr->rsize * statePtr->pixelSize);
}
return col;
}
-
-
/*
*-----------------------------------------------------------------------
*
@@ -1681,30 +1754,27 @@ ReadValue()
* http://www.hasc.com
* info@hasc.com
*
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation. This software is
- * provided "AS IS." The Hutchison Avenue Software Corporation
- * disclaims all warranties, either express or implied, including but
- * not limited to implied warranties of merchantability and fitness
- * for a particular purpose, with respect to this code and
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. This software is provided "AS IS." The Hutchison Avenue
+ * Software Corporation disclaims all warranties, either express or implied,
+ * including but not limited to implied warranties of merchantability and
+ * fitness for a particular purpose, with respect to this code and
* accompanying documentation.
- *
- * The miGIF compression routines do not, strictly speaking, generate
- * files conforming to the GIF spec, since the image data is not
- * LZW-compressed (this is the point: in order to avoid transgression
- * of the Unisys patent on the LZW algorithm.) However, miGIF
- * generates data streams that any reasonably sane LZW decompresser
- * will decompress to what we want.
- *
- * miGIF compression uses run length encoding. It compresses
- * horizontal runs of pixels of the same color. This type of
- * compression gives good results on images with many runs, for
- * example images with lines, text and solid shapes on a solid-colored
- * background. It gives little or no compression on images with few
- * runs, for example digital or scanned photos.
+ *
+ * The miGIF compression routines do not, strictly speaking, generate files
+ * conforming to the GIF spec, since the image data is not LZW-compressed
+ * (this is the point: in order to avoid transgression of the Unisys patent on
+ * the LZW algorithm.) However, miGIF generates data streams that any
+ * reasonably sane LZW decompresser will decompress to what we want.
+ *
+ * miGIF compression uses run length encoding. It compresses horizontal runs
+ * of pixels of the same color. This type of compression gives good results on
+ * images with many runs, for example images with lines, text and solid shapes
+ * on a solid-colored background. It gives little or no compression on images
+ * with few runs, for example digital or scanned photos.
*
* der Mouse
* mouse@rodents.montreal.qc.ca
@@ -1712,35 +1782,36 @@ ReadValue()
*
* ivo@hasc.com
*
- * The Graphics Interchange Format(c) is the Copyright property of
- * CompuServe Incorporated. GIF(sm) is a Service Mark property of
- * CompuServe Incorporated.
+ * The Graphics Interchange Format(c) is the Copyright property of CompuServe
+ * Incorporated. GIF(sm) is a Service Mark property of CompuServe Incorporated.
*
*-----------------------------------------------------------------------
*/
-static int rl_pixel;
-static int rl_basecode;
-static int rl_count;
-static int rl_table_pixel;
-static int rl_table_max;
-static int just_cleared;
-static int out_bits;
-static int out_bits_init;
-static int out_count;
-static int out_bump;
-static int out_bump_init;
-static int out_clear;
-static int out_clear_init;
-static int max_ocodes;
-static int code_clear;
-static int code_eof;
-static unsigned int obuf;
-static int obits;
-static Tcl_Channel ofile;
-static unsigned char oblock[256];
-static int oblen;
-
+typedef struct {
+ int runlengthPixel;
+ int runlengthBaseCode;
+ int runlengthCount;
+ int runlengthTablePixel;
+ int runlengthTableMax;
+ int justCleared;
+ int outputBits;
+ int outputBitsInit;
+ int outputCount;
+ int outputBump;
+ int outputBumpInit;
+ int outputClear;
+ int outputClearInit;
+ int maxOcodes;
+ int codeClear;
+ int codeEOF;
+ unsigned int obuf;
+ int obits;
+ Tcl_Channel ofile;
+ unsigned char oblock[256];
+ int oblen;
+} miGIFState_t;
+
/*
* Used only when debugging GIF compression code
*/
@@ -1748,23 +1819,28 @@ static int oblen;
#ifdef MIGIF_DEBUGGING_ENVARS
-static int verbose_set = 0;
+/*
+ * This debugging code is _absolutely_ not thread-safe. It's also not normally
+ * enabled either.
+ */
+
+static int verboseSet = 0;
static int verbose;
-#define MIGIF_VERBOSE (verbose_set?verbose:set_verbose())
-#define DEBUGMSG(printf_args) if (MIGIF_VERBOSE) { printf printf_args; }
+#define MIGIF_VERBOSE (verboseSet?verbose:setVerbose())
+#define DEBUGMSG(printfArgs) if (MIGIF_VERBOSE) { printf printfArgs; }
static int
-set_verbose(void)
+setVerbose(void)
{
verbose = !!getenv("MIGIF_VERBOSE");
- verbose_set = 1;
+ verboseSet = 1;
return verbose;
}
-static CONST char *
-binformat(v, nbits)
- unsigned int v;
- int nbits;
+static const char *
+binformat(
+ unsigned int v,
+ int nbits)
{
static char bufs[8][64];
static int bhand = 0;
@@ -1786,112 +1862,119 @@ binformat(v, nbits)
*bp = '\0';
return &bufs[bhand][0];
}
-
-#else
-
-#define MIGIF_VERBOSE 0
-#define DEBUGMSG(printf_args) /* do nothing */
-
+#else /* !MIGIF_DEBUGGING_ENVARS */
+#define DEBUGMSG(printfArgs) /* do nothing */
#endif
-
+
static void
-write_block()
+writeBlock(
+ miGIFState_t *statePtr)
{
- int i;
unsigned char c;
+#ifdef MIGIF_DEBUGGING_ENVARS
if (MIGIF_VERBOSE) {
- printf("write_block %d:", oblen);
- for (i=0 ; i<oblen ; i++) {
- printf(" %02x", oblock[i]);
+ int i;
+ printf("writeBlock %d:", statePtr->oblen);
+ for (i=0 ; i<statePtr->oblen ; i++) {
+ printf(" %02x", statePtr->oblock[i]);
}
printf("\n");
}
- c = oblen;
- Tcl_Write(ofile, (char *) &c, 1);
- Tcl_Write(ofile, (char *) &oblock[0], oblen);
- oblen = 0;
+#endif
+ c = statePtr->oblen;
+ Tcl_Write(statePtr->ofile, (char *) &c, 1);
+ Tcl_Write(statePtr->ofile, (char *) &statePtr->oblock[0], statePtr->oblen);
+ statePtr->oblen = 0;
}
-
+
static void
-block_out(c)
- unsigned char c;
+blockOut(
+ miGIFState_t *statePtr,
+ unsigned c)
{
- DEBUGMSG(("block_out %s\n", binformat(c, 8)));
- oblock[oblen++] = c;
- if (oblen >= 255) {
- write_block();
+ DEBUGMSG(("blockOut %s\n", binformat(c, 8)));
+ statePtr->oblock[statePtr->oblen++] = (unsigned char) c;
+ if (statePtr->oblen >= 255) {
+ writeBlock(statePtr);
}
}
-
+
static void
-block_flush()
+blockFlush(
+ miGIFState_t *statePtr)
{
- DEBUGMSG(("block_flush\n"));
- if (oblen > 0) {
- write_block();
+ DEBUGMSG(("blockFlush\n"));
+ if (statePtr->oblen > 0) {
+ writeBlock(statePtr);
}
}
-
+
static void
-output(val)
- int val;
+output(
+ miGIFState_t *statePtr,
+ int val)
{
- DEBUGMSG(("output %s [%s %d %d]\n", binformat(val, out_bits),
- binformat(obuf, obits), obits, out_bits));
- obuf |= val << obits;
- obits += out_bits;
- while (obits >= 8) {
- block_out(UCHAR(obuf&0xff));
- obuf >>= 8;
- obits -= 8;
- }
- DEBUGMSG(("output leaving [%s %d]\n", binformat(obuf, obits), obits));
+ DEBUGMSG(("output %s [%s %d %d]\n", binformat(val, statePtr->outputBits),
+ binformat(statePtr->obuf, statePtr->obits), statePtr->obits,
+ statePtr->outputBits));
+ statePtr->obuf |= val << statePtr->obits;
+ statePtr->obits += statePtr->outputBits;
+ while (statePtr->obits >= 8) {
+ blockOut(statePtr, statePtr->obuf & 0xff);
+ statePtr->obuf >>= 8;
+ statePtr->obits -= 8;
+ }
+ DEBUGMSG(("output leaving [%s %d]\n",
+ binformat(statePtr->obuf, statePtr->obits), statePtr->obits));
}
-
+
static void
-output_flush()
+outputFlush(
+ miGIFState_t *statePtr)
{
- DEBUGMSG(("output_flush\n"));
- if (obits > 0) {
- block_out(UCHAR(obuf));
+ DEBUGMSG(("outputFlush\n"));
+ if (statePtr->obits > 0) {
+ blockOut(statePtr, statePtr->obuf);
}
- block_flush();
+ blockFlush(statePtr);
}
-
+
static void
-did_clear()
+didClear(
+ miGIFState_t *statePtr)
{
- DEBUGMSG(("did_clear\n"));
- out_bits = out_bits_init;
- out_bump = out_bump_init;
- out_clear = out_clear_init;
- out_count = 0;
- rl_table_max = 0;
- just_cleared = 1;
+ DEBUGMSG(("didClear\n"));
+ statePtr->outputBits = statePtr->outputBitsInit;
+ statePtr->outputBump = statePtr->outputBumpInit;
+ statePtr->outputClear = statePtr->outputClearInit;
+ statePtr->outputCount = 0;
+ statePtr->runlengthTableMax = 0;
+ statePtr->justCleared = 1;
}
-
+
static void
-output_plain(c)
- int c;
+outputPlain(
+ miGIFState_t *statePtr,
+ int c)
{
- DEBUGMSG(("output_plain %s\n", binformat(c, out_bits)));
- just_cleared = 0;
- output(c);
- out_count++;
- if (out_count >= out_bump) {
- out_bits++;
- out_bump += 1 << (out_bits - 1);
- }
- if (out_count >= out_clear) {
- output(code_clear);
- did_clear();
+ DEBUGMSG(("outputPlain %s\n", binformat(c, statePtr->outputBits)));
+ statePtr->justCleared = 0;
+ output(statePtr, c);
+ statePtr->outputCount++;
+ if (statePtr->outputCount >= statePtr->outputBump) {
+ statePtr->outputBits++;
+ statePtr->outputBump += 1 << (statePtr->outputBits - 1);
+ }
+ if (statePtr->outputCount >= statePtr->outputClear) {
+ output(statePtr, statePtr->codeClear);
+ didClear(statePtr);
}
}
-
+
static unsigned int
-isqrt(x)
- unsigned int x;
+isqrt(
+ unsigned int x)
{
unsigned int r;
unsigned int v;
@@ -1908,11 +1991,11 @@ isqrt(x)
r = v;
}
}
-
-static unsigned int
-compute_triangle_count(count, nrepcodes)
- unsigned int count;
- unsigned int nrepcodes;
+
+static int
+computeTriangleCount(
+ unsigned int count,
+ unsigned int nrepcodes)
{
unsigned int perrep;
unsigned int cost;
@@ -1924,8 +2007,8 @@ compute_triangle_count(count, nrepcodes)
count -= perrep;
}
if (count > 0) {
- unsigned int n;
- n = isqrt(count);
+ unsigned int n = isqrt(count);
+
while (n*(n+1) >= 2*count) {
n--;
}
@@ -1934,204 +2017,233 @@ compute_triangle_count(count, nrepcodes)
}
cost += n;
}
- return cost;
+ return (int) cost + 1;
}
-
+
static void
-max_out_clear()
+maxOutputClear(
+ miGIFState_t *statePtr)
{
- out_clear = max_ocodes;
+ statePtr->outputClear = statePtr->maxOcodes;
}
-
+
static void
-reset_out_clear()
+resetOutputClear(
+ miGIFState_t *statePtr)
{
- out_clear = out_clear_init;
- if (out_count >= out_clear) {
- output(code_clear);
- did_clear();
+ statePtr->outputClear = statePtr->outputClearInit;
+ if (statePtr->outputCount >= statePtr->outputClear) {
+ output(statePtr, statePtr->codeClear);
+ didClear(statePtr);
}
}
-
+
static void
-rl_flush_fromclear(count)
- int count;
+runlengthFlushFromClear(
+ miGIFState_t *statePtr,
+ int count)
{
int n;
- DEBUGMSG(("rl_flush_fromclear %d\n", count));
- max_out_clear();
- rl_table_pixel = rl_pixel;
+ DEBUGMSG(("runlengthFlushFromClear %d\n", count));
+ maxOutputClear(statePtr);
+ statePtr->runlengthTablePixel = statePtr->runlengthPixel;
n = 1;
while (count > 0) {
if (n == 1) {
- rl_table_max = 1;
- output_plain(rl_pixel);
+ statePtr->runlengthTableMax = 1;
+ outputPlain(statePtr, statePtr->runlengthPixel);
count--;
} else if (count >= n) {
- rl_table_max = n;
- output_plain(rl_basecode+n-2);
+ statePtr->runlengthTableMax = n;
+ outputPlain(statePtr, statePtr->runlengthBaseCode+n-2);
count -= n;
} else if (count == 1) {
- rl_table_max++;
- output_plain(rl_pixel);
+ statePtr->runlengthTableMax++;
+ outputPlain(statePtr, statePtr->runlengthPixel);
count = 0;
} else {
- rl_table_max++;
- output_plain(rl_basecode+count-2);
+ statePtr->runlengthTableMax++;
+ outputPlain(statePtr, statePtr->runlengthBaseCode+count-2);
count = 0;
}
- if (out_count == 0) {
+ if (statePtr->outputCount == 0) {
n = 1;
} else {
n++;
}
}
- reset_out_clear();
- DEBUGMSG(("rl_flush_fromclear leaving table_max=%d\n", rl_table_max));
+ resetOutputClear(statePtr);
+ DEBUGMSG(("runlengthFlushFromClear leaving tableMax=%d\n",
+ statePtr->runlengthTableMax));
}
-
+
static void
-rl_flush_clearorrep(count)
- int count;
+runlengthFlushClearOrRep(
+ miGIFState_t *statePtr,
+ int count)
{
int withclr;
- DEBUGMSG(("rl_flush_clearorrep %d\n", count));
- withclr = 1 + compute_triangle_count(count, max_ocodes);
+ DEBUGMSG(("runlengthFlushClearOrRep %d\n", count));
+ withclr = computeTriangleCount((unsigned) count,
+ (unsigned) statePtr->maxOcodes);
if (withclr < count) {
- output(code_clear);
- did_clear();
- rl_flush_fromclear(count);
+ output(statePtr, statePtr->codeClear);
+ didClear(statePtr);
+ runlengthFlushFromClear(statePtr, count);
} else {
for (; count>0 ; count--) {
- output_plain(rl_pixel);
+ outputPlain(statePtr, statePtr->runlengthPixel);
}
}
}
-
+
static void
-rl_flush_withtable(count)
- int count;
+runlengthFlushWithTable(
+ miGIFState_t *statePtr,
+ int count)
{
int repmax;
int repleft;
int leftover;
- DEBUGMSG(("rl_flush_withtable %d\n", count));
- repmax = count / rl_table_max;
- leftover = count % rl_table_max;
+ DEBUGMSG(("runlengthFlushWithTable %d\n", count));
+ repmax = count / statePtr->runlengthTableMax;
+ leftover = count % statePtr->runlengthTableMax;
repleft = (leftover ? 1 : 0);
- if (out_count+repmax+repleft > max_ocodes) {
- repmax = max_ocodes - out_count;
- leftover = count - (repmax * rl_table_max);
- repleft = 1 + compute_triangle_count(leftover, max_ocodes);
+ if (statePtr->outputCount+repmax+repleft > statePtr->maxOcodes) {
+ repmax = statePtr->maxOcodes - statePtr->outputCount;
+ leftover = count - (repmax * statePtr->runlengthTableMax);
+ repleft = computeTriangleCount((unsigned) leftover,
+ (unsigned) statePtr->maxOcodes);
}
- DEBUGMSG(("rl_flush_withtable repmax=%d leftover=%d repleft=%d\n",
+ DEBUGMSG(("runlengthFlushWithTable repmax=%d leftover=%d repleft=%d\n",
repmax, leftover, repleft));
- if (1+(int)compute_triangle_count(count, max_ocodes) < repmax+repleft) {
- output(code_clear);
- did_clear();
- rl_flush_fromclear(count);
+ if (computeTriangleCount((unsigned) count, (unsigned) statePtr->maxOcodes)
+ < repmax+repleft) {
+ output(statePtr, statePtr->codeClear);
+ didClear(statePtr);
+ runlengthFlushFromClear(statePtr, count);
return;
}
- max_out_clear();
+ maxOutputClear(statePtr);
for (; repmax>0 ; repmax--) {
- output_plain(rl_basecode + rl_table_max - 2);
+ outputPlain(statePtr,
+ statePtr->runlengthBaseCode + statePtr->runlengthTableMax - 2);
}
if (leftover) {
- if (just_cleared) {
- rl_flush_fromclear(leftover);
+ if (statePtr->justCleared) {
+ runlengthFlushFromClear(statePtr, leftover);
} else if (leftover == 1) {
- output_plain(rl_pixel);
+ outputPlain(statePtr, statePtr->runlengthPixel);
} else {
- output_plain(rl_basecode + leftover - 2);
+ outputPlain(statePtr, statePtr->runlengthBaseCode + leftover - 2);
}
}
- reset_out_clear();
+ resetOutputClear(statePtr);
}
-
+
static void
-rl_flush()
+runlengthFlush(
+ miGIFState_t *statePtr)
{
- DEBUGMSG(("rl_flush [ %d %d\n", rl_count, rl_pixel));
- if (rl_count == 1) {
- output_plain(rl_pixel);
- rl_count = 0;
- DEBUGMSG(("rl_flush ]\n"));
+ DEBUGMSG(("runlengthFlush [ %d %d\n", statePtr->runlengthCount,
+ statePtr->runlengthPixel));
+ if (statePtr->runlengthCount == 1) {
+ outputPlain(statePtr, statePtr->runlengthPixel);
+ statePtr->runlengthCount = 0;
+ DEBUGMSG(("runlengthFlush ]\n"));
return;
}
- if (just_cleared) {
- rl_flush_fromclear(rl_count);
- } else if ((rl_table_max < 2) || (rl_table_pixel != rl_pixel)) {
- rl_flush_clearorrep(rl_count);
+ if (statePtr->justCleared) {
+ runlengthFlushFromClear(statePtr, statePtr->runlengthCount);
+ } else if ((statePtr->runlengthTableMax < 2)
+ || (statePtr->runlengthTablePixel != statePtr->runlengthPixel)) {
+ runlengthFlushClearOrRep(statePtr, statePtr->runlengthCount);
} else {
- rl_flush_withtable(rl_count);
+ runlengthFlushWithTable(statePtr, statePtr->runlengthCount);
}
- DEBUGMSG(("rl_flush ]\n"));
- rl_count = 0;
+ DEBUGMSG(("runlengthFlush ]\n"));
+ statePtr->runlengthCount = 0;
}
-
-
+
static void
-compress(init_bits, handle, readValue)
- int init_bits;
- Tcl_Channel handle;
- ifunptr readValue;
+compress(
+ int initBits,
+ Tcl_Channel handle,
+ ifunptr readValue,
+ ClientData clientData)
{
int c;
+ miGIFState_t state, *statePtr = &state;
+
+ memset(statePtr, 0, sizeof(state));
+
+ statePtr->ofile = handle;
+ statePtr->obuf = 0;
+ statePtr->obits = 0;
+ statePtr->oblen = 0;
+ statePtr->codeClear = 1 << (initBits - 1);
+ statePtr->codeEOF = statePtr->codeClear + 1;
+ statePtr->runlengthBaseCode = statePtr->codeEOF + 1;
+ statePtr->outputBumpInit = (1 << (initBits - 1)) - 1;
- ofile = handle;
- obuf = 0;
- obits = 0;
- oblen = 0;
- code_clear = 1 << (init_bits - 1);
- code_eof = code_clear + 1;
- rl_basecode = code_eof + 1;
- out_bump_init = (1 << (init_bits - 1)) - 1;
/*
- * For images with a lot of runs, making out_clear_init larger
- * will give better compression.
+ * For images with a lot of runs, making outputClearInit larger will give
+ * better compression.
*/
- out_clear_init = (init_bits <= 3) ? 9 : (out_bump_init-1);
+
+ statePtr->outputClearInit =
+ (initBits <= 3) ? 9 : (statePtr->outputBumpInit-1);
#ifdef MIGIF_DEBUGGING_ENVARS
{
- CONST char *ocienv;
- ocienv = getenv("MIGIF_OUT_CLEAR_INIT");
+ const char *ocienv = getenv("MIGIF_OUT_CLEAR_INIT");
+
if (ocienv) {
- out_clear_init = atoi(ocienv);
- DEBUGMSG(("[overriding out_clear_init to %d]\n", out_clear_init));
+ statePtr->outputClearInit = atoi(ocienv);
+ DEBUGMSG(("[overriding outputClearInit to %d]\n",
+ statePtr->outputClearInit));
}
}
#endif
- out_bits_init = init_bits;
- max_ocodes = (1 << GIFBITS) - ((1 << (out_bits_init - 1)) + 3);
- did_clear();
- output(code_clear);
- rl_count = 0;
+ statePtr->outputBitsInit = initBits;
+ statePtr->maxOcodes =
+ (1 << GIFBITS) - ((1 << (statePtr->outputBitsInit - 1)) + 3);
+ didClear(statePtr);
+ output(statePtr, statePtr->codeClear);
+ statePtr->runlengthCount = 0;
while (1) {
- c = readValue();
- if ((rl_count > 0) && (c != rl_pixel)) {
- rl_flush();
+ c = readValue(clientData);
+ if (statePtr->runlengthCount>0 && statePtr->runlengthPixel!=c) {
+ runlengthFlush(statePtr);
}
if (c == EOF) {
break;
}
- if (rl_pixel == c) {
- rl_count++;
+ if (statePtr->runlengthPixel == c) {
+ statePtr->runlengthCount++;
} else {
- rl_pixel = c;
- rl_count = 1;
+ statePtr->runlengthPixel = c;
+ statePtr->runlengthCount = 1;
}
}
- output(code_eof);
- output_flush();
+ output(statePtr, statePtr->codeEOF);
+ outputFlush(statePtr);
}
/*
*-----------------------------------------------------------------------
*
- * End of miGIF section - See copyright notice at start of section.
+ * End of miGIF section - See copyright notice at start of section.
*
*-----------------------------------------------------------------------
*/
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkImgPPM.c b/generic/tkImgPPM.c
index ffa369d..8a46fde 100644
--- a/generic/tkImgPPM.c
+++ b/generic/tkImgPPM.c
@@ -6,20 +6,19 @@
* Copyright (c) 1994 The Australian National University.
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* Author: Paul Mackerras (paulus@cs.anu.edu.au),
- * Department of Computer Science,
- * Australian National University.
+ * Department of Computer Science,
+ * Australian National University.
*/
#include "tkInt.h"
-#include "tkPort.h"
/*
- * The maximum amount of memory to allocate for data read from the
- * file. If we need more than this, we do it in pieces.
+ * The maximum amount of memory to allocate for data read from the file. If we
+ * need more than this, we do it in pieces.
*/
#define MAX_MEMORY 10000 /* don't allocate > 10KB */
@@ -35,28 +34,23 @@
* The format record for the PPM file format:
*/
-static int FileMatchPPM _ANSI_ARGS_((Tcl_Channel chan,
+static int FileMatchPPM(Tcl_Channel chan, CONST char *fileName,
+ Tcl_Obj *format, int *widthPtr, int *heightPtr,
+ Tcl_Interp *interp);
+static int FileReadPPM(Tcl_Interp *interp, Tcl_Channel chan,
CONST char *fileName, Tcl_Obj *format,
- int *widthPtr, int *heightPtr,
- Tcl_Interp *interp));
-static int FileReadPPM _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Channel chan, CONST char *fileName,
+ Tk_PhotoHandle imageHandle, int destX, int destY,
+ int width, int height, int srcX, int srcY);
+static int FileWritePPM(Tcl_Interp *interp, CONST char *fileName,
+ Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr);
+static int StringWritePPM(Tcl_Interp *interp, Tcl_Obj *format,
+ Tk_PhotoImageBlock *blockPtr);
+static int StringMatchPPM(Tcl_Obj *dataObj, Tcl_Obj *format,
+ int *widthPtr, int *heightPtr, Tcl_Interp *interp);
+static int StringReadPPM(Tcl_Interp *interp, Tcl_Obj *dataObj,
Tcl_Obj *format, Tk_PhotoHandle imageHandle,
int destX, int destY, int width, int height,
- int srcX, int srcY));
-static int FileWritePPM _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *fileName, Tcl_Obj *format,
- Tk_PhotoImageBlock *blockPtr));
-static int StringWritePPM _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr));
-static int StringMatchPPM _ANSI_ARGS_((Tcl_Obj *dataObj,
- Tcl_Obj *format, int *widthPtr, int *heightPtr,
- Tcl_Interp *interp));
-static int StringReadPPM _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Obj *dataObj, Tcl_Obj *format,
- Tk_PhotoHandle imageHandle, int destX, int destY,
- int width, int height, int srcX, int srcY));
-
+ int srcX, int srcY);
Tk_PhotoImageFormat tkImgFmtPPM = {
"ppm", /* name */
@@ -69,28 +63,26 @@ Tk_PhotoImageFormat tkImgFmtPPM = {
};
/*
- * Prototypes for local procedures defined in this file:
+ * Prototypes for local functions defined in this file:
*/
-static int ReadPPMFileHeader _ANSI_ARGS_((Tcl_Channel chan,
- int *widthPtr, int *heightPtr,
- int *maxIntensityPtr));
-static int ReadPPMStringHeader _ANSI_ARGS_((Tcl_Obj *dataObj,
- int *widthPtr, int *heightPtr,
- int *maxIntensityPtr,
- unsigned char **dataBufferPtr, int *dataSizePtr));
+static int ReadPPMFileHeader(Tcl_Channel chan, int *widthPtr,
+ int *heightPtr, int *maxIntensityPtr);
+static int ReadPPMStringHeader(Tcl_Obj *dataObj, int *widthPtr,
+ int *heightPtr, int *maxIntensityPtr,
+ unsigned char **dataBufferPtr, int *dataSizePtr);
/*
*----------------------------------------------------------------------
*
* FileMatchPPM --
*
- * This procedure is invoked by the photo image type to see if
- * a file contains image data in PPM format.
+ * This function is invoked by the photo image type to see if a file
+ * contains image data in PPM format.
*
* Results:
- * The return value is >0 if the first characters in file "f" look
- * like PPM data, and 0 otherwise.
+ * The return value is >0 if the first characters in file "f" look like
+ * PPM data, and 0 otherwise.
*
* Side effects:
* The access position in f may change.
@@ -99,14 +91,15 @@ static int ReadPPMStringHeader _ANSI_ARGS_((Tcl_Obj *dataObj,
*/
static int
-FileMatchPPM(chan, fileName, format, widthPtr, heightPtr, interp)
- Tcl_Channel chan; /* The image file, open for reading. */
- CONST char *fileName; /* The name of the image file. */
- Tcl_Obj *format; /* User-specified format string, or NULL. */
- int *widthPtr, *heightPtr; /* The dimensions of the image are
- * returned here if the file is a valid
- * raw PPM file. */
- Tcl_Interp *interp;
+FileMatchPPM(
+ Tcl_Channel chan, /* The image file, open for reading. */
+ CONST char *fileName, /* The name of the image file. */
+ Tcl_Obj *format, /* User-specified format string, or NULL. */
+ int *widthPtr, int *heightPtr,
+ /* The dimensions of the image are returned
+ * here if the file is a valid raw PPM
+ * file. */
+ Tcl_Interp *interp) /* unused */
{
int dummy;
@@ -118,35 +111,33 @@ FileMatchPPM(chan, fileName, format, widthPtr, heightPtr, interp)
*
* FileReadPPM --
*
- * This procedure is called by the photo image type to read
- * PPM format data from a file and write it into a given
- * photo image.
+ * This function is called by the photo image type to read PPM format
+ * data from a file and write it into a given photo image.
*
* Results:
- * A standard TCL completion code. If TCL_ERROR is returned
- * then an error message is left in the interp's result.
+ * A standard TCL completion code. If TCL_ERROR is returned 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
- * added to the image given by imageHandle.
+ * The access position in file f is changed, and new data is added to the
+ * image given by imageHandle.
*
*----------------------------------------------------------------------
*/
static int
-FileReadPPM(interp, chan, fileName, format, imageHandle, destX, destY,
- width, height, srcX, srcY)
- Tcl_Interp *interp; /* Interpreter to use for reporting errors. */
- Tcl_Channel chan; /* The image file, open for reading. */
- CONST char *fileName; /* The name of the image file. */
- Tcl_Obj *format; /* User-specified format string, or NULL. */
- Tk_PhotoHandle imageHandle; /* The photo image to write into. */
- int destX, destY; /* Coordinates of top-left pixel in
- * photo image to be written to. */
- int width, height; /* Dimensions of block of photo image to
- * be written to. */
- int srcX, srcY; /* Coordinates of top-left pixel to be used
- * in image being read. */
+FileReadPPM(
+ Tcl_Interp *interp, /* Interpreter to use for reporting errors. */
+ Tcl_Channel chan, /* The image file, open for reading. */
+ CONST char *fileName, /* The name of the image file. */
+ Tcl_Obj *format, /* User-specified format string, or NULL. */
+ Tk_PhotoHandle imageHandle, /* The photo image to write into. */
+ int destX, int destY, /* Coordinates of top-left pixel in photo
+ * image to be written to. */
+ int width, int height, /* Dimensions of block of photo image to be
+ * written to. */
+ int srcX, int srcY) /* Coordinates of top-left pixel to be used in
+ * image being read. */
{
int fileWidth, fileHeight, maxIntensity;
int nLines, nBytes, h, type, count;
@@ -185,14 +176,13 @@ FileReadPPM(interp, chan, fileName, format, imageHandle, destX, destY,
}
if (type == PGM) {
- block.pixelSize = 1;
- block.offset[0] = 0;
+ block.pixelSize = 1;
+ block.offset[0] = 0;
block.offset[1] = 0;
block.offset[2] = 0;
- }
- else {
- block.pixelSize = 3;
- block.offset[0] = 0;
+ } else {
+ block.pixelSize = 3;
+ block.offset[0] = 0;
block.offset[1] = 1;
block.offset[2] = 2;
}
@@ -200,7 +190,10 @@ FileReadPPM(interp, chan, fileName, format, imageHandle, destX, destY,
block.width = width;
block.pitch = block.pixelSize * fileWidth;
- Tk_PhotoExpand(imageHandle, destX + width, destY + height);
+ if (Tk_PhotoExpand(interp, imageHandle,
+ destX + width, destY + height) != TCL_OK) {
+ return TCL_ERROR;
+ }
if (srcY > 0) {
Tcl_Seek(chan, (Tcl_WideInt)(srcY * block.pitch), SEEK_CUR);
@@ -239,8 +232,11 @@ FileReadPPM(interp, chan, fileName, format, imageHandle, destX, destY,
}
}
block.height = nLines;
- Tk_PhotoPutBlock(imageHandle, &block, destX, destY, width, nLines,
- TK_PHOTO_COMPOSITE_SET);
+ if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
+ width, nLines, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
+ ckfree((char *) pixelPtr);
+ return TCL_ERROR;
+ }
destY += nLines;
}
@@ -253,12 +249,12 @@ FileReadPPM(interp, chan, fileName, format, imageHandle, destX, destY,
*
* FileWritePPM --
*
- * This procedure is invoked to write image data to a file in PPM
- * format.
+ * This function is invoked to write image data to a file in PPM format
+ * (although we can read PGM files, we never write them).
*
* Results:
- * A standard TCL completion code. If TCL_ERROR is returned
- * then an error message is left in the interp's result.
+ * A standard TCL completion code. If TCL_ERROR is returned then an error
+ * message is left in the interp's result.
*
* Side effects:
* Data is written to the file given by "fileName".
@@ -267,15 +263,14 @@ FileReadPPM(interp, chan, fileName, format, imageHandle, destX, destY,
*/
static int
-FileWritePPM(interp, fileName, format, blockPtr)
- Tcl_Interp *interp;
- CONST char *fileName;
- Tcl_Obj *format;
- Tk_PhotoImageBlock *blockPtr;
+FileWritePPM(
+ Tcl_Interp *interp,
+ CONST char *fileName,
+ Tcl_Obj *format,
+ Tk_PhotoImageBlock *blockPtr)
{
Tcl_Channel chan;
- int w, h;
- int greenOffset, blueOffset, nBytes;
+ int w, h, greenOffset, blueOffset, nBytes;
unsigned char *pixelPtr, *pixLinePtr;
char header[16 + TCL_INTEGER_SPACE * 2];
@@ -312,9 +307,9 @@ FileWritePPM(interp, fileName, format, blockPtr)
for (h = blockPtr->height; h > 0; h--) {
pixelPtr = pixLinePtr;
for (w = blockPtr->width; w > 0; w--) {
- if ((Tcl_Write(chan, (char *) &pixelPtr[0], 1) == -1)
- || (Tcl_Write(chan, (char *) &pixelPtr[greenOffset], 1) == -1)
- || (Tcl_Write(chan, (char *) &pixelPtr[blueOffset], 1) == -1)) {
+ if ( Tcl_Write(chan,(char *)&pixelPtr[0], 1) == -1 ||
+ Tcl_Write(chan,(char *)&pixelPtr[greenOffset],1)==-1 ||
+ Tcl_Write(chan,(char *)&pixelPtr[blueOffset],1) ==-1) {
goto writeerror;
}
pixelPtr += blockPtr->pixelSize;
@@ -328,7 +323,7 @@ FileWritePPM(interp, fileName, format, blockPtr)
}
chan = NULL;
- writeerror:
+ writeerror:
Tcl_AppendResult(interp, "error writing \"", fileName, "\": ",
Tcl_PosixError(interp), NULL);
if (chan != NULL) {
@@ -342,12 +337,12 @@ FileWritePPM(interp, fileName, format, blockPtr)
*
* StringWritePPM --
*
- * This procedure is invoked to write image data to a string in PPM
+ * This function is invoked to write image data to a string in PPM
* format.
*
* Results:
- * A standard TCL completion code. If TCL_ERROR is returned
- * then an error message is left in the interp's result.
+ * A standard TCL completion code. If TCL_ERROR is returned then an error
+ * message is left in the interp's result.
*
* Side effects:
* None.
@@ -356,10 +351,10 @@ FileWritePPM(interp, fileName, format, blockPtr)
*/
static int
-StringWritePPM(interp, format, blockPtr)
- Tcl_Interp *interp;
- Tcl_Obj *format;
- Tk_PhotoImageBlock *blockPtr;
+StringWritePPM(
+ Tcl_Interp *interp,
+ Tcl_Obj *format,
+ Tk_PhotoImageBlock *blockPtr)
{
int w, h, size, greenOffset, blueOffset;
unsigned char *pixLinePtr, *byteArray;
@@ -367,10 +362,12 @@ StringWritePPM(interp, format, blockPtr)
Tcl_Obj *byteArrayObj;
sprintf(header, "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);
+
/*
* Construct a byte array of the right size with the header and
* get a pointer to the data part of it.
*/
+
size = strlen(header);
byteArrayObj = Tcl_NewByteArrayObj((unsigned char *)header, size);
byteArray = Tcl_SetByteArrayLength(byteArrayObj,
@@ -384,6 +381,7 @@ StringWritePPM(interp, format, blockPtr)
/*
* Check if we can do the data move in single action.
*/
+
if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3)
&& (blockPtr->pitch == (blockPtr->width * 3))) {
memcpy(byteArray, pixLinePtr,
@@ -405,6 +403,7 @@ StringWritePPM(interp, format, blockPtr)
/*
* Return the object in the interpreter result.
*/
+
Tcl_SetObjResult(interp, byteArrayObj);
return TCL_OK;
}
@@ -414,12 +413,12 @@ StringWritePPM(interp, format, blockPtr)
*
* StringMatchPPM --
*
- * This procedure is invoked by the photo image type to see if
- * a string contains image data in PPM format.
+ * This function is invoked by the photo image type to see if a string
+ * contains image data in PPM format.
*
* Results:
- * The return value is >0 if the first characters in file "f" look
- * like PPM data, and 0 otherwise.
+ * The return value is >0 if the first characters in file "f" look like
+ * PPM data, and 0 otherwise.
*
* Side effects:
* The access position in f may change.
@@ -428,13 +427,14 @@ StringWritePPM(interp, format, blockPtr)
*/
static int
-StringMatchPPM(dataObj, format, widthPtr, heightPtr, interp)
- Tcl_Obj *dataObj; /* The image data. */
- Tcl_Obj *format; /* User-specified format string, or NULL. */
- int *widthPtr, *heightPtr; /* The dimensions of the image are
- * returned here if the file is a valid
- * raw PPM file. */
- Tcl_Interp *interp; /* unused */
+StringMatchPPM(
+ Tcl_Obj *dataObj, /* The image data. */
+ Tcl_Obj *format, /* User-specified format string, or NULL. */
+ int *widthPtr, int *heightPtr,
+ /* The dimensions of the image are returned
+ * here if the file is a valid raw PPM
+ * file. */
+ Tcl_Interp *interp) /* unused */
{
int dummy;
@@ -447,13 +447,12 @@ StringMatchPPM(dataObj, format, widthPtr, heightPtr, interp)
*
* StringReadPPM --
*
- * This procedure is called by the photo image type to read
- * PPM format data from a string and write it into a given
- * photo image.
+ * This function is called by the photo image type to read PPM format
+ * data from a string and write it into a given photo image.
*
* Results:
- * A standard TCL completion code. If TCL_ERROR is returned
- * then an error message is left in the interp's result.
+ * A standard TCL completion code. If TCL_ERROR is returned then an error
+ * message is left in the interp's result.
*
* Side effects:
* New data is added to the image given by imageHandle.
@@ -462,18 +461,17 @@ StringMatchPPM(dataObj, format, widthPtr, heightPtr, interp)
*/
static int
-StringReadPPM(interp, dataObj, format, imageHandle, destX, destY,
- width, height, srcX, srcY)
- Tcl_Interp *interp; /* Interpreter to use for reporting errors. */
- Tcl_Obj *dataObj; /* The image data. */
- Tcl_Obj *format; /* User-specified format string, or NULL. */
- Tk_PhotoHandle imageHandle; /* The photo image to write into. */
- int destX, destY; /* Coordinates of top-left pixel in
- * photo image to be written to. */
- int width, height; /* Dimensions of block of photo image to
- * be written to. */
- int srcX, srcY; /* Coordinates of top-left pixel to be used
- * in image being read. */
+StringReadPPM(
+ Tcl_Interp *interp, /* Interpreter to use for reporting errors. */
+ Tcl_Obj *dataObj, /* The image data. */
+ Tcl_Obj *format, /* User-specified format string, or NULL. */
+ Tk_PhotoHandle imageHandle, /* The photo image to write into. */
+ int destX, int destY, /* Coordinates of top-left pixel in photo
+ * image to be written to. */
+ int width, int height, /* Dimensions of block of photo image to be
+ * written to. */
+ int srcX, int srcY) /* Coordinates of top-left pixel to be used in
+ * image being read. */
{
int fileWidth, fileHeight, maxIntensity;
int nLines, nBytes, h, type, count, dataSize;
@@ -514,13 +512,13 @@ StringReadPPM(interp, dataObj, format, imageHandle, destX, destY,
}
if (type == PGM) {
- block.pixelSize = 1;
- block.offset[0] = 0;
+ block.pixelSize = 1;
+ block.offset[0] = 0;
block.offset[1] = 0;
block.offset[2] = 0;
} else {
- block.pixelSize = 3;
- block.offset[0] = 0;
+ block.pixelSize = 3;
+ block.offset[0] = 0;
block.offset[1] = 1;
block.offset[2] = 2;
}
@@ -535,21 +533,23 @@ StringReadPPM(interp, dataObj, format, imageHandle, destX, destY,
if (maxIntensity == 255) {
/*
- * We have all the data in memory, so write everything in one
- * go.
+ * We have all the data in memory, so write everything in one go.
*/
+
if (block.pitch*height > dataSize) {
Tcl_AppendResult(interp, "truncated PPM data", NULL);
return TCL_ERROR;
}
block.pixelPtr = dataBuffer + srcX * block.pixelSize;
block.height = height;
- Tk_PhotoPutBlock(imageHandle, &block, destX, destY, width, height,
- TK_PHOTO_COMPOSITE_SET);
- return TCL_OK;
+ return Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
+ width, height, TK_PHOTO_COMPOSITE_SET);
}
- Tk_PhotoExpand(imageHandle, destX + width, destY + height);
+ if (Tk_PhotoExpand(interp, imageHandle,
+ destX + width, destY + height) != TCL_OK) {
+ return TCL_ERROR;
+ }
nLines = (MAX_MEMORY + block.pitch - 1) / block.pitch;
if (nLines > height) {
@@ -579,8 +579,11 @@ StringReadPPM(interp, dataObj, format, imageHandle, destX, destY,
}
dataSize -= nBytes;
block.height = nLines;
- Tk_PhotoPutBlock(imageHandle, &block, destX, destY, width, nLines,
- TK_PHOTO_COMPOSITE_SET);
+ if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
+ width, nLines, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
+ ckfree((char *) pixelPtr);
+ return TCL_ERROR;
+ }
destY += nLines;
}
@@ -593,16 +596,15 @@ StringReadPPM(interp, dataObj, format, imageHandle, destX, destY,
*
* ReadPPMFileHeader --
*
- * This procedure reads the PPM header from the beginning of a
- * PPM file and returns information from the header.
+ * This function reads the PPM header from the beginning of a PPM file
+ * and returns information from the header.
*
* Results:
- * The return value is PGM if file "f" appears to start with
- * a valid PGM header, PPM if "f" appears to start with a valid
- * PPM header, and 0 otherwise. If the header is valid,
- * then *widthPtr and *heightPtr are modified to hold the
- * dimensions of the image and *maxIntensityPtr is modified to
- * hold the value of a "fully on" intensity value.
+ * The return value is PGM if file "f" appears to start with a valid PGM
+ * header, PPM if "f" appears to start with a valid PPM header, and 0
+ * otherwise. If the header is valid, then *widthPtr and *heightPtr are
+ * modified to hold the dimensions of the image and *maxIntensityPtr is
+ * modified to hold the value of a "fully on" intensity value.
*
* Side effects:
* The access position in f advances.
@@ -611,22 +613,21 @@ StringReadPPM(interp, dataObj, format, imageHandle, destX, destY,
*/
static int
-ReadPPMFileHeader(chan, widthPtr, heightPtr, maxIntensityPtr)
- Tcl_Channel chan; /* Image file to read the header from */
- int *widthPtr, *heightPtr; /* The dimensions of the image are
- * returned here. */
- int *maxIntensityPtr; /* The maximum intensity value for
- * the image is stored here. */
+ReadPPMFileHeader(
+ Tcl_Channel chan, /* Image file to read the header from. */
+ int *widthPtr, int *heightPtr,
+ /* The dimensions of the image are returned
+ * here. */
+ int *maxIntensityPtr) /* The maximum intensity value for the image
+ * is stored here. */
{
#define BUFFER_SIZE 1000
- char buffer[BUFFER_SIZE];
- int i, numFields;
- int type = 0;
- char c;
+ char buffer[BUFFER_SIZE], c;
+ int i, numFields, type = 0;
/*
- * Read 4 space-separated fields from the file, ignoring
- * comments (any line that starts with "#").
+ * Read 4 space-separated fields from the file, ignoring comments (any
+ * line that starts with "#").
*/
if (Tcl_Read(chan, &c, 1) != 1) {
@@ -672,7 +673,8 @@ ReadPPMFileHeader(chan, widthPtr, heightPtr, maxIntensityPtr)
i++;
}
}
- done:
+
+ done:
buffer[i] = 0;
/*
@@ -698,16 +700,16 @@ ReadPPMFileHeader(chan, widthPtr, heightPtr, maxIntensityPtr)
*
* ReadPPMStringHeader --
*
- * This procedure reads the PPM header from the beginning of a
- * PPM-format string and returns information from the header.
+ * This function reads the PPM header from the beginning of a PPM-format
+ * string and returns information from the header.
*
* Results:
- * The return value is PGM if the string appears to start with
- * a valid PGM header, PPM if the string appears to start with
- * a valid PPM header, and 0 otherwise. If the header is valid,
- * then *widthPtr and *heightPtr are modified to hold the
- * dimensions of the image and *maxIntensityPtr is modified to
- * hold the value of a "fully on" intensity value.
+ * The return value is PGM if the string appears to start with a valid
+ * PGM header, PPM if the string appears to start with a valid PPM
+ * header, and 0 otherwise. If the header is valid, then *widthPtr and
+ * *heightPtr are modified to hold the dimensions of the image and
+ * *maxIntensityPtr is modified to hold the value of a "fully on"
+ * intensity value.
*
* Side effects:
* None
@@ -716,28 +718,26 @@ ReadPPMFileHeader(chan, widthPtr, heightPtr, maxIntensityPtr)
*/
static int
-ReadPPMStringHeader(dataPtr, widthPtr, heightPtr, maxIntensityPtr,
- dataBufferPtr, dataSizePtr)
- Tcl_Obj *dataPtr; /* Object to read the header from. */
- int *widthPtr, *heightPtr; /* The dimensions of the image are
- * returned here. */
- int *maxIntensityPtr; /* The maximum intensity value for
- * the image is stored here. */
- unsigned char **dataBufferPtr;
- int *dataSizePtr;
+ReadPPMStringHeader(
+ Tcl_Obj *dataPtr, /* Object to read the header from. */
+ int *widthPtr, int *heightPtr,
+ /* The dimensions of the image are returned
+ * here. */
+ int *maxIntensityPtr, /* The maximum intensity value for the image
+ * is stored here. */
+ unsigned char **dataBufferPtr,
+ int *dataSizePtr)
{
#define BUFFER_SIZE 1000
- char buffer[BUFFER_SIZE];
- int i, numFields, dataSize;
- int type = 0;
- char c;
+ char buffer[BUFFER_SIZE], c;
+ int i, numFields, dataSize, type = 0;
unsigned char *dataBuffer;
dataBuffer = Tcl_GetByteArrayFromObj(dataPtr, &dataSize);
/*
- * Read 4 space-separated fields from the string, ignoring
- * comments (any line that starts with "#").
+ * Read 4 space-separated fields from the string, ignoring comments (any
+ * line that starts with "#").
*/
if (dataSize-- < 1) {
@@ -787,7 +787,8 @@ ReadPPMStringHeader(dataPtr, widthPtr, heightPtr, maxIntensityPtr,
i++;
}
}
- done:
+
+ done:
buffer[i] = 0;
/*
@@ -811,3 +812,11 @@ ReadPPMStringHeader(dataPtr, widthPtr, heightPtr, maxIntensityPtr,
}
return type;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c
index 7c87c42..85c7de5 100644
--- a/generic/tkImgPhoto.c
+++ b/generic/tkImgPhoto.c
@@ -1,17 +1,17 @@
/*
* tkImgPhoto.c --
*
- * Implements images of type "photo" for Tk. Photo images are
- * stored in full color (32 bits per pixel including alpha channel)
- * and displayed using dithering if necessary.
+ * Implements images of type "photo" for Tk. Photo images are stored in
+ * full color (32 bits per pixel including alpha channel) and displayed
+ * using dithering if necessary.
*
* Copyright (c) 1994 The Australian National University.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
- * Copyright (c) 2002 Donal K. Fellows
+ * Copyright (c) 2002-2003 Donal K. Fellows
* Copyright (c) 2003 ActiveState Corporation.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* Author: Paul Mackerras (paulus@cs.anu.edu.au),
* Department of Computer Science,
@@ -19,8 +19,6 @@
*/
#include "tkInt.h"
-#include "tkPort.h"
-#include "tclMath.h"
#include <ctype.h>
#ifdef __WIN32__
@@ -33,12 +31,12 @@
* Declaration for internal Xlib function used here:
*/
-extern int _XInitImageFuncPtrs _ANSI_ARGS_((XImage *image));
+extern int _XInitImageFuncPtrs(XImage *image);
/*
- * A signed 8-bit integral type. If chars are unsigned and the compiler
- * isn't an ANSI one, then we have to use short instead (which wastes
- * space) to get signed behavior.
+ * A signed 8-bit integral type. If chars are unsigned and the compiler isn't
+ * an ANSI one, then we have to use short instead (which wastes space) to get
+ * signed behavior.
*/
#if defined(__STDC__) || defined(_AIX)
@@ -52,16 +50,15 @@ extern int _XInitImageFuncPtrs _ANSI_ARGS_((XImage *image));
#endif
/*
- * An unsigned 32-bit integral type, used for pixel values.
- * We use int rather than long here to accommodate those systems
- * where longs are 64 bits.
+ * An unsigned 32-bit integral type, used for pixel values. We use int rather
+ * than long here to accommodate those systems where longs are 64 bits.
*/
typedef unsigned int pixel;
/*
- * The maximum number of pixels to transmit to the server in a
- * single XPutImage call.
+ * The maximum number of pixels to transmit to the server in a single
+ * XPutImage call.
*/
#define MAX_PIXELS 65536
@@ -69,20 +66,19 @@ typedef unsigned int pixel;
/*
* The set of colors required to display a photo image in a window depends on:
* - the visual used by the window
- * - the palette, which specifies how many levels of each primary
- * color to use, and
+ * - the palette, which specifies how many levels of each primary color to
+ * use, and
* - the gamma value for the image.
*
- * Pixel values allocated for specific colors are valid only for the
- * colormap in which they were allocated. Sets of pixel values
- * allocated for displaying photos are re-used in other windows if
- * possible, that is, if the display, colormap, palette and gamma
- * values match. A hash table is used to locate these sets of pixel
- * values, using the following data structure as key:
+ * Pixel values allocated for specific colors are valid only for the colormap
+ * in which they were allocated. Sets of pixel values allocated for displaying
+ * photos are re-used in other windows if possible, that is, if the display,
+ * colormap, palette and gamma values match. A hash table is used to locate
+ * these sets of pixel values, using the following data structure as key:
*/
typedef struct {
- Display *display; /* Qualifies the colormap resource ID */
+ Display *display; /* Qualifies the colormap resource ID. */
Colormap colormap; /* Colormap that the windows are using. */
double gamma; /* Gamma exponent value for images. */
Tk_Uid palette; /* Specifies how many shades of each primary
@@ -90,33 +86,33 @@ typedef struct {
} ColorTableId;
/*
- * For a particular (display, colormap, palette, gamma) combination,
- * a data structure of the following type is used to store the allocated
- * pixel values and other information:
+ * For a particular (display, colormap, palette, gamma) combination, a data
+ * structure of the following type is used to store the allocated pixel values
+ * and other information:
*/
typedef struct ColorTable {
- ColorTableId id; /* Information used in selecting this
- * color table. */
+ ColorTableId id; /* Information used in selecting this color
+ * table. */
int flags; /* See below. */
int refCount; /* Number of instances using this map. */
- int liveRefCount; /* Number of instances which are actually
- * in use, using this map. */
+ int liveRefCount; /* Number of instances which are actually in
+ * use, using this map. */
int numColors; /* Number of colors allocated for this map. */
XVisualInfo visualInfo; /* Information about the visual for windows
* using this color table. */
- pixel redValues[256]; /* Maps 8-bit values of red intensity
- * to a pixel value or index in pixelMap. */
- pixel greenValues[256]; /* Ditto for green intensity */
- pixel blueValues[256]; /* Ditto for blue intensity */
+ pixel redValues[256]; /* Maps 8-bit values of red intensity to a
+ * pixel value or index in pixelMap. */
+ pixel greenValues[256]; /* Ditto for green intensity. */
+ pixel blueValues[256]; /* Ditto for blue intensity. */
unsigned long *pixelMap; /* Actual pixel values allocated. */
unsigned char colorQuant[3][256];
/* Maps 8-bit intensities to quantized
- * intensities. The first index is 0 for
- * red, 1 for green, 2 for blue. */
+ * intensities. The first index is 0 for red,
+ * 1 for green, 2 for blue. */
} ColorTable;
/*
@@ -125,12 +121,13 @@ typedef struct ColorTable {
* available.
* COLOR_WINDOW: 1 means a full 3-D color cube has been
* allocated.
- * DISPOSE_PENDING: 1 means a call to DisposeColorTable has
- * been scheduled as an idle handler, but it
- * hasn't been invoked yet.
- * MAP_COLORS: 1 means pixel values should be mapped
- * through pixelMap.
+ * DISPOSE_PENDING: 1 means a call to DisposeColorTable has been
+ * scheduled as an idle handler, but it hasn't
+ * been invoked yet.
+ * MAP_COLORS: 1 means pixel values should be mapped through
+ * pixelMap.
*/
+
#ifdef COLOR_WINDOW
#undef COLOR_WINDOW
#endif
@@ -145,14 +142,13 @@ typedef struct ColorTable {
*/
typedef struct PhotoMaster {
- Tk_ImageMaster tkMaster; /* Tk's token for image master. NULL means
- * the image is being deleted. */
- Tcl_Interp *interp; /* Interpreter associated with the
- * application using this image. */
- Tcl_Command imageCmd; /* Token for image command (used to delete
- * it when the image goes away). NULL means
- * the image command has already been
- * deleted. */
+ Tk_ImageMaster tkMaster; /* Tk's token for image master. NULL means the
+ * image is being deleted. */
+ Tcl_Interp *interp; /* Interpreter associated with the application
+ * using this image. */
+ Tcl_Command imageCmd; /* Token for image command (used to delete it
+ * when the image goes away). NULL means the
+ * image command has already been deleted. */
int flags; /* Sundry flags, defined below. */
int width, height; /* Dimensions of image. */
int userWidth, userHeight; /* User-declared image dimensions. */
@@ -161,26 +157,27 @@ typedef struct PhotoMaster {
double gamma; /* Display gamma value to correct for. */
char *fileString; /* Name of file to read into image. */
Tcl_Obj *dataString; /* Object to use as contents of image. */
- Tcl_Obj *format; /* User-specified format of data in image
- * file or string value. */
+ Tcl_Obj *format; /* User-specified format of data in image file
+ * or string value. */
unsigned char *pix32; /* Local storage for 32-bit image. */
- int ditherX, ditherY; /* Location of first incorrectly
- * dithered pixel in image. */
- TkRegion validRegion; /* Tk region indicating which parts of
- * the image have valid image data. */
+ int ditherX, ditherY; /* Location of first incorrectly dithered
+ * pixel in image. */
+ TkRegion validRegion; /* Tk region indicating which parts of the
+ * image have valid image data. */
struct PhotoInstance *instancePtr;
- /* First in the list of instances
- * associated with this master. */
+ /* First in the list of instances associated
+ * with this master. */
} PhotoMaster;
/*
* Bit definitions for the flags field of a PhotoMaster.
* COLOR_IMAGE: 1 means that the image has different color
* components.
- * IMAGE_CHANGED: 1 means that the instances of this image
- * need to be redithered.
- * COMPLEX_ALPHA: 1 means that the instances of this image
- * have alpha values that aren't 0 or 255.
+ * IMAGE_CHANGED: 1 means that the instances of this image need
+ * to be redithered.
+ * COMPLEX_ALPHA: 1 means that the instances of this image have
+ * alpha values that aren't 0 or 255, and so need
+ * the copy-merge-replace renderer .
*/
#define COLOR_IMAGE 1
@@ -195,9 +192,8 @@ typedef struct PhotoMaster {
#define SOURCE_IS_SIMPLE_ALPHA_PHOTO 0x10000000
/*
- * The following data structure represents all of the instances of
- * a photo image in windows on a given screen that are using the
- * same colormap.
+ * The following data structure represents all of the instances of a photo
+ * image in windows on a given screen that are using the same colormap.
*/
typedef struct PhotoInstance {
@@ -206,34 +202,34 @@ typedef struct PhotoInstance {
Colormap colormap; /* The image may only be used in windows with
* this particular colormap. */
struct PhotoInstance *nextPtr;
- /* Pointer to the next instance in the list
- * of instances associated with this master. */
+ /* Pointer to the next instance in the list of
+ * instances associated with this master. */
int refCount; /* Number of instances using this structure. */
Tk_Uid palette; /* Palette for these particular instances. */
double gamma; /* Gamma value for these instances. */
- Tk_Uid defaultPalette; /* Default palette to use if a palette
- * is not specified for the master. */
+ Tk_Uid defaultPalette; /* Default palette to use if a palette is not
+ * specified for the master. */
ColorTable *colorTablePtr; /* Pointer to information about colors
- * allocated for image display in windows
- * like this one. */
+ * allocated for image display in windows like
+ * this one. */
Pixmap pixels; /* X pixmap containing dithered image. */
int width, height; /* Dimensions of the pixmap. */
schar *error; /* Error image, used in dithering. */
XImage *imagePtr; /* Image structure for converted pixels. */
XVisualInfo visualInfo; /* Information about the visual that these
* windows are using. */
- GC gc; /* Graphics context for writing images
- * to the pixmap. */
+ GC gc; /* Graphics context for writing images to the
+ * pixmap. */
} PhotoInstance;
/*
- * The following data structure is used to return information
- * from ParseSubcommandOptions:
+ * The following data structure is used to return information from
+ * ParseSubcommandOptions:
*/
struct SubcommandOptions {
- int options; /* Individual bits indicate which
- * options were specified - see below. */
+ int options; /* Individual bits indicate which options were
+ * specified - see below. */
Tcl_Obj *name; /* Name specified without an option. */
int fromX, fromY; /* Values specified for -from option. */
int fromX2, fromY2; /* Second coordinate pair for -from option. */
@@ -243,15 +239,16 @@ struct SubcommandOptions {
int subsampleX, subsampleY; /* Values specified for -subsample option. */
Tcl_Obj *format; /* Value specified for -format option. */
XColor *background; /* Value specified for -background option. */
- int compositingRule; /* Value specified for -compositingrule opt */
+ int compositingRule; /* Value specified for -compositingrule
+ * option. */
};
/*
- * Bit definitions for use with ParseSubcommandOptions:
- * Each bit is set in the allowedOptions parameter on a call to
- * ParseSubcommandOptions if that option is allowed for the current
- * photo image subcommand. On return, the bit is set in the options
- * field of the SubcommandOptions structure if that option was specified.
+ * Bit definitions for use with ParseSubcommandOptions: each bit is set in the
+ * allowedOptions parameter on a call to ParseSubcommandOptions if that option
+ * is allowed for the current photo image subcommand. On return, the bit is
+ * set in the options field of the SubcommandOptions structure if that option
+ * was specified.
*
* OPT_BACKGROUND: Set if -format option allowed/specified.
* OPT_COMPOSITE: Set if -compositingrule option allowed/spec'd.
@@ -275,11 +272,11 @@ struct SubcommandOptions {
#define OPT_ZOOM 0x100
/*
- * List of option names. The order here must match the order of
- * declarations of the OPT_* constants above.
+ * List of option names. The order here must match the order of declarations
+ * of the OPT_* constants above.
*/
-static char *optionNames[] = {
+static const char *const optionNames[] = {
"-background",
"-compositingrule",
"-format",
@@ -289,13 +286,14 @@ static char *optionNames[] = {
"-subsample",
"-to",
"-zoom",
- (char *) NULL
+ NULL
};
/*
- * Message to generate when an attempt to resize an image fails due
- * to memory problems.
+ * Message to generate when an attempt to resize an image fails due to memory
+ * problems.
*/
+
#define TK_PHOTO_ALLOC_FAILURE_MESSAGE \
"not enough free memory for image buffer"
@@ -303,23 +301,21 @@ static char *optionNames[] = {
* Functions used in the type record for photo images.
*/
-static int ImgPhotoCreate _ANSI_ARGS_((Tcl_Interp *interp,
- char *name, int objc, Tcl_Obj *CONST objv[],
+static int ImgPhotoCreate(Tcl_Interp *interp, char *name,
+ int objc, Tcl_Obj *CONST objv[],
Tk_ImageType *typePtr, Tk_ImageMaster master,
- ClientData *clientDataPtr));
-static ClientData ImgPhotoGet _ANSI_ARGS_((Tk_Window tkwin,
- ClientData clientData));
-static void ImgPhotoDisplay _ANSI_ARGS_((ClientData clientData,
+ ClientData *clientDataPtr);
+static ClientData ImgPhotoGet(Tk_Window tkwin, ClientData clientData);
+static void ImgPhotoDisplay(ClientData clientData,
Display *display, Drawable drawable,
int imageX, int imageY, int width, int height,
- int drawableX, int drawableY));
-static void ImgPhotoFree _ANSI_ARGS_((ClientData clientData,
- Display *display));
-static void ImgPhotoDelete _ANSI_ARGS_((ClientData clientData));
-static int ImgPhotoPostscript _ANSI_ARGS_((ClientData clientData,
+ int drawableX, int drawableY);
+static void ImgPhotoFree(ClientData clientData, Display *display);
+static void ImgPhotoDelete(ClientData clientData);
+static int ImgPhotoPostscript(ClientData clientData,
Tcl_Interp *interp, Tk_Window tkwin,
Tk_PostscriptInfo psInfo, int x, int y, int width,
- int height, int prepass));
+ int height, int prepass);
/*
* The type record itself for photo images:
@@ -333,15 +329,18 @@ Tk_ImageType tkPhotoImageType = {
ImgPhotoFree, /* freeProc */
ImgPhotoDelete, /* deleteProc */
ImgPhotoPostscript, /* postscriptProc */
- (Tk_ImageType *) NULL /* nextPtr */
+ NULL /* nextPtr */
};
typedef struct ThreadSpecificData {
- Tk_PhotoImageFormat *formatList; /* Pointer to the first in the
- * list of known photo image formats.*/
- Tk_PhotoImageFormat *oldFormatList; /* Pointer to the first in the
- * list of known photo image formats.*/
- int initialized; /* set to 1 if we've initialized the strucuture */
+ Tk_PhotoImageFormat *formatList;
+ /* Pointer to the first in the list of known
+ * photo image formats.*/
+ Tk_PhotoImageFormat *oldFormatList;
+ /* Pointer to the first in the list of known
+ * photo image formats.*/
+ int initialized; /* Set to 1 if we've initialized the
+ * strucuture. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
@@ -357,24 +356,24 @@ static Tcl_ThreadDataKey dataKey;
/*
* Information used for parsing configuration specifications:
*/
+
static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_STRING, "-file", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(PhotoMaster, fileString), TK_CONFIG_NULL_OK},
- {TK_CONFIG_DOUBLE, "-gamma", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_STRING, "-file", NULL, NULL,
+ NULL, Tk_Offset(PhotoMaster, fileString), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_DOUBLE, "-gamma", NULL, NULL,
DEF_PHOTO_GAMMA, Tk_Offset(PhotoMaster, gamma), 0},
- {TK_CONFIG_INT, "-height", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_INT, "-height", NULL, NULL,
DEF_PHOTO_HEIGHT, Tk_Offset(PhotoMaster, userHeight), 0},
- {TK_CONFIG_UID, "-palette", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_UID, "-palette", NULL, NULL,
DEF_PHOTO_PALETTE, Tk_Offset(PhotoMaster, palette), 0},
- {TK_CONFIG_INT, "-width", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_INT, "-width", NULL, NULL,
DEF_PHOTO_WIDTH, Tk_Offset(PhotoMaster, userWidth), 0},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+ {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};
/*
- * Hash table used to hash from (display, colormap, palette, gamma)
- * to ColorTable address.
+ * Hash table used to hash from (display, colormap, palette, gamma) to
+ * ColorTable address.
*/
static Tcl_HashTable imgPhotoColorHash;
@@ -394,61 +393,53 @@ static int imgPhotoColorHashInitialized;
* Forward declarations
*/
-static void PhotoFormatThreadExitProc _ANSI_ARGS_((
- ClientData clientData));
-static int ImgPhotoCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
-static int ParseSubcommandOptions _ANSI_ARGS_((
+static void PhotoFormatThreadExitProc(ClientData clientData);
+static int ImgPhotoCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int ParseSubcommandOptions(
struct SubcommandOptions *optPtr,
Tcl_Interp *interp, int allowedOptions,
- int *indexPtr, int objc, Tcl_Obj *CONST objv[]));
-static void ImgPhotoCmdDeletedProc _ANSI_ARGS_((
- ClientData clientData));
-static int ImgPhotoConfigureMaster _ANSI_ARGS_((
- Tcl_Interp *interp, PhotoMaster *masterPtr,
- int objc, Tcl_Obj *CONST objv[], int flags));
-static void ImgPhotoConfigureInstance _ANSI_ARGS_((
- PhotoInstance *instancePtr));
-static int ToggleComplexAlphaIfNeeded _ANSI_ARGS_((
- PhotoMaster *mPtr));
-static void ImgPhotoBlendComplexAlpha _ANSI_ARGS_((
- XImage *bgImg, PhotoInstance *iPtr,
- int xOffset, int yOffset, int width, int height));
-static int ImgPhotoSetSize _ANSI_ARGS_((PhotoMaster *masterPtr,
- int width, int height));
-static void ImgPhotoInstanceSetSize _ANSI_ARGS_((
- PhotoInstance *instancePtr));
-static int ImgStringWrite _ANSI_ARGS_((Tcl_Interp *interp,
+ int *indexPtr, int objc, Tcl_Obj *const objv[]);
+static void ImgPhotoCmdDeletedProc(ClientData clientData);
+static int ImgPhotoConfigureMaster(Tcl_Interp *interp,
+ PhotoMaster *masterPtr, int objc,
+ Tcl_Obj *const objv[], int flags);
+static void ImgPhotoConfigureInstance(PhotoInstance *instancePtr);
+static int ToggleComplexAlphaIfNeeded(PhotoMaster *mPtr);
+static void ImgPhotoBlendComplexAlpha(XImage *bgImg,
+ PhotoInstance *iPtr, int xOffset, int yOffset,
+ int width, int height);
+static int ImgPhotoSetSize(PhotoMaster *masterPtr, int width,
+ int height);
+static void ImgPhotoInstanceSetSize(PhotoInstance *instancePtr);
+static int ImgStringWrite(Tcl_Interp *interp,
Tcl_Obj *formatString,
- Tk_PhotoImageBlock *blockPtr));
-static char * ImgGetPhoto _ANSI_ARGS_((PhotoMaster *masterPtr,
+ Tk_PhotoImageBlock *blockPtr);
+static char * ImgGetPhoto(PhotoMaster *masterPtr,
Tk_PhotoImageBlock *blockPtr,
- struct SubcommandOptions *optPtr));
-static int IsValidPalette _ANSI_ARGS_((PhotoInstance *instancePtr,
- CONST char *palette));
-static int CountBits _ANSI_ARGS_((pixel mask));
-static void GetColorTable _ANSI_ARGS_((PhotoInstance *instancePtr));
-static void FreeColorTable _ANSI_ARGS_((ColorTable *colorPtr,
- int force));
-static void AllocateColors _ANSI_ARGS_((ColorTable *colorPtr));
-static void DisposeColorTable _ANSI_ARGS_((ClientData clientData));
-static void DisposeInstance _ANSI_ARGS_((ClientData clientData));
-static int ReclaimColors _ANSI_ARGS_((ColorTableId *id,
- int numColors));
-static int MatchFileFormat _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Channel chan, char *fileName, Tcl_Obj *formatString,
+ struct SubcommandOptions *optPtr);
+static int IsValidPalette(PhotoInstance *instancePtr,
+ const char *palette);
+static int CountBits(pixel mask);
+static void GetColorTable(PhotoInstance *instancePtr);
+static void FreeColorTable(ColorTable *colorPtr, int force);
+static void AllocateColors(ColorTable *colorPtr);
+static void DisposeColorTable(ClientData clientData);
+static void DisposeInstance(ClientData clientData);
+static int ReclaimColors(ColorTableId *id, int numColors);
+static int MatchFileFormat(Tcl_Interp *interp, Tcl_Channel chan,
+ char *fileName, Tcl_Obj *formatString,
Tk_PhotoImageFormat **imageFormatPtr,
- int *widthPtr, int *heightPtr, int *oldformat));
-static int MatchStringFormat _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Obj *data, Tcl_Obj *formatString,
+ int *widthPtr, int *heightPtr, int *oldformat);
+static int MatchStringFormat(Tcl_Interp *interp, Tcl_Obj *data,
+ Tcl_Obj *formatString,
Tk_PhotoImageFormat **imageFormatPtr,
- int *widthPtr, int *heightPtr, int *oldformat));
-static Tcl_ObjCmdProc * PhotoOptionFind _ANSI_ARGS_((Tcl_Interp * interp,
- Tcl_Obj *obj));
-static void DitherInstance _ANSI_ARGS_((PhotoInstance *instancePtr,
- int x, int y, int width, int height));
-static void PhotoOptionCleanupProc _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp));
+ int *widthPtr, int *heightPtr, int *oldformat);
+static Tcl_ObjCmdProc * PhotoOptionFind(Tcl_Interp *interp, Tcl_Obj *obj);
+static void DitherInstance(PhotoInstance *instancePtr, int x,
+ int y, int width, int height);
+static void PhotoOptionCleanupProc(ClientData clientData,
+ Tcl_Interp *interp);
#undef MIN
#define MIN(a, b) ((a) < (b)? (a): (b))
@@ -458,35 +449,30 @@ static void PhotoOptionCleanupProc _ANSI_ARGS_((
/*
*----------------------------------------------------------------------
*
- * Tk_CreateOldPhotoImageFormat, Tk_CreatePhotoImageFormat --
+ * PhotoFormatThreadExitProc --
*
- * This procedure is invoked by an image file handler to register
- * a new photo image format and the procedures that handle the
- * new format. The procedure is typically invoked during
- * Tcl_AppInit.
+ * Clean up the registered list of photo formats.
*
* Results:
* None.
*
* Side effects:
- * The new image file format is entered into a table used in the
- * photo image "read" and "write" subcommands.
+ * The thread's linked lists of photo image formats is deleted.
*
*----------------------------------------------------------------------
*/
static void
-PhotoFormatThreadExitProc(clientData)
- ClientData clientData; /* not used */
+PhotoFormatThreadExitProc(
+ ClientData clientData) /* not used */
{
Tk_PhotoImageFormat *freePtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
while (tsdPtr->oldFormatList != NULL) {
freePtr = tsdPtr->oldFormatList;
tsdPtr->oldFormatList = tsdPtr->oldFormatList->nextPtr;
- ckfree((char *) freePtr->name);
ckfree((char *) freePtr);
}
while (tsdPtr->formatList != NULL) {
@@ -502,31 +488,30 @@ PhotoFormatThreadExitProc(clientData)
*
* Tk_CreateOldPhotoImageFormat, Tk_CreatePhotoImageFormat --
*
- * This procedure is invoked by an image file handler to register
- * a new photo image format and the procedures that handle the
- * new format. The procedure is typically invoked during
- * Tcl_AppInit.
+ * This function is invoked by an image file handler to register a new
+ * photo image format and the functions that handle the new format. The
+ * function is typically invoked during Tcl_AppInit.
*
* Results:
* None.
*
* Side effects:
- * The new image file format is entered into a table used in the
- * photo image "read" and "write" subcommands.
+ * The new image file format is entered into a table used in the photo
+ * image "read" and "write" subcommands.
*
*----------------------------------------------------------------------
*/
+
void
-Tk_CreateOldPhotoImageFormat(formatPtr)
- Tk_PhotoImageFormat *formatPtr;
- /* Structure describing the format. All of
- * the fields except "nextPtr" must be filled
- * in by caller. Must not have been passed
- * to Tk_CreatePhotoImageFormat previously. */
+Tk_CreateOldPhotoImageFormat(
+ Tk_PhotoImageFormat *formatPtr)
+ /* Structure describing the format. All of the
+ * fields except "nextPtr" must be filled in
+ * by caller. */
{
Tk_PhotoImageFormat *copyPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (!tsdPtr->initialized) {
tsdPtr->initialized = 1;
@@ -534,23 +519,20 @@ Tk_CreateOldPhotoImageFormat(formatPtr)
}
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 = tsdPtr->oldFormatList;
tsdPtr->oldFormatList = copyPtr;
}
void
-Tk_CreatePhotoImageFormat(formatPtr)
- Tk_PhotoImageFormat *formatPtr;
- /* Structure describing the format. All of
- * the fields except "nextPtr" must be filled
- * in by caller. Must not have been passed
- * to Tk_CreatePhotoImageFormat previously. */
+Tk_CreatePhotoImageFormat(
+ Tk_PhotoImageFormat *formatPtr)
+ /* Structure describing the format. All of the
+ * fields except "nextPtr" must be filled in
+ * by caller. */
{
Tk_PhotoImageFormat *copyPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (!tsdPtr->initialized) {
tsdPtr->initialized = 1;
@@ -558,12 +540,14 @@ Tk_CreatePhotoImageFormat(formatPtr)
}
copyPtr = (Tk_PhotoImageFormat *) ckalloc(sizeof(Tk_PhotoImageFormat));
*copyPtr = *formatPtr;
- copyPtr->name = (char *) ckalloc((unsigned) (strlen(formatPtr->name) + 1));
- strcpy(copyPtr->name, formatPtr->name);
if (isupper((unsigned char) *formatPtr->name)) {
copyPtr->nextPtr = tsdPtr->oldFormatList;
tsdPtr->oldFormatList = copyPtr;
} else {
+ /* for compatibility with aMSN: make a copy of formatPtr->name */
+ char *name = ckalloc(strlen(formatPtr->name) + 1);
+ strcpy(name, formatPtr->name);
+ copyPtr->name = name;
copyPtr->nextPtr = tsdPtr->formatList;
tsdPtr->formatList = copyPtr;
}
@@ -574,32 +558,31 @@ Tk_CreatePhotoImageFormat(formatPtr)
*
* ImgPhotoCreate --
*
- * This procedure is called by the Tk image code to create
- * a new photo image.
+ * This function is called by the Tk image code to create a new photo
+ * image.
*
* Results:
* A standard Tcl result.
*
* Side effects:
- * The data structure for a new photo image is allocated and
- * initialized.
+ * The data structure for a new photo image is allocated and initialized.
*
*----------------------------------------------------------------------
*/
static int
-ImgPhotoCreate(interp, name, objc, objv, typePtr, master, clientDataPtr)
- Tcl_Interp *interp; /* Interpreter for application containing
+ImgPhotoCreate(
+ Tcl_Interp *interp, /* Interpreter for application containing
* image. */
- char *name; /* Name to use for image. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects for options (doesn't
+ char *name, /* Name to use for image. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[], /* Argument objects for options (doesn't
* include image name or type). */
- Tk_ImageType *typePtr; /* Pointer to our type record (not used). */
- Tk_ImageMaster master; /* Token for image, to be used by us in
- * later callbacks. */
- ClientData *clientDataPtr; /* Store manager's token for image here;
- * it will be returned in later callbacks. */
+ Tk_ImageType *typePtr, /* Pointer to our type record (not used). */
+ Tk_ImageMaster master, /* Token for image, to be used by us in later
+ * callbacks. */
+ ClientData *clientDataPtr) /* Store manager's token for image here; it
+ * will be returned in later callbacks. */
{
PhotoMaster *masterPtr;
@@ -608,7 +591,7 @@ ImgPhotoCreate(interp, name, objc, objv, typePtr, master, clientDataPtr)
*/
masterPtr = (PhotoMaster *) ckalloc(sizeof(PhotoMaster));
- memset((void *) masterPtr, 0, sizeof(PhotoMaster));
+ memset(masterPtr, 0, sizeof(PhotoMaster));
masterPtr->tkMaster = master;
masterPtr->interp = interp;
masterPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgPhotoCmd,
@@ -636,9 +619,9 @@ ImgPhotoCreate(interp, name, objc, objv, typePtr, master, clientDataPtr)
*
* ImgPhotoCmd --
*
- * This procedure is invoked to process the Tcl command that
- * corresponds to a photo image. See the user documentation
- * for details on what it does.
+ * This function is invoked to process the Tcl command that corresponds
+ * to a photo image. See the user documentation for details on what it
+ * does.
*
* Results:
* A standard Tcl result.
@@ -650,42 +633,35 @@ ImgPhotoCreate(interp, name, objc, objv, typePtr, master, clientDataPtr)
*/
static int
-ImgPhotoCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Information about photo master. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+ImgPhotoCmd(
+ ClientData clientData, /* Information about photo master. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- int oldformat = 0;
- static CONST char *photoOptions[] = {
+ static const char *photoOptions[] = {
"blank", "cget", "configure", "copy", "data", "get", "put",
- "read", "redither", "transparency", "write", (char *) NULL
+ "read", "redither", "transparency", "write", NULL
};
- enum options {
+ enum PhotoOptions {
PHOTO_BLANK, PHOTO_CGET, PHOTO_CONFIGURE, PHOTO_COPY, PHOTO_DATA,
PHOTO_GET, PHOTO_PUT, PHOTO_READ, PHOTO_REDITHER, PHOTO_TRANS,
PHOTO_WRITE
};
PhotoMaster *masterPtr = (PhotoMaster *) clientData;
- int result, index;
- int x, y, width, height;
- int dataWidth, dataHeight;
+ int result, index, x, y, width, height, dataWidth, dataHeight, listObjc;
struct SubcommandOptions options;
- int listArgc;
- CONST char **listArgv;
- CONST char **srcArgv;
+ Tcl_Obj **listObjv, **srcObjv;
unsigned char *pixelPtr;
Tk_PhotoImageBlock block;
Tk_Window tkwin;
- XColor color;
Tk_PhotoImageFormat *imageFormat;
- int imageWidth, imageHeight;
- int length, matched;
+ int imageWidth, imageHeight, matched, length, oldformat = 0;
Tcl_Channel chan;
Tk_PhotoHandle srcHandle;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
@@ -696,13 +672,13 @@ ImgPhotoCmd(clientData, interp, objc, objv)
&index) != TCL_OK) {
Tcl_ObjCmdProc *proc;
proc = PhotoOptionFind(interp, objv[1]);
- if (proc == (Tcl_ObjCmdProc *) NULL) {
+ if (proc == NULL) {
return TCL_ERROR;
}
return proc(clientData, interp, objc, objv);
}
- switch ((enum options) index) {
+ switch ((enum PhotoOptions) index) {
case PHOTO_BLANK:
/*
* photo blank command - just call Tk_PhotoBlank.
@@ -712,7 +688,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
Tk_PhotoBlank(masterPtr);
return TCL_OK;
} else {
- Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL);
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
return TCL_ERROR;
}
@@ -746,53 +722,51 @@ ImgPhotoCmd(clientData, interp, objc, objv)
if (objc == 2) {
Tcl_Obj *obj, *subobj;
+
result = Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
- configSpecs, (char *) masterPtr, (char *) NULL, 0);
+ configSpecs, (char *) masterPtr, NULL, 0);
if (result != TCL_OK) {
return result;
}
obj = Tcl_NewObj();
subobj = Tcl_NewStringObj("-data {} {} {}", 14);
if (masterPtr->dataString) {
- Tcl_ListObjAppendElement(interp, subobj, masterPtr->dataString);
+ Tcl_ListObjAppendElement(NULL, subobj, masterPtr->dataString);
} else {
- Tcl_AppendStringsToObj(subobj, " {}", (char *) NULL);
+ Tcl_AppendStringsToObj(subobj, " {}", NULL);
}
Tcl_ListObjAppendElement(interp, obj, subobj);
subobj = Tcl_NewStringObj("-format {} {} {}", 16);
if (masterPtr->format) {
- Tcl_ListObjAppendElement(interp, subobj, masterPtr->format);
+ Tcl_ListObjAppendElement(NULL, subobj, masterPtr->format);
} else {
- Tcl_AppendStringsToObj(subobj, " {}", (char *) NULL);
+ Tcl_AppendStringsToObj(subobj, " {}", NULL);
}
Tcl_ListObjAppendElement(interp, obj, subobj);
Tcl_ListObjAppendList(interp, obj, Tcl_GetObjResult(interp));
Tcl_SetObjResult(interp, obj);
return TCL_OK;
- }
- if (objc == 3) {
+
+ } else if (objc == 3) {
char *arg = Tcl_GetStringFromObj(objv[2], &length);
- if (!strncmp(arg, "-data", (unsigned) length)) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "-data {} {} {}", (char *) NULL);
+ if (length > 1 && !strncmp(arg, "-data", (unsigned) length)) {
+ Tcl_AppendResult(interp, "-data {} {} {}", NULL);
if (masterPtr->dataString) {
Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp),
masterPtr->dataString);
} else {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- " {}", (char *) NULL);
+ Tcl_AppendResult(interp, " {}", NULL);
}
return TCL_OK;
- } else if (!strncmp(arg, "-format", (unsigned) length)) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "-format {} {} {}", (char *) NULL);
+ } else if (length > 1 &&
+ !strncmp(arg, "-format", (unsigned) length)) {
+ Tcl_AppendResult(interp, "-format {} {} {}", NULL);
if (masterPtr->format) {
Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp),
masterPtr->format);
} else {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- " {}", (char *) NULL);
+ Tcl_AppendResult(interp, " {}", NULL);
}
return TCL_OK;
} else {
@@ -809,7 +783,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
*/
index = 2;
- memset((VOID *) &options, 0, sizeof(options));
+ memset(&options, 0, sizeof(options));
options.zoomX = options.zoomY = 1;
options.subsampleX = options.subsampleY = 1;
options.name = NULL;
@@ -834,7 +808,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
if (srcHandle == NULL) {
Tcl_AppendResult(interp, "image \"",
Tcl_GetString(options.name), "\" doesn't",
- " exist or is not a photo image", (char *) NULL);
+ " exist or is not a photo image", NULL);
return TCL_ERROR;
}
Tk_PhotoGetImage(srcHandle, &block);
@@ -842,7 +816,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
|| (options.fromX2 > block.width)
|| (options.fromY2 > block.height)) {
Tcl_AppendResult(interp, "coordinates for -from option extend ",
- "outside source image", (char *) NULL);
+ "outside source image", NULL);
return TCL_ERROR;
}
@@ -895,8 +869,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
if (ImgPhotoSetSize(masterPtr, options.toX2,
options.toY2) != TCL_OK) {
Tcl_ResetResult(interp);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- TK_PHOTO_ALLOC_FAILURE_MESSAGE, (char *) NULL);
+ Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);
return TCL_ERROR;
}
}
@@ -909,12 +882,11 @@ ImgPhotoCmd(clientData, interp, objc, objv)
+ options.fromY * block.pitch;
block.width = options.fromX2 - options.fromX;
block.height = options.fromY2 - options.fromY;
- Tk_PhotoPutZoomedBlock((Tk_PhotoHandle) masterPtr, &block,
- options.toX, options.toY, options.toX2 - options.toX,
+ return Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) masterPtr,
+ &block, options.toX, options.toY, options.toX2 - options.toX,
options.toY2 - options.toY, options.zoomX, options.zoomY,
options.subsampleX, options.subsampleY,
options.compositingRule);
- return TCL_OK;
case PHOTO_DATA: {
char *data;
@@ -922,10 +894,11 @@ ImgPhotoCmd(clientData, interp, objc, objv)
/*
* photo data command - first parse and check any options given.
*/
+
Tk_ImageStringWriteProc *stringWriteProc = NULL;
index = 2;
- memset((VOID *) &options, 0, sizeof(options));
+ memset(&options, 0, sizeof(options));
options.name = NULL;
options.format = NULL;
options.fromX = 0;
@@ -944,7 +917,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
|| (options.fromX2 > masterPtr->width)
|| (options.fromY2 > masterPtr->height)) {
Tcl_AppendResult(interp, "coordinates for -from option extend ",
- "outside image", (char *) NULL);
+ "outside image", NULL);
return TCL_ERROR;
}
@@ -992,8 +965,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
if (stringWriteProc == NULL) {
Tcl_AppendResult(interp, "image string format \"",
Tcl_GetString(options.format), "\" is ",
- (matched ? "not supported" : "unknown"),
- (char *) NULL);
+ (matched ? "not supported" : "unknown"), NULL);
return TCL_ERROR;
}
} else {
@@ -1001,8 +973,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
}
/*
- * Call the handler's string write procedure to write out
- * the image.
+ * Call the handler's string write function to write out the image.
*/
data = ImgGetPhoto(masterPtr, &block, &options);
@@ -1011,9 +982,9 @@ ImgPhotoCmd(clientData, interp, objc, objv)
Tcl_DString buffer;
Tcl_DStringInit(&buffer);
- result = ((int (*) _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_DString *buffer, char *formatString,
- Tk_PhotoImageBlock *blockPtr))) stringWriteProc)
+ result = ((int (*) (Tcl_Interp *interp,
+ Tcl_DString *dataPtr, char *formatString,
+ Tk_PhotoImageBlock *blockPtr)) stringWriteProc)
(interp, &buffer, Tcl_GetString(options.format), &block);
if (result == TCL_OK) {
Tcl_DStringResult(interp, &buffer);
@@ -1021,10 +992,11 @@ ImgPhotoCmd(clientData, interp, objc, objv)
Tcl_DStringFree(&buffer);
}
} else {
- result = ((int (*) _ANSI_ARGS_((Tcl_Interp *interp,
+
+ result = ((int (*) (Tcl_Interp *interp,
Tcl_Obj *formatString, Tk_PhotoImageBlock *blockPtr,
- VOID *dummy))) stringWriteProc)
- (interp, options.format, &block, (VOID *) NULL);
+ void *dummy)) stringWriteProc)
+ (interp, options.format, &block, NULL);
}
if (options.background) {
Tk_FreeColor(options.background);
@@ -1053,7 +1025,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
if ((x < 0) || (x >= masterPtr->width)
|| (y < 0) || (y >= masterPtr->height)) {
Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " get: ",
- "coordinates out of range", (char *) NULL);
+ "coordinates out of range", NULL);
return TCL_ERROR;
}
@@ -1064,7 +1036,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
sprintf(string, "%d %d %d", pixelPtr[0], pixelPtr[1],
pixelPtr[2]);
- Tcl_AppendResult(interp, string, (char *) NULL);
+ Tcl_AppendResult(interp, string, NULL);
return TCL_OK;
}
@@ -1074,7 +1046,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
*/
index = 2;
- memset((VOID *) &options, 0, sizeof(options));
+ memset(&options, 0, sizeof(options));
options.name = NULL;
if (ParseSubcommandOptions(&options, interp, OPT_TO|OPT_FORMAT,
&index, objc, objv) != TCL_OK) {
@@ -1085,7 +1057,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
- if (MatchStringFormat(interp, options.name ? objv[2]:NULL,
+ if (MatchStringFormat(interp, options.name ? objv[2]:NULL,
options.format, &imageFormat, &imageWidth,
&imageHeight, &oldformat) == TCL_OK) {
Tcl_Obj *format, *data;
@@ -1121,8 +1093,8 @@ ImgPhotoCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
Tcl_ResetResult(interp);
- if (Tcl_SplitList(interp, Tcl_GetString(options.name),
- &dataHeight, &srcArgv) != TCL_OK) {
+ if (Tcl_ListObjGetElements(interp, options.name,
+ &dataHeight, &srcObjv) != TCL_OK) {
return TCL_ERROR;
}
tkwin = Tk_MainWindow(interp);
@@ -1130,44 +1102,80 @@ ImgPhotoCmd(clientData, interp, objc, objv)
dataWidth = 0;
pixelPtr = NULL;
for (y = 0; y < dataHeight; ++y) {
- if (Tcl_SplitList(interp, srcArgv[y], &listArgc, &listArgv)
- != TCL_OK) {
+ if (Tcl_ListObjGetElements(interp, srcObjv[y],
+ &listObjc, &listObjv) != TCL_OK) {
break;
}
+
if (y == 0) {
- if (listArgc == 0) {
+ if (listObjc == 0) {
/*
* Lines must be non-empty...
*/
+
break;
}
- dataWidth = listArgc;
+ dataWidth = listObjc;
pixelPtr = (unsigned char *)
ckalloc((unsigned) dataWidth * dataHeight * 3);
block.pixelPtr = pixelPtr;
- } else if (listArgc != dataWidth) {
+ } else if (listObjc != dataWidth) {
Tcl_AppendResult(interp, "all elements of color list must",
- " have the same number of elements", (char *) NULL);
- ckfree((char *) listArgv);
+ " have the same number of elements", NULL);
break;
}
+
for (x = 0; x < dataWidth; ++x) {
+ char *colorString = Tcl_GetString(listObjv[x]);
+ XColor color;
+ int tmpr, tmpg, tmpb;
+
+ /*
+ * We do not use Tk_GetColorFromObj() because we absolutely do
+ * not want to invoke the fallback code.
+ */
+
+ if (colorString[0] == '#') {
+ if (isxdigit(UCHAR(colorString[1])) &&
+ isxdigit(UCHAR(colorString[2])) &&
+ isxdigit(UCHAR(colorString[3]))) {
+ if (colorString[4] == '\0') {
+ /* Got #rgb */
+ sscanf(colorString+1, "%1x%1x%1x",
+ &tmpr, &tmpg, &tmpb);
+ *pixelPtr++ = tmpr * 0x11;
+ *pixelPtr++ = tmpg * 0x11;
+ *pixelPtr++ = tmpb * 0x11;
+ continue;
+ } else if (isxdigit(UCHAR(colorString[4])) &&
+ isxdigit(UCHAR(colorString[5])) &&
+ isxdigit(UCHAR(colorString[6])) &&
+ colorString[7] == '\0') {
+ /* Got #rrggbb */
+ sscanf(colorString+1, "%2x%2x%2x",
+ &tmpr, &tmpg, &tmpb);
+ *pixelPtr++ = tmpr;
+ *pixelPtr++ = tmpg;
+ *pixelPtr++ = tmpb;
+ continue;
+ }
+ }
+ }
+
if (!TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin),
- listArgv[x], &color)) {
+ colorString, &color)) {
Tcl_AppendResult(interp, "can't parse color \"",
- listArgv[x], "\"", (char *) NULL);
+ colorString, "\"", NULL);
break;
}
*pixelPtr++ = color.red >> 8;
*pixelPtr++ = color.green >> 8;
*pixelPtr++ = color.blue >> 8;
}
- ckfree((char *) listArgv);
if (x < dataWidth) {
break;
}
}
- ckfree((char *) srcArgv);
if (y < dataHeight || dataHeight == 0 || dataWidth == 0) {
if (block.pixelPtr != NULL) {
ckfree((char *) block.pixelPtr);
@@ -1179,8 +1187,8 @@ ImgPhotoCmd(clientData, interp, objc, objv)
}
/*
- * Fill in default values for the -to option, then
- * copy the block in using Tk_PhotoPutBlock.
+ * Fill in default values for the -to option, then copy the block in
+ * using Tk_PhotoPutBlock.
*/
if (!(options.options & OPT_TO) || (options.toX2 < 0)) {
@@ -1195,11 +1203,12 @@ ImgPhotoCmd(clientData, interp, objc, objv)
block.offset[1] = 1;
block.offset[2] = 2;
block.offset[3] = 0;
- Tk_PhotoPutBlock((ClientData)masterPtr, &block,
+ result = Tk_PhotoPutBlock(interp, (ClientData)masterPtr, &block,
options.toX, options.toY, options.toX2 - options.toX,
- options.toY2 - options.toY, TK_PHOTO_COMPOSITE_SET);
+ options.toY2 - options.toY,
+ TK_PHOTO_COMPOSITE_SET);
ckfree((char *) block.pixelPtr);
- return TCL_OK;
+ return result;
case PHOTO_READ: {
Tcl_Obj *format;
@@ -1209,7 +1218,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
*/
index = 2;
- memset((VOID *) &options, 0, sizeof(options));
+ memset(&options, 0, sizeof(options));
options.name = NULL;
options.format = NULL;
if (ParseSubcommandOptions(&options, interp,
@@ -1222,16 +1231,16 @@ ImgPhotoCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
- /*
- * Prevent file system access in safe interpreters.
- */
+ /*
+ * Prevent file system access in safe interpreters.
+ */
+
+ if (Tcl_IsSafe(interp)) {
+ Tcl_AppendResult(interp, "can't get image from a file in a",
+ " safe interpreter", NULL);
+ return TCL_ERROR;
+ }
- if (Tcl_IsSafe(interp)) {
- Tcl_AppendResult(interp, "can't get image from a file in a",
- " safe interpreter", (char *) NULL);
- return TCL_ERROR;
- }
-
/*
* Open the image file and look for a handler for it.
*/
@@ -1241,17 +1250,17 @@ ImgPhotoCmd(clientData, interp, objc, objv)
if (chan == NULL) {
return TCL_ERROR;
}
- if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")
+ if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")
!= TCL_OK) {
Tcl_Close(NULL, chan);
- return TCL_ERROR;
- }
- if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary")
+ return TCL_ERROR;
+ }
+ if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary")
!= TCL_OK) {
Tcl_Close(NULL, chan);
- return TCL_ERROR;
- }
-
+ return TCL_ERROR;
+ }
+
if (MatchFileFormat(interp, chan,
Tcl_GetString(options.name), options.format, &imageFormat,
&imageWidth, &imageHeight, &oldformat) != TCL_OK) {
@@ -1267,7 +1276,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
|| (options.fromX2 > imageWidth)
|| (options.fromY2 > imageHeight)) {
Tcl_AppendResult(interp, "coordinates for -from option extend ",
- "outside source image", (char *) NULL);
+ "outside source image", NULL);
Tcl_Close(NULL, chan);
return TCL_ERROR;
}
@@ -1287,15 +1296,14 @@ ImgPhotoCmd(clientData, interp, objc, objv)
if (ImgPhotoSetSize(masterPtr, options.toX + width,
options.toY + height) != TCL_OK) {
Tcl_ResetResult(interp);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- TK_PHOTO_ALLOC_FAILURE_MESSAGE, (char *) NULL);
+ Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);
return TCL_ERROR;
}
}
/*
- * Call the handler's file read procedure to read the data
- * into the image.
+ * Call the handler's file read function to read the data into the
+ * image.
*/
format = options.format;
@@ -1314,13 +1322,13 @@ ImgPhotoCmd(clientData, interp, objc, objv)
case PHOTO_REDITHER:
if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL);
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
return TCL_ERROR;
}
/*
- * Call Dither if any part of the image is not correctly
- * dithered at present.
+ * Call Dither if any part of the image is not correctly dithered at
+ * present.
*/
x = masterPtr->ditherX;
@@ -1348,8 +1356,8 @@ ImgPhotoCmd(clientData, interp, objc, objv)
return TCL_OK;
case PHOTO_TRANS: {
- static CONST char *photoTransOptions[] = {
- "get", "set", (char *) NULL
+ static const char *photoTransOptions[] = {
+ "get", "set", NULL
};
enum transOptions {
PHOTO_TRANS_GET, PHOTO_TRANS_SET
@@ -1380,8 +1388,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
if ((x < 0) || (x >= masterPtr->width)
|| (y < 0) || (y >= masterPtr->height)) {
Tcl_AppendResult(interp, Tcl_GetString(objv[0]),
- " transparency get: coordinates out of range",
- (char *) NULL);
+ " transparency get: coordinates out of range", NULL);
return TCL_ERROR;
}
@@ -1418,8 +1425,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
if ((x < 0) || (x >= masterPtr->width)
|| (y < 0) || (y >= masterPtr->height)) {
Tcl_AppendResult(interp, Tcl_GetString(objv[0]),
- " transparency set: coordinates out of range",
- (char *) NULL);
+ " transparency set: coordinates out of range", NULL);
return TCL_ERROR;
}
@@ -1433,20 +1439,24 @@ ImgPhotoCmd(clientData, interp, objc, objv)
/*
* Make pixel transparent.
*/
+
TkRegion clearRegion = TkCreateRegion();
TkUnionRectWithRegion(&setBox, clearRegion, clearRegion);
TkSubtractRegion(masterPtr->validRegion, clearRegion,
masterPtr->validRegion);
TkDestroyRegion(clearRegion);
+
/*
* Set the alpha value correctly.
*/
+
pixelPtr[3] = 0;
} else {
/*
* Make pixel opaque.
*/
+
TkUnionRectWithRegion(&setBox, masterPtr->validRegion,
masterPtr->validRegion);
pixelPtr[3] = 255;
@@ -1462,31 +1472,31 @@ ImgPhotoCmd(clientData, interp, objc, objv)
masterPtr->flags &= ~IMAGE_CHANGED;
return TCL_OK;
}
- }
- panic("unexpected fallthrough");
+ }
+ Tcl_Panic("unexpected fallthrough");
}
case PHOTO_WRITE: {
char *data;
Tcl_Obj *format;
- /*
- * Prevent file system access in safe interpreters.
- */
+ /*
+ * Prevent file system access in safe interpreters.
+ */
+
+ if (Tcl_IsSafe(interp)) {
+ Tcl_AppendResult(interp, "can't write image to a file in a",
+ " safe interpreter", NULL);
+ return TCL_ERROR;
+ }
- if (Tcl_IsSafe(interp)) {
- Tcl_AppendResult(interp, "can't write image to a file in a",
- " safe interpreter", (char *) NULL);
- return TCL_ERROR;
- }
-
/*
* photo write command - first parse and check any options given.
*/
index = 2;
- memset((VOID *) &options, 0, sizeof(options));
+ memset(&options, 0, sizeof(options));
options.name = NULL;
options.format = NULL;
if (ParseSubcommandOptions(&options, interp,
@@ -1503,7 +1513,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
|| (options.fromX2 > masterPtr->width)
|| (options.fromY2 > masterPtr->height)) {
Tcl_AppendResult(interp, "coordinates for -from option extend ",
- "outside image", (char *) NULL);
+ "outside image", NULL);
return TCL_ERROR;
}
@@ -1517,8 +1527,8 @@ ImgPhotoCmd(clientData, interp, objc, objv)
}
/*
- * Search for an appropriate image file format handler,
- * and give an error if none is found.
+ * Search for an appropriate image file format handler, and give an
+ * error if none is found.
*/
matched = 0;
@@ -1550,23 +1560,21 @@ ImgPhotoCmd(clientData, interp, objc, objv)
if (imageFormat == NULL) {
if (options.format == NULL) {
Tcl_AppendResult(interp, "no available image file format ",
- "has file writing capability", (char *) NULL);
+ "has file writing capability", NULL);
} else if (!matched) {
Tcl_AppendResult(interp, "image file format \"",
Tcl_GetString(options.format),
- "\" is unknown", (char *) NULL);
+ "\" is unknown", NULL);
} else {
Tcl_AppendResult(interp, "image file format \"",
Tcl_GetString(options.format),
- "\" has no file writing capability",
- (char *) NULL);
+ "\" has no file writing capability", NULL);
}
return TCL_ERROR;
}
/*
- * Call the handler's file write procedure to write out
- * the image.
+ * Call the handler's file write function to write out the image.
*/
data = ImgGetPhoto(masterPtr, &block, &options);
@@ -1586,7 +1594,7 @@ ImgPhotoCmd(clientData, interp, objc, objv)
}
}
- panic("unexpected fallthrough");
+ Tcl_Panic("unexpected fallthrough");
return TCL_ERROR; /* NOT REACHED */
}
@@ -1595,10 +1603,9 @@ ImgPhotoCmd(clientData, interp, objc, objv)
*
* ParseSubcommandOptions --
*
- * This procedure is invoked to process one of the options
- * which may be specified for the photo image subcommands,
- * namely, -from, -to, -zoom, -subsample, -format, -shrink,
- * and -compositingrule.
+ * This function is invoked to process one of the options which may be
+ * specified for the photo image subcommands, namely, -from, -to, -zoom,
+ * -subsample, -format, -shrink, and -compositingrule.
*
* Results:
* A standard Tcl result.
@@ -1610,29 +1617,28 @@ ImgPhotoCmd(clientData, interp, objc, objv)
*/
static int
-ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv)
- struct SubcommandOptions *optPtr;
- /* Information about the options specified
- * and the values given is returned here. */
- Tcl_Interp *interp; /* Interpreter to use for reporting errors. */
- int allowedOptions; /* Indicates which options are valid for
- * the current command. */
- int *optIndexPtr; /* Points to a variable containing the
- * current index in objv; this variable is
- * updated by this procedure. */
- int objc; /* Number of arguments in objv[]. */
- Tcl_Obj *CONST objv[]; /* Arguments to be parsed. */
+ParseSubcommandOptions(
+ struct SubcommandOptions *optPtr,
+ /* Information about the options specified and
+ * the values given is returned here. */
+ Tcl_Interp *interp, /* Interpreter to use for reporting errors. */
+ int allowedOptions, /* Indicates which options are valid for the
+ * current command. */
+ int *optIndexPtr, /* Points to a variable containing the current
+ * index in objv; this variable is updated by
+ * this function. */
+ int objc, /* Number of arguments in objv[]. */
+ Tcl_Obj *const objv[]) /* Arguments to be parsed. */
{
- int index, c, bit, currentBit;
- int length;
- char *option, **listPtr;
- int values[4];
- int numValues, maxValues, argIndex;
+ int index, c, bit, currentBit, length;
+ int values[4], numValues, maxValues, argIndex;
+ char *option;
+ const char *const *listPtr;
for (index = *optIndexPtr; index < objc; *optIndexPtr = ++index) {
/*
- * We can have one value specified without an option;
- * it goes into optPtr->name.
+ * We can have one value specified without an option; it goes into
+ * optPtr->name.
*/
option = Tcl_GetStringFromObj(objv[index], &length);
@@ -1664,24 +1670,24 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv)
}
/*
- * If this option is not recognized and allowed, put
- * an error message in the interpreter and return.
+ * If this option is not recognized and allowed, put an error message
+ * in the interpreter and return.
*/
if ((allowedOptions & bit) == 0) {
Tcl_AppendResult(interp, "unrecognized option \"",
Tcl_GetString(objv[index]),
- "\": must be ", (char *)NULL);
+ "\": must be ", NULL);
bit = 1;
for (listPtr = optionNames; *listPtr != NULL; ++listPtr) {
if ((allowedOptions & bit) != 0) {
if ((allowedOptions & (bit - 1)) != 0) {
- Tcl_AppendResult(interp, ", ", (char *) NULL);
+ Tcl_AppendResult(interp, ", ", NULL);
if ((allowedOptions & ~((bit << 1) - 1)) == 0) {
- Tcl_AppendResult(interp, "or ", (char *) NULL);
+ Tcl_AppendResult(interp, "or ", NULL);
}
}
- Tcl_AppendResult(interp, *listPtr, (char *) NULL);
+ Tcl_AppendResult(interp, *listPtr, NULL);
}
bit <<= 1;
}
@@ -1689,9 +1695,8 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv)
}
/*
- * For the -from, -to, -zoom and -subsample options,
- * parse the values given. Report an error if too few
- * or too many values are given.
+ * For the -from, -to, -zoom and -subsample options, parse the values
+ * given. Report an error if too few or too many values are given.
*/
if (bit == OPT_BACKGROUND) {
@@ -1708,14 +1713,13 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv)
}
} else {
Tcl_AppendResult(interp, "the \"-background\" option ",
- "requires a value", (char *) NULL);
+ "requires a value", NULL);
return TCL_ERROR;
}
} else if (bit == OPT_FORMAT) {
/*
- * The -format option takes a single string value. Note
- * that parsing this is outside the scope of this
- * function.
+ * The -format option takes a single string value. Note that
+ * parsing this is outside the scope of this function.
*/
if (index + 1 < objc) {
@@ -1723,13 +1727,13 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv)
optPtr->format = objv[index];
} else {
Tcl_AppendResult(interp, "the \"-format\" option ",
- "requires a value", (char *) NULL);
+ "requires a value", NULL);
return TCL_ERROR;
}
} else if (bit == OPT_COMPOSITE) {
/*
- * The -compositingrule option takes a single value from
- * a well-known set.
+ * The -compositingrule option takes a single value from a
+ * well-known set.
*/
if (index + 1 < objc) {
@@ -1737,9 +1741,9 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv)
* Note that these must match the TK_PHOTO_COMPOSITE_*
* constants.
*/
- static CONST char *compositingRules[] = {
- "overlay", "set",
- NULL
+
+ static const char *compositingRules[] = {
+ "overlay", "set", NULL
};
index++;
@@ -1751,7 +1755,7 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv)
*optIndexPtr = index;
} else {
Tcl_AppendResult(interp, "the \"-compositingrule\" option ",
- "requires a value", (char *) NULL);
+ "requires a value", NULL);
return TCL_ERROR;
}
} else if ((bit != OPT_SHRINK) && (bit != OPT_GRAYSCALE)) {
@@ -1762,7 +1766,7 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv)
if (argIndex >= objc) {
break;
}
- val = Tcl_GetString(objv[argIndex]);
+ val = Tcl_GetString(objv[argIndex]);
if ((argIndex < objc) && (isdigit(UCHAR(val[0]))
|| ((val[0] == '-') && isdigit(UCHAR(val[1]))))) {
if (Tcl_GetInt(interp, val, &values[numValues])
@@ -1778,7 +1782,7 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv)
if (numValues == 0) {
Tcl_AppendResult(interp, "the \"", option, "\" option ",
"requires one ", maxValues == 2? "or two": "to four",
- " integer values", (char *) NULL);
+ " integer values", NULL);
return TCL_ERROR;
}
*optIndexPtr = (index += numValues);
@@ -1795,62 +1799,62 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv)
}
/*
- * Check the values given and put them in the appropriate
- * field of the SubcommandOptions structure.
+ * Check the values given and put them in the appropriate field of
+ * the SubcommandOptions structure.
*/
switch (bit) {
- case OPT_FROM:
- if ((values[0] < 0) || (values[1] < 0) || ((numValues > 2)
- && ((values[2] < 0) || (values[3] < 0)))) {
- Tcl_AppendResult(interp, "value(s) for the -from",
- " option must be non-negative", (char *) NULL);
- return TCL_ERROR;
- }
- if (numValues <= 2) {
- optPtr->fromX = values[0];
- optPtr->fromY = values[1];
- optPtr->fromX2 = -1;
- optPtr->fromY2 = -1;
- } else {
- optPtr->fromX = MIN(values[0], values[2]);
- optPtr->fromY = MIN(values[1], values[3]);
- optPtr->fromX2 = MAX(values[0], values[2]);
- optPtr->fromY2 = MAX(values[1], values[3]);
- }
- break;
- case OPT_SUBSAMPLE:
- optPtr->subsampleX = values[0];
- optPtr->subsampleY = values[1];
- break;
- case OPT_TO:
- if ((values[0] < 0) || (values[1] < 0) || ((numValues > 2)
- && ((values[2] < 0) || (values[3] < 0)))) {
- Tcl_AppendResult(interp, "value(s) for the -to",
- " option must be non-negative", (char *) NULL);
- return TCL_ERROR;
- }
- if (numValues <= 2) {
- optPtr->toX = values[0];
- optPtr->toY = values[1];
- optPtr->toX2 = -1;
- optPtr->toY2 = -1;
- } else {
- optPtr->toX = MIN(values[0], values[2]);
- optPtr->toY = MIN(values[1], values[3]);
- optPtr->toX2 = MAX(values[0], values[2]);
- optPtr->toY2 = MAX(values[1], values[3]);
- }
- break;
- case OPT_ZOOM:
- if ((values[0] <= 0) || (values[1] <= 0)) {
- Tcl_AppendResult(interp, "value(s) for the -zoom",
- " option must be positive", (char *) NULL);
- return TCL_ERROR;
- }
- optPtr->zoomX = values[0];
- optPtr->zoomY = values[1];
- break;
+ case OPT_FROM:
+ if ((values[0] < 0) || (values[1] < 0) || ((numValues > 2)
+ && ((values[2] < 0) || (values[3] < 0)))) {
+ Tcl_AppendResult(interp, "value(s) for the -from",
+ " option must be non-negative", NULL);
+ return TCL_ERROR;
+ }
+ if (numValues <= 2) {
+ optPtr->fromX = values[0];
+ optPtr->fromY = values[1];
+ optPtr->fromX2 = -1;
+ optPtr->fromY2 = -1;
+ } else {
+ optPtr->fromX = MIN(values[0], values[2]);
+ optPtr->fromY = MIN(values[1], values[3]);
+ optPtr->fromX2 = MAX(values[0], values[2]);
+ optPtr->fromY2 = MAX(values[1], values[3]);
+ }
+ break;
+ case OPT_SUBSAMPLE:
+ optPtr->subsampleX = values[0];
+ optPtr->subsampleY = values[1];
+ break;
+ case OPT_TO:
+ if ((values[0] < 0) || (values[1] < 0) || ((numValues > 2)
+ && ((values[2] < 0) || (values[3] < 0)))) {
+ Tcl_AppendResult(interp, "value(s) for the -to",
+ " option must be non-negative", NULL);
+ return TCL_ERROR;
+ }
+ if (numValues <= 2) {
+ optPtr->toX = values[0];
+ optPtr->toY = values[1];
+ optPtr->toX2 = -1;
+ optPtr->toY2 = -1;
+ } else {
+ optPtr->toX = MIN(values[0], values[2]);
+ optPtr->toY = MIN(values[1], values[3]);
+ optPtr->toX2 = MAX(values[0], values[2]);
+ optPtr->toY2 = MAX(values[1], values[3]);
+ }
+ break;
+ case OPT_ZOOM:
+ if ((values[0] <= 0) || (values[1] <= 0)) {
+ Tcl_AppendResult(interp, "value(s) for the -zoom",
+ " option must be positive", NULL);
+ return TCL_ERROR;
+ }
+ optPtr->zoomX = values[0];
+ optPtr->zoomY = values[1];
+ break;
}
}
@@ -1869,45 +1873,42 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv)
*
* ImgPhotoConfigureMaster --
*
- * This procedure is called when a photo image is created or
- * reconfigured. It processes configuration options and resets
- * any instances of the image.
+ * This function is called when a photo image is created or reconfigured.
+ * It processes configuration options and resets any instances of the
+ * image.
*
* Results:
- * A standard Tcl return value. If TCL_ERROR is returned then
- * an error message is left in the masterPtr->interp's result.
+ * A standard Tcl return value. If TCL_ERROR is returned then an error
+ * message is left in the masterPtr->interp's result.
*
* Side effects:
- * Existing instances of the image will be redisplayed to match
- * the new configuration options.
+ * Existing instances of the image will be redisplayed to match the new
+ * configuration options.
*
*----------------------------------------------------------------------
*/
static int
-ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags)
- Tcl_Interp *interp; /* Interpreter to use for reporting errors. */
- PhotoMaster *masterPtr; /* Pointer to data structure describing
+ImgPhotoConfigureMaster(
+ Tcl_Interp *interp, /* Interpreter to use for reporting errors. */
+ PhotoMaster *masterPtr, /* Pointer to data structure describing
* overall photo image to (re)configure. */
- int objc; /* Number of entries in objv. */
- Tcl_Obj *CONST objv[]; /* Pairs of configuration options for image. */
- int flags; /* Flags to pass to Tk_ConfigureWidget,
- * such as TK_CONFIG_ARGV_ONLY. */
+ int objc, /* Number of entries in objv. */
+ Tcl_Obj *const objv[], /* Pairs of configuration options for image. */
+ int flags) /* Flags to pass to Tk_ConfigureWidget, such
+ * as TK_CONFIG_ARGV_ONLY. */
{
PhotoInstance *instancePtr;
- CONST char *oldFileString, *oldPaletteString;
+ const char *oldFileString, *oldPaletteString;
Tcl_Obj *oldData, *data = NULL, *oldFormat, *format = NULL;
- int length, i, j;
+ Tcl_Obj *tempdata, *tempformat;
+ int length, i, j, result, imageWidth, imageHeight, oldformat;
double oldGamma;
- int result;
Tcl_Channel chan;
Tk_PhotoImageFormat *imageFormat;
- int imageWidth, imageHeight;
- CONST char **args;
- int oldformat;
- Tcl_Obj *tempdata, *tempformat;
+ const char **args;
- args = (CONST char **) ckalloc((objc + 1) * sizeof(char *));
+ args = (const char **) ckalloc((objc + 1) * sizeof(char *));
for (i = 0, j = 0; i < objc; i++,j++) {
args[j] = Tcl_GetStringFromObj(objv[i], &length);
if ((length > 1) && (args[j][0] == '-')) {
@@ -1918,7 +1919,7 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags)
j--;
} else {
Tcl_AppendResult(interp,
- "value for \"-data\" missing", (char *) NULL);
+ "value for \"-data\" missing", NULL);
return TCL_ERROR;
}
} else if ((args[j][1] == 'f') &&
@@ -1928,7 +1929,7 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags)
j--;
} else {
Tcl_AppendResult(interp,
- "value for \"-format\" missing", (char *) NULL);
+ "value for \"-format\" missing", NULL);
return TCL_ERROR;
}
}
@@ -1936,12 +1937,10 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags)
}
/*
- * Save the current values for fileString and dataString, so we
- * can tell if the user specifies them anew.
- * IMPORTANT: if the format changes we have to interpret
- * "-file" and "-data" again as well!!!!!!! It might be
- * that the format string influences how "-data" or "-file"
- * is interpreted.
+ * Save the current values for fileString and dataString, so we can tell
+ * if the user specifies them anew. IMPORTANT: if the format changes we
+ * have to interpret "-file" and "-data" again as well! It might be that
+ * the format string influences how "-data" or "-file" is interpreted.
*/
oldFileString = masterPtr->fileString;
@@ -1972,8 +1971,7 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags)
ckfree((char *) args);
/*
- * Regard the empty string for -file, -data or -format as the null
- * value.
+ * Regard the empty string for -file, -data or -format as the null value.
*/
if ((masterPtr->fileString != NULL) && (masterPtr->fileString[0] == 0)) {
@@ -1982,9 +1980,10 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags)
}
if (data) {
/*
- * Force into ByteArray format, which most (all) image handlers
- * will use anyway. Empty length means ignore the -data option.
+ * Force into ByteArray format, which most (all) image handlers will
+ * use anyway. Empty length means ignore the -data option.
*/
+
(void) Tcl_GetByteArrayFromObj(data, &length);
if (length) {
Tcl_IncrRefCount(data);
@@ -1998,9 +1997,10 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags)
}
if (format) {
/*
- * Stringify to ignore -format "". It may come in as a list or
- * other object.
+ * Stringify to ignore -format "". It may come in as a list or other
+ * object.
*/
+
(void) Tcl_GetStringFromObj(format, &length);
if (length) {
Tcl_IncrRefCount(format);
@@ -2013,47 +2013,47 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags)
masterPtr->format = format;
}
/*
- * Set the image to the user-requested size, if any,
- * and make sure storage is correctly allocated for this image.
+ * Set the image to the user-requested size, if any, and make sure storage
+ * is correctly allocated for this image.
*/
if (ImgPhotoSetSize(masterPtr, masterPtr->width,
masterPtr->height) != TCL_OK) {
Tcl_ResetResult(interp);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- TK_PHOTO_ALLOC_FAILURE_MESSAGE, (char *) NULL);
+ Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);
goto errorExit;
}
/*
- * Read in the image from the file or string if the user has
- * specified the -file or -data option.
+ * Read in the image from the file or string if the user has specified the
+ * -file or -data option.
*/
if ((masterPtr->fileString != NULL)
&& ((masterPtr->fileString != oldFileString)
|| (masterPtr->format != oldFormat))) {
- /*
- * Prevent file system access in a safe interpreter.
- */
+ /*
+ * Prevent file system access in a safe interpreter.
+ */
- if (Tcl_IsSafe(interp)) {
+ if (Tcl_IsSafe(interp)) {
Tcl_ResetResult(interp);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "can't get image from a file in a safe interpreter",
- (char *) NULL);
+ Tcl_AppendResult(interp,
+ "can't get image from a file in a safe interpreter", NULL);
goto errorExit;
- }
-
+ }
+
chan = Tcl_OpenFileChannel(interp, masterPtr->fileString, "r", 0);
if (chan == NULL) {
goto errorExit;
}
+
/*
* -translation binary also sets -encoding binary
*/
- if ((Tcl_SetChannelOption(interp, chan,
+
+ if ((Tcl_SetChannelOption(interp, chan,
"-translation", "binary") != TCL_OK) ||
(MatchFileFormat(interp, chan, masterPtr->fileString,
masterPtr->format, &imageFormat, &imageWidth,
@@ -2065,8 +2065,7 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags)
if (result != TCL_OK) {
Tcl_Close(NULL, chan);
Tcl_ResetResult(interp);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- TK_PHOTO_ALLOC_FAILURE_MESSAGE, (char *) NULL);
+ Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);
goto errorExit;
}
tempformat = masterPtr->format;
@@ -2074,9 +2073,8 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags)
tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
}
result = (*imageFormat->fileReadProc)(interp, chan,
- masterPtr->fileString, tempformat,
- (Tk_PhotoHandle) masterPtr, 0, 0,
- imageWidth, imageHeight, 0, 0);
+ masterPtr->fileString, tempformat, (Tk_PhotoHandle) masterPtr,
+ 0, 0, imageWidth, imageHeight, 0, 0);
Tcl_Close(NULL, chan);
if (result != TCL_OK) {
goto errorExit;
@@ -2097,8 +2095,7 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags)
}
if (ImgPhotoSetSize(masterPtr, imageWidth, imageHeight) != TCL_OK) {
Tcl_ResetResult(interp);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- TK_PHOTO_ALLOC_FAILURE_MESSAGE, (char *) NULL);
+ Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);
goto errorExit;
}
tempformat = masterPtr->format;
@@ -2133,9 +2130,9 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags)
}
/*
- * Cycle through all of the instances of this image, regenerating
- * the information for each instance. Then force the image to be
- * redisplayed everywhere that it is used.
+ * Cycle through all of the instances of this image, regenerating the
+ * information for each instance. Then force the image to be redisplayed
+ * everywhere that it is used.
*/
for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
@@ -2144,8 +2141,7 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags)
}
/*
- * Inform the generic image code that the image
- * has (potentially) changed.
+ * Inform the generic image code that the image has (potentially) changed.
*/
Tk_ImageChanged(masterPtr->tkMaster, 0, 0, masterPtr->width,
@@ -2178,24 +2174,24 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags)
*
* ImgPhotoConfigureInstance --
*
- * This procedure is called to create displaying information for
- * a photo image instance based on the configuration information
- * in the master. It is invoked both when new instances are
- * created and when the master is reconfigured.
+ * This function is called to create displaying information for a photo
+ * image instance based on the configuration information in the master.
+ * It is invoked both when new instances are created and when the master
+ * is reconfigured.
*
* Results:
* None.
*
* Side effects:
- * Generates errors via Tcl_BackgroundError if there are problems
- * in setting up the instance.
+ * Generates errors via Tcl_BackgroundError if there are problems in
+ * setting up the instance.
*
*----------------------------------------------------------------------
*/
static void
-ImgPhotoConfigureInstance(instancePtr)
- PhotoInstance *instancePtr; /* Instance to reconfigure. */
+ImgPhotoConfigureInstance(
+ PhotoInstance *instancePtr) /* Instance to reconfigure. */
{
PhotoMaster *masterPtr = instancePtr->masterPtr;
XImage *imagePtr;
@@ -2204,10 +2200,9 @@ ImgPhotoConfigureInstance(instancePtr)
XRectangle validBox;
/*
- * If the -palette configuration option has been set for the master,
- * use the value specified for our palette, but only if it is
- * a valid palette for our windows. Use the gamma value specified
- * the master.
+ * If the -palette configuration option has been set for the master, use
+ * the value specified for our palette, but only if it is a valid palette
+ * for our windows. Use the gamma value specified the master.
*/
if ((masterPtr->palette && masterPtr->palette[0])
@@ -2219,9 +2214,9 @@ ImgPhotoConfigureInstance(instancePtr)
instancePtr->gamma = masterPtr->gamma;
/*
- * If we don't currently have a color table, or if the one we
- * have no longer applies (e.g. because our palette or gamma
- * has changed), get a new one.
+ * If we don't currently have a color table, or if the one we have no
+ * longer applies (e.g. because our palette or gamma has changed), get a
+ * new one.
*/
colorTablePtr = instancePtr->colorTablePtr;
@@ -2240,8 +2235,8 @@ ImgPhotoConfigureInstance(instancePtr)
GetColorTable(instancePtr);
/*
- * Create a new XImage structure for sending data to
- * the X server, if necessary.
+ * Create a new XImage structure for sending data to the X server, if
+ * necessary.
*/
if (instancePtr->colorTablePtr->flags & BLACK_AND_WHITE) {
@@ -2257,7 +2252,7 @@ ImgPhotoConfigureInstance(instancePtr)
}
imagePtr = XCreateImage(instancePtr->display,
instancePtr->visualInfo.visual, (unsigned) bitsPerPixel,
- (bitsPerPixel > 1? ZPixmap: XYBitmap), 0, (char *) NULL,
+ (bitsPerPixel > 1? ZPixmap: XYBitmap), 0, NULL,
1, 1, 32, 0);
instancePtr->imagePtr = imagePtr;
@@ -2280,11 +2275,10 @@ ImgPhotoConfigureInstance(instancePtr)
}
/*
- * If the user has specified a width and/or height for the master
- * which is different from our current width/height, set the size
- * to the values specified by the user. If we have no pixmap, we
- * do this also, since it has the side effect of allocating a
- * pixmap for us.
+ * If the user has specified a width and/or height for the master which is
+ * different from our current width/height, set the size to the values
+ * specified by the user. If we have no pixmap, we do this also, since it
+ * has the side effect of allocating a pixmap for us.
*/
if ((instancePtr->pixels == None) || (instancePtr->error == NULL)
@@ -2312,62 +2306,60 @@ ImgPhotoConfigureInstance(instancePtr)
*
* ImgPhotoGet --
*
- * This procedure is called for each use of a photo image in a
- * widget.
+ * This function is called for each use of a photo image in a widget.
*
* Results:
- * The return value is a token for the instance, which is passed
- * back to us in calls to ImgPhotoDisplay and ImgPhotoFree.
+ * The return value is a token for the instance, which is passed back to
+ * us in calls to ImgPhotoDisplay and ImgPhotoFree.
*
* Side effects:
- * A data structure is set up for the instance (or, an existing
- * instance is re-used for the new one).
+ * A data structure is set up for the instance (or, an existing instance
+ * is re-used for the new one).
*
*----------------------------------------------------------------------
*/
static ClientData
-ImgPhotoGet(tkwin, masterData)
- Tk_Window tkwin; /* Window in which the instance will be
+ImgPhotoGet(
+ Tk_Window tkwin, /* Window in which the instance will be
* used. */
- ClientData masterData; /* Pointer to our master structure for the
+ ClientData masterData) /* Pointer to our master structure for the
* image. */
{
PhotoMaster *masterPtr = (PhotoMaster *) masterData;
PhotoInstance *instancePtr;
Colormap colormap;
- int mono, nRed, nGreen, nBlue;
+ int mono, nRed, nGreen, nBlue, numVisuals;
XVisualInfo visualInfo, *visInfoPtr;
char buf[TCL_INTEGER_SPACE * 3];
- int numVisuals;
XColor *white, *black;
XGCValues gcValues;
/*
- * Table of "best" choices for palette for PseudoColor displays
- * with between 3 and 15 bits/pixel.
+ * Table of "best" choices for palette for PseudoColor displays with
+ * between 3 and 15 bits/pixel.
*/
- static int paletteChoice[13][3] = {
+ static const int paletteChoice[13][3] = {
/* #red, #green, #blue */
- {2, 2, 2, /* 3 bits, 8 colors */},
- {2, 3, 2, /* 4 bits, 12 colors */},
- {3, 4, 2, /* 5 bits, 24 colors */},
- {4, 5, 3, /* 6 bits, 60 colors */},
- {5, 6, 4, /* 7 bits, 120 colors */},
- {7, 7, 4, /* 8 bits, 198 colors */},
- {8, 10, 6, /* 9 bits, 480 colors */},
- {10, 12, 8, /* 10 bits, 960 colors */},
- {14, 15, 9, /* 11 bits, 1890 colors */},
- {16, 20, 12, /* 12 bits, 3840 colors */},
- {20, 24, 16, /* 13 bits, 7680 colors */},
- {26, 30, 20, /* 14 bits, 15600 colors */},
- {32, 32, 30, /* 15 bits, 30720 colors */}
+ {2, 2, 2, /* 3 bits, 8 colors */},
+ {2, 3, 2, /* 4 bits, 12 colors */},
+ {3, 4, 2, /* 5 bits, 24 colors */},
+ {4, 5, 3, /* 6 bits, 60 colors */},
+ {5, 6, 4, /* 7 bits, 120 colors */},
+ {7, 7, 4, /* 8 bits, 198 colors */},
+ {8, 10, 6, /* 9 bits, 480 colors */},
+ {10, 12, 8, /* 10 bits, 960 colors */},
+ {14, 15, 9, /* 11 bits, 1890 colors */},
+ {16, 20, 12, /* 12 bits, 3840 colors */},
+ {20, 24, 16, /* 13 bits, 7680 colors */},
+ {26, 30, 20, /* 14 bits, 15600 colors */},
+ {32, 32, 30, /* 15 bits, 30720 colors */}
};
/*
- * See if there is already an instance for windows using
- * the same colormap. If so then just re-use it.
+ * See if there is already an instance for windows using the same
+ * colormap. If so then just re-use it.
*/
colormap = Tk_Colormap(tkwin);
@@ -2375,7 +2367,6 @@ ImgPhotoGet(tkwin, masterData)
instancePtr = instancePtr->nextPtr) {
if ((colormap == instancePtr->colormap)
&& (Tk_Display(tkwin) == instancePtr->display)) {
-
/*
* Re-use this instance.
*/
@@ -2397,8 +2388,8 @@ ImgPhotoGet(tkwin, masterData)
}
/*
- * The image isn't already in use in a window with the same colormap.
- * Make a new instance of the image.
+ * The image isn't already in use in a window with the same colormap. Make
+ * a new instance of the image.
*/
instancePtr = (PhotoInstance *) ckalloc(sizeof(PhotoInstance));
@@ -2417,53 +2408,51 @@ ImgPhotoGet(tkwin, masterData)
masterPtr->instancePtr = instancePtr;
/*
- * Obtain information about the visual and decide on the
- * default palette.
+ * Obtain information about the visual and decide on the default palette.
*/
visualInfo.screen = Tk_ScreenNumber(tkwin);
visualInfo.visualid = XVisualIDFromVisual(Tk_Visual(tkwin));
visInfoPtr = XGetVisualInfo(Tk_Display(tkwin),
VisualScreenMask | VisualIDMask, &visualInfo, &numVisuals);
+ if (visInfoPtr == NULL) {
+ Tcl_Panic("ImgPhotoGet couldn't find visual for window");
+ }
+
nRed = 2;
nGreen = nBlue = 0;
mono = 1;
- if (visInfoPtr != NULL) {
- instancePtr->visualInfo = *visInfoPtr;
- switch (visInfoPtr->class) {
- case DirectColor:
- case TrueColor:
- nRed = 1 << CountBits(visInfoPtr->red_mask);
- nGreen = 1 << CountBits(visInfoPtr->green_mask);
- nBlue = 1 << CountBits(visInfoPtr->blue_mask);
- mono = 0;
- break;
- case PseudoColor:
- case StaticColor:
- if (visInfoPtr->depth > 15) {
- nRed = 32;
- nGreen = 32;
- nBlue = 32;
- mono = 0;
- } else if (visInfoPtr->depth >= 3) {
- int *ip = paletteChoice[visInfoPtr->depth - 3];
-
- nRed = ip[0];
- nGreen = ip[1];
- nBlue = ip[2];
- mono = 0;
- }
- break;
- case GrayScale:
- case StaticGray:
- nRed = 1 << visInfoPtr->depth;
- break;
- }
- XFree((char *) visInfoPtr);
-
- } else {
- panic("ImgPhotoGet couldn't find visual for window");
- }
+ instancePtr->visualInfo = *visInfoPtr;
+ switch (visInfoPtr->class) {
+ case DirectColor:
+ case TrueColor:
+ nRed = 1 << CountBits(visInfoPtr->red_mask);
+ nGreen = 1 << CountBits(visInfoPtr->green_mask);
+ nBlue = 1 << CountBits(visInfoPtr->blue_mask);
+ mono = 0;
+ break;
+ case PseudoColor:
+ case StaticColor:
+ if (visInfoPtr->depth > 15) {
+ nRed = 32;
+ nGreen = 32;
+ nBlue = 32;
+ mono = 0;
+ } else if (visInfoPtr->depth >= 3) {
+ const int *ip = paletteChoice[visInfoPtr->depth - 3];
+
+ nRed = ip[0];
+ nGreen = ip[1];
+ nBlue = ip[2];
+ mono = 0;
+ }
+ break;
+ case GrayScale:
+ case StaticGray:
+ nRed = 1 << visInfoPtr->depth;
+ break;
+ }
+ XFree((char *) visInfoPtr);
sprintf(buf, ((mono) ? "%d": "%d/%d/%d"), nRed, nGreen, nBlue);
instancePtr->defaultPalette = Tk_GetUid(buf);
@@ -2485,8 +2474,8 @@ ImgPhotoGet(tkwin, masterData)
GCForeground|GCBackground|GCGraphicsExposures, &gcValues);
/*
- * Set configuration options and finish the initialization of the instance.
- * This will also dither the image if necessary.
+ * Set configuration options and finish the initialization of the
+ * instance. This will also dither the image if necessary.
*/
ImgPhotoConfigureInstance(instancePtr);
@@ -2508,9 +2497,9 @@ ImgPhotoGet(tkwin, masterData)
*
* ToggleComplexAlphaIfNeeded --
*
- * This procedure is called when an image is modified to
- * check if any partially transparent pixels exist, which
- * requires blending instead of straight copy.
+ * This function is called when an image is modified to check if any
+ * partially transparent pixels exist, which requires blending instead of
+ * straight copy.
*
* Results:
* None.
@@ -2522,19 +2511,21 @@ ImgPhotoGet(tkwin, masterData)
*/
static int
-ToggleComplexAlphaIfNeeded(PhotoMaster *mPtr)
+ToggleComplexAlphaIfNeeded(
+ PhotoMaster *mPtr)
{
size_t len = MAX(mPtr->userWidth, mPtr->width) *
- MAX(mPtr->userHeight, mPtr->height) * 4;
- unsigned char *c = mPtr->pix32;
+ MAX(mPtr->userHeight, mPtr->height) * 4;
+ unsigned char *c = mPtr->pix32;
unsigned char *end = c + len;
/*
* Set the COMPLEX_ALPHA flag if we have an image with partially
* transparent bits.
*/
+
mPtr->flags &= ~COMPLEX_ALPHA;
- c += 3; /* start at first alpha byte */
+ c += 3; /* Start at first alpha byte. */
for (; c < end; c += 4) {
if (*c && *c != 255) {
mPtr->flags |= COMPLEX_ALPHA;
@@ -2549,8 +2540,13 @@ ToggleComplexAlphaIfNeeded(PhotoMaster *mPtr)
*
* ImgPhotoBlendComplexAlpha --
*
- * This procedure is called when an image with partially
- * transparent pixels must be drawn over another image.
+ * This function is called when an image with partially transparent
+ * pixels must be drawn over another image. It blends the photo data onto
+ * a local copy of the surface that we are drawing on, *including* the
+ * pixels drawn by everything that should be drawn underneath the image.
+ *
+ * Much of this code has hard-coded values in for speed because this
+ * routine is performance critical for complex image drawing.
*
* Results:
* None.
@@ -2558,53 +2554,61 @@ ToggleComplexAlphaIfNeeded(PhotoMaster *mPtr)
* Side effects:
* Background image passed in gets drawn over with image data.
*
- *----------------------------------------------------------------------
- */
-
-/*
- * This should work on all platforms that set mask and shift data properly
- * from the visualInfo.
- * RGB is really only a 24+ bpp version whereas RGB15 is the correct version
- * and works for 15bpp+, but it slower, so it's only used for 15bpp+.
+ * Notes:
+ * This should work on all platforms that set mask and shift data
+ * properly from the visualInfo. RGB is really only a 24+ bpp version
+ * whereas RGB15 is the correct version and works for 15bpp+, but it
+ * slower, so it's only used for 15bpp+.
+ *
+ * Note that Win32 pre-defines those operations that we really need.
*
- * Note that Win32 pre-defines those operations that we really need.
+ *----------------------------------------------------------------------
*/
#ifndef __WIN32__
-#define GetRValue(rgb) (UCHAR((rgb & red_mask) >> red_shift))
-#define GetGValue(rgb) (UCHAR((rgb & green_mask) >> green_shift))
-#define GetBValue(rgb) (UCHAR((rgb & blue_mask) >> blue_shift))
-#define RGB(r,g,b) ((unsigned)((UCHAR(r)<<red_shift)|(UCHAR(g)<<green_shift)|(UCHAR(b)<<blue_shift)))
-#define RGB15(r,g,b) ((unsigned)(((r*red_mask/255)&red_mask)|((g*green_mask/255)&green_mask)|((b*blue_mask/255)&blue_mask)))
+#define GetRValue(rgb) (UCHAR(((rgb) & red_mask) >> red_shift))
+#define GetGValue(rgb) (UCHAR(((rgb) & green_mask) >> green_shift))
+#define GetBValue(rgb) (UCHAR(((rgb) & blue_mask) >> blue_shift))
+#define RGB(r, g, b) ((unsigned)( \
+ (UCHAR(r) << red_shift) | \
+ (UCHAR(g) << green_shift) | \
+ (UCHAR(b) << blue_shift) ))
+#define RGB15(r, g, b) ((unsigned)( \
+ (((r) * red_mask / 255) & red_mask) | \
+ (((g) * green_mask / 255) & green_mask) | \
+ (((b) * blue_mask / 255) & blue_mask) ))
#endif /* !__WIN32__ */
static void
-ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height)
- XImage *bgImg; /* background image to draw on */
- PhotoInstance *iPtr; /* image instance to draw */
- int xOffset, yOffset; /* X & Y offset into image instance to draw */
- int width, height; /* width & height of image to draw */
+ImgPhotoBlendComplexAlpha(
+ XImage *bgImg, /* Background image to draw on. */
+ PhotoInstance *iPtr, /* Image instance to draw. */
+ int xOffset, int yOffset, /* X & Y offset into image instance to
+ * draw. */
+ int width, int height) /* Width & height of image to draw. */
{
int x, y, line;
unsigned long pixel;
- unsigned char r, g, b, alpha, unalpha;
+ unsigned char r, g, b, alpha, unalpha, *masterPtr;
unsigned char *alphaAr = iPtr->masterPtr->pix32;
- unsigned char *masterPtr;
/*
- * This blending is an integer version of the Source-Over
- * compositing rule (see Porter&Duff, "Compositing Digital
- * Images", proceedings of SIGGRAPH 1984) that has been hard-coded
- * (for speed) to work with targetting a solid surface.
+ * This blending is an integer version of the Source-Over compositing rule
+ * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH
+ * 1984) that has been hard-coded (for speed) to work with targetting a
+ * solid surface.
+ *
+ * The 'unalpha' field must be 255-alpha; it is separated out to encourage
+ * more efficient compilation.
*/
#define ALPHA_BLEND(bgPix, imgPix, alpha, unalpha) \
((bgPix * unalpha + imgPix * alpha) / 255)
/*
- * We have to get the mask and shift info from the visual on
- * non-Win32 so that the macros Get*Value(), RGB() and RGB15()
- * work correctly. This might be cached for better performance.
+ * We have to get the mask and shift info from the visual on non-Win32 so
+ * that the macros Get*Value(), RGB() and RGB15() work correctly. This
+ * might be cached for better performance.
*/
#ifndef __WIN32__
@@ -2630,9 +2634,9 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height)
#endif /* !__WIN32__ */
/*
- * Only unix requires the special case for <24bpp. It varies with
- * 3 extra shifts and uses RGB15. The 24+bpp version could also
- * then be further optimized.
+ * Only UNIX requires the special case for <24bpp. It varies with 3 extra
+ * shifts and uses RGB15. The 24+bpp version could also then be further
+ * optimized.
*/
#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
@@ -2647,14 +2651,17 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height)
for (x = 0; x < width; x++) {
masterPtr = alphaAr + ((line + x + xOffset) * 4);
alpha = masterPtr[3];
+
/*
* Ignore pixels that are fully transparent
*/
+
if (alpha) {
/*
* We could perhaps be more efficient than XGetPixel for
* 24 and 32 bit displays, but this seems "fast enough".
*/
+
r = masterPtr[0];
g = masterPtr[1];
b = masterPtr[2];
@@ -2662,13 +2669,14 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height)
/*
* Only blend pixels that have some transparency
*/
+
unsigned char ra, ga, ba;
pixel = XGetPixel(bgImg, x, y);
ra = GetRValue(pixel) << red_mlen;
ga = GetGValue(pixel) << green_mlen;
ba = GetBValue(pixel) << blue_mlen;
- unalpha = 255 - alpha;
+ unalpha = 255 - alpha; /* Calculate once. */
r = ALPHA_BLEND(ra, r, alpha, unalpha);
g = ALPHA_BLEND(ga, g, alpha, unalpha);
b = ALPHA_BLEND(ba, b, alpha, unalpha);
@@ -2686,14 +2694,17 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height)
for (x = 0; x < width; x++) {
masterPtr = alphaAr + ((line + x + xOffset) * 4);
alpha = masterPtr[3];
+
/*
* Ignore pixels that are fully transparent
*/
+
if (alpha) {
/*
- * We could perhaps be more efficient than XGetPixel for
- * 24 and 32 bit displays, but this seems "fast enough".
+ * We could perhaps be more efficient than XGetPixel for 24
+ * and 32 bit displays, but this seems "fast enough".
*/
+
r = masterPtr[0];
g = masterPtr[1];
b = masterPtr[2];
@@ -2701,13 +2712,14 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height)
/*
* Only blend pixels that have some transparency
*/
+
unsigned char ra, ga, ba;
pixel = XGetPixel(bgImg, x, y);
ra = GetRValue(pixel);
ga = GetGValue(pixel);
ba = GetBValue(pixel);
- unalpha = 255 - alpha;
+ unalpha = 255 - alpha; /* Calculate once. */
r = ALPHA_BLEND(ra, r, alpha, unalpha);
g = ALPHA_BLEND(ga, g, alpha, unalpha);
b = ALPHA_BLEND(ba, b, alpha, unalpha);
@@ -2716,7 +2728,6 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height)
}
}
}
-
#undef ALPHA_BLEND
}
@@ -2725,7 +2736,7 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height)
*
* ImgPhotoDisplay --
*
- * This procedure is invoked to draw a photo image.
+ * This function is invoked to draw a photo image.
*
* Results:
* None.
@@ -2737,39 +2748,30 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height)
*/
static void
-ImgPhotoDisplay(clientData, display, drawable, imageX, imageY, width,
- height, drawableX, drawableY)
- ClientData clientData; /* Pointer to PhotoInstance structure for
- * for instance to be displayed. */
- Display *display; /* Display on which to draw image. */
- Drawable drawable; /* Pixmap or window in which to draw image. */
- int imageX, imageY; /* Upper-left corner of region within image
- * to draw. */
- int width, height; /* Dimensions of region within image to draw. */
- int drawableX, drawableY; /* Coordinates within drawable that
- * correspond to imageX and imageY. */
+ImgPhotoDisplay(
+ ClientData clientData, /* Pointer to PhotoInstance structure for
+ * instance to be displayed. */
+ Display *display, /* Display on which to draw image. */
+ Drawable drawable, /* Pixmap or window in which to draw image. */
+ int imageX, int imageY, /* Upper-left corner of region within image to
+ * draw. */
+ int width, int height, /* Dimensions of region within image to
+ * draw. */
+ int drawableX,int drawableY)/* Coordinates within drawable that correspond
+ * to imageX and imageY. */
{
PhotoInstance *instancePtr = (PhotoInstance *) clientData;
XVisualInfo visInfo = instancePtr->visualInfo;
/*
- * If there's no pixmap, it means that an error occurred
- * while creating the image instance so it can't be displayed.
+ * If there's no pixmap, it means that an error occurred while creating
+ * the image instance so it can't be displayed.
*/
if (instancePtr->pixels == None) {
return;
}
- /*
- * Check for bogus widths/heights. This prevents us from calling
- * XGetImage with a zero size, which it does not like. [Bug 979239]
- */
-
- if (width < 1 || height < 1) {
- return;
- }
-
if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA)
&& visInfo.depth >= 15
&& (visInfo.class == DirectColor || visInfo.class == TrueColor)) {
@@ -2780,25 +2782,30 @@ ImgPhotoDisplay(clientData, display, drawable, imageX, imageY, width,
* Create an error handler to suppress the case where the input was
* not properly constrained, which can cause an X error. [Bug 979239]
*/
- handler = Tk_CreateErrorHandler(display, -1, -1, -1,
- (Tk_ErrorProc *) NULL, (ClientData) NULL);
+
+ handler = Tk_CreateErrorHandler(display, -1, -1, -1, NULL,
+ (ClientData) NULL);
+
/*
* Pull the current background from the display to blend with
*/
+
bgImg = XGetImage(display, drawable, drawableX, drawableY,
(unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap);
if (bgImg == NULL) {
Tk_DeleteErrorHandler(handler);
- return;
+ /* We failed to get the image so draw without blending alpha. It's the best we can do */
+ goto fallBack;
}
- ImgPhotoBlendComplexAlpha(bgImg, instancePtr,
- imageX, imageY, width, height);
+ ImgPhotoBlendComplexAlpha(bgImg, instancePtr, imageX, imageY, width,
+ height);
/*
- * Color info is unimportant as we only do this operation for
- * depth >= 15.
+ * Color info is unimportant as we only do this operation for depth >=
+ * 15.
*/
+
TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
bgImg, 0, 0, drawableX, drawableY,
(unsigned int) width, (unsigned int) height);
@@ -2806,21 +2813,23 @@ ImgPhotoDisplay(clientData, display, drawable, imageX, imageY, width,
Tk_DeleteErrorHandler(handler);
} else {
/*
- * masterPtr->region describes which parts of the image contain
- * valid data. We set this region as the clip mask for the gc,
- * setting its origin appropriately, and use it when drawing the
- * image.
+ * masterPtr->region describes which parts of the image contain valid
+ * data. We set this region as the clip mask for the gc, setting its
+ * origin appropriately, and use it when drawing the image.
*/
- TkSetRegion(display, instancePtr->gc, instancePtr->masterPtr->validRegion);
+
+ fallBack:
+ TkSetRegion(display, instancePtr->gc,
+ instancePtr->masterPtr->validRegion);
XSetClipOrigin(display, instancePtr->gc, drawableX - imageX,
- drawableY - imageY);
+ drawableY - imageY);
XCopyArea(display, instancePtr->pixels, drawable, instancePtr->gc,
- imageX, imageY, (unsigned) width, (unsigned) height,
- drawableX, drawableY);
+ imageX, imageY, (unsigned) width, (unsigned) height,
+ drawableX, drawableY);
XSetClipMask(display, instancePtr->gc, None);
XSetClipOrigin(display, instancePtr->gc, 0, 0);
}
- XFlush (display);
+ XFlush(display);
}
/*
@@ -2828,10 +2837,9 @@ ImgPhotoDisplay(clientData, display, drawable, imageX, imageY, width,
*
* ImgPhotoFree --
*
- * This procedure is called when a widget ceases to use a
- * particular instance of an image. We don't actually get
- * rid of the instance until later because we may be about
- * to get this instance again.
+ * This function is called when a widget ceases to use a particular
+ * instance of an image. We don't actually get rid of the instance until
+ * later because we may be about to get this instance again.
*
* Results:
* None.
@@ -2843,10 +2851,11 @@ ImgPhotoDisplay(clientData, display, drawable, imageX, imageY, width,
*/
static void
-ImgPhotoFree(clientData, display)
- ClientData clientData; /* Pointer to PhotoInstance structure for
- * for instance to be displayed. */
- Display *display; /* Display containing window that used image. */
+ImgPhotoFree(
+ ClientData clientData, /* Pointer to PhotoInstance structure for
+ * instance to be displayed. */
+ Display *display) /* Display containing window that used
+ * image. */
{
PhotoInstance *instancePtr = (PhotoInstance *) clientData;
ColorTable *colorPtr;
@@ -2857,17 +2866,17 @@ ImgPhotoFree(clientData, display)
}
/*
- * There are no more uses of the image within this widget.
- * Decrement the count of live uses of its color table, so
- * that its colors can be reclaimed if necessary, and
- * set up an idle call to free the instance structure.
+ * There are no more uses of the image within this widget. Decrement the
+ * count of live uses of its color table, so that its colors can be
+ * reclaimed if necessary, and set up an idle call to free the instance
+ * structure.
*/
colorPtr = instancePtr->colorTablePtr;
if (colorPtr != NULL) {
colorPtr->liveRefCount -= 1;
}
-
+
Tcl_DoWhenIdle(DisposeInstance, (ClientData) instancePtr);
}
@@ -2876,8 +2885,8 @@ ImgPhotoFree(clientData, display)
*
* ImgPhotoDelete --
*
- * This procedure is called by the image code to delete the
- * master structure for an image.
+ * This function is called by the image code to delete the master
+ * structure for an image.
*
* Results:
* None.
@@ -2889,16 +2898,16 @@ ImgPhotoFree(clientData, display)
*/
static void
-ImgPhotoDelete(masterData)
- ClientData masterData; /* Pointer to PhotoMaster structure for
- * image. Must not have any more instances. */
+ImgPhotoDelete(
+ ClientData masterData) /* Pointer to PhotoMaster structure for image.
+ * Must not have any more instances. */
{
PhotoMaster *masterPtr = (PhotoMaster *) masterData;
PhotoInstance *instancePtr;
while ((instancePtr = masterPtr->instancePtr) != NULL) {
if (instancePtr->refCount > 0) {
- panic("tried to delete photo image when instances still exist");
+ Tcl_Panic("tried to delete photo image when instances still exist");
}
Tcl_CancelIdleCall(DisposeInstance, (ClientData) instancePtr);
DisposeInstance((ClientData) instancePtr);
@@ -2919,7 +2928,7 @@ ImgPhotoDelete(masterData)
if (masterPtr->format != NULL) {
Tcl_DecrRefCount(masterPtr->format);
}
- Tk_FreeOptions(configSpecs, (char *) masterPtr, (Display *) NULL, 0);
+ Tk_FreeOptions(configSpecs, (char *) masterPtr, NULL, 0);
ckfree((char *) masterPtr);
}
@@ -2928,8 +2937,8 @@ ImgPhotoDelete(masterData)
*
* ImgPhotoCmdDeletedProc --
*
- * This procedure is invoked when the image command for an image
- * is deleted. It deletes the image.
+ * This function is invoked when the image command for an image is
+ * deleted. It deletes the image.
*
* Results:
* None.
@@ -2941,8 +2950,8 @@ ImgPhotoDelete(masterData)
*/
static void
-ImgPhotoCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to PhotoMaster structure for
+ImgPhotoCmdDeletedProc(
+ ClientData clientData) /* Pointer to PhotoMaster structure for
* image. */
{
PhotoMaster *masterPtr = (PhotoMaster *) clientData;
@@ -2958,13 +2967,13 @@ ImgPhotoCmdDeletedProc(clientData)
*
* ImgPhotoSetSize --
*
- * This procedure reallocates the image storage and instance
- * pixmaps for a photo image, as necessary, to change the
- * image's size to `width' x `height' pixels.
+ * This function reallocates the image storage and instance pixmaps for a
+ * photo image, as necessary, to change the image's size to `width' x
+ * `height' pixels.
*
* Results:
- * TCL_OK if successful, TCL_ERROR if failure occurred (currently
- * just with memory allocation.)
+ * TCL_OK if successful, TCL_ERROR if failure occurred (currently just
+ * with memory allocation.)
*
* Side effects:
* Storage gets reallocated, for the master and all its instances.
@@ -2973,9 +2982,9 @@ ImgPhotoCmdDeletedProc(clientData)
*/
static int
-ImgPhotoSetSize(masterPtr, width, height)
- PhotoMaster *masterPtr;
- int width, height;
+ImgPhotoSetSize(
+ PhotoMaster *masterPtr,
+ int width, int height)
{
unsigned char *newPix32 = NULL;
int h, offset, pitch;
@@ -2994,19 +3003,22 @@ ImgPhotoSetSize(masterPtr, width, height)
pitch = width * 4;
/*
- * Test if we're going to (re)allocate the main buffer now, so
- * that any failures will leave the photo unchanged.
+ * Test if we're going to (re)allocate the main buffer now, so that any
+ * failures will leave the photo unchanged.
*/
+
if ((width != masterPtr->width) || (height != masterPtr->height)
|| (masterPtr->pix32 == NULL)) {
/*
* Not a u-long, but should be one.
*/
+
unsigned /*long*/ newPixSize = (unsigned /*long*/) (height * pitch);
/*
* Some mallocs() really hate allocating zero bytes. [Bug 619544]
*/
+
if (newPixSize == 0) {
newPix32 = NULL;
} else {
@@ -3018,8 +3030,8 @@ ImgPhotoSetSize(masterPtr, width, height)
}
/*
- * We have to trim the valid region if it is currently
- * larger than the new image size.
+ * We have to trim the valid region if it is currently larger than the new
+ * image size.
*/
TkClipBox(masterPtr->validRegion, &validBox);
@@ -3038,36 +3050,35 @@ ImgPhotoSetSize(masterPtr, width, height)
}
/*
- * Use the reallocated storage (allocation above) for the 32-bit
- * image and copy over valid regions. Note that this test is true
- * precisely when the allocation has already been done.
+ * Use the reallocated storage (allocation above) for the 32-bit image and
+ * copy over valid regions. Note that this test is true precisely when the
+ * allocation has already been done.
*/
+
if (newPix32 != NULL) {
/*
- * Zero the new array. The dithering code shouldn't read the
- * areas outside validBox, but they might be copied to another
- * photo image or written to a file.
+ * Zero the new array. The dithering code shouldn't read the areas
+ * outside validBox, but they might be copied to another photo image
+ * or written to a file.
*/
if ((masterPtr->pix32 != NULL)
&& ((width == masterPtr->width) || (width == validBox.width))) {
if (validBox.y > 0) {
- memset((VOID *) newPix32, 0, (size_t) (validBox.y * pitch));
+ memset(newPix32, 0, (size_t) (validBox.y * pitch));
}
h = validBox.y + validBox.height;
if (h < height) {
- memset((VOID *) (newPix32 + h * pitch), 0,
- (size_t) ((height - h) * pitch));
+ memset(newPix32 + h*pitch, 0, (size_t) ((height - h) * pitch));
}
} else {
- memset((VOID *) newPix32, 0, (size_t) (height * pitch));
+ memset(newPix32, 0, (size_t) (height * pitch));
}
if (masterPtr->pix32 != NULL) {
-
/*
- * Copy the common area over to the new array array and
- * free the old array.
+ * Copy the common area over to the new array array and free the
+ * old array.
*/
if (width == masterPtr->width) {
@@ -3077,12 +3088,10 @@ ImgPhotoSetSize(masterPtr, width, height)
*/
offset = validBox.y * pitch;
- memcpy((VOID *) (newPix32 + offset),
- (VOID *) (masterPtr->pix32 + offset),
+ memcpy(newPix32 + offset, masterPtr->pix32 + offset,
(size_t) (validBox.height * pitch));
} else if ((validBox.width > 0) && (validBox.height > 0)) {
-
/*
* Area to be copied is not contiguous - copy line by line.
*/
@@ -3091,8 +3100,7 @@ ImgPhotoSetSize(masterPtr, width, height)
srcPtr = masterPtr->pix32 + (validBox.y * masterPtr->width
+ validBox.x) * 4;
for (h = validBox.height; h > 0; h--) {
- memcpy((VOID *) destPtr, (VOID *) srcPtr,
- (size_t) (validBox.width * 4));
+ memcpy(destPtr, srcPtr, (size_t) (validBox.width * 4));
destPtr += width * 4;
srcPtr += masterPtr->width * 4;
}
@@ -3106,8 +3114,8 @@ ImgPhotoSetSize(masterPtr, width, height)
masterPtr->height = height;
/*
- * Dithering will be correct up to the end of the last
- * pre-existing complete scanline.
+ * Dithering will be correct up to the end of the last pre-existing
+ * complete scanline.
*/
if ((validBox.x > 0) || (validBox.y > 0)) {
@@ -3144,9 +3152,9 @@ ImgPhotoSetSize(masterPtr, width, height)
*
* ImgPhotoInstanceSetSize --
*
- * This procedure reallocates the instance pixmap and dithering
- * error array for a photo instance, as necessary, to change the
- * image's size to `width' x `height' pixels.
+ * This function reallocates the instance pixmap and dithering error
+ * array for a photo instance, as necessary, to change the image's size
+ * to `width' x `height' pixels.
*
* Results:
* None.
@@ -3158,13 +3166,11 @@ ImgPhotoSetSize(masterPtr, width, height)
*/
static void
-ImgPhotoInstanceSetSize(instancePtr)
- PhotoInstance *instancePtr; /* Instance whose size is to be
- * changed. */
+ImgPhotoInstanceSetSize(
+ PhotoInstance *instancePtr) /* Instance whose size is to be changed. */
{
PhotoMaster *masterPtr;
- schar *newError;
- schar *errSrcPtr, *errDestPtr;
+ schar *newError, *errSrcPtr, *errDestPtr;
int h, offset;
XRectangle validBox;
Pixmap newPixmap;
@@ -3177,22 +3183,21 @@ ImgPhotoInstanceSetSize(instancePtr)
|| (instancePtr->pixels == None)) {
newPixmap = Tk_GetPixmap(instancePtr->display,
RootWindow(instancePtr->display,
- instancePtr->visualInfo.screen),
+ instancePtr->visualInfo.screen),
(masterPtr->width > 0) ? masterPtr->width: 1,
(masterPtr->height > 0) ? masterPtr->height: 1,
instancePtr->visualInfo.depth);
- if (!newPixmap) {
- panic("Fail to create pixmap with Tk_GetPixmap in ImgPhotoInstanceSetSize.\n");
- return;
- }
+ if (!newPixmap) {
+ Tcl_Panic("Fail to create pixmap with Tk_GetPixmap in ImgPhotoInstanceSetSize.\n");
+ }
/*
* The following is a gross hack needed to properly support colormaps
- * under Windows. Before the pixels can be copied to the pixmap,
- * the relevent colormap must be associated with the drawable.
- * Normally we can infer this association from the window that
- * was used to create the pixmap. However, in this case we're
- * using the root window, so we have to be more explicit.
+ * under Windows. Before the pixels can be copied to the pixmap, the
+ * relevent colormap must be associated with the drawable. Normally we
+ * can infer this association from the window that was used to create
+ * the pixmap. However, in this case we're using the root window, so
+ * we have to be more explicit.
*/
TkSetPixmapColormap(newPixmap, instancePtr->colormap);
@@ -3201,6 +3206,7 @@ ImgPhotoInstanceSetSize(instancePtr)
/*
* Copy any common pixels from the old pixmap and free it.
*/
+
XCopyArea(instancePtr->display, instancePtr->pixels, newPixmap,
instancePtr->gc, validBox.x, validBox.y,
validBox.width, validBox.height, validBox.x, validBox.y);
@@ -3218,54 +3224,51 @@ ImgPhotoInstanceSetSize(instancePtr)
masterPtr->height * masterPtr->width * 3 * sizeof(schar));
/*
- * Zero the new array so that we don't get bogus error
- * values propagating into areas we dither later.
+ * Zero the new array so that we don't get bogus error values
+ * propagating into areas we dither later.
*/
if ((instancePtr->error != NULL)
&& ((instancePtr->width == masterPtr->width)
|| (validBox.width == masterPtr->width))) {
if (validBox.y > 0) {
- memset((VOID *) newError, 0, (size_t)
+ memset(newError, 0, (size_t)
validBox.y * masterPtr->width * 3 * sizeof(schar));
}
h = validBox.y + validBox.height;
if (h < masterPtr->height) {
- memset((VOID *) (newError + h * masterPtr->width * 3), 0,
+ memset(newError + h*masterPtr->width*3, 0,
(size_t) (masterPtr->height - h)
* masterPtr->width * 3 * sizeof(schar));
}
} else {
- memset((VOID *) newError, 0, (size_t)
- masterPtr->height * masterPtr->width * 3 * sizeof(schar));
+ memset(newError, 0, (size_t)
+ masterPtr->height * masterPtr->width *3*sizeof(schar));
}
} else {
newError = NULL;
}
if (instancePtr->error != NULL) {
-
/*
- * Copy the common area over to the new array
- * and free the old array.
+ * Copy the common area over to the new array and free the old
+ * array.
*/
if (masterPtr->width == instancePtr->width) {
-
offset = validBox.y * masterPtr->width * 3;
- memcpy((VOID *) (newError + offset),
- (VOID *) (instancePtr->error + offset),
+ memcpy(newError + offset, instancePtr->error + offset,
(size_t) (validBox.height
* masterPtr->width * 3 * sizeof(schar)));
} else if (validBox.width > 0 && validBox.height > 0) {
+ errDestPtr = newError +
+ (validBox.y * masterPtr->width + validBox.x) * 3;
+ errSrcPtr = instancePtr->error +
+ (validBox.y * instancePtr->width + validBox.x) * 3;
- errDestPtr = newError
- + (validBox.y * masterPtr->width + validBox.x) * 3;
- errSrcPtr = instancePtr->error
- + (validBox.y * instancePtr->width + validBox.x) * 3;
for (h = validBox.height; h > 0; --h) {
- memcpy((VOID *) errDestPtr, (VOID *) errSrcPtr,
+ memcpy(errDestPtr, errSrcPtr,
validBox.width * 3 * sizeof(schar));
errDestPtr += masterPtr->width * 3;
errSrcPtr += instancePtr->width * 3;
@@ -3286,9 +3289,8 @@ ImgPhotoInstanceSetSize(instancePtr)
*
* IsValidPalette --
*
- * This procedure is called to check whether a value given for
- * the -palette option is valid for a particular instance
- * of a photo image.
+ * This function is called to check whether a value given for the
+ * -palette option is valid for a particular instance of a photo image.
*
* Results:
* A boolean value: 1 if the palette is acceptable, 0 otherwise.
@@ -3300,17 +3302,16 @@ ImgPhotoInstanceSetSize(instancePtr)
*/
static int
-IsValidPalette(instancePtr, palette)
- PhotoInstance *instancePtr; /* Instance to which the palette
- * specification is to be applied. */
- CONST char *palette; /* Palette specification string. */
+IsValidPalette(
+ PhotoInstance *instancePtr, /* Instance to which the palette specification
+ * is to be applied. */
+ const char *palette) /* Palette specification string. */
{
int nRed, nGreen, nBlue, mono, numColors;
char *endp;
/*
- * First parse the specification: it must be of the form
- * %d or %d/%d/%d.
+ * First parse the specification: it must be of the form %d or %d/%d/%d.
*/
nRed = strtol(palette, &endp, 10);
@@ -3339,32 +3340,30 @@ IsValidPalette(instancePtr, palette)
}
switch (instancePtr->visualInfo.class) {
- case DirectColor:
- case TrueColor:
- if ((nRed > (1 << CountBits(instancePtr->visualInfo.red_mask)))
- || (nGreen > (1
- << CountBits(instancePtr->visualInfo.green_mask)))
- || (nBlue > (1
- << CountBits(instancePtr->visualInfo.blue_mask)))) {
- return 0;
- }
- break;
- case PseudoColor:
- case StaticColor:
- numColors = nRed;
- if (!mono) {
- numColors *= nGreen*nBlue;
- }
- if (numColors > (1 << instancePtr->visualInfo.depth)) {
- return 0;
- }
- break;
- case GrayScale:
- case StaticGray:
- if (!mono || (nRed > (1 << instancePtr->visualInfo.depth))) {
- return 0;
- }
- break;
+ case DirectColor:
+ case TrueColor:
+ if ((nRed > (1 << CountBits(instancePtr->visualInfo.red_mask)))
+ || (nGreen>(1<<CountBits(instancePtr->visualInfo.green_mask)))
+ || (nBlue>(1<<CountBits(instancePtr->visualInfo.blue_mask)))) {
+ return 0;
+ }
+ break;
+ case PseudoColor:
+ case StaticColor:
+ numColors = nRed;
+ if (!mono) {
+ numColors *= nGreen*nBlue;
+ }
+ if (numColors > (1 << instancePtr->visualInfo.depth)) {
+ return 0;
+ }
+ break;
+ case GrayScale:
+ case StaticGray:
+ if (!mono || (nRed > (1 << instancePtr->visualInfo.depth))) {
+ return 0;
+ }
+ break;
}
return 1;
@@ -3375,7 +3374,7 @@ IsValidPalette(instancePtr, palette)
*
* CountBits --
*
- * This procedure counts how many bits are set to 1 in `mask'.
+ * This function counts how many bits are set to 1 in `mask'.
*
* Results:
* The integer number of bits.
@@ -3387,13 +3386,14 @@ IsValidPalette(instancePtr, palette)
*/
static int
-CountBits(mask)
- pixel mask; /* Value to count the 1 bits in. */
+CountBits(
+ pixel mask) /* Value to count the 1 bits in. */
{
int n;
- for( n = 0; mask != 0; mask &= mask - 1 )
+ for (n=0 ; mask!=0 ; mask&=mask-1) {
n++;
+ }
return n;
}
@@ -3402,28 +3402,27 @@ CountBits(mask)
*
* GetColorTable --
*
- * This procedure is called to allocate a table of colormap
- * information for an instance of a photo image. Only one such
- * table is allocated for all photo instances using the same
- * display, colormap, palette and gamma values, so that the
- * application need only request a set of colors from the X
- * server once for all such photo widgets. This procedure
- * maintains a hash table to find previously-allocated
+ * This function is called to allocate a table of colormap information
+ * for an instance of a photo image. Only one such table is allocated for
+ * all photo instances using the same display, colormap, palette and
+ * gamma values, so that the application need only request a set of
+ * colors from the X server once for all such photo widgets. This
+ * function maintains a hash table to find previously-allocated
* ColorTables.
*
* Results:
* None.
*
* Side effects:
- * A new ColorTable may be allocated and placed in the hash
- * table, and have colors allocated for it.
+ * A new ColorTable may be allocated and placed in the hash table, and
+ * have colors allocated for it.
*
*----------------------------------------------------------------------
*/
static void
-GetColorTable(instancePtr)
- PhotoInstance *instancePtr; /* Instance needing a color table. */
+GetColorTable(
+ PhotoInstance *instancePtr) /* Instance needing a color table. */
{
ColorTable *colorPtr;
Tcl_HashEntry *entry;
@@ -3434,7 +3433,7 @@ GetColorTable(instancePtr)
* Look for an existing ColorTable in the hash table.
*/
- memset((VOID *) &id, 0, sizeof(id));
+ memset(&id, 0, sizeof(id));
id.display = instancePtr->display;
id.colormap = instancePtr->colormap;
id.palette = instancePtr->palette;
@@ -3451,7 +3450,6 @@ GetColorTable(instancePtr)
*/
colorPtr = (ColorTable *) Tcl_GetHashValue(entry);
-
} else {
/*
* No color table currently available; need to make one.
@@ -3460,16 +3458,15 @@ GetColorTable(instancePtr)
colorPtr = (ColorTable *) ckalloc(sizeof(ColorTable));
/*
- * The following line of code should not normally be needed due
- * to the assignment in the following line. However, it compensates
- * for bugs in some compilers (HP, for example) where
- * sizeof(ColorTable) is 24 but the assignment only copies 20 bytes,
- * leaving 4 bytes uninitialized; these cause problems when using
- * the id for lookups in imgPhotoColorHash, and can result in
- * core dumps.
+ * The following line of code should not normally be needed due to the
+ * assignment in the following line. However, it compensates for bugs
+ * in some compilers (HP, for example) where sizeof(ColorTable) is 24
+ * but the assignment only copies 20 bytes, leaving 4 bytes
+ * uninitialized; these cause problems when using the id for lookups
+ * in imgPhotoColorHash, and can result in core dumps.
*/
- memset((VOID *) &colorPtr->id, 0, sizeof(ColorTableId));
+ memset(&colorPtr->id, 0, sizeof(ColorTableId));
colorPtr->id = id;
Tk_PreserveColormap(colorPtr->id.display, colorPtr->id.colormap);
colorPtr->flags = 0;
@@ -3504,30 +3501,30 @@ GetColorTable(instancePtr)
*
* FreeColorTable --
*
- * This procedure is called when an instance ceases using a
- * color table.
+ * This function is called when an instance ceases using a color table.
*
* Results:
* None.
*
* Side effects:
- * If no other instances are using this color table, a when-idle
- * handler is registered to free up the color table and the colors
- * allocated for it.
+ * If no other instances are using this color table, a when-idle handler
+ * is registered to free up the color table and the colors allocated for
+ * it.
*
*----------------------------------------------------------------------
*/
static void
-FreeColorTable(colorPtr, force)
- ColorTable *colorPtr; /* Pointer to the color table which is
- * no longer required by an instance. */
- int force; /* Force free to happen immediately. */
+FreeColorTable(
+ ColorTable *colorPtr, /* Pointer to the color table which is no
+ * longer required by an instance. */
+ int force) /* Force free to happen immediately. */
{
colorPtr->refCount--;
if (colorPtr->refCount > 0) {
return;
}
+
if (force) {
if ((colorPtr->flags & DISPOSE_PENDING) != 0) {
Tcl_CancelIdleCall(DisposeColorTable, (ClientData) colorPtr);
@@ -3545,24 +3542,24 @@ FreeColorTable(colorPtr, force)
*
* AllocateColors --
*
- * This procedure allocates the colors required by a color table,
- * and sets up the fields in the color table data structure which
- * are used in dithering.
+ * This function allocates the colors required by a color table, and sets
+ * up the fields in the color table data structure which are used in
+ * dithering.
*
* Results:
* None.
*
* Side effects:
- * Colors are allocated from the X server. Fields in the
- * color table data structure are updated.
+ * Colors are allocated from the X server. Fields in the color table data
+ * structure are updated.
*
*----------------------------------------------------------------------
*/
static void
-AllocateColors(colorPtr)
- ColorTable *colorPtr; /* Pointer to the color table requiring
- * colors to be allocated. */
+AllocateColors(
+ ColorTable *colorPtr) /* Pointer to the color table requiring colors
+ * to be allocated. */
{
int i, r, g, b, rMult, mono;
int numColors, nRed, nGreen, nBlue;
@@ -3570,11 +3567,13 @@ AllocateColors(colorPtr)
XColor *colors;
unsigned long *pixels;
- /* 16-bit intensity value for i/n of full intensity. */
-# define CFRAC(i, n) ((i) * 65535 / (n))
+ /*
+ * 16-bit intensity value for i/n of full intensity.
+ */
+#define CFRAC(i, n) ((i) * 65535 / (n))
/* As for CFRAC, but apply exponent of g. */
-# define CGFRAC(i, n, g) ((int)(65535 * pow((double)(i) / (n), (g))))
+#define CGFRAC(i, n, g) ((int)(65535 * pow((double)(i) / (n), (g))))
/*
* First parse the palette specification to get the required number of
@@ -3586,16 +3585,14 @@ AllocateColors(colorPtr)
igam = 1.0 / colorPtr->id.gamma;
/*
- * Each time around this loop, we reduce the number of colors we're
- * trying to allocate until we succeed in allocating all of the colors
- * we need.
+ * Each time around this loop, we reduce the number of colors we're trying
+ * to allocate until we succeed in allocating all of the colors we need.
*/
for (;;) {
/*
- * If we are using 1 bit/pixel, we don't need to allocate
- * any colors (we just use the foreground and background
- * colors in the GC).
+ * If we are using 1 bit/pixel, we don't need to allocate any colors
+ * (we just use the foreground and background colors in the GC).
*/
if (mono && (nRed <= 2)) {
@@ -3604,12 +3601,12 @@ AllocateColors(colorPtr)
}
/*
- * Calculate the RGB coordinates of the colors we want to
- * allocate and store them in *colors.
+ * Calculate the RGB coordinates of the colors we want to allocate and
+ * store them in *colors.
*/
if ((colorPtr->visualInfo.class == DirectColor)
- || (colorPtr->visualInfo.class == TrueColor)) {
+ || (colorPtr->visualInfo.class == TrueColor)) {
/*
* Direct/True Color: allocate shades of red, green, blue
@@ -3636,8 +3633,8 @@ AllocateColors(colorPtr)
}
} else {
/*
- * PseudoColor, StaticColor, GrayScale or StaticGray visual:
- * we have to allocate each color in the color cube separately.
+ * PseudoColor, StaticColor, GrayScale or StaticGray visual: we
+ * have to allocate each color in the color cube separately.
*/
numColors = (mono) ? nRed: (nRed * nGreen * nBlue);
@@ -3689,7 +3686,6 @@ AllocateColors(colorPtr)
for (i = 0; i < numColors; ++i) {
if (!XAllocColor(colorPtr->id.display, colorPtr->id.colormap,
&colors[i])) {
-
/*
* Can't get all the colors we want in the default colormap;
* first try freeing colors from other unused color tables.
@@ -3701,6 +3697,7 @@ AllocateColors(colorPtr)
/*
* Still can't allocate the color.
*/
+
break;
}
}
@@ -3708,9 +3705,8 @@ AllocateColors(colorPtr)
}
/*
- * If we didn't get all of the colors, reduce the
- * resolution of the color cube, free the ones we got,
- * and try again.
+ * If we didn't get all of the colors, reduce the resolution of the
+ * color cube, free the ones we got, and try again.
*/
if (i >= numColors) {
@@ -3729,10 +3725,10 @@ AllocateColors(colorPtr)
mono = 1;
} else {
/*
- * Reduce the number of shades of each primary to about
- * 3/4 of the previous value. This should reduce the
- * total number of colors required to about half the
- * previous value for PseudoColor displays.
+ * Reduce the number of shades of each primary to about 3/4 of
+ * the previous value. This should reduce the total number of
+ * colors required to about half the previous value for
+ * PseudoColor displays.
*/
nRed = (nRed * 3 + 2) / 4;
@@ -3747,23 +3743,22 @@ AllocateColors(colorPtr)
nRed = nRed / 2;
}
}
-
+
/*
- * We have allocated all of the necessary colors:
- * fill in various fields of the ColorTable record.
+ * We have allocated all of the necessary colors: fill in various fields
+ * of the ColorTable record.
*/
if (!mono) {
colorPtr->flags |= COLOR_WINDOW;
/*
- * The following is a hairy hack. We only want to index into
- * the pixelMap on colormap displays. However, if the display
- * is on Windows, then we actually want to store the index not
- * the value since we will be passing the color table into the
- * TkPutImage call.
+ * The following is a hairy hack. We only want to index into the
+ * pixelMap on colormap displays. However, if the display is on
+ * Windows, then we actually want to store the index not the value
+ * since we will be passing the color table into the TkPutImage call.
*/
-
+
#ifndef __WIN32__
if ((colorPtr->visualInfo.class != DirectColor)
&& (colorPtr->visualInfo.class != TrueColor)) {
@@ -3778,6 +3773,7 @@ AllocateColors(colorPtr)
/*
* Set up quantization tables for dithering.
*/
+
rMult = nGreen * nBlue;
for (i = 0; i < 256; ++i) {
r = (i * (nRed - 1) + 127) / 255;
@@ -3793,12 +3789,12 @@ AllocateColors(colorPtr)
b = (i * (nBlue - 1) + 127) / 255;
if ((colorPtr->visualInfo.class == DirectColor)
|| (colorPtr->visualInfo.class == TrueColor)) {
- colorPtr->redValues[i] = colors[r].pixel
- & colorPtr->visualInfo.red_mask;
- colorPtr->greenValues[i] = colors[g].pixel
- & colorPtr->visualInfo.green_mask;
- colorPtr->blueValues[i] = colors[b].pixel
- & colorPtr->visualInfo.blue_mask;
+ colorPtr->redValues[i] =
+ colors[r].pixel & colorPtr->visualInfo.red_mask;
+ colorPtr->greenValues[i] =
+ colors[g].pixel & colorPtr->visualInfo.green_mask;
+ colorPtr->blueValues[i] =
+ colors[b].pixel & colorPtr->visualInfo.blue_mask;
} else {
r *= rMult;
g *= nBlue;
@@ -3828,27 +3824,27 @@ AllocateColors(colorPtr)
*
* DisposeColorTable --
*
+ * Release a color table and its associated resources.
*
* Results:
* None.
*
* Side effects:
- * The colors in the argument color table are freed, as is the
- * color table structure itself. The color table is removed
- * from the hash table which is used to locate color tables.
+ * The colors in the argument color table are freed, as is the color
+ * table structure itself. The color table is removed from the hash table
+ * which is used to locate color tables.
*
*----------------------------------------------------------------------
*/
static void
-DisposeColorTable(clientData)
- ClientData clientData; /* Pointer to the ColorTable whose
+DisposeColorTable(
+ ClientData clientData) /* Pointer to the ColorTable whose
* colors are to be released. */
{
- ColorTable *colorPtr;
+ ColorTable *colorPtr = (ColorTable *) clientData;
Tcl_HashEntry *entry;
- colorPtr = (ColorTable *) clientData;
if (colorPtr->pixelMap != NULL) {
if (colorPtr->numColors > 0) {
XFreeColors(colorPtr->id.display, colorPtr->id.colormap,
@@ -3860,7 +3856,7 @@ DisposeColorTable(clientData)
entry = Tcl_FindHashEntry(&imgPhotoColorHash, (char *) &colorPtr->id);
if (entry == NULL) {
- panic("DisposeColorTable couldn't find hash entry");
+ Tcl_Panic("DisposeColorTable couldn't find hash entry");
}
Tcl_DeleteHashEntry(entry);
@@ -3872,48 +3868,46 @@ DisposeColorTable(clientData)
*
* ReclaimColors --
*
- * This procedure is called to try to free up colors in the
- * colormap used by a color table. It looks for other color
- * tables with the same colormap and with a zero live reference
- * count, and frees their colors. It only does so if there is
- * the possibility of freeing up at least `numColors' colors.
+ * This function is called to try to free up colors in the colormap used
+ * by a color table. It looks for other color tables with the same
+ * colormap and with a zero live reference count, and frees their colors.
+ * It only does so if there is the possibility of freeing up at least
+ * `numColors' colors.
*
* Results:
- * The return value is TRUE if any colors were freed, FALSE
- * otherwise.
+ * The return value is TRUE if any colors were freed, FALSE otherwise.
*
* Side effects:
- * ColorTables which are not currently in use may lose their
- * color allocations.
+ * ColorTables which are not currently in use may lose their color
+ * allocations.
*
- *---------------------------------------------------------------------- */
+ *----------------------------------------------------------------------
+ */
static int
-ReclaimColors(id, numColors)
- ColorTableId *id; /* Pointer to information identifying
+ReclaimColors(
+ ColorTableId *id, /* Pointer to information identifying
* the color table which needs more colors. */
- int numColors; /* Number of colors required. */
+ int numColors) /* Number of colors required. */
{
Tcl_HashSearch srch;
Tcl_HashEntry *entry;
ColorTable *colorPtr;
- int nAvail;
+ int nAvail = 0;
/*
- * First scan through the color hash table to get an
- * upper bound on how many colors we might be able to free.
+ * First scan through the color hash table to get an upper bound on how
+ * many colors we might be able to free.
*/
- nAvail = 0;
entry = Tcl_FirstHashEntry(&imgPhotoColorHash, &srch);
while (entry != NULL) {
colorPtr = (ColorTable *) Tcl_GetHashValue(entry);
if ((colorPtr->id.display == id->display)
- && (colorPtr->id.colormap == id->colormap)
- && (colorPtr->liveRefCount == 0 )&& (colorPtr->numColors != 0)
- && ((colorPtr->id.palette != id->palette)
- || (colorPtr->id.gamma != id->gamma))) {
-
+ && (colorPtr->id.colormap == id->colormap)
+ && (colorPtr->liveRefCount == 0 )&& (colorPtr->numColors != 0)
+ && ((colorPtr->id.palette != id->palette)
+ || (colorPtr->id.gamma != id->gamma))) {
/*
* We could take this guy's colors off him.
*/
@@ -3942,8 +3936,7 @@ ReclaimColors(id, numColors)
&& (colorPtr->id.colormap == id->colormap)
&& (colorPtr->liveRefCount == 0) && (colorPtr->numColors != 0)
&& ((colorPtr->id.palette != id->palette)
- || (colorPtr->id.gamma != id->gamma))) {
-
+ || (colorPtr->id.gamma != id->gamma))) {
/*
* Free the colors that this ColorTable has.
*/
@@ -3958,7 +3951,7 @@ ReclaimColors(id, numColors)
entry = Tcl_NextHashEntry(&srch);
}
- return 1; /* we freed some colors */
+ return 1; /* We freed some colors. */
}
/*
@@ -3966,23 +3959,22 @@ ReclaimColors(id, numColors)
*
* DisposeInstance --
*
- * This procedure is called to finally free up an instance
- * of a photo image which is no longer required.
+ * This function is called to finally free up an instance of a photo
+ * image which is no longer required.
*
* Results:
* None.
*
* Side effects:
- * The instance data structure and the resources it references
- * are freed.
+ * The instance data structure and the resources it references are freed.
*
*----------------------------------------------------------------------
*/
static void
-DisposeInstance(clientData)
- ClientData clientData; /* Pointer to the instance whose resources
- * are to be released. */
+DisposeInstance(
+ ClientData clientData) /* Pointer to the instance whose resources are
+ * to be released. */
{
PhotoInstance *instancePtr = (PhotoInstance *) clientData;
PhotoInstance *prevPtr;
@@ -4008,7 +4000,7 @@ DisposeInstance(clientData)
} else {
for (prevPtr = instancePtr->masterPtr->instancePtr;
prevPtr->nextPtr != instancePtr; prevPtr = prevPtr->nextPtr) {
- /* Empty loop body */
+ /* Empty loop body. */
}
prevPtr->nextPtr = instancePtr->nextPtr;
}
@@ -4021,16 +4013,16 @@ DisposeInstance(clientData)
*
* MatchFileFormat --
*
- * This procedure is called to find a photo image file format
- * handler which can parse the image data in the given file.
- * If a user-specified format string is provided, only handlers
- * whose names match a prefix of the format string are tried.
+ * This function is called to find a photo image file format handler
+ * which can parse the image data in the given file. If a user-specified
+ * format string is provided, only handlers whose names match a prefix of
+ * the format string are tried.
*
* Results:
- * A standard TCL return value. If the return value is TCL_OK, a
- * pointer to the image format record is returned in
- * *imageFormatPtr, and the width and height of the image are
- * returned in *widthPtr and *heightPtr.
+ * A standard TCL return value. If the return value is TCL_OK, a pointer
+ * to the image format record is returned in *imageFormatPtr, and the
+ * width and height of the image are returned in *widthPtr and
+ * *heightPtr.
*
* Side effects:
* None.
@@ -4039,24 +4031,23 @@ DisposeInstance(clientData)
*/
static int
-MatchFileFormat(interp, chan, fileName, formatObj, imageFormatPtr,
- widthPtr, heightPtr, oldformat)
- Tcl_Interp *interp; /* Interpreter to use for reporting errors. */
- Tcl_Channel chan; /* The image file, open for reading. */
- char *fileName; /* The name of the image file. */
- Tcl_Obj *formatObj; /* User-specified format string, or NULL. */
- Tk_PhotoImageFormat **imageFormatPtr;
- /* A pointer to the photo image format
- * record is returned here. */
- int *widthPtr, *heightPtr; /* The dimensions of the image are
- * returned here. */
- int *oldformat;
+MatchFileFormat(
+ Tcl_Interp *interp, /* Interpreter to use for reporting errors. */
+ Tcl_Channel chan, /* The image file, open for reading. */
+ char *fileName, /* The name of the image file. */
+ Tcl_Obj *formatObj, /* User-specified format string, or NULL. */
+ Tk_PhotoImageFormat **imageFormatPtr,
+ /* A pointer to the photo image format record
+ * is returned here. */
+ int *widthPtr, int *heightPtr,
+ /* The dimensions of the image are returned
+ * here. */
+ int *oldformat) /* Returns 1 if the old image API is used. */
{
- int matched;
- int useoldformat = 0;
+ int matched = 0, useoldformat = 0;
Tk_PhotoImageFormat *formatPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
char *formatString = NULL;
if (formatObj) {
@@ -4064,13 +4055,12 @@ MatchFileFormat(interp, chan, fileName, formatObj, imageFormatPtr,
}
/*
- * Scan through the table of file format handlers to find
- * one which can handle the image.
+ * Scan through the table of file format handlers to find one which can
+ * handle the image.
*/
- matched = 0;
for (formatPtr = tsdPtr->formatList; formatPtr != NULL;
- formatPtr = formatPtr->nextPtr) {
+ formatPtr = formatPtr->nextPtr) {
if (formatObj != NULL) {
if (strncasecmp(formatString,
formatPtr->name, strlen(formatPtr->name)) != 0) {
@@ -4079,13 +4069,13 @@ MatchFileFormat(interp, chan, fileName, formatObj, imageFormatPtr,
matched = 1;
if (formatPtr->fileMatchProc == NULL) {
Tcl_AppendResult(interp, "-file option isn't supported for ",
- formatString, " images", (char *) NULL);
+ formatString, " images", NULL);
return TCL_ERROR;
}
}
if (formatPtr->fileMatchProc != NULL) {
(void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);
-
+
if ((*formatPtr->fileMatchProc)(chan, fileName, formatObj,
widthPtr, heightPtr, interp)) {
if (*widthPtr < 1) {
@@ -4110,7 +4100,7 @@ MatchFileFormat(interp, chan, fileName, formatObj, imageFormatPtr,
matched = 1;
if (formatPtr->fileMatchProc == NULL) {
Tcl_AppendResult(interp, "-file option isn't supported",
- " for ", formatString, " images", (char *) NULL);
+ " for ", formatString, " images", NULL);
return TCL_ERROR;
}
}
@@ -4132,13 +4122,12 @@ MatchFileFormat(interp, chan, fileName, formatObj, imageFormatPtr,
if (formatPtr == NULL) {
if ((formatObj != NULL) && !matched) {
- Tcl_AppendResult(interp, "image file format \"",
- formatString,
- "\" is not supported", (char *) NULL);
+ Tcl_AppendResult(interp, "image file format \"", formatString,
+ "\" is not supported", NULL);
} else {
Tcl_AppendResult(interp,
- "couldn't recognize data in image file \"",
- fileName, "\"", (char *) NULL);
+ "couldn't recognize data in image file \"", fileName, "\"",
+ NULL);
}
return TCL_ERROR;
}
@@ -4154,16 +4143,16 @@ MatchFileFormat(interp, chan, fileName, formatObj, imageFormatPtr,
*
* MatchStringFormat --
*
- * This procedure is called to find a photo image file format
- * handler which can parse the image data in the given string.
- * If a user-specified format string is provided, only handlers
- * whose names match a prefix of the format string are tried.
+ * This function is called to find a photo image file format handler
+ * which can parse the image data in the given string. If a
+ * user-specified format string is provided, only handlers whose names
+ * match a prefix of the format string are tried.
*
* Results:
- * A standard TCL return value. If the return value is TCL_OK, a
- * pointer to the image format record is returned in
- * *imageFormatPtr, and the width and height of the image are
- * returned in *widthPtr and *heightPtr.
+ * A standard TCL return value. If the return value is TCL_OK, a pointer
+ * to the image format record is returned in *imageFormatPtr, and the
+ * width and height of the image are returned in *widthPtr and
+ * *heightPtr.
*
* Side effects:
* None.
@@ -4172,35 +4161,33 @@ MatchFileFormat(interp, chan, fileName, formatObj, imageFormatPtr,
*/
static int
-MatchStringFormat(interp, data, formatObj, imageFormatPtr,
- widthPtr, heightPtr, oldformat)
- Tcl_Interp *interp; /* Interpreter to use for reporting errors. */
- Tcl_Obj *data; /* Object containing the image data. */
- Tcl_Obj *formatObj; /* User-specified format string, or NULL. */
- Tk_PhotoImageFormat **imageFormatPtr;
- /* A pointer to the photo image format
- * record is returned here. */
- int *widthPtr, *heightPtr; /* The dimensions of the image are
- * returned here. */
- int *oldformat; /* returns 1 if the old image API is used */
+MatchStringFormat(
+ Tcl_Interp *interp, /* Interpreter to use for reporting errors. */
+ Tcl_Obj *data, /* Object containing the image data. */
+ Tcl_Obj *formatObj, /* User-specified format string, or NULL. */
+ Tk_PhotoImageFormat **imageFormatPtr,
+ /* A pointer to the photo image format record
+ * is returned here. */
+ int *widthPtr, int *heightPtr,
+ /* The dimensions of the image are returned
+ * here. */
+ int *oldformat) /* Returns 1 if the old image API is used. */
{
- int matched;
- int useoldformat = 0;
+ int matched = 0, useoldformat = 0;
Tk_PhotoImageFormat *formatPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
char *formatString = NULL;
-
+
if (formatObj) {
formatString = Tcl_GetString(formatObj);
}
/*
- * Scan through the table of file format handlers to find
- * one which can handle the image.
+ * Scan through the table of file format handlers to find one which can
+ * handle the image.
*/
- matched = 0;
for (formatPtr = tsdPtr->formatList; formatPtr != NULL;
formatPtr = formatPtr->nextPtr) {
if (formatObj != NULL) {
@@ -4211,7 +4198,7 @@ MatchStringFormat(interp, data, formatObj, imageFormatPtr,
matched = 1;
if (formatPtr->stringMatchProc == NULL) {
Tcl_AppendResult(interp, "-data option isn't supported for ",
- formatString, " images", (char *) NULL);
+ formatString, " images", NULL);
return TCL_ERROR;
}
}
@@ -4235,7 +4222,7 @@ MatchStringFormat(interp, data, formatObj, imageFormatPtr,
matched = 1;
if (formatPtr->stringMatchProc == NULL) {
Tcl_AppendResult(interp, "-data option isn't supported",
- " for ", formatString, " images", (char *) NULL);
+ " for ", formatString, " images", NULL);
return TCL_ERROR;
}
}
@@ -4252,10 +4239,9 @@ MatchStringFormat(interp, data, formatObj, imageFormatPtr,
if (formatPtr == NULL) {
if ((formatObj != NULL) && !matched) {
Tcl_AppendResult(interp, "image format \"", formatString,
- "\" is not supported", (char *) NULL);
+ "\" is not supported", NULL);
} else {
- Tcl_AppendResult(interp, "couldn't recognize image data",
- (char *) NULL);
+ Tcl_AppendResult(interp, "couldn't recognize image data", NULL);
}
return TCL_ERROR;
}
@@ -4270,14 +4256,14 @@ MatchStringFormat(interp, data, formatObj, imageFormatPtr,
*
* Tk_FindPhoto --
*
- * This procedure is called to get an opaque handle (actually a
- * PhotoMaster *) for a given image, which can be used in
- * subsequent calls to Tk_PhotoPutBlock, etc. The `name'
- * parameter is the name of the image.
+ * This function is called to get an opaque handle (actually a
+ * PhotoMaster *) for a given image, which can be used in subsequent
+ * calls to Tk_PhotoPutBlock, etc. The `name' parameter is the name of
+ * the image.
*
* Results:
- * The handle for the photo image, or NULL if there is no
- * photo image with the name given.
+ * The handle for the photo image, or NULL if there is no photo image
+ * with the name given.
*
* Side effects:
* None.
@@ -4286,16 +4272,16 @@ MatchStringFormat(interp, data, formatObj, imageFormatPtr,
*/
Tk_PhotoHandle
-Tk_FindPhoto(interp, imageName)
- Tcl_Interp *interp; /* Interpreter (application) in which image
+Tk_FindPhoto(
+ Tcl_Interp *interp, /* Interpreter (application) in which image
* exists. */
- CONST char *imageName; /* Name of the desired photo image. */
+ CONST char *imageName) /* Name of the desired photo image. */
{
ClientData clientData;
Tk_ImageType *typePtr;
clientData = Tk_GetImageMasterData(interp, imageName, &typePtr);
- if (typePtr != &tkPhotoImageType) {
+ if ((typePtr == NULL) || (typePtr->name != tkPhotoImageType.name)) {
return NULL;
}
return (Tk_PhotoHandle) clientData;
@@ -4306,39 +4292,40 @@ Tk_FindPhoto(interp, imageName)
*
* Tk_PhotoPutBlock --
*
- * This procedure is called to put image data into a photo image.
+ * This function is called to put image data into a photo image.
*
* Results:
- * None.
+ * A standard Tcl result code.
*
* Side effects:
- * The image data is stored. The image may be expanded.
- * The Tk image code is informed that the image has changed.
+ * The image data is stored. The image may be expanded. The Tk image code
+ * is informed that the image has changed. If the result code is
+ * TCL_ERROR, an error message will be placed in the interpreter (if
+ * non-NULL).
*
- *---------------------------------------------------------------------- */
+ *----------------------------------------------------------------------
+ */
-void
-Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule)
- Tk_PhotoHandle handle; /* Opaque handle for the photo image
- * to be updated. */
- register Tk_PhotoImageBlock *blockPtr;
- /* Pointer to a structure describing the
- * pixel data to be copied into the image. */
- int x, y; /* Coordinates of the top-left pixel to
- * be updated in the image. */
- int width, height; /* Dimensions of the area of the image
- * to be updated. */
- int compRule; /* Compositing rule to use when processing
+int
+Tk_PhotoPutBlock(
+ Tcl_Interp *interp, /* Interpreter for passing back error
+ * messages, or NULL. */
+ Tk_PhotoHandle handle, /* Opaque handle for the photo image to be
+ * updated. */
+ register Tk_PhotoImageBlock *blockPtr,
+ /* Pointer to a structure describing the pixel
+ * data to be copied into the image. */
+ int x, int y, /* Coordinates of the top-left pixel to be
+ * updated in the image. */
+ int width, int height, /* Dimensions of the area of the image to be
+ * updated. */
+ int compRule) /* Compositing rule to use when processing
* transparent pixels. */
{
register PhotoMaster *masterPtr;
- int xEnd, yEnd;
- int greenOffset, blueOffset, alphaOffset;
- int wLeft, hLeft;
- int wCopy, hCopy;
- unsigned char *srcPtr, *srcLinePtr;
- unsigned char *destPtr, *destLinePtr;
- int pitch;
+ int xEnd, yEnd, greenOffset, blueOffset, alphaOffset;
+ int wLeft, hLeft, wCopy, hCopy, pitch;
+ unsigned char *srcPtr, *srcLinePtr, *destPtr, *destLinePtr;
int sourceIsSimplePhoto = compRule & SOURCE_IS_SIMPLE_ALPHA_PHOTO;
XRectangle rect;
@@ -4353,16 +4340,21 @@ Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule)
height = masterPtr->userHeight - y;
}
if ((width <= 0) || (height <= 0)) {
- return;
+ return TCL_OK;
}
xEnd = x + width;
yEnd = y + height;
if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) {
int sameSrc = (blockPtr->pixelPtr == masterPtr->pix32);
+
if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width),
MAX(yEnd, masterPtr->height)) == TCL_ERROR) {
- panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
+ if (interp != NULL) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);
+ }
+ return TCL_ERROR;
}
if (sameSrc) {
blockPtr->pixelPtr = masterPtr->pix32;
@@ -4370,12 +4362,12 @@ Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule)
}
}
-
if ((y < masterPtr->ditherY) || ((y == masterPtr->ditherY)
&& (x < masterPtr->ditherX))) {
/*
* The dithering isn't correct past the start of this block.
*/
+
masterPtr->ditherX = x;
masterPtr->ditherY = y;
}
@@ -4399,111 +4391,162 @@ Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule)
}
/*
- * Copy the data into our local 32-bit/pixel array.
- * If we can do it with a single memmove, we do.
+ * Copy the data into our local 32-bit/pixel array. If we can do it with a
+ * single memmove, we do.
*/
destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
pitch = masterPtr->width * 4;
/*
- * This test is probably too restrictive. We should also be able to
- * do a memmove if pixelSize == 3 and alphaOffset == 0. Maybe other cases
- * too.
+ * Test to see if we can do the whole write in a single copy. This test is
+ * probably too restrictive. We should also be able to do a memmove if
+ * pixelSize == 3 and alphaOffset == 0. Maybe other cases too.
*/
+
if ((blockPtr->pixelSize == 4)
&& (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3)
&& (width <= blockPtr->width) && (height <= blockPtr->height)
&& ((height == 1) || ((x == 0) && (width == masterPtr->width)
&& (blockPtr->pitch == pitch)))
&& (compRule == TK_PHOTO_COMPOSITE_SET)) {
- memmove((VOID *) destLinePtr,
- (VOID *) (blockPtr->pixelPtr + blockPtr->offset[0]),
+ memmove(destLinePtr, blockPtr->pixelPtr + blockPtr->offset[0],
(size_t) (height * width * 4));
- } else {
- int alpha;
- for (hLeft = height; hLeft > 0;) {
- srcLinePtr = blockPtr->pixelPtr + blockPtr->offset[0];
- hCopy = MIN(hLeft, blockPtr->height);
- hLeft -= hCopy;
- for (; hCopy > 0; --hCopy) {
- if ((blockPtr->pixelSize == 4) && (greenOffset == 1)
+
+ /*
+ * We know there's an alpha offset and we're setting the data, so skip
+ * directly to the point when we recompute the photo validity region.
+ */
+
+ goto recalculateValidRegion;
+ }
+
+ /*
+ * Copy and merge pixels according to the compositing rule.
+ */
+
+ for (hLeft = height; hLeft > 0;) {
+ int pixelSize = blockPtr->pixelSize;
+ int compRuleSet = (compRule == TK_PHOTO_COMPOSITE_SET);
+
+ srcLinePtr = blockPtr->pixelPtr + blockPtr->offset[0];
+ hCopy = MIN(hLeft, blockPtr->height);
+ hLeft -= hCopy;
+ for (; hCopy > 0; --hCopy) {
+ /*
+ * If the layout of the source line matches our memory layout and
+ * we're setting, we can just copy the bytes directly, which is
+ * much faster.
+ */
+
+ if ((pixelSize == 4) && (greenOffset == 1)
&& (blueOffset == 2) && (alphaOffset == 3)
&& (width <= blockPtr->width)
- && (compRule == TK_PHOTO_COMPOSITE_SET)) {
- memcpy((VOID *) destLinePtr, (VOID *) srcLinePtr,
- (size_t) (width * 4));
- } else {
- destPtr = destLinePtr;
- for (wLeft = width; wLeft > 0;) {
- wCopy = MIN(wLeft, blockPtr->width);
- wLeft -= wCopy;
- srcPtr = srcLinePtr;
- for (; wCopy > 0; --wCopy) {
- alpha = srcPtr[alphaOffset];
-
- /*
- * In the easy case, we can just copy.
- */
- if (!alphaOffset || (alpha == 255)) {
- /* new solid part of the image */
- *destPtr++ = srcPtr[0];
- *destPtr++ = srcPtr[greenOffset];
- *destPtr++ = srcPtr[blueOffset];
- *destPtr++ = 255;
- srcPtr += blockPtr->pixelSize;
- continue;
- }
+ && compRuleSet) {
+ memcpy(destLinePtr, srcLinePtr, (size_t) (width * 4));
+ srcLinePtr += blockPtr->pitch;
+ destLinePtr += pitch;
+ continue;
+ }
- /*
- * Combine according to the compositing rule.
- */
- switch (compRule) {
- case TK_PHOTO_COMPOSITE_OVERLAY:
- if (!destPtr[3]) {
- /*
- * The destination is entirely
- * blank, so set it to the source,
- * just as if we used the SET
- * compositing rule.
- */
- case TK_PHOTO_COMPOSITE_SET:
- *destPtr++ = srcPtr[0];
- *destPtr++ = srcPtr[greenOffset];
- *destPtr++ = srcPtr[blueOffset];
- *destPtr++ = alpha;
- break;
- }
+ /*
+ * Have to copy the slow way.
+ */
+
+ destPtr = destLinePtr;
+ for (wLeft = width; wLeft > 0;) {
+ wCopy = MIN(wLeft, blockPtr->width);
+ wLeft -= wCopy;
+ srcPtr = srcLinePtr;
- if (alpha) {
- int Alpha = destPtr[3];
+ /*
+ * But we might be lucky and be able to use fairly fast loops.
+ * It's worth checking...
+ */
- /*
- * This implements the Porter-Duff
- * Source-Over compositing rule.
- */
+ if (alphaOffset == 0) {
+ /*
+ * This is the non-alpha case, so can still be fairly
+ * fast. Note that in the non-alpha-source case, the
+ * compositing rule doesn't apply.
+ */
- destPtr[0] = PD_SRC_OVER(srcPtr[0],alpha,destPtr[0],Alpha);
- destPtr[1] = PD_SRC_OVER(srcPtr[greenOffset],alpha,destPtr[1],Alpha);
- destPtr[2] = PD_SRC_OVER(srcPtr[blueOffset],alpha,destPtr[2],Alpha);
- destPtr[3] = PD_SRC_OVER_ALPHA(alpha,Alpha);
- }
- /*
- * else should be empty space
- */
- destPtr += 4;
- break;
-
- default:
- panic("unknown compositing rule: %d", compRule);
- }
- srcPtr += blockPtr->pixelSize;
- }
+ for (; wCopy>0 ; --wCopy, srcPtr+=pixelSize) {
+ *destPtr++ = srcPtr[0];
+ *destPtr++ = srcPtr[greenOffset];
+ *destPtr++ = srcPtr[blueOffset];
+ *destPtr++ = 255;
+ }
+ continue;
+ } else if (compRuleSet) {
+ /*
+ * This is the SET compositing rule, which just replaces
+ * what was there before with the new data. This is
+ * another fairly fast case. No point in doing a memcpy();
+ * the order of channels is probably wrong.
+ */
+
+ for (; wCopy>0 ; --wCopy, srcPtr+=pixelSize) {
+ *destPtr++ = srcPtr[0];
+ *destPtr++ = srcPtr[greenOffset];
+ *destPtr++ = srcPtr[blueOffset];
+ *destPtr++ = srcPtr[alphaOffset];
}
+ continue;
+ }
+
+ /*
+ * Bother; need to consider the alpha value of each pixel to
+ * know what to do.
+ */
+
+ for (; wCopy>0 ; --wCopy, srcPtr+=pixelSize) {
+ int alpha = srcPtr[alphaOffset];
+
+ if (alpha == 255 || !destPtr[3]) {
+ /*
+ * Either the source is 100% opaque, or the
+ * destination is entirely blank. In all cases, we
+ * just set the destination to the source.
+ */
+
+ *destPtr++ = srcPtr[0];
+ *destPtr++ = srcPtr[greenOffset];
+ *destPtr++ = srcPtr[blueOffset];
+ *destPtr++ = alpha;
+ continue;
+ }
+
+ /*
+ * Can still skip doing work if the source is 100%
+ * transparent at this point.
+ */
+
+ if (alpha) {
+ int Alpha = destPtr[3];
+
+ /*
+ * OK, there's real work to be done. Luckily, there's
+ * a substantial literature on what to do in this
+ * case. In particular, Porter and Duff have done a
+ * taxonomy of compositing rules, and the right one is
+ * the "Source Over" rule. This code implements that.
+ */
+
+ destPtr[0] = PD_SRC_OVER(srcPtr[0], alpha, destPtr[0],
+ Alpha);
+ destPtr[1] = PD_SRC_OVER(srcPtr[greenOffset], alpha,
+ destPtr[1], Alpha);
+ destPtr[2] = PD_SRC_OVER(srcPtr[blueOffset], alpha,
+ destPtr[2], Alpha);
+ destPtr[3] = PD_SRC_OVER_ALPHA(alpha, Alpha);
+ }
+
+ destPtr += 4;
}
- srcLinePtr += blockPtr->pitch;
- destLinePtr += pitch;
}
+ srcLinePtr += blockPtr->pitch;
+ destLinePtr += pitch;
}
}
@@ -4512,34 +4555,35 @@ Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule)
*/
if (alphaOffset) {
- int x1, y1, end;
-
/*
- * This block is grossly inefficient. For each row in the image, it
+ * This block is grossly inefficient. For each row in the image, it
* finds each continguous string of nontransparent pixels, then marks
- * those areas as valid in the validRegion mask. This makes drawing
+ * those areas as valid in the validRegion mask. This makes drawing
* very efficient, because of the way we use X: we just say, here's
- * your mask, and here's your data. We need not worry about the
- * current background color, etc. But this costs us a lot on the
- * image setup. Still, image setup only happens once, whereas the
- * drawing happens many times, so this might be the best way to go.
+ * your mask, and here's your data. We need not worry about the
+ * current background color, etc. But this costs us a lot on the image
+ * setup. Still, image setup only happens once, whereas the drawing
+ * happens many times, so this might be the best way to go.
*
* An alternative might be to not set up this mask, and instead, at
* drawing time, for each transparent pixel, set its color to the
- * color of the background behind that pixel. This is what I suspect
- * most of programs do. However, they don't have to deal with the
+ * color of the background behind that pixel. This is what I suspect
+ * most of programs do. However, they don't have to deal with the
* canvas, which could have many different background colors.
* Determining the correct bg color for a given pixel might be
* expensive.
*/
if (compRule != TK_PHOTO_COMPOSITE_OVERLAY) {
+ TkRegion workRgn;
+
/*
- * Don't need this when using the OVERLAY compositing rule,
- * which always strictly increases the valid region.
+ * Don't need this when using the OVERLAY compositing rule, which
+ * always strictly increases the valid region.
*/
- TkRegion workRgn = TkCreateRegion();
+ recalculateValidRegion:
+ workRgn = TkCreateRegion();
rect.x = x;
rect.y = y;
rect.width = width;
@@ -4550,34 +4594,15 @@ Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule)
TkDestroyRegion(workRgn);
}
- destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4 + 3;
- for (y1 = 0; y1 < height; y1++) {
- x1 = 0;
- destPtr = destLinePtr;
- while (x1 < width) {
- /* search for first non-transparent pixel */
- while ((x1 < width) && !*destPtr) {
- x1++;
- destPtr += 4;
- }
- end = x1;
- /* search for first transparent pixel */
- while ((end < width) && *destPtr) {
- end++;
- destPtr += 4;
- }
- if (end > x1) {
- rect.x = x + x1;
- rect.y = y + y1;
- rect.width = end - x1;
- rect.height = 1;
- TkUnionRectWithRegion(&rect, masterPtr->validRegion,
- masterPtr->validRegion);
- }
- x1 = end;
- }
- destLinePtr += masterPtr->width * 4;
- }
+ /*
+ * Factorize out the main part of the building of the region data to
+ * allow for more efficient per-platform implementations. [Bug 919066]
+ */
+
+ TkpBuildRegionFromAlphaData(masterPtr->validRegion, (unsigned) x,
+ (unsigned) y, (unsigned) width, (unsigned) height,
+ masterPtr->pix32 + (y * masterPtr->width + x) * 4 + 3,
+ 4, (unsigned) masterPtr->width * 4);
} else {
rect.x = x;
rect.y = y;
@@ -4597,6 +4622,7 @@ Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule)
* builds up large simple-alpha images by single pixels. We don't
* negate COMPLEX_ALPHA in this case. [Bug 1409140]
*/
+
if (!(masterPtr->flags & COMPLEX_ALPHA)) {
unsigned char newAlpha;
@@ -4614,6 +4640,7 @@ Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule)
* Toggle to only checking the changed pixels requires knowing where
* the alpha pixels are.
*/
+
ToggleComplexAlphaIfNeeded(masterPtr);
}
@@ -4627,8 +4654,9 @@ Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule)
* Tell the core image code that this image has changed.
*/
- Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height, masterPtr->width,
- masterPtr->height);
+ Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height,
+ masterPtr->width, masterPtr->height);
+ return TCL_OK;
}
/*
@@ -4636,60 +4664,56 @@ Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule)
*
* Tk_PhotoPutZoomedBlock --
*
- * This procedure is called to put image data into a photo image,
- * with possible subsampling and/or zooming of the pixels.
+ * This function is called to put image data into a photo image, with
+ * possible subsampling and/or zooming of the pixels.
*
* Results:
* None.
*
* Side effects:
- * The image data is stored. The image may be expanded.
- * The Tk image code is informed that the image has changed.
+ * The image data is stored. The image may be expanded. The Tk image code
+ * is informed that the image has changed.
*
*----------------------------------------------------------------------
*/
-void
-Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY,
- subsampleX, subsampleY, compRule)
- Tk_PhotoHandle handle; /* Opaque handle for the photo image
- * to be updated. */
- register Tk_PhotoImageBlock *blockPtr;
- /* Pointer to a structure describing the
- * pixel data to be copied into the image. */
- int x, y; /* Coordinates of the top-left pixel to
- * be updated in the image. */
- int width, height; /* Dimensions of the area of the image
- * to be updated. */
- int zoomX, zoomY; /* Zoom factors for the X and Y axes. */
- int subsampleX, subsampleY; /* Subsampling factors for the X and Y axes. */
- int compRule; /* Compositing rule to use when processing
+int
+Tk_PhotoPutZoomedBlock(
+ Tcl_Interp *interp, /* Interpreter for passing back error
+ * messages, or NULL. */
+ Tk_PhotoHandle handle, /* Opaque handle for the photo image to be
+ * updated. */
+ register Tk_PhotoImageBlock *blockPtr,
+ /* Pointer to a structure describing the pixel
+ * data to be copied into the image. */
+ int x, int y, /* Coordinates of the top-left pixel to be
+ * updated in the image. */
+ int width, int height, /* Dimensions of the area of the image to be
+ * updated. */
+ int zoomX, int zoomY, /* Zoom factors for the X and Y axes. */
+ int subsampleX, int subsampleY,
+ /* Subsampling factors for the X and Y
+ * axes. */
+ int compRule) /* Compositing rule to use when processing
* transparent pixels. */
{
- register PhotoMaster *masterPtr;
- int xEnd, yEnd;
- int greenOffset, blueOffset, alphaOffset;
- int wLeft, hLeft;
- int wCopy, hCopy;
- int blockWid, blockHt;
- unsigned char *srcPtr, *srcLinePtr, *srcOrigPtr;
- unsigned char *destPtr, *destLinePtr;
- int pitch;
- int xRepeat, yRepeat;
- int blockXSkip, blockYSkip, sourceIsSimplePhoto;
+ register PhotoMaster *masterPtr = (PhotoMaster *) handle;
+ int xEnd, yEnd, greenOffset, blueOffset, alphaOffset;
+ int wLeft, hLeft, wCopy, hCopy, blockWid, blockHt;
+ unsigned char *srcPtr, *srcLinePtr, *srcOrigPtr, *destPtr, *destLinePtr;
+ int pitch, xRepeat, yRepeat, blockXSkip, blockYSkip, sourceIsSimplePhoto;
XRectangle rect;
if (zoomX==1 && zoomY==1 && subsampleX==1 && subsampleY==1) {
- Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height, compRule);
- return;
+ return Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height,
+ compRule);
}
sourceIsSimplePhoto = compRule & SOURCE_IS_SIMPLE_ALPHA_PHOTO;
compRule &= ~SOURCE_IS_SIMPLE_ALPHA_PHOTO;
- masterPtr = (PhotoMaster *) handle;
if (zoomX <= 0 || zoomY <= 0) {
- return;
+ return TCL_OK;
}
if ((masterPtr->userWidth != 0) && ((x + width) > masterPtr->userWidth)) {
width = masterPtr->userWidth - x;
@@ -4699,7 +4723,7 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY,
height = masterPtr->userHeight - y;
}
if (width <= 0 || height <= 0) {
- return;
+ return TCL_OK;
}
xEnd = x + width;
@@ -4708,7 +4732,11 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY,
int sameSrc = (blockPtr->pixelPtr == masterPtr->pix32);
if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width),
MAX(yEnd, masterPtr->height)) == TCL_ERROR) {
- panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
+ if (interp != NULL) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);
+ }
+ return TCL_ERROR;
}
if (sameSrc) {
blockPtr->pixelPtr = masterPtr->pix32;
@@ -4793,10 +4821,12 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY,
srcPtr = srcLinePtr;
for (; wCopy > 0; wCopy -= zoomX) {
for (xRepeat = MIN(wCopy, zoomX); xRepeat > 0; xRepeat--) {
- int alpha = srcPtr[alphaOffset];
+ int alpha = srcPtr[alphaOffset];/* Source alpha. */
+
/*
* Common case (solid pixels) first
*/
+
if (!alphaOffset || (alpha == 255)) {
*destPtr++ = srcPtr[0];
*destPtr++ = srcPtr[greenOffset];
@@ -4805,32 +4835,33 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY,
continue;
}
- switch (compRule) {
- case TK_PHOTO_COMPOSITE_OVERLAY:
- if (!destPtr[3]) {
- /*
- * The destination is entirely blank,
- * so set it to the source, just as if
- * we used the SET compositing rule.
- */
- case TK_PHOTO_COMPOSITE_SET:
- *destPtr++ = srcPtr[0];
- *destPtr++ = srcPtr[greenOffset];
- *destPtr++ = srcPtr[blueOffset];
- *destPtr++ = alpha;
- break;
- }
- if (alpha) {
- int Alpha = destPtr[3];
- destPtr[0] = PD_SRC_OVER(srcPtr[0],alpha,destPtr[0],Alpha);
- destPtr[1] = PD_SRC_OVER(srcPtr[greenOffset],alpha,destPtr[1],Alpha);
- destPtr[2] = PD_SRC_OVER(srcPtr[blueOffset],alpha,destPtr[2],Alpha);
- destPtr[3] = PD_SRC_OVER_ALPHA(alpha,Alpha);
- }
+ if (compRule==TK_PHOTO_COMPOSITE_SET || !destPtr[3]) {
+ /*
+ * Either this is the SET rule (we overwrite
+ * whatever is there) or the destination is
+ * entirely blank. In both cases, we just set the
+ * destination to the source.
+ */
+
+ *destPtr++ = srcPtr[0];
+ *destPtr++ = srcPtr[greenOffset];
+ *destPtr++ = srcPtr[blueOffset];
+ *destPtr++ = alpha;
+ } else if (alpha) {
+ int Alpha = destPtr[3]; /* Destination
+ * alpha. */
+
+ destPtr[0] = PD_SRC_OVER(srcPtr[0], alpha,
+ destPtr[0], Alpha);
+ destPtr[1] = PD_SRC_OVER(srcPtr[greenOffset],alpha,
+ destPtr[1], Alpha);
+ destPtr[2] = PD_SRC_OVER(srcPtr[blueOffset], alpha,
+ destPtr[2], Alpha);
+ destPtr[3] = PD_SRC_OVER_ALPHA(alpha, Alpha);
+
+ destPtr += 4;
+ } else {
destPtr += 4;
- break;
- default:
- panic("unknown compositing rule: %d", compRule);
}
}
srcPtr += blockXSkip;
@@ -4850,13 +4881,12 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY,
*/
if (alphaOffset) {
- int x1, y1, end;
-
if (compRule != TK_PHOTO_COMPOSITE_OVERLAY) {
/*
* Don't need this when using the OVERLAY compositing rule, which
* always strictly increases the valid region.
*/
+
TkRegion workRgn = TkCreateRegion();
rect.x = x;
@@ -4869,34 +4899,10 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY,
TkDestroyRegion(workRgn);
}
- destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4 + 3;
- for (y1 = 0; y1 < height; y1++) {
- x1 = 0;
- destPtr = destLinePtr;
- while (x1 < width) {
- /* search for first non-transparent pixel */
- while ((x1 < width) && !*destPtr) {
- x1++;
- destPtr += 4;
- }
- end = x1;
- /* search for first transparent pixel */
- while ((end < width) && *destPtr) {
- end++;
- destPtr += 4;
- }
- if (end > x1) {
- rect.x = x + x1;
- rect.y = y + y1;
- rect.width = end - x1;
- rect.height = 1;
- TkUnionRectWithRegion(&rect, masterPtr->validRegion,
- masterPtr->validRegion);
- }
- x1 = end;
- }
- destLinePtr += masterPtr->width * 4;
- }
+ TkpBuildRegionFromAlphaData(masterPtr->validRegion,
+ (unsigned)x, (unsigned)y, (unsigned)width, (unsigned)height,
+ &masterPtr->pix32[(y * masterPtr->width + x) * 4 + 3], 4,
+ (unsigned) masterPtr->width * 4);
} else {
rect.x = x;
rect.y = y;
@@ -4940,7 +4946,7 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY,
* Update each instance.
*/
- Tk_DitherPhoto((Tk_PhotoHandle)masterPtr, x, y, width, height);
+ Tk_DitherPhoto((Tk_PhotoHandle) masterPtr, x, y, width, height);
/*
* Tell the core image code that this image has changed.
@@ -4948,6 +4954,7 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY,
Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height, masterPtr->width,
masterPtr->height);
+ return TCL_OK;
}
/*
@@ -4955,27 +4962,27 @@ Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY,
*
* Tk_DitherPhoto --
*
- * This procedure is called to update an area of each instance's
- * pixmap by dithering the corresponding area of the image master.
+ * This function is called to update an area of each instance's pixmap by
+ * dithering the corresponding area of the image master.
*
* Results:
* None.
*
* Side effects:
- * The pixmap of each instance of this image gets updated.
- * The fields in *masterPtr indicating which area of the image
- * is correctly dithered get updated.
+ * The pixmap of each instance of this image gets updated. The fields in
+ * *masterPtr indicating which area of the image is correctly dithered
+ * get updated.
*
*----------------------------------------------------------------------
*/
void
-Tk_DitherPhoto(photo, x, y, width, height)
- Tk_PhotoHandle photo; /* Image master whose instances are
- * to be updated. */
- int x, y; /* Coordinates of the top-left pixel
- * in the area to be dithered. */
- int width, height; /* Dimensions of the area to be dithered. */
+Tk_DitherPhoto(
+ Tk_PhotoHandle photo, /* Image master whose instances are to be
+ * updated. */
+ int x, int y, /* Coordinates of the top-left pixel in the
+ * area to be dithered. */
+ int width, int height) /* Dimensions of the area to be dithered. */
{
PhotoMaster *masterPtr = (PhotoMaster *) photo;
PhotoInstance *instancePtr;
@@ -4990,14 +4997,13 @@ Tk_DitherPhoto(photo, x, y, width, height)
}
/*
- * Work out whether this block will be correctly dithered
- * and whether it will extend the correctly dithered region.
+ * Work out whether this block will be correctly dithered and whether it
+ * will extend the correctly dithered region.
*/
if (((y < masterPtr->ditherY)
|| ((y == masterPtr->ditherY) && (x <= masterPtr->ditherX)))
&& ((y + height) > (masterPtr->ditherY))) {
-
/*
* This block starts inside (or immediately after) the correctly
* dithered region, so the first scan line at least will be right.
@@ -5006,8 +5012,8 @@ Tk_DitherPhoto(photo, x, y, width, height)
if ((x == 0) && (width == masterPtr->width)) {
/*
- * We are doing the full width, therefore the dithering
- * will be correct to the end.
+ * We are doing the full width, therefore the dithering will be
+ * correct to the end.
*/
masterPtr->ditherX = 0;
@@ -5015,8 +5021,8 @@ Tk_DitherPhoto(photo, x, y, width, height)
} else {
/*
* We are doing partial scanlines, therefore the
- * correctly-dithered region will be extended by
- * at most one scan line.
+ * correctly-dithered region will be extended by at most one scan
+ * line.
*/
if (x <= masterPtr->ditherX) {
@@ -5028,16 +5034,15 @@ Tk_DitherPhoto(photo, x, y, width, height)
}
}
}
-
-}
+}
/*
*----------------------------------------------------------------------
*
* DitherInstance --
*
- * This procedure is called to update an area of an instance's
- * pixmap by dithering the corresponding area of the master.
+ * This function is called to update an area of an instance's pixmap by
+ * dithering the corresponding area of the master.
*
* Results:
* None.
@@ -5049,33 +5054,24 @@ Tk_DitherPhoto(photo, x, y, width, height)
*/
static void
-DitherInstance(instancePtr, xStart, yStart, width, height)
- PhotoInstance *instancePtr; /* The instance to be updated. */
- int xStart, yStart; /* Coordinates of the top-left pixel in the
+DitherInstance(
+ PhotoInstance *instancePtr, /* The instance to be updated. */
+ int xStart, int yStart, /* Coordinates of the top-left pixel in the
* block to be dithered. */
- int width, height; /* Dimensions of the block to be dithered. */
+ int width, int height) /* Dimensions of the block to be dithered. */
{
- PhotoMaster *masterPtr;
- ColorTable *colorPtr;
+ PhotoMaster *masterPtr = instancePtr->masterPtr;
+ ColorTable *colorPtr = instancePtr->colorTablePtr;
XImage *imagePtr;
- int nLines, bigEndian;
- int i, c, x, y;
- int xEnd, yEnd;
+ int nLines, bigEndian, i, c, x, y, xEnd, doDithering = 1;
int bitsPerPixel, bytesPerLine, lineLength;
- unsigned char *srcLinePtr, *srcPtr;
- schar *errLinePtr, *errPtr;
- unsigned char *destBytePtr, *dstLinePtr;
- pixel *destLongPtr;
+ unsigned char *srcLinePtr;
+ schar *errLinePtr;
pixel firstBit, word, mask;
- int col[3];
- int doDithering = 1;
-
- colorPtr = instancePtr->colorTablePtr;
- masterPtr = instancePtr->masterPtr;
/*
- * Turn dithering off in certain cases where it is not
- * needed (TrueColor, DirectColor with many colors).
+ * Turn dithering off in certain cases where it is not needed (TrueColor,
+ * DirectColor with many colors).
*/
if ((colorPtr->visualInfo.class == DirectColor)
@@ -5091,9 +5087,8 @@ DitherInstance(instancePtr, xStart, yStart, width, height)
}
/*
- * First work out how many lines to do at a time,
- * then how many bytes we'll need for pixel storage,
- * and allocate it.
+ * First work out how many lines to do at a time, then how many bytes
+ * we'll need for pixel storage, and allocate it.
*/
nLines = (MAX_PIXELS + width - 1) / width;
@@ -5106,14 +5101,15 @@ DitherInstance(instancePtr, xStart, yStart, width, height)
imagePtr = instancePtr->imagePtr;
if (imagePtr == NULL) {
- return; /* we must be really tight on memory */
+ return; /* We must be really tight on memory. */
}
bitsPerPixel = imagePtr->bits_per_pixel;
bytesPerLine = ((bitsPerPixel * width + 31) >> 3) & ~3;
imagePtr->width = width;
imagePtr->height = nLines;
imagePtr->bytes_per_line = bytesPerLine;
- imagePtr->data = (char *) ckalloc((unsigned) (imagePtr->bytes_per_line * nLines));
+ imagePtr->data = (char *)
+ ckalloc((unsigned) (imagePtr->bytes_per_line * nLines));
bigEndian = imagePtr->bitmap_bit_order == MSBFirst;
firstBit = bigEndian? (1 << (imagePtr->bitmap_unit - 1)): 1;
@@ -5123,46 +5119,50 @@ DitherInstance(instancePtr, xStart, yStart, width, height)
xEnd = xStart + width;
/*
- * Loop over the image, doing at most nLines lines before
- * updating the screen image.
+ * Loop over the image, doing at most nLines lines before updating the
+ * screen image.
*/
for (; height > 0; height -= nLines) {
+ unsigned char *dstLinePtr = (unsigned char *) imagePtr->data;
+ int yEnd;
+
if (nLines > height) {
nLines = height;
}
- dstLinePtr = (unsigned char *) imagePtr->data;
yEnd = yStart + nLines;
for (y = yStart; y < yEnd; ++y) {
- srcPtr = srcLinePtr;
- errPtr = errLinePtr;
- destBytePtr = dstLinePtr;
- destLongPtr = (pixel *) dstLinePtr;
+ unsigned char *srcPtr = srcLinePtr;
+ schar *errPtr = errLinePtr;
+ unsigned char *destBytePtr = dstLinePtr;
+ pixel *destLongPtr = (pixel *) dstLinePtr;
+
if (colorPtr->flags & COLOR_WINDOW) {
/*
- * Color window. We dither the three components
- * independently, using Floyd-Steinberg dithering,
- * which propagates errors from the quantization of
- * pixels to the pixels below and to the right.
+ * Color window. We dither the three components independently,
+ * using Floyd-Steinberg dithering, which propagates errors
+ * from the quantization of pixels to the pixels below and to
+ * the right.
*/
for (x = xStart; x < xEnd; ++x) {
+ int col[3];
+
if (doDithering) {
for (i = 0; i < 3; ++i) {
/*
* Compute the error propagated into this pixel
- * for this component.
- * If e[x,y] is the array of quantization error
- * values, we compute
+ * for this component. If e[x,y] is the array of
+ * quantization error values, we compute
* 7/16 * e[x-1,y] + 1/16 * e[x-1,y-1]
* + 5/16 * e[x,y-1] + 3/16 * e[x+1,y-1]
* and round it to an integer.
*
- * The expression ((c + 2056) >> 4) - 128
- * computes round(c / 16), and works correctly on
- * machines without a sign-extending right shift.
+ * The expression ((c + 2056) >> 4) - 128 computes
+ * round(c / 16), and works correctly on machines
+ * without a sign-extending right shift.
*/
-
+
c = (x > 0) ? errPtr[-3] * 7: 0;
if (y > 0) {
if (x > 0) {
@@ -5173,13 +5173,13 @@ DitherInstance(instancePtr, xStart, yStart, width, height)
c += errPtr[-lineLength+3] * 3;
}
}
-
+
/*
* Add the propagated error to the value of this
* component, quantize it, and store the
* quantization error.
*/
-
+
c = ((c + 2056) >> 4) - 128 + *srcPtr++;
if (c < 0) {
c = 0;
@@ -5190,9 +5190,9 @@ DitherInstance(instancePtr, xStart, yStart, width, height)
*errPtr++ = c - col[i];
}
} else {
- /*
- * Output is virtually continuous in this case,
- * so don't bother dithering.
+ /*
+ * Output is virtually continuous in this case, so
+ * don't bother dithering.
*/
col[0] = *srcPtr++;
@@ -5202,8 +5202,8 @@ DitherInstance(instancePtr, xStart, yStart, width, height)
srcPtr++;
/*
- * Translate the quantized component values into
- * an X pixel value, and store it in the image.
+ * Translate the quantized component values into an X
+ * pixel value, and store it in the image.
*/
i = colorPtr->redValues[col[0]]
@@ -5213,32 +5213,34 @@ DitherInstance(instancePtr, xStart, yStart, width, height)
i = colorPtr->pixelMap[i];
}
switch (bitsPerPixel) {
- case NBBY:
- *destBytePtr++ = i;
- break;
+ case NBBY:
+ *destBytePtr++ = i;
+ break;
#ifndef __WIN32__
-/*
- * This case is not valid for Windows because the image format is different
- * from the pixel format in Win32. Eventually we need to fix the image
- * code in Tk to use the Windows native image ordering. This would speed
- * up the image code for all of the common sizes.
- */
+ /*
+ * This case is not valid for Windows because the
+ * image format is different from the pixel format in
+ * Win32. Eventually we need to fix the image code in
+ * Tk to use the Windows native image ordering. This
+ * would speed up the image code for all of the common
+ * sizes.
+ */
- case NBBY * sizeof(pixel):
- *destLongPtr++ = i;
- break;
+ case NBBY * sizeof(pixel):
+ *destLongPtr++ = i;
+ break;
#endif
- default:
- XPutPixel(imagePtr, x - xStart, y - yStart,
- (unsigned) i);
+ default:
+ XPutPixel(imagePtr, x - xStart, y - yStart,
+ (unsigned) i);
}
}
} else if (bitsPerPixel > 1) {
/*
- * Multibit monochrome window. The operation here is similar
+ * Multibit monochrome window. The operation here is similar
* to the color window case above, except that there is only
- * one component. If the master image is in color, use the
+ * one component. If the master image is in color, use the
* luminance computed as
* 0.344 * red + 0.5 * green + 0.156 * blue.
*/
@@ -5260,7 +5262,7 @@ DitherInstance(instancePtr, xStart, yStart, width, height)
c += srcPtr[0];
} else {
c += (unsigned)(srcPtr[0] * 11 + srcPtr[1] * 16
- + srcPtr[2] * 5 + 16) >> 5;
+ + srcPtr[2] * 5 + 16) >> 5;
}
srcPtr += 4;
@@ -5273,40 +5275,42 @@ DitherInstance(instancePtr, xStart, yStart, width, height)
*errPtr++ = c - i;
i = colorPtr->redValues[i];
switch (bitsPerPixel) {
- case NBBY:
- *destBytePtr++ = i;
- break;
+ case NBBY:
+ *destBytePtr++ = i;
+ break;
#ifndef __WIN32__
-/*
- * This case is not valid for Windows because the image format is different
- * from the pixel format in Win32. Eventually we need to fix the image
- * code in Tk to use the Windows native image ordering. This would speed
- * up the image code for all of the common sizes.
- */
+ /*
+ * This case is not valid for Windows because the
+ * image format is different from the pixel format in
+ * Win32. Eventually we need to fix the image code in
+ * Tk to use the Windows native image ordering. This
+ * would speed up the image code for all of the common
+ * sizes.
+ */
- case NBBY * sizeof(pixel):
- *destLongPtr++ = i;
- break;
+ case NBBY * sizeof(pixel):
+ *destLongPtr++ = i;
+ break;
#endif
- default:
- XPutPixel(imagePtr, x - xStart, y - yStart,
- (unsigned) i);
+ default:
+ XPutPixel(imagePtr, x - xStart, y - yStart,
+ (unsigned) i);
}
}
} else {
/*
- * 1-bit monochrome window. This is similar to the
- * multibit monochrome case above, except that the
- * quantization is simpler (we only have black = 0
- * and white = 255), and we produce an XY-Bitmap.
+ * 1-bit monochrome window. This is similar to the multibit
+ * monochrome case above, except that the quantization is
+ * simpler (we only have black = 0 and white = 255), and we
+ * produce an XY-Bitmap.
*/
word = 0;
mask = firstBit;
for (x = xStart; x < xEnd; ++x) {
/*
- * If we have accumulated a whole word, store it
- * in the image and start a new word.
+ * If we have accumulated a whole word, store it in the
+ * image and start a new word.
*/
if (mask == 0) {
@@ -5331,7 +5335,7 @@ DitherInstance(instancePtr, xStart, yStart, width, height)
c += srcPtr[0];
} else {
c += (unsigned)(srcPtr[0] * 11 + srcPtr[1] * 16
- + srcPtr[2] * 5 + 16) >> 5;
+ + srcPtr[2] * 5 + 16) >> 5;
}
srcPtr += 4;
@@ -5356,8 +5360,8 @@ DitherInstance(instancePtr, xStart, yStart, width, height)
}
/*
- * Update the pixmap for this instance with the block of
- * pixels that we have just computed.
+ * Update the pixmap for this instance with the block of pixels that
+ * we have just computed.
*/
TkPutImage(colorPtr->pixelMap, colorPtr->numColors,
@@ -5365,7 +5369,6 @@ DitherInstance(instancePtr, xStart, yStart, width, height)
instancePtr->gc, imagePtr, 0, 0, xStart, yStart,
(unsigned) width, (unsigned) nLines);
yStart = yEnd;
-
}
ckfree(imagePtr->data);
@@ -5377,26 +5380,25 @@ DitherInstance(instancePtr, xStart, yStart, width, height)
*
* Tk_PhotoBlank --
*
- * This procedure is called to clear an entire photo image.
+ * This function is called to clear an entire photo image.
*
* Results:
* None.
*
* Side effects:
- * The valid region for the image is set to the null region.
- * The generic image code is notified that the image has changed.
+ * The valid region for the image is set to the null region. The generic
+ * image code is notified that the image has changed.
*
*----------------------------------------------------------------------
*/
void
-Tk_PhotoBlank(handle)
- Tk_PhotoHandle handle; /* Handle for the image to be blanked. */
+Tk_PhotoBlank(
+ Tk_PhotoHandle handle) /* Handle for the image to be blanked. */
{
- PhotoMaster *masterPtr;
+ PhotoMaster *masterPtr = (PhotoMaster *) handle;
PhotoInstance *instancePtr;
- masterPtr = (PhotoMaster *) handle;
masterPtr->ditherX = masterPtr->ditherY = 0;
masterPtr->flags = 0;
@@ -5410,16 +5412,16 @@ Tk_PhotoBlank(handle)
masterPtr->validRegion = TkCreateRegion();
/*
- * Clear out the 32-bit pixel storage array.
- * Clear out the dithering error arrays for each instance.
+ * Clear out the 32-bit pixel storage array. Clear out the dithering error
+ * arrays for each instance.
*/
- memset((VOID *) masterPtr->pix32, 0,
+ memset(masterPtr->pix32, 0,
(size_t) (masterPtr->width * masterPtr->height * 4));
for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
instancePtr = instancePtr->nextPtr) {
if (instancePtr->error) {
- memset((VOID *) instancePtr->error, 0,
+ memset(instancePtr->error, 0,
(size_t) (masterPtr->width * masterPtr->height
* 3 * sizeof(schar)));
}
@@ -5438,30 +5440,29 @@ Tk_PhotoBlank(handle)
*
* Tk_PhotoExpand --
*
- * This procedure is called to request that a photo image be
- * expanded if necessary to be at least `width' pixels wide and
- * `height' pixels high. If the user has declared a definite
- * image size (using the -width and -height configuration
- * options) then this call has no effect.
+ * This function is called to request that a photo image be expanded if
+ * necessary to be at least `width' pixels wide and `height' pixels high.
+ * If the user has declared a definite image size (using the -width and
+ * -height configuration options) then this call has no effect.
*
* Results:
* None.
*
* Side effects:
- * The size of the photo image may change; if so the generic
- * image code is informed.
+ * The size of the photo image may change; if so the generic image code
+ * is informed.
*
*----------------------------------------------------------------------
*/
-void
-Tk_PhotoExpand(handle, width, height)
- Tk_PhotoHandle handle; /* Handle for the image to be expanded. */
- int width, height; /* Desired minimum dimensions of the image. */
+int
+Tk_PhotoExpand(
+ Tcl_Interp *interp, /* Interpreter for passing back error
+ * messages, or NULL. */
+ Tk_PhotoHandle handle, /* Handle for the image to be expanded. */
+ int width, int height) /* Desired minimum dimensions of the image. */
{
- PhotoMaster *masterPtr;
-
- masterPtr = (PhotoMaster *) handle;
+ PhotoMaster *masterPtr = (PhotoMaster *) handle;
if (width <= masterPtr->width) {
width = masterPtr->width;
@@ -5472,11 +5473,16 @@ Tk_PhotoExpand(handle, width, height)
if ((width != masterPtr->width) || (height != masterPtr->height)) {
if (ImgPhotoSetSize(masterPtr, MAX(width, masterPtr->width),
MAX(height, masterPtr->height)) == TCL_ERROR) {
- panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
+ if (interp != NULL) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);
+ }
+ return TCL_ERROR;
}
Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0, masterPtr->width,
masterPtr->height);
}
+ return TCL_OK;
}
/*
@@ -5484,12 +5490,10 @@ Tk_PhotoExpand(handle, width, height)
*
* Tk_PhotoGetSize --
*
- * This procedure is called to obtain the current size of a photo
- * image.
+ * This function is called to obtain the current size of a photo image.
*
* Results:
- * The image's width and height are returned in *widthp
- * and *heightp.
+ * The image's width and height are returned in *widthp and *heightp.
*
* Side effects:
* None.
@@ -5498,15 +5502,15 @@ Tk_PhotoExpand(handle, width, height)
*/
void
-Tk_PhotoGetSize(handle, widthPtr, heightPtr)
- Tk_PhotoHandle handle; /* Handle for the image whose dimensions
- * are requested. */
- int *widthPtr, *heightPtr; /* The dimensions of the image are returned
+Tk_PhotoGetSize(
+ Tk_PhotoHandle handle, /* Handle for the image whose dimensions are
+ * requested. */
+ int *widthPtr, int *heightPtr)
+ /* The dimensions of the image are returned
* here. */
{
- PhotoMaster *masterPtr;
+ PhotoMaster *masterPtr = (PhotoMaster *) handle;
- masterPtr = (PhotoMaster *) handle;
*widthPtr = masterPtr->width;
*heightPtr = masterPtr->height;
}
@@ -5516,38 +5520,42 @@ Tk_PhotoGetSize(handle, widthPtr, heightPtr)
*
* Tk_PhotoSetSize --
*
- * This procedure is called to set size of a photo image.
- * This call is equivalent to using the -width and -height
- * configuration options.
+ * This function is called to set size of a photo image. This call is
+ * equivalent to using the -width and -height configuration options.
*
* Results:
* None.
*
* Side effects:
- * The size of the image may change; if so the generic
- * image code is informed.
+ * The size of the image may change; if so the generic image code is
+ * informed.
*
*----------------------------------------------------------------------
*/
-void
-Tk_PhotoSetSize(handle, width, height)
- Tk_PhotoHandle handle; /* Handle for the image whose size is to
- * be set. */
- int width, height; /* New dimensions for the image. */
+int
+Tk_PhotoSetSize(
+ Tcl_Interp *interp, /* Interpreter for passing back error
+ * messages, or NULL. */
+ Tk_PhotoHandle handle, /* Handle for the image whose size is to be
+ * set. */
+ int width, int height) /* New dimensions for the image. */
{
- PhotoMaster *masterPtr;
-
- masterPtr = (PhotoMaster *) handle;
+ PhotoMaster *masterPtr = (PhotoMaster *) handle;
masterPtr->userWidth = width;
masterPtr->userHeight = height;
if (ImgPhotoSetSize(masterPtr, ((width > 0) ? width: masterPtr->width),
((height > 0) ? height: masterPtr->height)) == TCL_ERROR) {
- panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
+ if (interp != NULL) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL);
+ }
+ return TCL_ERROR;
}
Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0,
masterPtr->width, masterPtr->height);
+ return TCL_OK;
}
/*
@@ -5555,14 +5563,14 @@ Tk_PhotoSetSize(handle, width, height)
*
* TkGetPhotoValidRegion --
*
- * This procedure is called to get the part of the photo where
- * there is valid data. Or, conversely, the part of the photo
- * which is transparent.
+ * This function is called to get the part of the photo where there is
+ * valid data. Or, conversely, the part of the photo which is
+ * transparent.
*
* Results:
- * A TkRegion value that indicates the current area of the photo
- * that is valid. This value should not be used after any
- * modification to the photo image.
+ * A TkRegion value that indicates the current area of the photo that is
+ * valid. This value should not be used after any modification to the
+ * photo image.
*
* Side Effects:
* None.
@@ -5571,13 +5579,12 @@ Tk_PhotoSetSize(handle, width, height)
*/
TkRegion
-TkPhotoGetValidRegion(handle)
- Tk_PhotoHandle handle; /* Handle for the image whose valid region
- * is to obtained. */
+TkPhotoGetValidRegion(
+ Tk_PhotoHandle handle) /* Handle for the image whose valid region is
+ * to obtained. */
{
- PhotoMaster *masterPtr;
+ PhotoMaster *masterPtr = (PhotoMaster *) handle;
- masterPtr = (PhotoMaster *) handle;
return masterPtr->validRegion;
}
@@ -5586,15 +5593,15 @@ TkPhotoGetValidRegion(handle)
*
* ImgGetPhoto --
*
- * This procedure is called to obtain image data from a photo
- * image. This procedure fills in the Tk_PhotoImageBlock structure
- * pointed to by `blockPtr' with details of the address and
- * layout of the image data in memory.
+ * This function is called to obtain image data from a photo image. This
+ * function fills in the Tk_PhotoImageBlock structure pointed to by
+ * `blockPtr' with details of the address and layout of the image data in
+ * memory.
*
* Results:
- * A pointer to the allocated data which should be freed later.
- * NULL if there is no need to free data because
- * blockPtr->pixelPtr points directly to the image data.
+ * A pointer to the allocated data which should be freed later. NULL if
+ * there is no need to free data because blockPtr->pixelPtr points
+ * directly to the image data.
*
* Side effects:
* None.
@@ -5603,13 +5610,13 @@ TkPhotoGetValidRegion(handle)
*/
static char *
-ImgGetPhoto(masterPtr, blockPtr, optPtr)
- PhotoMaster *masterPtr; /* Handle for the photo image from which
- * image data is desired. */
- Tk_PhotoImageBlock *blockPtr;
- /* Information about the address and layout
- * of the image data is returned here. */
- struct SubcommandOptions *optPtr;
+ImgGetPhoto(
+ PhotoMaster *masterPtr, /* Handle for the photo image from which image
+ * data is desired. */
+ Tk_PhotoImageBlock *blockPtr,
+ /* Information about the address and layout of
+ * the image data is returned here. */
+ struct SubcommandOptions *optPtr)
{
unsigned char *pixelPtr;
int x, y, greenOffset, blueOffset, alphaOffset;
@@ -5624,8 +5631,7 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr)
(!(optPtr->options & OPT_BACKGROUND)
|| ((optPtr->background->red == optPtr->background->green)
&& (optPtr->background->red == optPtr->background->blue)))) {
- blockPtr->offset[0] = blockPtr->offset[1] =
- blockPtr->offset[2];
+ blockPtr->offset[0] = blockPtr->offset[1] = blockPtr->offset[2];
}
alphaOffset = 0;
for (y = 0; y < blockPtr->height; y++) {
@@ -5651,13 +5657,14 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr)
greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
blueOffset = blockPtr->offset[2] - blockPtr->offset[0];
if (((optPtr->options & OPT_BACKGROUND) && alphaOffset) ||
- ((optPtr->options & OPT_GRAYSCALE) && (greenOffset || blueOffset))) {
+ ((optPtr->options & OPT_GRAYSCALE) && (greenOffset||blueOffset))) {
int newPixelSize,x,y;
unsigned char *srcPtr, *destPtr;
char *data;
- newPixelSize = (!(optPtr->options & OPT_BACKGROUND) && alphaOffset) ? 2 : 1;
- if ((greenOffset || blueOffset) && !(optPtr->options & OPT_GRAYSCALE)) {
+ newPixelSize = (!(optPtr->options & OPT_BACKGROUND) && alphaOffset)
+ ? 2 : 1;
+ if ((greenOffset||blueOffset) && !(optPtr->options & OPT_GRAYSCALE)) {
newPixelSize += 2;
}
data = ckalloc((unsigned int) (newPixelSize *
@@ -5671,17 +5678,19 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr)
srcPtr += blockPtr->pixelSize;
destPtr += newPixelSize;
}
- srcPtr += blockPtr->pitch - (blockPtr->width * blockPtr->pixelSize);
+ srcPtr += blockPtr->pitch -
+ blockPtr->width * blockPtr->pixelSize;
}
} else if (optPtr->options & OPT_GRAYSCALE) {
for (y = blockPtr->height; y > 0; y--) {
for (x = blockPtr->width; x > 0; x--) {
- *destPtr = (unsigned char) ((srcPtr[0] * 11 + srcPtr[1] * 16
- + srcPtr[2] * 5 + 16) >> 5);
+ *destPtr = (unsigned char) ((srcPtr[0]*11 + srcPtr[1]*16
+ + srcPtr[2]*5 + 16) >> 5);
srcPtr += blockPtr->pixelSize;
destPtr += newPixelSize;
}
- srcPtr += blockPtr->pitch - (blockPtr->width * blockPtr->pixelSize);
+ srcPtr += blockPtr->pitch -
+ blockPtr->width * blockPtr->pixelSize;
}
} else {
for (y = blockPtr->height; y > 0; y--) {
@@ -5692,18 +5701,22 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr)
srcPtr += blockPtr->pixelSize;
destPtr += newPixelSize;
}
- srcPtr += blockPtr->pitch - (blockPtr->width * blockPtr->pixelSize);
+ srcPtr += blockPtr->pitch -
+ blockPtr->width * blockPtr->pixelSize;
}
}
srcPtr = blockPtr->pixelPtr + alphaOffset;
destPtr = (unsigned char *) data;
if (!alphaOffset) {
- /* nothing to be done */
+ /*
+ * Nothing to be done.
+ */
} else if (optPtr->options & OPT_BACKGROUND) {
if (newPixelSize > 2) {
- int red = optPtr->background->red>>8;
- int green = optPtr->background->green>>8;
- int blue = optPtr->background->blue>>8;
+ int red = optPtr->background->red>>8;
+ int green = optPtr->background->green>>8;
+ int blue = optPtr->background->blue>>8;
+
for (y = blockPtr->height; y > 0; y--) {
for (x = blockPtr->width; x > 0; x--) {
destPtr[0] += (unsigned char) (((255 - *srcPtr) *
@@ -5715,12 +5728,14 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr)
srcPtr += blockPtr->pixelSize;
destPtr += newPixelSize;
}
- srcPtr += blockPtr->pitch - (blockPtr->width * blockPtr->pixelSize);
+ srcPtr += blockPtr->pitch -
+ blockPtr->width * blockPtr->pixelSize;
}
} else {
int gray = (unsigned char) (((optPtr->background->red>>8) * 11
- + (optPtr->background->green>>8) * 16
- + (optPtr->background->blue>>8) * 5 + 16) >> 5);
+ + (optPtr->background->green>>8) * 16
+ + (optPtr->background->blue>>8) * 5 + 16) >> 5);
+
for (y = blockPtr->height; y > 0; y--) {
for (x = blockPtr->width; x > 0; x--) {
destPtr[0] += ((255 - *srcPtr) *
@@ -5728,7 +5743,8 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr)
srcPtr += blockPtr->pixelSize;
destPtr += newPixelSize;
}
- srcPtr += blockPtr->pitch - (blockPtr->width * blockPtr->pixelSize);
+ srcPtr += blockPtr->pitch -
+ blockPtr->width * blockPtr->pixelSize;
}
}
} else {
@@ -5739,7 +5755,8 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr)
srcPtr += blockPtr->pixelSize;
destPtr += newPixelSize;
}
- srcPtr += blockPtr->pitch - (blockPtr->width * blockPtr->pixelSize);
+ srcPtr += blockPtr->pitch -
+ blockPtr->width * blockPtr->pixelSize;
}
}
blockPtr->pixelPtr = (unsigned char *) data;
@@ -5763,8 +5780,8 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr)
*
* ImgStringWrite --
*
- * Default string write function. The data is formatted in
- * the default format as accepted by the "<img> put" command.
+ * Default string write function. The data is formatted in the default
+ * format as accepted by the "<img> put" command.
*
* Results:
* A standard Tcl result.
@@ -5776,12 +5793,12 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr)
*/
static int
-ImgStringWrite(interp, formatString, blockPtr)
- Tcl_Interp *interp;
- Tcl_Obj *formatString;
- Tk_PhotoImageBlock *blockPtr;
+ImgStringWrite(
+ Tcl_Interp *interp,
+ Tcl_Obj *formatString,
+ Tk_PhotoImageBlock *blockPtr)
{
- int row,col;
+ int row, col;
char *line, *linePtr;
unsigned char *pixelPtr;
int greenOffset, blueOffset;
@@ -5816,14 +5833,14 @@ ImgStringWrite(interp, formatString, blockPtr)
*
* Tk_PhotoGetImage --
*
- * This procedure is called to obtain image data from a photo
- * image. This procedure fills in the Tk_PhotoImageBlock structure
- * pointed to by `blockPtr' with details of the address and
- * layout of the image data in memory.
+ * This function is called to obtain image data from a photo image. This
+ * function fills in the Tk_PhotoImageBlock structure pointed to by
+ * `blockPtr' with details of the address and layout of the image data in
+ * memory.
*
* Results:
- * TRUE (1) indicating that image data is available,
- * for backwards compatibility with the old photo widget.
+ * TRUE (1) indicating that image data is available, for backwards
+ * compatibility with the old photo widget.
*
* Side effects:
* None.
@@ -5832,16 +5849,15 @@ ImgStringWrite(interp, formatString, blockPtr)
*/
int
-Tk_PhotoGetImage(handle, blockPtr)
- Tk_PhotoHandle handle; /* Handle for the photo image from which
- * image data is desired. */
- Tk_PhotoImageBlock *blockPtr;
- /* Information about the address and layout
- * of the image data is returned here. */
+Tk_PhotoGetImage(
+ Tk_PhotoHandle handle, /* Handle for the photo image from which image
+ * data is desired. */
+ Tk_PhotoImageBlock *blockPtr)
+ /* Information about the address and layout of
+ * the image data is returned here. */
{
- PhotoMaster *masterPtr;
+ PhotoMaster *masterPtr = (PhotoMaster *) handle;
- masterPtr = (PhotoMaster *) handle;
blockPtr->pixelPtr = masterPtr->pix32;
blockPtr->width = masterPtr->width;
blockPtr->height = masterPtr->height;
@@ -5853,7 +5869,7 @@ Tk_PhotoGetImage(handle, blockPtr)
blockPtr->offset[3] = 3;
return 1;
}
-
+
/*
*----------------------------------------------------------------------
*
@@ -5871,57 +5887,56 @@ Tk_PhotoGetImage(handle, blockPtr)
*/
typedef struct OptionAssocData {
- struct OptionAssocData *nextPtr; /* pointer to next OptionAssocData */
- Tcl_ObjCmdProc *command; /* command associated with this
- * option */
- char name[1]; /* name of option (remaining chars) */
+ struct OptionAssocData *nextPtr;
+ /* Pointer to next OptionAssocData. */
+ Tcl_ObjCmdProc *command; /* Command associated with this option. */
+ char name[1]; /* Name of option (remaining chars) */
} OptionAssocData;
static Tcl_ObjCmdProc *
-PhotoOptionFind(interp, obj)
- Tcl_Interp *interp; /* Interpreter that is being deleted. */
- Tcl_Obj *obj; /* Name of option to be found. */
+PhotoOptionFind(
+ Tcl_Interp *interp, /* Interpreter that is being deleted. */
+ Tcl_Obj *obj) /* Name of option to be found. */
{
int length;
char *name = Tcl_GetStringFromObj(obj, &length);
- OptionAssocData *list;
char *prevname = NULL;
- Tcl_ObjCmdProc *proc = (Tcl_ObjCmdProc *) NULL;
+ Tcl_ObjCmdProc *proc = NULL;
+ OptionAssocData *list = (OptionAssocData *) Tcl_GetAssocData(interp,
+ "photoOption", NULL);
- list = (OptionAssocData *) Tcl_GetAssocData(interp, "photoOption",
- (Tcl_InterpDeleteProc **) NULL);
- while (list != (OptionAssocData *) NULL) {
+ while (list != NULL) {
if (strncmp(name, list->name, (unsigned) length) == 0) {
- if (proc != (Tcl_ObjCmdProc *) NULL) {
+ if (proc != NULL) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "ambiguous option \"", name,
- "\": must be ", prevname, (char *) NULL);
- while (list->nextPtr != (OptionAssocData *) NULL) {
- Tcl_AppendResult(interp, prevname, ", ",(char *) NULL);
+ "\": must be ", prevname, NULL);
+ while (list->nextPtr != NULL) {
+ Tcl_AppendResult(interp, prevname, ", ",NULL);
list = list->nextPtr;
prevname = list->name;
}
- Tcl_AppendResult(interp, ", or", prevname, (char *) NULL);
- return (Tcl_ObjCmdProc *) NULL;
+ Tcl_AppendResult(interp, ", or", prevname, NULL);
+ return NULL;
}
proc = list->command;
prevname = list->name;
}
list = list->nextPtr;
}
- if (proc != (Tcl_ObjCmdProc *) NULL) {
+ if (proc != NULL) {
Tcl_ResetResult(interp);
}
return proc;
}
-
+
/*
*----------------------------------------------------------------------
*
* PhotoOptionCleanupProc --
*
- * This procedure is invoked whenever an interpreter is deleted
- * to cleanup the AssocData for "photoVisitor".
+ * This function is invoked whenever an interpreter is deleted to cleanup
+ * the AssocData for "photoVisitor".
*
* Results:
* None.
@@ -5933,49 +5948,47 @@ PhotoOptionFind(interp, obj)
*/
static void
-PhotoOptionCleanupProc(clientData, interp)
- ClientData clientData; /* Points to "photoVisitor" AssocData
- * for the interpreter. */
- Tcl_Interp *interp; /* Interpreter that is being deleted. */
+PhotoOptionCleanupProc(
+ ClientData clientData, /* Points to "photoVisitor" AssocData for the
+ * interpreter. */
+ Tcl_Interp *interp) /* Interpreter that is being deleted. */
{
OptionAssocData *list = (OptionAssocData *) clientData;
- OptionAssocData *ptr;
while (list != NULL) {
+ register OptionAssocData *ptr;
+
list = (ptr = list)->nextPtr;
ckfree((char *) ptr);
}
}
-
+
/*
*--------------------------------------------------------------
*
* Tk_CreatePhotoOption --
*
- * This procedure may be invoked to add a new kind of photo
- * option to the core photo command supported by Tk.
+ * This function may be invoked to add a new kind of photo option to the
+ * core photo command supported by Tk.
*
* Results:
* None.
*
* Side effects:
- * From now on, the new option will be useable by the
- * photo command.
+ * From now on, the new option will be useable by the photo command.
*
*--------------------------------------------------------------
*/
-void
-Tk_CreatePhotoOption(interp, name, proc)
- Tcl_Interp *interp; /* interpreter */
- CONST char *name; /* option name */
- Tcl_ObjCmdProc *proc; /* proc to execute command */
+MODULE_SCOPE void
+Tk_CreatePhotoOption(
+ Tcl_Interp *interp, /* Interpreter. */
+ CONST char *name, /* Option name. */
+ Tcl_ObjCmdProc *proc) /* Function to execute command. */
{
OptionAssocData *typePtr2, *prevPtr, *ptr;
- OptionAssocData *list;
-
- list = (OptionAssocData *) Tcl_GetAssocData(interp, "photoOption",
- (Tcl_InterpDeleteProc **) NULL);
+ OptionAssocData *list = (OptionAssocData *)
+ Tcl_GetAssocData(interp, "photoOption", NULL);
/*
* If there's already a photo option with the given name, remove it.
@@ -5998,7 +6011,7 @@ Tk_CreatePhotoOption(interp, name, proc)
ptr->command = proc;
ptr->nextPtr = list;
Tcl_SetAssocData(interp, "photoOption", PhotoOptionCleanupProc,
- (ClientData) ptr);
+ (ClientData) ptr);
}
/*
@@ -6006,9 +6019,8 @@ Tk_CreatePhotoOption(interp, name, proc)
*
* TkPostscriptPhoto --
*
- * This procedure is called to output the contents of a
- * photo image in Postscript by calling the Tk_PostscriptPhoto
- * function.
+ * This function is called to output the contents of a photo image in
+ * Postscript by calling the Tk_PostscriptPhoto function.
*
* Results:
* Returns a standard Tcl return value.
@@ -6018,16 +6030,16 @@ Tk_CreatePhotoOption(interp, name, proc)
*
*--------------------------------------------------------------
*/
+
static int
-ImgPhotoPostscript(clientData, interp, tkwin, psInfo,
- x, y, width, height, prepass)
- ClientData clientData; /* Handle for the photo image */
- Tcl_Interp *interp; /* Interpreter */
- Tk_Window tkwin; /* (unused) */
- Tk_PostscriptInfo psInfo; /* postscript info */
- int x, y; /* First pixel to output */
- int width, height; /* Width and height of area */
- int prepass; /* (unused) */
+ImgPhotoPostscript(
+ ClientData clientData, /* Handle for the photo image. */
+ Tcl_Interp *interp, /* Interpreter. */
+ Tk_Window tkwin, /* (unused) */
+ Tk_PostscriptInfo psInfo, /* Postscript info. */
+ int x, int y, /* First pixel to output. */
+ int width, int height, /* Width and height of area. */
+ int prepass) /* (unused) */
{
Tk_PhotoImageBlock block;
@@ -6042,29 +6054,105 @@ ImgPhotoPostscript(clientData, interp, tkwin, psInfo,
*
* Tk_PhotoPutBlock_NoComposite, Tk_PhotoPutZoomedBlock_NoComposite --
*
- * These backward-compatability functions just exist to fill slots in
- * stubs table. For the behaviour of *_NoComposite, refer to the
- * corresponding function without the extra suffix.
+ * These backward-compatability functions just exist to fill slots in stubs
+ * table. For the behaviour of *_NoComposite, refer to the corresponding
+ * function without the extra suffix, except that the compositing rule is
+ * always "overlay" and the function always panics on memory-allocation
+ * failure.
*
*----------------------------------------------------------------------
*/
+
void
-Tk_PhotoPutBlock_NoComposite(handle, blockPtr, x, y, width, height)
- Tk_PhotoHandle handle;
- Tk_PhotoImageBlock *blockPtr;
- int x, y, width, height;
+Tk_PhotoPutBlock_NoComposite(
+ Tk_PhotoHandle handle,
+ Tk_PhotoImageBlock *blockPtr,
+ int x, int y, int width, int height)
{
- Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height,
- TK_PHOTO_COMPOSITE_OVERLAY);
+ if (Tk_PhotoPutBlock(NULL, handle, blockPtr, x, y, width, height,
+ TK_PHOTO_COMPOSITE_OVERLAY) != TCL_OK) {
+ Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
+ }
}
void
-Tk_PhotoPutZoomedBlock_NoComposite(handle, blockPtr, x, y, width, height,
- zoomX, zoomY, subsampleX, subsampleY)
- Tk_PhotoHandle handle;
- Tk_PhotoImageBlock *blockPtr;
- int x, y, width, height, zoomX, zoomY, subsampleX, subsampleY;
+Tk_PhotoPutZoomedBlock_NoComposite(
+ Tk_PhotoHandle handle,
+ Tk_PhotoImageBlock *blockPtr,
+ int x, int y, int width, int height,
+ int zoomX, int zoomY, int subsampleX, int subsampleY)
{
- Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height,
- zoomX, zoomY, subsampleX, subsampleY, TK_PHOTO_COMPOSITE_OVERLAY);
+ if (Tk_PhotoPutZoomedBlock(NULL, handle, blockPtr, x, y, width, height,
+ zoomX, zoomY, subsampleX, subsampleY,
+ TK_PHOTO_COMPOSITE_OVERLAY) != TCL_OK) {
+ Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
+ }
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_PhotoExpand_Panic, Tk_PhotoPutBlock_Panic,
+ * Tk_PhotoPutZoomedBlock_Panic, Tk_PhotoSetSize_Panic
+ *
+ * Backward compatability functions for preserving the old behaviour (i.e.
+ * panic on memory allocation failure) so that extensions do not need to be
+ * significantly updated to take account of TIP #116. These call the new
+ * interface (i.e. the interface without the extra suffix), but panic if an
+ * error condition is returned.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_PhotoExpand_Panic(
+ Tk_PhotoHandle handle,
+ int width, int height)
+{
+ if (Tk_PhotoExpand(NULL, handle, width, height) != TCL_OK) {
+ Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
+ }
+}
+
+void
+Tk_PhotoPutBlock_Panic(
+ Tk_PhotoHandle handle,
+ Tk_PhotoImageBlock *blockPtr,
+ int x, int y, int width, int height, int compRule)
+{
+ if (Tk_PhotoPutBlock(NULL, handle, blockPtr, x, y, width, height,
+ compRule) != TCL_OK) {
+ Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
+ }
+}
+
+void
+Tk_PhotoPutZoomedBlock_Panic(
+ Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr,
+ int x, int y, int width, int height,
+ int zoomX, int zoomY, int subsampleX, int subsampleY,
+ int compRule)
+{
+ if (Tk_PhotoPutZoomedBlock(NULL, handle, blockPtr, x, y, width, height,
+ zoomX, zoomY, subsampleX, subsampleY, compRule) != TCL_OK) {
+ Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
+ }
+}
+
+void
+Tk_PhotoSetSize_Panic(
+ Tk_PhotoHandle handle,
+ int width, int height)
+{
+ if (Tk_PhotoSetSize(NULL, handle, width, height) != TCL_OK) {
+ Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
+ }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkImgUtil.c b/generic/tkImgUtil.c
index 0bb599a..8ba6c0e 100644
--- a/generic/tkImgUtil.c
+++ b/generic/tkImgUtil.c
@@ -1,16 +1,15 @@
-/*
+/*
* tkImgUtil.c --
*
* This file contains image related utility functions.
*
* Copyright (c) 1995 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
-#include "tkPort.h"
#include "xbytes.h"
@@ -19,12 +18,11 @@
*
* TkAlignImageData --
*
- * This function takes an image and copies the data into an
- * aligned buffer, performing any necessary bit swapping.
+ * This function takes an image and copies the data into an aligned
+ * buffer, performing any necessary bit swapping.
*
* Results:
- * Returns a newly allocated buffer that should be freed by the
- * caller.
+ * Returns a newly allocated buffer that should be freed by the caller.
*
* Side effects:
* None.
@@ -33,18 +31,19 @@
*/
char *
-TkAlignImageData(image, alignment, bitOrder)
- XImage *image; /* Image to be aligned. */
- int alignment; /* Number of bytes to which the data should
- * be aligned (e.g. 2 or 4) */
- int bitOrder; /* Desired bit order: LSBFirst or MSBFirst. */
+TkAlignImageData(
+ XImage *image, /* Image to be aligned. */
+ int alignment, /* Number of bytes to which the data should be
+ * aligned (e.g. 2 or 4) */
+ int bitOrder) /* Desired bit order: LSBFirst or MSBFirst. */
{
long dataWidth;
char *data, *srcPtr, *destPtr;
int i, j;
if (image->bits_per_pixel != 1) {
- panic("TkAlignImageData: Can't handle image depths greater than 1.");
+ Tcl_Panic(
+ "TkAlignImageData: Can't handle image depths greater than 1.");
}
/*
@@ -56,7 +55,7 @@ TkAlignImageData(image, alignment, bitOrder)
dataWidth += (alignment - (dataWidth % alignment));
}
- data = ckalloc(dataWidth * image->height);
+ data = ckalloc((unsigned) dataWidth * image->height);
destPtr = data;
for (i = 0; i < image->height; i++) {
@@ -74,3 +73,11 @@ TkAlignImageData(image, alignment, bitOrder)
}
return data;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkInitScript.h b/generic/tkInitScript.h
deleted file mode 100644
index 4997fe7..0000000
--- a/generic/tkInitScript.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * tkInitScript.h --
- *
- * This file contains Unix & Windows common init script
- * It is not used on the Mac. (the mac init script is in tkMacInit.c)
- *
- * 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.
- */
-
-
-
-/*
- * In order to find tk.tcl during initialization, the following script
- * is invoked by Tk_Init(). It looks in several different directories:
- *
- * $tk_library - can specify a primary location, if set
- * no other locations will be checked
- *
- * $env(TK_LIBRARY) - highest priority so user can always override
- * the search path unless the application has
- * specified an exact directory above
- *
- * $tcl_library/../tk$tk_version
- * - look relative to init.tcl in an installed
- * lib directory (e.g. /usr/local)
- *
- * <executable directory>/../lib/tk$tk_version
- * - look for a lib/tk<ver> in a sibling of
- * the bin directory (e.g. /usr/local)
- *
- * <executable directory>/../library
- * - look in Tk build directory
- *
- * <executable directory>/../../tk$tk_patchLevel/library
- * - look for Tk build directory relative
- * to a parallel build directory
- *
- * The first directory on this path that contains a valid tk.tcl script
- * will be set ast the value of tk_library.
- *
- * Note that this entire search mechanism can be bypassed by defining an
- * alternate tkInit procedure before calling Tk_Init().
- */
-
-static char initScript[] = "if {[info proc tkInit]==\"\"} {\n\
- proc tkInit {} {\n\
- global tk_library tk_version tk_patchLevel\n\
- rename tkInit {}\n\
- tcl_findLibrary tk $tk_version $tk_patchLevel tk.tcl TK_LIBRARY tk_library\n\
- }\n\
-}\n\
-tkInit";
-
diff --git a/generic/tkInt.decls b/generic/tkInt.decls
index a37f986..6794edb 100644
--- a/generic/tkInt.decls
+++ b/generic/tkInt.decls
@@ -5,6 +5,8 @@
# tkIntDecls.h, tkIntPlatDecls.h, tkIntStub.c, and tkPlatStub.c files.
#
# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
+#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -485,11 +487,88 @@ declare 149 {
const Tk_OptionSpec *TkGetOptionSpec(const char *name,
Tk_OptionTable optionTable)
}
+
+# TIP#168
+declare 150 {
+ int TkMakeRawCurve(Tk_Canvas canvas, double *pointPtr, int numPoints,
+ int numSteps, XPoint xPoints[], double dblPoints[])
+}
+declare 151 {
+ void TkMakeRawCurvePostscript(Tcl_Interp *interp,
+ Tk_Canvas canvas, double *pointPtr, int numPoints)
+}
declare 152 {
void TkpDrawFrame(Tk_Window tkwin, Tk_3DBorder border,
int highlightWidth, int borderWidth, int relief)
}
+declare 153 {
+ void TkCreateThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData)
+}
+declare 154 {
+ void TkDeleteThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData)
+}
+# entries needed only by tktest:
+declare 156 {
+ int TkpTestembedCmd(ClientData clientData, Tcl_Interp *interp, int argc,
+ const char **argv)
+}
+declare 157 {
+ int TkpTesttextCmd(ClientData dummy, Tcl_Interp *interp, int argc,
+ const char **argv)
+}
+
+# Next group of functions exposed due to [Bug 2768945]. Numbers are chosen so
+# as to match 8.6 branch/HEAD.
+declare 169 {
+ int TkStateParseProc(ClientData clientData, Tcl_Interp *interp,
+ Tk_Window tkwin, const char *value, char *widgRec, int offset)
+}
+declare 170 {
+ char *TkStatePrintProc(ClientData clientData, Tk_Window tkwin,
+ char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
+}
+declare 171 {
+ int TkCanvasDashParseProc(ClientData clientData, Tcl_Interp *interp,
+ Tk_Window tkwin, const char *value, char *widgRec, int offset)
+}
+declare 172 {
+ char *TkCanvasDashPrintProc(ClientData clientData, Tk_Window tkwin,
+ char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
+}
+declare 173 {
+ int TkOffsetParseProc(ClientData clientData, Tcl_Interp *interp,
+ Tk_Window tkwin, const char *value, char *widgRec, int offset)
+}
+declare 174 {
+ char *TkOffsetPrintProc(ClientData clientData, Tk_Window tkwin,
+ char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
+}
+declare 175 {
+ int TkPixelParseProc(ClientData clientData, Tcl_Interp *interp,
+ Tk_Window tkwin, const char *value, char *widgRec, int offset)
+}
+declare 176 {
+ char *TkPixelPrintProc(ClientData clientData, Tk_Window tkwin,
+ char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
+}
+declare 177 {
+ int TkOrientParseProc(ClientData clientData, Tcl_Interp *interp,
+ Tk_Window tkwin, const char *value, char *widgRec, int offset)
+}
+declare 178 {
+ char *TkOrientPrintProc(ClientData clientData, Tk_Window tkwin,
+ char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
+}
+declare 179 {
+ int TkSmoothParseProc(ClientData clientData, Tcl_Interp *interp,
+ Tk_Window tkwin, const char *value, char *widgRec, int offset)
+}
+declare 180 {
+ char *TkSmoothPrintProc(ClientData clientData, Tk_Window tkwin,
+ char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
+}
+
##############################################################################
# Define the platform specific internal Tcl interface. These functions are
@@ -539,6 +618,11 @@ declare 11 x11 {
declare 12 x11 {
int TkpWmSetState(TkWindow *winPtr, int state)
}
+# only needed by tktest:
+declare 13 x11 {
+ int TkpTestsendCmd(ClientData clientData, Tcl_Interp *interp, int argc,
+ const char **argv)
+}
################################
# Windows specific functions
@@ -691,6 +775,12 @@ declare 43 win {
declare 44 win {
void TkSendCleanup(TkDisplay *dispPtr)
}
+# only needed by tktest:
+declare 45 win {
+ int TkpTestsendCmd(ClientData clientData, Tcl_Interp *interp, int argc,
+ const char **argv)
+}
+
################################
# Aqua specific functions
@@ -744,22 +834,22 @@ declare 12 aqua {
#}
declare 14 aqua {
- int TkMacOSXDoHLEvent(EventRecord *theEvent)
+ int TkMacOSXDoHLEvent(void *theEvent)
}
# removed duplicate from tkPlat table(tk.decls)
#declare 15 aqua {
-# GWorldPtr TkMacOSXGetDrawablePort(Drawable drawable)
+# void *TkMacOSXGetDrawablePort(Drawable drawable)
#}
declare 16 aqua {
- Window TkMacOSXGetXWindow(WindowRef macWinPtr)
+ Window TkMacOSXGetXWindow(void *macWinPtr)
}
declare 17 aqua {
- int TkMacOSXGrowToplevel(WindowRef whichWindow, Point start)
+ int TkMacOSXGrowToplevel(void *whichWindow, XPoint start)
}
declare 18 aqua {
- void TkMacOSXHandleMenuSelect(MenuID theMenu, MenuItemIndex theItem,
+ void TkMacOSXHandleMenuSelect(short theMenu, unsigned short theItem,
int optionKeyPressed)
}
@@ -782,13 +872,13 @@ declare 23 aqua {
void TkMacOSXMakeRealWindowExist(TkWindow *winPtr)
}
declare 24 aqua {
- BitMapPtr TkMacOSXMakeStippleMap(Drawable d1, Drawable d2)
+ void *TkMacOSXMakeStippleMap(Drawable d1, Drawable d2)
}
declare 25 aqua {
void TkMacOSXMenuClick(void)
}
declare 26 aqua {
- void TkMacOSXRegisterOffScreenWindow(Window window, GWorldPtr portPtr)
+ void TkMacOSXRegisterOffScreenWindow(Window window, void *portPtr)
}
declare 27 aqua {
int TkMacOSXResizable(TkWindow *winPtr)
@@ -803,28 +893,28 @@ declare 30 aqua {
void TkMacOSXSetUpClippingRgn(Drawable drawable)
}
declare 31 aqua {
- void TkMacOSXSetUpGraphicsPort(GC gc, GWorldPtr destPort)
+ void TkMacOSXSetUpGraphicsPort(GC gc, void *destPort)
}
declare 32 aqua {
void TkMacOSXUpdateClipRgn(TkWindow *winPtr)
}
declare 33 aqua {
- void TkMacOSXUnregisterMacWindow(WindowRef portPtr)
+ void TkMacOSXUnregisterMacWindow(void *portPtr)
}
declare 34 aqua {
int TkMacOSXUseMenuID(short macID)
}
declare 35 aqua {
- RgnHandle TkMacOSXVisableClipRgn(TkWindow *winPtr)
+ TkRegion TkMacOSXVisableClipRgn(TkWindow *winPtr)
}
declare 36 aqua {
- void TkMacOSXWinBounds(TkWindow *winPtr, Rect *geometry)
+ void TkMacOSXWinBounds(TkWindow *winPtr, void *geometry)
}
declare 37 aqua {
- void TkMacOSXWindowOffset(WindowRef wRef, int *xOffset, int *yOffset)
+ void TkMacOSXWindowOffset(void *wRef, int *xOffset, int *yOffset)
}
declare 38 aqua {
- int TkSetMacColor(unsigned long pixel, RGBColor *macColor)
+ int TkSetMacColor(unsigned long pixel, void *macColor)
}
declare 39 aqua {
void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid)
@@ -833,7 +923,7 @@ declare 40 aqua {
void TkSuspendClipboard(void)
}
declare 41 aqua {
- int TkMacOSXZoomToplevel(WindowPtr whichWindow, short zoomPart)
+ int TkMacOSXZoomToplevel(void *whichWindow, short zoomPart)
}
declare 42 aqua {
Tk_Window Tk_TopCoordsToWindow(Tk_Window tkwin, int rootX, int rootY,
@@ -849,7 +939,7 @@ declare 45 aqua {
void TkMacOSXPreprocessMenu(void)
}
declare 46 aqua {
- int TkpIsWindowFloating(WindowRef window)
+ int TkpIsWindowFloating(void *window)
}
declare 47 aqua {
Tk_Window TkMacOSXGetCapture(void)
@@ -873,6 +963,11 @@ declare 51 aqua {
declare 53 aqua {
unsigned long TkpGetMS(void)
}
+
+# For Canvas3d, requested by Sean Woods
+declare 54 aqua {
+ void *TkMacOSXDrawable(Drawable drawable)
+}
##############################################################################
diff --git a/generic/tkInt.h b/generic/tkInt.h
index c2211aa..9a36e1e 100644
--- a/generic/tkInt.h
+++ b/generic/tkInt.h
@@ -1,15 +1,15 @@
/*
* tkInt.h --
*
- * Declarations for things used internally by the Tk
- * procedures but not exported outside the module.
+ * Declarations for things used internally by the Tk functions but not
+ * exported outside the module.
*
* Copyright (c) 1990-1994 The Regents of the University of California.
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKINT
@@ -41,7 +41,7 @@
# ifdef BIG_ENDIAN
# if BYTE_ORDER == BIG_ENDIAN
# undef WORDS_BIGENDIAN
-# define WORDS_BIGENDIAN
+# define WORDS_BIGENDIAN 1
# endif
# endif
# ifdef LITTLE_ENDIAN
@@ -65,10 +65,36 @@
#endif
/*
+ * Macros used to cast between pointers and integers (e.g. when storing an int
+ * in ClientData), on 64-bit architectures they avoid gcc warning about "cast
+ * to/from pointer from/to integer of different size".
+ */
+
+#if !defined(INT2PTR) && !defined(PTR2INT)
+# if defined(HAVE_INTPTR_T) || defined(intptr_t)
+# define INT2PTR(p) ((void*)(intptr_t)(p))
+# define PTR2INT(p) ((int)(intptr_t)(p))
+# else
+# define INT2PTR(p) ((void*)(p))
+# define PTR2INT(p) ((int)(p))
+# endif
+#endif
+#if !defined(UINT2PTR) && !defined(PTR2UINT)
+# if defined(HAVE_UINTPTR_T) || defined(uintptr_t)
+# define UINT2PTR(p) ((void*)(uintptr_t)(p))
+# define PTR2UINT(p) ((unsigned int)(uintptr_t)(p))
+# else
+# define UINT2PTR(p) ((void*)(p))
+# define PTR2UINT(p) ((unsigned int)(p))
+# endif
+#endif
+
+/*
* Opaque type declarations:
*/
typedef struct TkColormap TkColormap;
+typedef struct TkFontAttributes TkFontAttributes;
typedef struct TkGrabEvent TkGrabEvent;
typedef struct TkpCursor_ *TkpCursor;
typedef struct TkRegion_ *TkRegion;
@@ -76,18 +102,17 @@ typedef struct TkStressedCmap TkStressedCmap;
typedef struct TkBindInfo_ *TkBindInfo;
/*
- * Procedure types.
+ * Function types.
*/
-typedef int (TkBindEvalProc) _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, XEvent *eventPtr, Tk_Window tkwin,
- KeySym keySym));
-typedef void (TkBindFreeProc) _ANSI_ARGS_((ClientData clientData));
+typedef int (TkBindEvalProc)(ClientData clientData, Tcl_Interp *interp,
+ XEvent *eventPtr, Tk_Window tkwin, KeySym keySym);
+typedef void (TkBindFreeProc)(ClientData clientData);
/*
- * One of the following structures is maintained for each cursor in
- * use in the system. This structure is used by tkCursor.c and the
- * various system specific cursor files.
+ * One of the following structures is maintained for each cursor in use in the
+ * system. This structure is used by tkCursor.c and the various system
+ * specific cursor files.
*/
typedef struct TkCursor {
@@ -96,65 +121,53 @@ typedef struct TkCursor {
* 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_Preserve).
- * 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. */
+ * Tk_AllocPreserveFromObj or Tk_Preserve). 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). */
+ 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. */
+ * the same name. Cursors with the same name
+ * but different displays are chained together
+ * off a single hash table entry. */
} TkCursor;
/*
- * This defines whether we should try to use XIM over-the-spot style
- * input. Allow users to override it. It is a much more elegant use
- * of XIM, but uses a bit more memory.
- */
-
-#ifndef TK_XIM_SPOT
-# define TK_XIM_SPOT 1
-#endif
-
-/*
* The following structure is kept one-per-TkDisplay to maintain information
- * about the caret (cursor location) on this display. This is used to
- * dictate global focus location (Windows Accessibility guidelines) and to
- * position the IME or XIM over-the-spot window.
+ * about the caret (cursor location) on this display. This is used to dictate
+ * global focus location (Windows Accessibility guidelines) and to position
+ * the IME or XIM over-the-spot window.
*/
typedef struct TkCaret {
- struct TkWindow *winPtr; /* the window on which we requested caret
- * placement */
- int x; /* relative x coord of the caret */
- int y; /* relative y coord of the caret */
- int height; /* specified height of the window */
+ struct TkWindow *winPtr; /* The window on which we requested caret
+ * placement. */
+ int x; /* Relative x coord of the caret. */
+ int y; /* Relative y coord of the caret. */
+ int height; /* Specified height of the window. */
} TkCaret;
/*
- * One of the following structures is maintained for each display
- * 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.
+ * One of the following structures is maintained for each display 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 {
Display *display; /* Xlib's info about display. */
struct TkDisplay *nextPtr; /* Next in list of all displays. */
- char *name; /* Name of display (with any screen
- * identifier removed). Malloc-ed. */
+ char *name; /* Name of display (with any screen identifier
+ * removed). Malloc-ed. */
Time lastEventTime; /* Time of last event received for this
* display. */
@@ -162,16 +175,16 @@ typedef struct TkDisplay {
* Information used primarily by tk3d.c:
*/
- int borderInit; /* 0 means borderTable needs initializing. */
- Tcl_HashTable borderTable; /* Maps from color name to TkBorder
+ 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. */
+ 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. */
@@ -179,139 +192,137 @@ typedef struct TkDisplay {
* Information used primarily by tkBind.c:
*/
- int bindInfoStale; /* Non-zero means the variables in this
- * part of the structure are potentially
- * incorrect and should be recomputed. */
+ int bindInfoStale; /* Non-zero means the variables in this part
+ * of the structure are potentially incorrect
+ * and should be recomputed. */
unsigned int modeModMask; /* Has one bit set to indicate the modifier
- * corresponding to "mode shift". If no
- * such modifier, than this is zero. */
+ * corresponding to "mode shift". If no such
+ * modifier, than this is zero. */
unsigned int metaModMask; /* Has one bit set to indicate the modifier
- * corresponding to the "Meta" key. If no
- * such modifier, then this is zero. */
+ * corresponding to the "Meta" key. If no such
+ * modifier, then this is zero. */
unsigned int altModMask; /* Has one bit set to indicate the modifier
- * corresponding to the "Meta" key. If no
- * such modifier, then this is zero. */
+ * corresponding to the "Meta" key. If no such
+ * modifier, then this is zero. */
enum {LU_IGNORE, LU_CAPS, LU_SHIFT} lockUsage;
- /* Indicates how to interpret lock modifier. */
+ /* Indicates how to interpret lock
+ * modifier. */
int numModKeyCodes; /* Number of entries in modKeyCodes array
* below. */
- KeyCode *modKeyCodes; /* Pointer to an array giving keycodes for
- * all of the keys that have modifiers
- * associated with them. Malloc'ed, but
- * may be NULL. */
+ KeyCode *modKeyCodes; /* Pointer to an array giving keycodes for all
+ * of the keys that have modifiers associated
+ * with them. Malloc'ed, but 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
+
+ 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. */
+ Tcl_HashTable bitmapDataTable;
+ /* Used by Tk_GetBitmapFromData to map from a
+ * collection of in-core data about a bitmap
+ * to a reference giving an automatically-
+ * generated name for the bitmap. */
/*
* Information used by tkCanvas.c only:
*/
- int numIdSearches;
+ 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. */
+ 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
+ /* Maps from color name to TkColor structure
* for that color. */
Tcl_HashTable colorValueTable;
- /* Maps from integer RGB values to TkColor
+ /* Maps from integer RGB values to TkColor
* structures. */
/*
* Used by tkCursor.c only:
*/
- int cursorInit; /* 0 means cursor module need initializing. */
+ int cursorInit; /* 0 means cursor module need initializing. */
Tcl_HashTable cursorNameTable;
- /* Maps from a string name to a cursor to the
+ /* 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
+ /* 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
+ /* 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. */
+ 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:
*/
struct TkErrorHandler *errorPtr;
- /* First in list of error handlers
- * for this display. NULL means
- * no handlers exist at present. */
- int deleteCount; /* Counts # of handlers deleted since
- * last time inactive handlers were
- * garbage-collected. When this number
- * gets big, handlers get cleaned up. */
+ /* First in list of error handlers for this
+ * display. NULL means no handlers exist at
+ * present. */
+ int deleteCount; /* Counts # of handlers deleted since last
+ * time inactive handlers were garbage-
+ * collected. When this number gets big,
+ * handlers get cleaned up. */
/*
* 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. */
+ /* 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 tkFocus.c only:
*/
- int focusDebug; /* 1 means collect focus debugging
+ 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. */
+ * 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
+ * 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. */
+ * the focus, this will refer to the innermost
+ * window in the innermost application. This
+ * information isn't used on Windows, but it's
+ * needed on the Mac, and also on X11 when XIM
+ * processing is being done. */
/*
* 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
+ Tcl_HashTable gcIdTable; /* Maps from a GC to a TkGC. */
+ int gcInit; /* 0 means the tables below need
* initializing. */
/*
@@ -319,24 +330,23 @@ typedef struct TkDisplay {
*/
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;
+ /* 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 tkGet.c only:
*/
-
- Tcl_HashTable uidTable; /* Stores all Tk_Uid used in a thread. */
- int uidInit; /* 0 means uidTable needs initializing. */
+
+ Tcl_HashTable uidTable; /* Stores all Tk_Uid used in a thread. */
+ int uidInit; /* 0 means uidTable needs initializing. */
/*
* Information used by tkGrab.c only:
*/
- struct TkWindow *grabWinPtr;
- /* Window in which the pointer is currently
+ struct TkWindow *grabWinPtr;/* Window in which the pointer is currently
* grabbed, or NULL if none. */
struct TkWindow *eventualGrabWinPtr;
/* Value that grabWinPtr will have once the
@@ -348,68 +358,65 @@ typedef struct TkDisplay {
* if no such press in effect. */
struct TkWindow *serverWinPtr;
/* If no application contains the pointer then
- * this is NULL. Otherwise it contains the
- * last window for which we've gotten an
- * Enter or Leave event from the server (i.e.
- * the last window known to have contained
- * the pointer). Doesn't reflect events
- * that were synthesized in tkGrab.c. */
+ * this is NULL. Otherwise it contains the
+ * last window for which we've gotten an Enter
+ * or Leave event from the server (i.e. the
+ * last window known to have contained the
+ * pointer). Doesn't reflect events that were
+ * synthesized in tkGrab.c. */
TkGrabEvent *firstGrabEventPtr;
/* First in list of enter/leave events
- * synthesized by grab code. These events
- * must be processed in order before any other
- * events are processed. NULL means no such
+ * synthesized by grab code. These events must
+ * be processed in order before any other
+ * events are processed. NULL means no such
* events. */
TkGrabEvent *lastGrabEventPtr;
/* Last in list of synthesized events, or NULL
* if list is empty. */
- int grabFlags; /* Miscellaneous flag values. See definitions
+ int grabFlags; /* Miscellaneous flag values. See definitions
* 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. */
+ 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. */
+ int imageId; /* Value used to number image ids. */
/*
* Information used by tkMacWinMenu.c only:
*/
- int postCommandGeneration;
+ int postCommandGeneration;
/*
* Information used by tkOption.c only.
*/
-
-
/*
* Information used by tkPack.c only.
*/
- int packInit; /* 0 means table below needs initializing. */
+ int packInit; /* 0 means table below needs initializing. */
Tcl_HashTable packerHashTable;
- /* Maps from Tk_Window tokens to
- * corresponding Packer structures. */
-
+ /* 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
+ 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
+ Tcl_HashTable slaveTable; /* Maps from Tk_Window toke to the Slave
* structure for the window, if it exists. */
/*
@@ -418,11 +425,11 @@ typedef struct TkDisplay {
struct TkSelectionInfo *selectionInfoPtr;
/* First in list of selection information
- * records. Each entry contains 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 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. */
@@ -443,7 +450,7 @@ typedef struct TkDisplay {
/* Last application that owned clipboard. */
struct TkClipboardTarget *clipTargetPtr;
/* First in list of clipboard type information
- * records. Each entry contains information
+ * records. Each entry contains information
* about the buffers for a given selection
* target. */
@@ -451,13 +458,13 @@ typedef struct TkDisplay {
* 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. */
+ 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 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. */
@@ -469,12 +476,11 @@ typedef struct TkDisplay {
/* First in list of chunks of free resource
* identifiers, or NULL if there are no free
* resources. */
- XID (*defaultAllocProc) _ANSI_ARGS_((Display *display));
+ XID (*defaultAllocProc) (Display *display);
/* Default resource allocator for display. */
struct TkIdStack *windowStackPtr;
- /* First in list of chunks of window
- * identifers that can't be reused right
- * now. */
+ /* First in list of chunks of window ids that
+ * can't be reused right now. */
Tcl_TimerToken idCleanupScheduled;
/* If set, it means a call to WindowIdCleanup
* has already been scheduled, 0 means it
@@ -484,17 +490,16 @@ typedef struct TkDisplay {
* Information used by tkUnixWm.c and tkWinWm.c only:
*/
- struct TkWmInfo *firstWmPtr; /* Points to first top-level window. */
- struct TkWmInfo *foregroundWmPtr;
- /* Points to the foreground window. */
+ 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:
*/
-
- int destroyCount; /* Number of Tk_DestroyWindow operations
- * in progress. */
+ int destroyCount; /* Number of Tk_DestroyWindow operations in
+ * progress. */
unsigned long lastDestroyRequest;
/* Id of most recent XDestroyWindow request;
* can re-use ids in windowStackPtr when
@@ -513,25 +518,25 @@ typedef struct TkDisplay {
*/
#ifdef TK_USE_INPUT_METHODS
- XIM inputMethod; /* Input method for this display */
-#if TK_XIM_SPOT
+ XIM inputMethod; /* Input method for this display. */
+ XIMStyle inputStyle; /* Input style selected for this display. */
XFontSet inputXfs; /* XFontSet cached for over-the-spot XIM. */
-#endif
#endif /* TK_USE_INPUT_METHODS */
Tcl_HashTable winTable; /* Maps from X window ids to TkWindow ptrs. */
int refCount; /* Reference count of how many Tk applications
- * are using this display. Used to clean up
- * the display when we no longer have any
- * Tk applications using it.
- */
+ * are using this display. Used to clean up
+ * the display when we no longer have any Tk
+ * applications using it. */
+
/*
* The following field were all added for Tk8.3
*/
- int mouseButtonState; /* current mouse button state for this
- * display */
- Window mouseButtonWindow; /* Window the button state was set in,
- * added in Tk 8.4. */
+
+ int mouseButtonState; /* Current mouse button state for this
+ * display. */
+ Window mouseButtonWindow; /* Window the button state was set in, added
+ * in Tk 8.4. */
Window warpWindow;
int warpX;
int warpY;
@@ -539,13 +544,14 @@ typedef struct TkDisplay {
/*
* The following field(s) were all added for Tk8.4
*/
- unsigned int flags; /* Various flag values: these are all
- * defined in below. */
- TkCaret caret; /* information about the caret for this
- * display. This is not a pointer. */
- int iconDataSize; /* size of default iconphoto image data */
- unsigned char *iconDataPtr; /* default iconphoto image data, if set */
+ unsigned int flags; /* Various flag values: these are all defined
+ * in below. */
+ TkCaret caret; /* Information about the caret for this
+ * display. This is not a pointer. */
+
+ int iconDataSize; /* Size of default iconphoto image data. */
+ unsigned char *iconDataPtr; /* Default iconphoto image data, if set. */
} TkDisplay;
/*
@@ -554,8 +560,6 @@ typedef struct TkDisplay {
* Indicates that we should collapse motion events on this display
* TK_DISPLAY_USE_IM: (default on, set via tk.tcl)
* Whether to use input methods for this display
- * TK_DISPLAY_XIM_SPOT: (default off)
- * Indicates that we should use over-the-spot XIM on this display
* TK_DISPLAY_WM_TRACING: (default off)
* Whether we should do wm tracing on this display.
* TK_DISPLAY_IN_WARP: (default off)
@@ -564,88 +568,75 @@ typedef struct TkDisplay {
#define TK_DISPLAY_COLLAPSE_MOTION_EVENTS (1 << 0)
#define TK_DISPLAY_USE_IM (1 << 1)
-#define TK_DISPLAY_XIM_SPOT (1 << 2)
#define TK_DISPLAY_WM_TRACING (1 << 3)
#define TK_DISPLAY_IN_WARP (1 << 4)
/*
- * One of the following structures exists for each error handler
- * created by a call to Tk_CreateErrorHandler. The structure
- * is managed by tkError.c.
+ * One of the following structures exists for each error handler created by a
+ * call to Tk_CreateErrorHandler. The structure is managed by tkError.c.
*/
typedef struct TkErrorHandler {
TkDisplay *dispPtr; /* Display to which handler applies. */
- unsigned long firstRequest; /* Only errors with serial numbers
- * >= to this are considered. */
- unsigned long lastRequest; /* Only errors with serial numbers
- * <= to this are considered. This
- * field is filled in when XUnhandle
- * is called. -1 means XUnhandle
- * hasn't been called yet. */
- int error; /* Consider only errors with this
- * error_code (-1 means consider
- * all errors). */
- int request; /* Consider only errors with this
- * major request code (-1 means
- * consider all major codes). */
- int minorCode; /* Consider only errors with this
- * minor request code (-1 means
- * consider all minor codes). */
- Tk_ErrorProc *errorProc; /* Procedure to invoke when a matching
- * error occurs. NULL means just ignore
- * errors. */
- ClientData clientData; /* Arbitrary value to pass to
- * errorProc. */
+ unsigned long firstRequest; /* Only errors with serial numbers >= to this
+ * are considered. */
+ unsigned long lastRequest; /* Only errors with serial numbers <= to this
+ * are considered. This field is filled in
+ * when XUnhandle is called. -1 means
+ * XUnhandle hasn't been called yet. */
+ int error; /* Consider only errors with this error_code
+ * (-1 means consider all errors). */
+ int request; /* Consider only errors with this major
+ * request code (-1 means consider all major
+ * codes). */
+ int minorCode; /* Consider only errors with this minor
+ * request code (-1 means consider all minor
+ * codes). */
+ Tk_ErrorProc *errorProc; /* Function to invoke when a matching error
+ * occurs. NULL means just ignore errors. */
+ ClientData clientData; /* Arbitrary value to pass to errorProc. */
struct TkErrorHandler *nextPtr;
- /* Pointer to next older handler for
- * this display, or NULL for end of
- * list. */
+ /* Pointer to next older handler for this
+ * display, or NULL for end of list. */
} TkErrorHandler;
-
/*
- * One of the following structures exists for each event handler
- * created by calling Tk_CreateEventHandler. This information
- * is used by tkEvent.c only.
+ * One of the following structures exists for each event handler created by
+ * calling Tk_CreateEventHandler. This information is used by tkEvent.c only.
*/
typedef struct TkEventHandler {
- unsigned long mask; /* Events for which to invoke
- * proc. */
- Tk_EventProc *proc; /* Procedure to invoke when an event
- * in mask occurs. */
+ unsigned long mask; /* Events for which to invoke proc. */
+ Tk_EventProc *proc; /* Function to invoke when an event in mask
+ * occurs. */
ClientData clientData; /* Argument to pass to proc. */
struct TkEventHandler *nextPtr;
- /* Next in list of handlers
- * associated with window (NULL means
- * end of list). */
+ /* Next in list of handlers associated with
+ * window (NULL means end of list). */
} TkEventHandler;
/*
- * Tk keeps one of the following data structures for each main
- * window (created by a call to TkCreateMainWindow). It stores
- * information that is shared by all of the windows associated
- * with a particular main window.
+ * Tk keeps one of the following data structures for each main window (created
+ * by a call to TkCreateMainWindow). It stores information that is shared by
+ * all of the windows associated with a particular main window.
*/
typedef struct TkMainInfo {
int refCount; /* Number of windows whose "mainPtr" fields
- * point here. When this becomes zero, can
- * free up the structure (the reference
- * count is zero because windows can get
- * deleted in almost any order; the main
- * window isn't necessarily the last one
- * deleted). */
+ * point here. When this becomes zero, can
+ * free up the structure (the reference count
+ * is zero because windows can get deleted in
+ * almost any order; the main window isn't
+ * necessarily the last one deleted). */
struct TkWindow *winPtr; /* Pointer to main window. */
Tcl_Interp *interp; /* Interpreter associated with application. */
Tcl_HashTable nameTable; /* Hash table mapping path names to TkWindow
* structs for all windows related to this
- * main window. Managed by tkWindow.c. */
- long deletionEpoch; /* Incremented by window deletions */
+ * main window. Managed by tkWindow.c. */
+ long deletionEpoch; /* Incremented by window deletions. */
Tk_BindingTable bindingTable;
- /* Used in conjunction with "bind" command
- * to bind events to Tcl commands. */
+ /* Used in conjunction with "bind" command to
+ * bind events to Tcl commands. */
TkBindInfo bindInfo; /* Information used by tkBind.c on a per
* application basis. */
struct TkFontInfo *fontInfoPtr;
@@ -659,21 +650,21 @@ typedef struct TkMainInfo {
struct TkToplevelFocusInfo *tlFocusPtr;
/* First in list of records containing focus
* information for each top-level in the
- * application. Used only by tkFocus.c. */
+ * application. Used only by tkFocus.c. */
struct TkDisplayFocusInfo *displayFocusPtr;
/* First in list of records containing focus
* information for each display that this
- * application has ever used. Used only
- * by tkFocus.c. */
+ * application has ever used. Used only by
+ * tkFocus.c. */
struct ElArray *optionRootPtr;
- /* Top level of option hierarchy for this
- * main window. NULL means uninitialized.
- * Managed by tkOption.c. */
+ /* Top level of option hierarchy for this main
+ * window. NULL means uninitialized. Managed
+ * by tkOption.c. */
Tcl_HashTable imageTable; /* Maps from image names to Tk_ImageMaster
- * structures. Managed by tkImage.c. */
- int strictMotif; /* This is linked to the tk_strictMotif
- * global variable. */
+ * structures. Managed by tkImage.c. */
+ int strictMotif; /* This is linked to the tk_strictMotif global
+ * variable. */
int alwaysShowSelection; /* This is linked to the
* ::tk::AlwaysShowSelection variable. */
struct TkMainInfo *nextPtr; /* Next in list of all main windows managed by
@@ -681,172 +672,157 @@ typedef struct TkMainInfo {
} TkMainInfo;
/*
- * Tk keeps the following data structure for each of it's builtin
- * bitmaps. This structure is only used by tkBitmap.c and other
- * platform specific bitmap files.
+ * Tk keeps the following data structure for each of it's builtin bitmaps.
+ * This structure is only used by tkBitmap.c and other platform specific
+ * bitmap files.
*/
typedef struct {
- CONST char *source; /* Bits for bitmap. */
+ const char *source; /* Bits for bitmap. */
int width, height; /* Dimensions of bitmap. */
- int native; /* 0 means generic (X style) bitmap,
- * 1 means native style bitmap. */
+ int native; /* 0 means generic (X style) bitmap, 1 means
+ * native style bitmap. */
} TkPredefBitmap;
/*
- * Tk keeps one of the following structures for each window.
- * Some of the information (like size and location) is a shadow
- * of information managed by the X server, and some is special
- * information used here, such as event and geometry management
- * information. This information is (mostly) managed by tkWindow.c.
- * WARNING: the declaration below must be kept consistent with the
- * Tk_FakeWin structure in tk.h. If you change one, be sure to
- * change the other!!
+ * Tk keeps one of the following structures for each window. Some of the
+ * information (like size and location) is a shadow of information managed by
+ * the X server, and some is special information used here, such as event and
+ * geometry management information. This information is (mostly) managed by
+ * tkWindow.c. WARNING: the declaration below must be kept consistent with the
+ * Tk_FakeWin structure in tk.h. If you change one, be sure to change the
+ * other!
*/
typedef struct TkWindow {
-
/*
* Structural information:
*/
Display *display; /* Display containing window. */
- TkDisplay *dispPtr; /* Tk's information about display
- * for window. */
- int screenNum; /* Index of screen for window, among all
- * those for dispPtr. */
- Visual *visual; /* Visual to use for window. If not default,
+ TkDisplay *dispPtr; /* Tk's information about display for
+ * window. */
+ int screenNum; /* Index of screen for window, among all those
+ * for dispPtr. */
+ Visual *visual; /* Visual to use for window. If not default,
* MUST be set before X window is created. */
int depth; /* Number of bits/pixel. */
- Window window; /* X's id for window. NULL means window
- * hasn't actually been created yet, or it's
- * been deleted. */
- struct TkWindow *childList; /* First in list of child windows,
- * or NULL if no children. List is in
- * stacking order, lowest window first.*/
- struct TkWindow *lastChildPtr;
- /* Last in list of child windows (highest
- * in stacking order), or NULL if no
- * children. */
- struct TkWindow *parentPtr; /* Pointer to parent window (logical
- * parent, not necessarily X parent). NULL
- * means either this is the main window, or
- * the window's parent has already been
+ Window window; /* X's id for window. NULL means window hasn't
+ * actually been created yet, or it's been
* deleted. */
- struct TkWindow *nextPtr; /* Next higher sibling (in stacking order)
- * in list of children with same parent. NULL
+ struct TkWindow *childList; /* First in list of child windows, or NULL if
+ * no children. List is in stacking order,
+ * lowest window first.*/
+ struct TkWindow *lastChildPtr;
+ /* Last in list of child windows (highest in
+ * stacking order), or NULL if no children. */
+ struct TkWindow *parentPtr; /* Pointer to parent window (logical parent,
+ * not necessarily X parent). NULL means
+ * either this is the main window, or the
+ * window's parent has already been deleted. */
+ struct TkWindow *nextPtr; /* Next higher sibling (in stacking order) in
+ * list of children with same parent. NULL
* means end of list. */
TkMainInfo *mainPtr; /* Information shared by all windows
- * associated with a particular main
- * window. NULL means this window is
- * a rogue that isn't associated with
- * any application (at present, this
- * only happens for the dummy windows
- * used for "send" communication). */
+ * associated with a particular main window.
+ * NULL means this window is a rogue that is
+ * not associated with any application (at
+ * present, this only happens for the dummy
+ * windows used for "send" communication). */
/*
* Name and type information for the window:
*/
- char *pathName; /* Path name of window (concatenation
- * of all names between this window and
- * its top-level ancestor). This is a
- * pointer into an entry in
- * mainPtr->nameTable. NULL means that
- * the window hasn't been completely
- * created yet. */
+ char *pathName; /* Path name of window (concatenation of all
+ * names between this window and its top-level
+ * ancestor). This is a pointer into an entry
+ * in mainPtr->nameTable. NULL means that the
+ * window hasn't been completely created
+ * yet. */
Tk_Uid nameUid; /* Name of the window within its parent
* (unique within the parent). */
- Tk_Uid classUid; /* Class of the window. NULL means window
+ Tk_Uid classUid; /* Class of the window. NULL means window
* hasn't been given a class yet. */
/*
- * Geometry and other attributes of window. This information
- * may not be updated on the server immediately; stuff that
- * hasn't been reflected in the server yet is called "dirty".
- * At present, information can be dirty only if the window
- * hasn't yet been created.
+ * Geometry and other attributes of window. This information may not be
+ * updated on the server immediately; stuff that hasn't been reflected in
+ * the server yet is called "dirty". At present, information can be dirty
+ * only if the window hasn't yet been created.
*/
- XWindowChanges changes; /* Geometry and other info about
- * window. */
- unsigned int dirtyChanges; /* Bits indicate fields of "changes"
- * that are dirty. */
+ XWindowChanges changes; /* Geometry and other info about window. */
+ unsigned int dirtyChanges; /* Bits indicate fields of "changes" that are
+ * dirty. */
XSetWindowAttributes atts; /* Current attributes of window. */
- unsigned long dirtyAtts; /* Bits indicate fields of "atts"
- * that are dirty. */
+ unsigned long dirtyAtts; /* Bits indicate fields of "atts" that are
+ * dirty. */
- unsigned int flags; /* Various flag values: these are all
- * defined in tk.h (confusing, but they're
- * needed there for some query macros). */
+ unsigned int flags; /* Various flag values: these are all defined
+ * in tk.h (confusing, but they're needed
+ * there for some query macros). */
/*
* Information kept by the event manager (tkEvent.c):
*/
- TkEventHandler *handlerList;/* First in list of event handlers
- * declared for this window, or
- * NULL if none. */
+ TkEventHandler *handlerList;/* First in list of event handlers declared
+ * for this window, or NULL if none. */
#ifdef TK_USE_INPUT_METHODS
XIC inputContext; /* XIM input context. */
#endif /* TK_USE_INPUT_METHODS */
/*
- * Information used for event bindings (see "bind" and "bindtags"
- * commands in tkCmds.c):
+ * Information used for event bindings (see "bind" and "bindtags" commands
+ * in tkCmds.c):
*/
ClientData *tagPtr; /* Points to array of tags used for bindings
- * on this window. Each tag is a Tk_Uid.
- * Malloc'ed. NULL means no tags. */
+ * on this window. Each tag is a Tk_Uid.
+ * Malloc'ed. NULL means no tags. */
int numTags; /* Number of tags at *tagPtr. */
/*
- * Information used by tkOption.c to manage options for the
- * window.
+ * Information used by tkOption.c to manage options for the window.
*/
- int optionLevel; /* -1 means no option information is
- * currently cached for this window.
- * Otherwise this gives the level in
- * the option stack at which info is
- * cached. */
+ int optionLevel; /* -1 means no option information is currently
+ * cached for this window. Otherwise this
+ * gives the level in the option stack at
+ * which info is cached. */
/*
* Information used by tkSelect.c to manage the selection.
*/
struct TkSelHandler *selHandlerList;
- /* First in list of handlers for
- * returning the selection in various
- * forms. */
+ /* First in list of handlers for returning the
+ * selection in various forms. */
/*
* Information used by tkGeometry.c for geometry management.
*/
- Tk_GeomMgr *geomMgrPtr; /* Information about geometry manager for
- * this window. */
- ClientData geomData; /* Argument for geometry manager procedures. */
+ const Tk_GeomMgr *geomMgrPtr; /* Information about geometry manager for this
+ * window. */
+ ClientData geomData; /* Argument for geometry manager functions. */
int reqWidth, reqHeight; /* Arguments from last call to
* Tk_GeometryRequest, or 0's if
- * Tk_GeometryRequest hasn't been
- * called. */
- int internalBorderLeft; /* Width of internal border of window
- * (0 means no internal border). Geometry
- * managers should not normally place children
- * on top of the border.
- * Fields for the other three sides are found
- * below. */
+ * Tk_GeometryRequest hasn't been called. */
+ int internalBorderLeft; /* Width of internal border of window (0 means
+ * no internal border). Geometry managers
+ * should not normally place children on top
+ * of the border. Fields for the other three
+ * sides are found below. */
/*
* Information maintained by tkWm.c for window manager communication.
*/
- struct TkWmInfo *wmInfoPtr; /* For top-level windows (and also
- * for special Unix menubar and wrapper
- * windows), points to structure with
- * wm-related info (see tkWm.c). For
- * other windows, this is NULL. */
+ struct TkWmInfo *wmInfoPtr; /* For top-level windows (and also for special
+ * Unix menubar and wrapper windows), points
+ * to structure with wm-related info (see
+ * tkWm.c). For other windows, this is NULL. */
/*
* Information used by widget classes.
@@ -866,32 +842,50 @@ typedef struct TkWindow {
*/
/* The remaining fields of internal border. */
- int internalBorderRight;
+ int internalBorderRight;
int internalBorderTop;
int internalBorderBottom;
-
+
int minReqWidth; /* Minimum requested width. */
int minReqHeight; /* Minimum requested height. */
} TkWindow;
/*
- * The following structure is used as a two way map between integers
- * and strings, usually to map between an internal C representation
- * and the strings used in Tcl.
+ * Real definition of some events. Note that these events come from outside
+ * but have internally generated pieces added to them.
+ */
+
+typedef struct {
+ XKeyEvent keyEvent; /* The real event from X11. */
+ char *charValuePtr; /* A pointer to a string that holds the key's
+ * %A substitution text (before backslash
+ * adding), or NULL if that has not been
+ * computed yet. If non-NULL, this string was
+ * allocated with ckalloc(). */
+ int charValueLen; /* Length of string in charValuePtr when that
+ * is non-NULL. */
+ KeySym keysym; /* Key symbol computed after input methods
+ * have been invoked */
+} TkKeyEvent;
+
+/*
+ * The following structure is used as a two way map between integers and
+ * strings, usually to map between an internal C representation and the
+ * strings used in Tcl.
*/
typedef struct TkStateMap {
int numKey; /* Integer representation of a value. */
- char *strKey; /* String representation of a value. */
+ const char *strKey; /* String representation of a value. */
} TkStateMap;
/*
- * This structure is used by the Mac and Window porting layers as
- * the internal representation of a clip_mask in a GC.
+ * This structure is used by the Mac and Window porting layers as the internal
+ * representation of a clip_mask in a GC.
*/
typedef struct TkpClipMask {
- int type; /* One of TKP_CLIP_PIXMAP or TKP_CLIP_REGION */
+ int type; /* TKP_CLIP_PIXMAP or TKP_CLIP_REGION. */
union {
Pixmap pixmap;
TkRegion region;
@@ -917,320 +911,304 @@ extern TkDisplay *tkDisplayList;
#define TK_GRAB_EXCLUDED 3
/*
- * The macro below is used to modify a "char" value (e.g. by casting
- * it to an unsigned character) so that it can be used safely with
- * macros such as isspace.
+ * Additional flag for TkpMeasureCharsInContext. Coordinate with other flags
+ * for this routine, but don't make public until TkpMeasureCharsInContext is
+ * made public, too.
+ */
+
+#define TK_ISOLATE_END 32
+
+/*
+ * The macro below is used to modify a "char" value (e.g. by casting it to an
+ * unsigned character) so that it can be used safely with macros such as
+ * isspace().
*/
#define UCHAR(c) ((unsigned char) (c))
/*
- * The following symbol is used in the mode field of FocusIn events
- * generated by an embedded application to request the input focus from
- * its container.
+ * The following symbol is used in the mode field of FocusIn events generated
+ * by an embedded application to request the input focus from its container.
*/
#define EMBEDDED_APP_WANTS_FOCUS (NotifyNormal + 20)
/*
- * The following special modifier mask bits are defined, to indicate
- * logical modifiers such as Meta and Alt that may float among the
- * actual modifier bits.
+ * The following special modifier mask bits are defined, to indicate logical
+ * modifiers such as Meta and Alt that may float among the actual modifier
+ * bits.
*/
#define META_MASK (AnyModifier<<1)
#define ALT_MASK (AnyModifier<<2)
+#define EXTENDED_MASK (AnyModifier<<3)
/*
- * Object types not declared in tkObj.c need to be mentioned here so
- * they can be properly registered with Tcl:
+ * Object types not declared in tkObj.c need to be mentioned here so they can
+ * be properly registered with Tcl:
*/
-extern Tcl_ObjType tkBorderObjType;
-extern Tcl_ObjType tkBitmapObjType;
-extern Tcl_ObjType tkColorObjType;
-extern Tcl_ObjType tkCursorObjType;
-extern Tcl_ObjType tkFontObjType;
-extern Tcl_ObjType tkOptionObjType;
-extern Tcl_ObjType tkStateKeyObjType;
+MODULE_SCOPE Tcl_ObjType tkBorderObjType;
+MODULE_SCOPE Tcl_ObjType tkBitmapObjType;
+MODULE_SCOPE Tcl_ObjType tkColorObjType;
+MODULE_SCOPE Tcl_ObjType tkCursorObjType;
+MODULE_SCOPE Tcl_ObjType tkFontObjType;
+MODULE_SCOPE Tcl_ObjType tkOptionObjType;
+MODULE_SCOPE Tcl_ObjType tkStateKeyObjType;
+MODULE_SCOPE Tcl_ObjType tkTextIndexType;
/*
- * Miscellaneous variables shared among Tk modules but not exported
- * to the outside world:
+ * Miscellaneous variables shared among Tk modules but not exported to the
+ * outside world:
*/
-extern Tk_SmoothMethod tkBezierSmoothMethod;
-extern Tk_ImageType tkBitmapImageType;
-extern Tk_PhotoImageFormat tkImgFmtGIF;
-extern void (*tkHandleEventProc) _ANSI_ARGS_((
- XEvent* eventPtr));
-extern Tk_PhotoImageFormat tkImgFmtPPM;
-extern TkMainInfo *tkMainWindowList;
-extern Tk_ImageType tkPhotoImageType;
-extern Tcl_HashTable tkPredefBitmapTable;
-extern int tkSendSerial;
+MODULE_SCOPE Tk_SmoothMethod tkBezierSmoothMethod;
+MODULE_SCOPE Tk_ImageType tkBitmapImageType;
+MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtGIF;
+MODULE_SCOPE void (*tkHandleEventProc) (XEvent* eventPtr);
+MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPPM;
+MODULE_SCOPE TkMainInfo *tkMainWindowList;
+MODULE_SCOPE Tk_ImageType tkPhotoImageType;
+MODULE_SCOPE Tcl_HashTable tkPredefBitmapTable;
-extern CONST char *const tkWebColors[20];
+MODULE_SCOPE CONST char *const tkWebColors[20];
#include "tkIntDecls.h"
#ifdef BUILD_tk
-# undef TCL_STORAGE_CLASS
-# define TCL_STORAGE_CLASS DLLEXPORT
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
#endif
/*
- * Internal procedures shared among Tk modules but not exported
- * to the outside world:
+ * Themed widget set init function:
+ */
+
+MODULE_SCOPE int Ttk_Init(Tcl_Interp *interp);
+
+/*
+ * Internal functions shared among Tk modules but not exported to the outside
+ * world:
*/
-EXTERN int Tk_BellObjCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_BindObjCmd _ANSI_ARGS_((ClientData clientData,
+MODULE_SCOPE int Tk_BellObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_BindtagsObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_BindObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_ButtonObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_BindtagsObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_CanvasObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_ButtonObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_CanvasObjCmd(ClientData clientData,
Tcl_Interp *interp, int argc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_CheckbuttonObjCmd _ANSI_ARGS_((
- ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_CheckbuttonObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_ClipboardObjCmd _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp,
- int objc, Tcl_Obj *CONST objv[]));
-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_DestroyObjCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-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_Obj *const objv[]);
+MODULE_SCOPE int Tk_ClipboardObjCmd(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_FrameObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_ChooseColorObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-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_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_GrabObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_ChooseDirectoryObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_GridObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_ChooseFontObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_ImageObjCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_LabelObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_DestroyObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_LabelframeObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_EntryObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_ListboxObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_EventObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_LowerObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_FrameObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-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_MessageObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_FocusObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_PanedWindowObjCmd _ANSI_ARGS_((
- ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_FontObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_OptionObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_GetOpenFileObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_PackObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_GetSaveFileObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_PlaceObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_GrabObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_RadiobuttonObjCmd _ANSI_ARGS_((
- ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_GridObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_RaiseObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_ImageObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-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, CONST char **argv));
-EXTERN int Tk_SelectionObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_LabelObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_SendCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int argc, CONST char **argv));
-EXTERN int Tk_SendObjCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_SpinboxObjCmd _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, CONST char **argv));
-EXTERN int Tk_TkObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_LabelframeObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_TkwaitObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_ListboxObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_ToplevelObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_LowerObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-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_Obj *const objv[]);
+MODULE_SCOPE int Tk_MenubuttonObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-EXTERN int Tk_WmObjCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_MessageBoxObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-
-EXTERN void TkEventInit _ANSI_ARGS_((void));
-
-EXTERN void TkRegisterObjTypes _ANSI_ARGS_((void));
-
-EXTERN int TkCreateMenuCmd _ANSI_ARGS_((Tcl_Interp *interp));
-EXTERN int TkDeadAppCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int argc, CONST char **argv));
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_MessageObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_PanedWindowObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_OptionObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_PackObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_PlaceObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_RadiobuttonObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_RaiseObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_ScaleObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_ScrollbarCmd(ClientData clientData,
+ Tcl_Interp *interp, int argc, const char **argv);
+MODULE_SCOPE int Tk_SelectionObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_SendCmd(ClientData clientData,
+ Tcl_Interp *interp, int argc, const char **argv);
+MODULE_SCOPE int Tk_SendObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_SpinboxObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_TextObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_TkObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_TkwaitObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_ToplevelObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_UpdateObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_WinfoObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_WmObjCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
-EXTERN int TkpTestembedCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int argc, CONST char **argv));
-EXTERN int TkCanvasGetCoordObj _ANSI_ARGS_((Tcl_Interp *interp,
+MODULE_SCOPE int Tk_GetDoublePixelsFromObj(Tcl_Interp *interp,
+ Tk_Window tkwin, Tcl_Obj *objPtr,
+ double *doublePtr);
+
+MODULE_SCOPE void TkEventInit(void);
+MODULE_SCOPE void TkRegisterObjTypes(void);
+MODULE_SCOPE int TkCreateMenuCmd(Tcl_Interp *interp);
+MODULE_SCOPE int TkDeadAppCmd(ClientData clientData,
+ Tcl_Interp *interp, int argc, const char **argv);
+MODULE_SCOPE int TkCanvasGetCoordObj(Tcl_Interp *interp,
Tk_Canvas canvas, Tcl_Obj *obj,
- double *doublePtr));
-EXTERN int TkCanvasDashParseProc _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *value, char *widgRec,
- int offset));
-EXTERN char * TkCanvasDashPrintProc _ANSI_ARGS_((
- ClientData clientData, Tk_Window tkwin,
- char *widgRec, int offset,
- Tcl_FreeProc **freeProcPtr));
-EXTERN int TkGetDoublePixels _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *string,
- double *doublePtr));
-EXTERN int TkOffsetParseProc _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *value, char *widgRec,
- int offset));
-EXTERN char * TkOffsetPrintProc _ANSI_ARGS_((
- ClientData clientData, Tk_Window tkwin,
- char *widgRec, int offset,
- Tcl_FreeProc **freeProcPtr));
-EXTERN int TkOrientParseProc _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *value,
- char *widgRec, int offset));
-EXTERN char * TkOrientPrintProc _ANSI_ARGS_((
- ClientData clientData, Tk_Window tkwin,
- char *widgRec, int offset,
- Tcl_FreeProc **freeProcPtr));
-EXTERN int TkPixelParseProc _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *value, char *widgRec,
- int offset));
-EXTERN char * TkPixelPrintProc _ANSI_ARGS_((
- ClientData clientData, Tk_Window tkwin,
- char *widgRec, int offset,
- Tcl_FreeProc **freeProcPtr));
-EXTERN int TkPostscriptImage _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, Tk_PostscriptInfo psInfo,
- XImage *ximage, int x, int y, int width,
- int height));
-EXTERN int TkSmoothParseProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, Tk_Window tkwin,
- CONST char *value, char *recordPtr, int offset));
-EXTERN char * TkSmoothPrintProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin, char *recordPtr, int offset,
- Tcl_FreeProc **freeProcPtr));
-EXTERN int TkStateParseProc _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *value,
- char *widgRec, int offset));
-EXTERN char * TkStatePrintProc _ANSI_ARGS_((
- ClientData clientData, Tk_Window tkwin,
- char *widgRec, int offset,
- Tcl_FreeProc **freeProcPtr));
-EXTERN int TkTileParseProc _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *value, char *widgRec,
- int offset));
-EXTERN char * TkTilePrintProc _ANSI_ARGS_((
- ClientData clientData, Tk_Window tkwin,
- char *widgRec, int offset,
- Tcl_FreeProc **freeProcPtr));
-EXTERN void TkCreateExitHandler _ANSI_ARGS_((Tcl_ExitProc *proc,
- ClientData clientData));
-EXTERN void TkDeleteExitHandler _ANSI_ARGS_((Tcl_ExitProc *proc,
- ClientData clientData));
-EXTERN Tcl_ExitProc TkFinalize;
-EXTERN void TkPrintPadAmount _ANSI_ARGS_((Tcl_Interp *interp,
- char *buffer, int pad1, int pad2));
-EXTERN int TkParsePadAmount _ANSI_ARGS_((Tcl_Interp *interp,
+ double *doublePtr);
+MODULE_SCOPE int TkGetDoublePixels(Tcl_Interp *interp, Tk_Window tkwin,
+ const char *string, double *doublePtr);
+MODULE_SCOPE int TkPostscriptImage(Tcl_Interp *interp, Tk_Window tkwin,
+ Tk_PostscriptInfo psInfo, XImage *ximage,
+ int x, int y, int width, int height);
+MODULE_SCOPE void TkMapTopFrame(Tk_Window tkwin);
+MODULE_SCOPE XEvent * TkpGetBindingXEvent(Tcl_Interp *interp);
+MODULE_SCOPE void TkCreateExitHandler(Tcl_ExitProc *proc,
+ ClientData clientData);
+MODULE_SCOPE void TkDeleteExitHandler(Tcl_ExitProc *proc,
+ ClientData clientData);
+MODULE_SCOPE Tcl_ExitProc TkFinalize;
+MODULE_SCOPE Tcl_ExitProc TkFinalizeThread;
+MODULE_SCOPE void TkpBuildRegionFromAlphaData(TkRegion region,
+ unsigned x, unsigned y, unsigned width,
+ unsigned height, unsigned char *dataPtr,
+ unsigned pixelStride, unsigned lineStride);
+MODULE_SCOPE void TkPrintPadAmount(Tcl_Interp *interp,
+ char *buffer, int pad1, int pad2);
+MODULE_SCOPE int TkParsePadAmount(Tcl_Interp *interp,
Tk_Window tkwin, Tcl_Obj *objPtr,
- int *pad1Ptr, int *pad2Ptr));
-EXTERN int TkpAlwaysShowSelection _ANSI_ARGS_((Tk_Window tkwin));
+ int *pad1Ptr, int *pad2Ptr);
+MODULE_SCOPE void TkFocusSplit(TkWindow *winPtr);
+MODULE_SCOPE void TkFocusJoin(TkWindow *winPtr);
+MODULE_SCOPE int TkpAlwaysShowSelection(Tk_Window tkwin);
+MODULE_SCOPE void TkpDrawCharsInContext(Display * display,
+ Drawable drawable, GC gc, Tk_Font tkfont,
+ const char *source, int numBytes, int rangeStart,
+ int rangeLength, int x, int y);
+MODULE_SCOPE int TkpMeasureCharsInContext(Tk_Font tkfont,
+ const char *source, int numBytes, int rangeStart,
+ int rangeLength, int maxLength, int flags,
+ int *lengthPtr);
+MODULE_SCOPE void TkUnderlineCharsInContext(Display *display,
+ Drawable drawable, GC gc, Tk_Font tkfont,
+ const char *string, int numBytes, int x, int y,
+ int firstByte, int lastByte);
+MODULE_SCOPE void TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont,
+ Tcl_UniChar c, struct TkFontAttributes *faPtr);
#ifdef __WIN32__
#define TkParseColor XParseColor
#else
-EXTERN Status TkParseColor _ANSI_ARGS_((Display * display,
+MODULE_SCOPE Status TkParseColor (Display * display,
Colormap map, CONST char* spec,
- XColor * colorPtr));
+ XColor * colorPtr);
+#endif
+#ifdef HAVE_XFT
+MODULE_SCOPE void TkUnixSetXftClipRegion(TkRegion clipRegion);
#endif
/*
* Unsupported commands.
*/
-EXTERN int TkUnsupported1ObjCmd _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp,
- int objc, Tcl_Obj *CONST objv[]));
-# undef TCL_STORAGE_CLASS
-# define TCL_STORAGE_CLASS DLLIMPORT
+MODULE_SCOPE int TkUnsupported1ObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
-#endif /* _TKINT */
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLIMPORT
+
+#endif /* _TKINT */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkIntDecls.h b/generic/tkIntDecls.h
index a590cf2..5fcce30 100644
--- a/generic/tkIntDecls.h
+++ b/generic/tkIntDecls.h
@@ -32,371 +32,702 @@
* Exported function declarations:
*/
+#ifndef TkAllocWindow_TCL_DECLARED
+#define TkAllocWindow_TCL_DECLARED
/* 0 */
-EXTERN TkWindow * TkAllocWindow _ANSI_ARGS_((TkDisplay *dispPtr,
- int screenNum, TkWindow *parentPtr));
+EXTERN TkWindow * TkAllocWindow(TkDisplay *dispPtr, int screenNum,
+ TkWindow *parentPtr);
+#endif
+#ifndef TkBezierPoints_TCL_DECLARED
+#define TkBezierPoints_TCL_DECLARED
/* 1 */
-EXTERN void TkBezierPoints _ANSI_ARGS_((double control[],
- int numSteps, double *coordPtr));
+EXTERN void TkBezierPoints(double control[], int numSteps,
+ double *coordPtr);
+#endif
+#ifndef TkBezierScreenPoints_TCL_DECLARED
+#define TkBezierScreenPoints_TCL_DECLARED
/* 2 */
-EXTERN void TkBezierScreenPoints _ANSI_ARGS_((Tk_Canvas canvas,
+EXTERN void TkBezierScreenPoints(Tk_Canvas canvas,
double control[], int numSteps,
- XPoint *xPointPtr));
+ XPoint *xPointPtr);
+#endif
+#ifndef TkBindDeadWindow_TCL_DECLARED
+#define TkBindDeadWindow_TCL_DECLARED
/* 3 */
-EXTERN void TkBindDeadWindow _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkBindDeadWindow(TkWindow *winPtr);
+#endif
+#ifndef TkBindEventProc_TCL_DECLARED
+#define TkBindEventProc_TCL_DECLARED
/* 4 */
-EXTERN void TkBindEventProc _ANSI_ARGS_((TkWindow *winPtr,
- XEvent *eventPtr));
+EXTERN void TkBindEventProc(TkWindow *winPtr, XEvent *eventPtr);
+#endif
+#ifndef TkBindFree_TCL_DECLARED
+#define TkBindFree_TCL_DECLARED
/* 5 */
-EXTERN void TkBindFree _ANSI_ARGS_((TkMainInfo *mainPtr));
+EXTERN void TkBindFree(TkMainInfo *mainPtr);
+#endif
+#ifndef TkBindInit_TCL_DECLARED
+#define TkBindInit_TCL_DECLARED
/* 6 */
-EXTERN void TkBindInit _ANSI_ARGS_((TkMainInfo *mainPtr));
+EXTERN void TkBindInit(TkMainInfo *mainPtr);
+#endif
+#ifndef TkChangeEventWindow_TCL_DECLARED
+#define TkChangeEventWindow_TCL_DECLARED
/* 7 */
-EXTERN void TkChangeEventWindow _ANSI_ARGS_((XEvent *eventPtr,
- TkWindow *winPtr));
+EXTERN void TkChangeEventWindow(XEvent *eventPtr,
+ TkWindow *winPtr);
+#endif
+#ifndef TkClipInit_TCL_DECLARED
+#define TkClipInit_TCL_DECLARED
/* 8 */
-EXTERN int TkClipInit _ANSI_ARGS_((Tcl_Interp *interp,
- TkDisplay *dispPtr));
+EXTERN int TkClipInit(Tcl_Interp *interp, TkDisplay *dispPtr);
+#endif
+#ifndef TkComputeAnchor_TCL_DECLARED
+#define TkComputeAnchor_TCL_DECLARED
/* 9 */
-EXTERN void TkComputeAnchor _ANSI_ARGS_((Tk_Anchor anchor,
- Tk_Window tkwin, int padX, int padY,
- int innerWidth, int innerHeight, int *xPtr,
- int *yPtr));
+EXTERN void TkComputeAnchor(Tk_Anchor anchor, Tk_Window tkwin,
+ int padX, int padY, int innerWidth,
+ int innerHeight, int *xPtr, int *yPtr);
+#endif
+#ifndef TkCopyAndGlobalEval_TCL_DECLARED
+#define TkCopyAndGlobalEval_TCL_DECLARED
/* 10 */
-EXTERN int TkCopyAndGlobalEval _ANSI_ARGS_((Tcl_Interp *interp,
- char *script));
+EXTERN int TkCopyAndGlobalEval(Tcl_Interp *interp, char *script);
+#endif
+#ifndef TkCreateBindingProcedure_TCL_DECLARED
+#define TkCreateBindingProcedure_TCL_DECLARED
/* 11 */
-EXTERN unsigned long TkCreateBindingProcedure _ANSI_ARGS_((
- Tcl_Interp *interp,
+EXTERN unsigned long TkCreateBindingProcedure(Tcl_Interp *interp,
Tk_BindingTable bindingTable,
ClientData object, CONST char *eventString,
TkBindEvalProc *evalProc,
TkBindFreeProc *freeProc,
- ClientData clientData));
+ ClientData clientData);
+#endif
+#ifndef TkCreateCursorFromData_TCL_DECLARED
+#define TkCreateCursorFromData_TCL_DECLARED
/* 12 */
-EXTERN TkCursor * TkCreateCursorFromData _ANSI_ARGS_((Tk_Window tkwin,
+EXTERN TkCursor * TkCreateCursorFromData(Tk_Window tkwin,
CONST char *source, CONST char *mask,
int width, int height, int xHot, int yHot,
- XColor fg, XColor bg));
+ XColor fg, XColor bg);
+#endif
+#ifndef TkCreateFrame_TCL_DECLARED
+#define TkCreateFrame_TCL_DECLARED
/* 13 */
-EXTERN int TkCreateFrame _ANSI_ARGS_((ClientData clientData,
+EXTERN int TkCreateFrame(ClientData clientData,
Tcl_Interp *interp, int argc, char **argv,
- int toplevel, char *appName));
+ int toplevel, char *appName);
+#endif
+#ifndef TkCreateMainWindow_TCL_DECLARED
+#define TkCreateMainWindow_TCL_DECLARED
/* 14 */
-EXTERN Tk_Window TkCreateMainWindow _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *screenName, char *baseName));
+EXTERN Tk_Window TkCreateMainWindow(Tcl_Interp *interp,
+ CONST char *screenName, char *baseName);
+#endif
+#ifndef TkCurrentTime_TCL_DECLARED
+#define TkCurrentTime_TCL_DECLARED
/* 15 */
-EXTERN Time TkCurrentTime _ANSI_ARGS_((TkDisplay *dispPtr));
+EXTERN Time TkCurrentTime(TkDisplay *dispPtr);
+#endif
+#ifndef TkDeleteAllImages_TCL_DECLARED
+#define TkDeleteAllImages_TCL_DECLARED
/* 16 */
-EXTERN void TkDeleteAllImages _ANSI_ARGS_((TkMainInfo *mainPtr));
+EXTERN void TkDeleteAllImages(TkMainInfo *mainPtr);
+#endif
+#ifndef TkDoConfigureNotify_TCL_DECLARED
+#define TkDoConfigureNotify_TCL_DECLARED
/* 17 */
-EXTERN void TkDoConfigureNotify _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkDoConfigureNotify(TkWindow *winPtr);
+#endif
+#ifndef TkDrawInsetFocusHighlight_TCL_DECLARED
+#define TkDrawInsetFocusHighlight_TCL_DECLARED
/* 18 */
-EXTERN void TkDrawInsetFocusHighlight _ANSI_ARGS_((
- Tk_Window tkwin, GC gc, int width,
- Drawable drawable, int padding));
+EXTERN void TkDrawInsetFocusHighlight(Tk_Window tkwin, GC gc,
+ int width, Drawable drawable, int padding);
+#endif
+#ifndef TkEventDeadWindow_TCL_DECLARED
+#define TkEventDeadWindow_TCL_DECLARED
/* 19 */
-EXTERN void TkEventDeadWindow _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkEventDeadWindow(TkWindow *winPtr);
+#endif
+#ifndef TkFillPolygon_TCL_DECLARED
+#define TkFillPolygon_TCL_DECLARED
/* 20 */
-EXTERN void TkFillPolygon _ANSI_ARGS_((Tk_Canvas canvas,
- double *coordPtr, int numPoints,
- Display *display, Drawable drawable, GC gc,
- GC outlineGC));
+EXTERN void TkFillPolygon(Tk_Canvas canvas, double *coordPtr,
+ int numPoints, Display *display,
+ Drawable drawable, GC gc, GC outlineGC);
+#endif
+#ifndef TkFindStateNum_TCL_DECLARED
+#define TkFindStateNum_TCL_DECLARED
/* 21 */
-EXTERN int TkFindStateNum _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN int TkFindStateNum(Tcl_Interp *interp,
CONST char *option, CONST TkStateMap *mapPtr,
- CONST char *strKey));
+ CONST char *strKey);
+#endif
+#ifndef TkFindStateString_TCL_DECLARED
+#define TkFindStateString_TCL_DECLARED
/* 22 */
-EXTERN char * TkFindStateString _ANSI_ARGS_((
- CONST TkStateMap *mapPtr, int numKey));
+EXTERN char * TkFindStateString(CONST TkStateMap *mapPtr,
+ int numKey);
+#endif
+#ifndef TkFocusDeadWindow_TCL_DECLARED
+#define TkFocusDeadWindow_TCL_DECLARED
/* 23 */
-EXTERN void TkFocusDeadWindow _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkFocusDeadWindow(TkWindow *winPtr);
+#endif
+#ifndef TkFocusFilterEvent_TCL_DECLARED
+#define TkFocusFilterEvent_TCL_DECLARED
/* 24 */
-EXTERN int TkFocusFilterEvent _ANSI_ARGS_((TkWindow *winPtr,
- XEvent *eventPtr));
+EXTERN int TkFocusFilterEvent(TkWindow *winPtr,
+ XEvent *eventPtr);
+#endif
+#ifndef TkFocusKeyEvent_TCL_DECLARED
+#define TkFocusKeyEvent_TCL_DECLARED
/* 25 */
-EXTERN TkWindow * TkFocusKeyEvent _ANSI_ARGS_((TkWindow *winPtr,
- XEvent *eventPtr));
+EXTERN TkWindow * TkFocusKeyEvent(TkWindow *winPtr, XEvent *eventPtr);
+#endif
+#ifndef TkFontPkgInit_TCL_DECLARED
+#define TkFontPkgInit_TCL_DECLARED
/* 26 */
-EXTERN void TkFontPkgInit _ANSI_ARGS_((TkMainInfo *mainPtr));
+EXTERN void TkFontPkgInit(TkMainInfo *mainPtr);
+#endif
+#ifndef TkFontPkgFree_TCL_DECLARED
+#define TkFontPkgFree_TCL_DECLARED
/* 27 */
-EXTERN void TkFontPkgFree _ANSI_ARGS_((TkMainInfo *mainPtr));
+EXTERN void TkFontPkgFree(TkMainInfo *mainPtr);
+#endif
+#ifndef TkFreeBindingTags_TCL_DECLARED
+#define TkFreeBindingTags_TCL_DECLARED
/* 28 */
-EXTERN void TkFreeBindingTags _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkFreeBindingTags(TkWindow *winPtr);
+#endif
+#ifndef TkpFreeCursor_TCL_DECLARED
+#define TkpFreeCursor_TCL_DECLARED
/* 29 */
-EXTERN void TkpFreeCursor _ANSI_ARGS_((TkCursor *cursorPtr));
+EXTERN void TkpFreeCursor(TkCursor *cursorPtr);
+#endif
+#ifndef TkGetBitmapData_TCL_DECLARED
+#define TkGetBitmapData_TCL_DECLARED
/* 30 */
-EXTERN char * TkGetBitmapData _ANSI_ARGS_((Tcl_Interp *interp,
- char *string, char *fileName, int *widthPtr,
- int *heightPtr, int *hotXPtr, int *hotYPtr));
+EXTERN char * TkGetBitmapData(Tcl_Interp *interp, char *string,
+ char *fileName, int *widthPtr,
+ int *heightPtr, int *hotXPtr, int *hotYPtr);
+#endif
+#ifndef TkGetButtPoints_TCL_DECLARED
+#define TkGetButtPoints_TCL_DECLARED
/* 31 */
-EXTERN void TkGetButtPoints _ANSI_ARGS_((double p1[],
- double p2[], double width, int project,
- double m1[], double m2[]));
+EXTERN void TkGetButtPoints(double p1[], double p2[],
+ double width, int project, double m1[],
+ double m2[]);
+#endif
+#ifndef TkGetCursorByName_TCL_DECLARED
+#define TkGetCursorByName_TCL_DECLARED
/* 32 */
-EXTERN TkCursor * TkGetCursorByName _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, Tk_Uid string));
+EXTERN TkCursor * TkGetCursorByName(Tcl_Interp *interp,
+ Tk_Window tkwin, Tk_Uid string);
+#endif
+#ifndef TkGetDefaultScreenName_TCL_DECLARED
+#define TkGetDefaultScreenName_TCL_DECLARED
/* 33 */
-EXTERN CONST84_RETURN char * TkGetDefaultScreenName _ANSI_ARGS_((
- Tcl_Interp *interp, CONST char *screenName));
+EXTERN CONST84_RETURN char * TkGetDefaultScreenName(Tcl_Interp *interp,
+ CONST char *screenName);
+#endif
+#ifndef TkGetDisplay_TCL_DECLARED
+#define TkGetDisplay_TCL_DECLARED
/* 34 */
-EXTERN TkDisplay * TkGetDisplay _ANSI_ARGS_((Display *display));
+EXTERN TkDisplay * TkGetDisplay(Display *display);
+#endif
+#ifndef TkGetDisplayOf_TCL_DECLARED
+#define TkGetDisplayOf_TCL_DECLARED
/* 35 */
-EXTERN int TkGetDisplayOf _ANSI_ARGS_((Tcl_Interp *interp,
- int objc, Tcl_Obj *CONST objv[],
- Tk_Window *tkwinPtr));
+EXTERN int TkGetDisplayOf(Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[], Tk_Window *tkwinPtr);
+#endif
+#ifndef TkGetFocusWin_TCL_DECLARED
+#define TkGetFocusWin_TCL_DECLARED
/* 36 */
-EXTERN TkWindow * TkGetFocusWin _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN TkWindow * TkGetFocusWin(TkWindow *winPtr);
+#endif
+#ifndef TkGetInterpNames_TCL_DECLARED
+#define TkGetInterpNames_TCL_DECLARED
/* 37 */
-EXTERN int TkGetInterpNames _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin));
+EXTERN int TkGetInterpNames(Tcl_Interp *interp, Tk_Window tkwin);
+#endif
+#ifndef TkGetMiterPoints_TCL_DECLARED
+#define TkGetMiterPoints_TCL_DECLARED
/* 38 */
-EXTERN int TkGetMiterPoints _ANSI_ARGS_((double p1[],
- double p2[], double p3[], double width,
- double m1[], double m2[]));
+EXTERN int TkGetMiterPoints(double p1[], double p2[],
+ double p3[], double width, double m1[],
+ double m2[]);
+#endif
+#ifndef TkGetPointerCoords_TCL_DECLARED
+#define TkGetPointerCoords_TCL_DECLARED
/* 39 */
-EXTERN void TkGetPointerCoords _ANSI_ARGS_((Tk_Window tkwin,
- int *xPtr, int *yPtr));
+EXTERN void TkGetPointerCoords(Tk_Window tkwin, int *xPtr,
+ int *yPtr);
+#endif
+#ifndef TkGetServerInfo_TCL_DECLARED
+#define TkGetServerInfo_TCL_DECLARED
/* 40 */
-EXTERN void TkGetServerInfo _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin));
+EXTERN void TkGetServerInfo(Tcl_Interp *interp, Tk_Window tkwin);
+#endif
+#ifndef TkGrabDeadWindow_TCL_DECLARED
+#define TkGrabDeadWindow_TCL_DECLARED
/* 41 */
-EXTERN void TkGrabDeadWindow _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkGrabDeadWindow(TkWindow *winPtr);
+#endif
+#ifndef TkGrabState_TCL_DECLARED
+#define TkGrabState_TCL_DECLARED
/* 42 */
-EXTERN int TkGrabState _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN int TkGrabState(TkWindow *winPtr);
+#endif
+#ifndef TkIncludePoint_TCL_DECLARED
+#define TkIncludePoint_TCL_DECLARED
/* 43 */
-EXTERN void TkIncludePoint _ANSI_ARGS_((Tk_Item *itemPtr,
- double *pointPtr));
+EXTERN void TkIncludePoint(Tk_Item *itemPtr, double *pointPtr);
+#endif
+#ifndef TkInOutEvents_TCL_DECLARED
+#define TkInOutEvents_TCL_DECLARED
/* 44 */
-EXTERN void TkInOutEvents _ANSI_ARGS_((XEvent *eventPtr,
- TkWindow *sourcePtr, TkWindow *destPtr,
- int leaveType, int enterType,
- Tcl_QueuePosition position));
+EXTERN void TkInOutEvents(XEvent *eventPtr, TkWindow *sourcePtr,
+ TkWindow *destPtr, int leaveType,
+ int enterType, Tcl_QueuePosition position);
+#endif
+#ifndef TkInstallFrameMenu_TCL_DECLARED
+#define TkInstallFrameMenu_TCL_DECLARED
/* 45 */
-EXTERN void TkInstallFrameMenu _ANSI_ARGS_((Tk_Window tkwin));
+EXTERN void TkInstallFrameMenu(Tk_Window tkwin);
+#endif
+#ifndef TkKeysymToString_TCL_DECLARED
+#define TkKeysymToString_TCL_DECLARED
/* 46 */
-EXTERN char * TkKeysymToString _ANSI_ARGS_((KeySym keysym));
+EXTERN char * TkKeysymToString(KeySym keysym);
+#endif
+#ifndef TkLineToArea_TCL_DECLARED
+#define TkLineToArea_TCL_DECLARED
/* 47 */
-EXTERN int TkLineToArea _ANSI_ARGS_((double end1Ptr[],
- double end2Ptr[], double rectPtr[]));
+EXTERN int TkLineToArea(double end1Ptr[], double end2Ptr[],
+ double rectPtr[]);
+#endif
+#ifndef TkLineToPoint_TCL_DECLARED
+#define TkLineToPoint_TCL_DECLARED
/* 48 */
-EXTERN double TkLineToPoint _ANSI_ARGS_((double end1Ptr[],
- double end2Ptr[], double pointPtr[]));
+EXTERN double TkLineToPoint(double end1Ptr[], double end2Ptr[],
+ double pointPtr[]);
+#endif
+#ifndef TkMakeBezierCurve_TCL_DECLARED
+#define TkMakeBezierCurve_TCL_DECLARED
/* 49 */
-EXTERN int TkMakeBezierCurve _ANSI_ARGS_((Tk_Canvas canvas,
- double *pointPtr, int numPoints,
- int numSteps, XPoint xPoints[],
- double dblPoints[]));
+EXTERN int TkMakeBezierCurve(Tk_Canvas canvas, double *pointPtr,
+ int numPoints, int numSteps,
+ XPoint xPoints[], double dblPoints[]);
+#endif
+#ifndef TkMakeBezierPostscript_TCL_DECLARED
+#define TkMakeBezierPostscript_TCL_DECLARED
/* 50 */
-EXTERN void TkMakeBezierPostscript _ANSI_ARGS_((
- Tcl_Interp *interp, Tk_Canvas canvas,
- double *pointPtr, int numPoints));
+EXTERN void TkMakeBezierPostscript(Tcl_Interp *interp,
+ Tk_Canvas canvas, double *pointPtr,
+ int numPoints);
+#endif
+#ifndef TkOptionClassChanged_TCL_DECLARED
+#define TkOptionClassChanged_TCL_DECLARED
/* 51 */
-EXTERN void TkOptionClassChanged _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkOptionClassChanged(TkWindow *winPtr);
+#endif
+#ifndef TkOptionDeadWindow_TCL_DECLARED
+#define TkOptionDeadWindow_TCL_DECLARED
/* 52 */
-EXTERN void TkOptionDeadWindow _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkOptionDeadWindow(TkWindow *winPtr);
+#endif
+#ifndef TkOvalToArea_TCL_DECLARED
+#define TkOvalToArea_TCL_DECLARED
/* 53 */
-EXTERN int TkOvalToArea _ANSI_ARGS_((double *ovalPtr,
- double *rectPtr));
+EXTERN int TkOvalToArea(double *ovalPtr, double *rectPtr);
+#endif
+#ifndef TkOvalToPoint_TCL_DECLARED
+#define TkOvalToPoint_TCL_DECLARED
/* 54 */
-EXTERN double TkOvalToPoint _ANSI_ARGS_((double ovalPtr[],
- double width, int filled, double pointPtr[]));
+EXTERN double TkOvalToPoint(double ovalPtr[], double width,
+ int filled, double pointPtr[]);
+#endif
+#ifndef TkpChangeFocus_TCL_DECLARED
+#define TkpChangeFocus_TCL_DECLARED
/* 55 */
-EXTERN int TkpChangeFocus _ANSI_ARGS_((TkWindow *winPtr,
- int force));
+EXTERN int TkpChangeFocus(TkWindow *winPtr, int force);
+#endif
+#ifndef TkpCloseDisplay_TCL_DECLARED
+#define TkpCloseDisplay_TCL_DECLARED
/* 56 */
-EXTERN void TkpCloseDisplay _ANSI_ARGS_((TkDisplay *dispPtr));
+EXTERN void TkpCloseDisplay(TkDisplay *dispPtr);
+#endif
+#ifndef TkpClaimFocus_TCL_DECLARED
+#define TkpClaimFocus_TCL_DECLARED
/* 57 */
-EXTERN void TkpClaimFocus _ANSI_ARGS_((TkWindow *topLevelPtr,
- int force));
+EXTERN void TkpClaimFocus(TkWindow *topLevelPtr, int force);
+#endif
+#ifndef TkpDisplayWarning_TCL_DECLARED
+#define TkpDisplayWarning_TCL_DECLARED
/* 58 */
-EXTERN void TkpDisplayWarning _ANSI_ARGS_((CONST char *msg,
- CONST char *title));
+EXTERN void TkpDisplayWarning(CONST char *msg, CONST char *title);
+#endif
+#ifndef TkpGetAppName_TCL_DECLARED
+#define TkpGetAppName_TCL_DECLARED
/* 59 */
-EXTERN void TkpGetAppName _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_DString *name));
+EXTERN void TkpGetAppName(Tcl_Interp *interp, Tcl_DString *name);
+#endif
+#ifndef TkpGetOtherWindow_TCL_DECLARED
+#define TkpGetOtherWindow_TCL_DECLARED
/* 60 */
-EXTERN TkWindow * TkpGetOtherWindow _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN TkWindow * TkpGetOtherWindow(TkWindow *winPtr);
+#endif
+#ifndef TkpGetWrapperWindow_TCL_DECLARED
+#define TkpGetWrapperWindow_TCL_DECLARED
/* 61 */
-EXTERN TkWindow * TkpGetWrapperWindow _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN TkWindow * TkpGetWrapperWindow(TkWindow *winPtr);
+#endif
+#ifndef TkpInit_TCL_DECLARED
+#define TkpInit_TCL_DECLARED
/* 62 */
-EXTERN int TkpInit _ANSI_ARGS_((Tcl_Interp *interp));
+EXTERN int TkpInit(Tcl_Interp *interp);
+#endif
+#ifndef TkpInitializeMenuBindings_TCL_DECLARED
+#define TkpInitializeMenuBindings_TCL_DECLARED
/* 63 */
-EXTERN void TkpInitializeMenuBindings _ANSI_ARGS_((
- Tcl_Interp *interp,
- Tk_BindingTable bindingTable));
+EXTERN void TkpInitializeMenuBindings(Tcl_Interp *interp,
+ Tk_BindingTable bindingTable);
+#endif
+#ifndef TkpMakeContainer_TCL_DECLARED
+#define TkpMakeContainer_TCL_DECLARED
/* 64 */
-EXTERN void TkpMakeContainer _ANSI_ARGS_((Tk_Window tkwin));
+EXTERN void TkpMakeContainer(Tk_Window tkwin);
+#endif
+#ifndef TkpMakeMenuWindow_TCL_DECLARED
+#define TkpMakeMenuWindow_TCL_DECLARED
/* 65 */
-EXTERN void TkpMakeMenuWindow _ANSI_ARGS_((Tk_Window tkwin,
- int transient));
+EXTERN void TkpMakeMenuWindow(Tk_Window tkwin, int transient);
+#endif
+#ifndef TkpMakeWindow_TCL_DECLARED
+#define TkpMakeWindow_TCL_DECLARED
/* 66 */
-EXTERN Window TkpMakeWindow _ANSI_ARGS_((TkWindow *winPtr,
- Window parent));
+EXTERN Window TkpMakeWindow(TkWindow *winPtr, Window parent);
+#endif
+#ifndef TkpMenuNotifyToplevelCreate_TCL_DECLARED
+#define TkpMenuNotifyToplevelCreate_TCL_DECLARED
/* 67 */
-EXTERN void TkpMenuNotifyToplevelCreate _ANSI_ARGS_((
- Tcl_Interp *interp, char *menuName));
+EXTERN void TkpMenuNotifyToplevelCreate(Tcl_Interp *interp,
+ char *menuName);
+#endif
+#ifndef TkpOpenDisplay_TCL_DECLARED
+#define TkpOpenDisplay_TCL_DECLARED
/* 68 */
-EXTERN TkDisplay * TkpOpenDisplay _ANSI_ARGS_((CONST char *display_name));
+EXTERN TkDisplay * TkpOpenDisplay(CONST char *display_name);
+#endif
+#ifndef TkPointerEvent_TCL_DECLARED
+#define TkPointerEvent_TCL_DECLARED
/* 69 */
-EXTERN int TkPointerEvent _ANSI_ARGS_((XEvent *eventPtr,
- TkWindow *winPtr));
+EXTERN int TkPointerEvent(XEvent *eventPtr, TkWindow *winPtr);
+#endif
+#ifndef TkPolygonToArea_TCL_DECLARED
+#define TkPolygonToArea_TCL_DECLARED
/* 70 */
-EXTERN int TkPolygonToArea _ANSI_ARGS_((double *polyPtr,
- int numPoints, double *rectPtr));
+EXTERN int TkPolygonToArea(double *polyPtr, int numPoints,
+ double *rectPtr);
+#endif
+#ifndef TkPolygonToPoint_TCL_DECLARED
+#define TkPolygonToPoint_TCL_DECLARED
/* 71 */
-EXTERN double TkPolygonToPoint _ANSI_ARGS_((double *polyPtr,
- int numPoints, double *pointPtr));
+EXTERN double TkPolygonToPoint(double *polyPtr, int numPoints,
+ double *pointPtr);
+#endif
+#ifndef TkPositionInTree_TCL_DECLARED
+#define TkPositionInTree_TCL_DECLARED
/* 72 */
-EXTERN int TkPositionInTree _ANSI_ARGS_((TkWindow *winPtr,
- TkWindow *treePtr));
+EXTERN int TkPositionInTree(TkWindow *winPtr, TkWindow *treePtr);
+#endif
+#ifndef TkpRedirectKeyEvent_TCL_DECLARED
+#define TkpRedirectKeyEvent_TCL_DECLARED
/* 73 */
-EXTERN void TkpRedirectKeyEvent _ANSI_ARGS_((TkWindow *winPtr,
- XEvent *eventPtr));
+EXTERN void TkpRedirectKeyEvent(TkWindow *winPtr,
+ XEvent *eventPtr);
+#endif
+#ifndef TkpSetMainMenubar_TCL_DECLARED
+#define TkpSetMainMenubar_TCL_DECLARED
/* 74 */
-EXTERN void TkpSetMainMenubar _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, char *menuName));
+EXTERN void TkpSetMainMenubar(Tcl_Interp *interp,
+ Tk_Window tkwin, char *menuName);
+#endif
+#ifndef TkpUseWindow_TCL_DECLARED
+#define TkpUseWindow_TCL_DECLARED
/* 75 */
-EXTERN int TkpUseWindow _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, CONST char *string));
+EXTERN int TkpUseWindow(Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *string);
+#endif
+#ifndef TkpWindowWasRecentlyDeleted_TCL_DECLARED
+#define TkpWindowWasRecentlyDeleted_TCL_DECLARED
/* 76 */
-EXTERN int TkpWindowWasRecentlyDeleted _ANSI_ARGS_((Window win,
- TkDisplay *dispPtr));
+EXTERN int TkpWindowWasRecentlyDeleted(Window win,
+ TkDisplay *dispPtr);
+#endif
+#ifndef TkQueueEventForAllChildren_TCL_DECLARED
+#define TkQueueEventForAllChildren_TCL_DECLARED
/* 77 */
-EXTERN void TkQueueEventForAllChildren _ANSI_ARGS_((
- TkWindow *winPtr, XEvent *eventPtr));
+EXTERN void TkQueueEventForAllChildren(TkWindow *winPtr,
+ XEvent *eventPtr);
+#endif
+#ifndef TkReadBitmapFile_TCL_DECLARED
+#define TkReadBitmapFile_TCL_DECLARED
/* 78 */
-EXTERN int TkReadBitmapFile _ANSI_ARGS_((Display *display,
- Drawable d, CONST char *filename,
+EXTERN int TkReadBitmapFile(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));
+ int *y_hot_return);
+#endif
+#ifndef TkScrollWindow_TCL_DECLARED
+#define TkScrollWindow_TCL_DECLARED
/* 79 */
-EXTERN int TkScrollWindow _ANSI_ARGS_((Tk_Window tkwin, GC gc,
- int x, int y, int width, int height, int dx,
- int dy, TkRegion damageRgn));
+EXTERN int TkScrollWindow(Tk_Window tkwin, GC gc, int x, int y,
+ int width, int height, int dx, int dy,
+ TkRegion damageRgn);
+#endif
+#ifndef TkSelDeadWindow_TCL_DECLARED
+#define TkSelDeadWindow_TCL_DECLARED
/* 80 */
-EXTERN void TkSelDeadWindow _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkSelDeadWindow(TkWindow *winPtr);
+#endif
+#ifndef TkSelEventProc_TCL_DECLARED
+#define TkSelEventProc_TCL_DECLARED
/* 81 */
-EXTERN void TkSelEventProc _ANSI_ARGS_((Tk_Window tkwin,
- XEvent *eventPtr));
+EXTERN void TkSelEventProc(Tk_Window tkwin, XEvent *eventPtr);
+#endif
+#ifndef TkSelInit_TCL_DECLARED
+#define TkSelInit_TCL_DECLARED
/* 82 */
-EXTERN void TkSelInit _ANSI_ARGS_((Tk_Window tkwin));
+EXTERN void TkSelInit(Tk_Window tkwin);
+#endif
+#ifndef TkSelPropProc_TCL_DECLARED
+#define TkSelPropProc_TCL_DECLARED
/* 83 */
-EXTERN void TkSelPropProc _ANSI_ARGS_((XEvent *eventPtr));
+EXTERN void TkSelPropProc(XEvent *eventPtr);
+#endif
/* Slot 84 is reserved */
+#ifndef TkSetWindowMenuBar_TCL_DECLARED
+#define TkSetWindowMenuBar_TCL_DECLARED
/* 85 */
-EXTERN void TkSetWindowMenuBar _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN void TkSetWindowMenuBar(Tcl_Interp *interp,
Tk_Window tkwin, char *oldMenuName,
- char *menuName));
+ char *menuName);
+#endif
+#ifndef TkStringToKeysym_TCL_DECLARED
+#define TkStringToKeysym_TCL_DECLARED
/* 86 */
-EXTERN KeySym TkStringToKeysym _ANSI_ARGS_((char *name));
+EXTERN KeySym TkStringToKeysym(char *name);
+#endif
+#ifndef TkThickPolyLineToArea_TCL_DECLARED
+#define TkThickPolyLineToArea_TCL_DECLARED
/* 87 */
-EXTERN int TkThickPolyLineToArea _ANSI_ARGS_((double *coordPtr,
+EXTERN int TkThickPolyLineToArea(double *coordPtr,
int numPoints, double width, int capStyle,
- int joinStyle, double *rectPtr));
+ int joinStyle, double *rectPtr);
+#endif
+#ifndef TkWmAddToColormapWindows_TCL_DECLARED
+#define TkWmAddToColormapWindows_TCL_DECLARED
/* 88 */
-EXTERN void TkWmAddToColormapWindows _ANSI_ARGS_((
- TkWindow *winPtr));
+EXTERN void TkWmAddToColormapWindows(TkWindow *winPtr);
+#endif
+#ifndef TkWmDeadWindow_TCL_DECLARED
+#define TkWmDeadWindow_TCL_DECLARED
/* 89 */
-EXTERN void TkWmDeadWindow _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkWmDeadWindow(TkWindow *winPtr);
+#endif
+#ifndef TkWmFocusToplevel_TCL_DECLARED
+#define TkWmFocusToplevel_TCL_DECLARED
/* 90 */
-EXTERN TkWindow * TkWmFocusToplevel _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN TkWindow * TkWmFocusToplevel(TkWindow *winPtr);
+#endif
+#ifndef TkWmMapWindow_TCL_DECLARED
+#define TkWmMapWindow_TCL_DECLARED
/* 91 */
-EXTERN void TkWmMapWindow _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkWmMapWindow(TkWindow *winPtr);
+#endif
+#ifndef TkWmNewWindow_TCL_DECLARED
+#define TkWmNewWindow_TCL_DECLARED
/* 92 */
-EXTERN void TkWmNewWindow _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkWmNewWindow(TkWindow *winPtr);
+#endif
+#ifndef TkWmProtocolEventProc_TCL_DECLARED
+#define TkWmProtocolEventProc_TCL_DECLARED
/* 93 */
-EXTERN void TkWmProtocolEventProc _ANSI_ARGS_((TkWindow *winPtr,
- XEvent *evenvPtr));
+EXTERN void TkWmProtocolEventProc(TkWindow *winPtr,
+ XEvent *evenvPtr);
+#endif
+#ifndef TkWmRemoveFromColormapWindows_TCL_DECLARED
+#define TkWmRemoveFromColormapWindows_TCL_DECLARED
/* 94 */
-EXTERN void TkWmRemoveFromColormapWindows _ANSI_ARGS_((
- TkWindow *winPtr));
+EXTERN void TkWmRemoveFromColormapWindows(TkWindow *winPtr);
+#endif
+#ifndef TkWmRestackToplevel_TCL_DECLARED
+#define TkWmRestackToplevel_TCL_DECLARED
/* 95 */
-EXTERN void TkWmRestackToplevel _ANSI_ARGS_((TkWindow *winPtr,
- int aboveBelow, TkWindow *otherPtr));
+EXTERN void TkWmRestackToplevel(TkWindow *winPtr, int aboveBelow,
+ TkWindow *otherPtr);
+#endif
+#ifndef TkWmSetClass_TCL_DECLARED
+#define TkWmSetClass_TCL_DECLARED
/* 96 */
-EXTERN void TkWmSetClass _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkWmSetClass(TkWindow *winPtr);
+#endif
+#ifndef TkWmUnmapWindow_TCL_DECLARED
+#define TkWmUnmapWindow_TCL_DECLARED
/* 97 */
-EXTERN void TkWmUnmapWindow _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkWmUnmapWindow(TkWindow *winPtr);
+#endif
+#ifndef TkDebugBitmap_TCL_DECLARED
+#define TkDebugBitmap_TCL_DECLARED
/* 98 */
-EXTERN Tcl_Obj * TkDebugBitmap _ANSI_ARGS_((Tk_Window tkwin,
- char *name));
+EXTERN Tcl_Obj * TkDebugBitmap(Tk_Window tkwin, char *name);
+#endif
+#ifndef TkDebugBorder_TCL_DECLARED
+#define TkDebugBorder_TCL_DECLARED
/* 99 */
-EXTERN Tcl_Obj * TkDebugBorder _ANSI_ARGS_((Tk_Window tkwin,
- char *name));
+EXTERN Tcl_Obj * TkDebugBorder(Tk_Window tkwin, char *name);
+#endif
+#ifndef TkDebugCursor_TCL_DECLARED
+#define TkDebugCursor_TCL_DECLARED
/* 100 */
-EXTERN Tcl_Obj * TkDebugCursor _ANSI_ARGS_((Tk_Window tkwin,
- char *name));
+EXTERN Tcl_Obj * TkDebugCursor(Tk_Window tkwin, char *name);
+#endif
+#ifndef TkDebugColor_TCL_DECLARED
+#define TkDebugColor_TCL_DECLARED
/* 101 */
-EXTERN Tcl_Obj * TkDebugColor _ANSI_ARGS_((Tk_Window tkwin,
- char *name));
+EXTERN Tcl_Obj * TkDebugColor(Tk_Window tkwin, char *name);
+#endif
+#ifndef TkDebugConfig_TCL_DECLARED
+#define TkDebugConfig_TCL_DECLARED
/* 102 */
-EXTERN Tcl_Obj * TkDebugConfig _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_OptionTable table));
+EXTERN Tcl_Obj * TkDebugConfig(Tcl_Interp *interp,
+ Tk_OptionTable table);
+#endif
+#ifndef TkDebugFont_TCL_DECLARED
+#define TkDebugFont_TCL_DECLARED
/* 103 */
-EXTERN Tcl_Obj * TkDebugFont _ANSI_ARGS_((Tk_Window tkwin, char *name));
+EXTERN Tcl_Obj * TkDebugFont(Tk_Window tkwin, char *name);
+#endif
+#ifndef TkFindStateNumObj_TCL_DECLARED
+#define TkFindStateNumObj_TCL_DECLARED
/* 104 */
-EXTERN int TkFindStateNumObj _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN int TkFindStateNumObj(Tcl_Interp *interp,
Tcl_Obj *optionPtr, CONST TkStateMap *mapPtr,
- Tcl_Obj *keyPtr));
+ Tcl_Obj *keyPtr);
+#endif
+#ifndef TkGetBitmapPredefTable_TCL_DECLARED
+#define TkGetBitmapPredefTable_TCL_DECLARED
/* 105 */
-EXTERN Tcl_HashTable * TkGetBitmapPredefTable _ANSI_ARGS_((void));
+EXTERN Tcl_HashTable * TkGetBitmapPredefTable(void);
+#endif
+#ifndef TkGetDisplayList_TCL_DECLARED
+#define TkGetDisplayList_TCL_DECLARED
/* 106 */
-EXTERN TkDisplay * TkGetDisplayList _ANSI_ARGS_((void));
+EXTERN TkDisplay * TkGetDisplayList(void);
+#endif
+#ifndef TkGetMainInfoList_TCL_DECLARED
+#define TkGetMainInfoList_TCL_DECLARED
/* 107 */
-EXTERN TkMainInfo * TkGetMainInfoList _ANSI_ARGS_((void));
+EXTERN TkMainInfo * TkGetMainInfoList(void);
+#endif
+#ifndef TkGetWindowFromObj_TCL_DECLARED
+#define TkGetWindowFromObj_TCL_DECLARED
/* 108 */
-EXTERN int TkGetWindowFromObj _ANSI_ARGS_((Tcl_Interp *interp,
+EXTERN int TkGetWindowFromObj(Tcl_Interp *interp,
Tk_Window tkwin, Tcl_Obj *objPtr,
- Tk_Window *windowPtr));
+ Tk_Window *windowPtr);
+#endif
+#ifndef TkpGetString_TCL_DECLARED
+#define TkpGetString_TCL_DECLARED
/* 109 */
-EXTERN char * TkpGetString _ANSI_ARGS_((TkWindow *winPtr,
- XEvent *eventPtr, Tcl_DString *dsPtr));
+EXTERN char * TkpGetString(TkWindow *winPtr, XEvent *eventPtr,
+ Tcl_DString *dsPtr);
+#endif
+#ifndef TkpGetSubFonts_TCL_DECLARED
+#define TkpGetSubFonts_TCL_DECLARED
/* 110 */
-EXTERN void TkpGetSubFonts _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Font tkfont));
+EXTERN void TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont);
+#endif
+#ifndef TkpGetSystemDefault_TCL_DECLARED
+#define TkpGetSystemDefault_TCL_DECLARED
/* 111 */
-EXTERN Tcl_Obj * TkpGetSystemDefault _ANSI_ARGS_((Tk_Window tkwin,
- CONST char *dbName, CONST char *className));
+EXTERN Tcl_Obj * TkpGetSystemDefault(Tk_Window tkwin,
+ CONST char *dbName, CONST char *className);
+#endif
+#ifndef TkpMenuThreadInit_TCL_DECLARED
+#define TkpMenuThreadInit_TCL_DECLARED
/* 112 */
-EXTERN void TkpMenuThreadInit _ANSI_ARGS_((void));
+EXTERN void TkpMenuThreadInit(void);
+#endif
+#ifndef TkClipBox_TCL_DECLARED
+#define TkClipBox_TCL_DECLARED
/* 113 */
-EXTERN void TkClipBox _ANSI_ARGS_((TkRegion rgn,
- XRectangle *rect_return));
+EXTERN void TkClipBox(TkRegion rgn, XRectangle *rect_return);
+#endif
+#ifndef TkCreateRegion_TCL_DECLARED
+#define TkCreateRegion_TCL_DECLARED
/* 114 */
-EXTERN TkRegion TkCreateRegion _ANSI_ARGS_((void));
+EXTERN TkRegion TkCreateRegion(void);
+#endif
+#ifndef TkDestroyRegion_TCL_DECLARED
+#define TkDestroyRegion_TCL_DECLARED
/* 115 */
-EXTERN void TkDestroyRegion _ANSI_ARGS_((TkRegion rgn));
+EXTERN void TkDestroyRegion(TkRegion rgn);
+#endif
+#ifndef TkIntersectRegion_TCL_DECLARED
+#define TkIntersectRegion_TCL_DECLARED
/* 116 */
-EXTERN void TkIntersectRegion _ANSI_ARGS_((TkRegion sra,
- TkRegion srcb, TkRegion dr_return));
+EXTERN void TkIntersectRegion(TkRegion sra, TkRegion srcb,
+ TkRegion dr_return);
+#endif
+#ifndef TkRectInRegion_TCL_DECLARED
+#define TkRectInRegion_TCL_DECLARED
/* 117 */
-EXTERN int TkRectInRegion _ANSI_ARGS_((TkRegion rgn, int x,
- int y, unsigned int width,
- unsigned int height));
+EXTERN int TkRectInRegion(TkRegion rgn, int x, int y,
+ unsigned int width, unsigned int height);
+#endif
+#ifndef TkSetRegion_TCL_DECLARED
+#define TkSetRegion_TCL_DECLARED
/* 118 */
-EXTERN void TkSetRegion _ANSI_ARGS_((Display *display, GC gc,
- TkRegion rgn));
+EXTERN void TkSetRegion(Display *display, GC gc, TkRegion rgn);
+#endif
+#ifndef TkUnionRectWithRegion_TCL_DECLARED
+#define TkUnionRectWithRegion_TCL_DECLARED
/* 119 */
-EXTERN void TkUnionRectWithRegion _ANSI_ARGS_((XRectangle *rect,
- TkRegion src, TkRegion dr_return));
+EXTERN void TkUnionRectWithRegion(XRectangle *rect, TkRegion src,
+ TkRegion dr_return);
+#endif
/* Slot 120 is reserved */
#ifdef MAC_OSX_TK /* AQUA */
+#ifndef TkpCreateNativeBitmap_TCL_DECLARED
+#define TkpCreateNativeBitmap_TCL_DECLARED
/* 121 */
-EXTERN Pixmap TkpCreateNativeBitmap _ANSI_ARGS_((Display *display,
- CONST char *source));
+EXTERN Pixmap TkpCreateNativeBitmap(Display *display,
+ CONST char *source);
+#endif
#endif /* AQUA */
#ifdef MAC_OSX_TK /* AQUA */
+#ifndef TkpDefineNativeBitmaps_TCL_DECLARED
+#define TkpDefineNativeBitmaps_TCL_DECLARED
/* 122 */
-EXTERN void TkpDefineNativeBitmaps _ANSI_ARGS_((void));
+EXTERN void TkpDefineNativeBitmaps(void);
+#endif
#endif /* AQUA */
/* Slot 123 is reserved */
#ifdef MAC_OSX_TK /* AQUA */
+#ifndef TkpGetNativeAppBitmap_TCL_DECLARED
+#define TkpGetNativeAppBitmap_TCL_DECLARED
/* 124 */
-EXTERN Pixmap TkpGetNativeAppBitmap _ANSI_ARGS_((Display *display,
- CONST char *name, int *width, int *height));
+EXTERN Pixmap TkpGetNativeAppBitmap(Display *display,
+ CONST char *name, int *width, int *height);
+#endif
#endif /* AQUA */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
@@ -408,177 +739,354 @@ EXTERN Pixmap TkpGetNativeAppBitmap _ANSI_ARGS_((Display *display,
/* Slot 132 is reserved */
/* Slot 133 is reserved */
/* Slot 134 is reserved */
+#ifndef TkpDrawHighlightBorder_TCL_DECLARED
+#define TkpDrawHighlightBorder_TCL_DECLARED
/* 135 */
-EXTERN void TkpDrawHighlightBorder _ANSI_ARGS_((Tk_Window tkwin,
- GC fgGC, GC bgGC, int highlightWidth,
- Drawable drawable));
+EXTERN void TkpDrawHighlightBorder(Tk_Window tkwin, GC fgGC,
+ GC bgGC, int highlightWidth,
+ Drawable drawable);
+#endif
+#ifndef TkSetFocusWin_TCL_DECLARED
+#define TkSetFocusWin_TCL_DECLARED
/* 136 */
-EXTERN void TkSetFocusWin _ANSI_ARGS_((TkWindow *winPtr,
- int force));
+EXTERN void TkSetFocusWin(TkWindow *winPtr, int force);
+#endif
+#ifndef TkpSetKeycodeAndState_TCL_DECLARED
+#define TkpSetKeycodeAndState_TCL_DECLARED
/* 137 */
-EXTERN void TkpSetKeycodeAndState _ANSI_ARGS_((Tk_Window tkwin,
- KeySym keySym, XEvent *eventPtr));
+EXTERN void TkpSetKeycodeAndState(Tk_Window tkwin, KeySym keySym,
+ XEvent *eventPtr);
+#endif
+#ifndef TkpGetKeySym_TCL_DECLARED
+#define TkpGetKeySym_TCL_DECLARED
/* 138 */
-EXTERN KeySym TkpGetKeySym _ANSI_ARGS_((TkDisplay *dispPtr,
- XEvent *eventPtr));
+EXTERN KeySym TkpGetKeySym(TkDisplay *dispPtr, XEvent *eventPtr);
+#endif
+#ifndef TkpInitKeymapInfo_TCL_DECLARED
+#define TkpInitKeymapInfo_TCL_DECLARED
/* 139 */
-EXTERN void TkpInitKeymapInfo _ANSI_ARGS_((TkDisplay *dispPtr));
+EXTERN void TkpInitKeymapInfo(TkDisplay *dispPtr);
+#endif
+#ifndef TkPhotoGetValidRegion_TCL_DECLARED
+#define TkPhotoGetValidRegion_TCL_DECLARED
/* 140 */
-EXTERN TkRegion TkPhotoGetValidRegion _ANSI_ARGS_((
- Tk_PhotoHandle handle));
+EXTERN TkRegion TkPhotoGetValidRegion(Tk_PhotoHandle handle);
+#endif
+#ifndef TkWmStackorderToplevel_TCL_DECLARED
+#define TkWmStackorderToplevel_TCL_DECLARED
/* 141 */
-EXTERN TkWindow ** TkWmStackorderToplevel _ANSI_ARGS_((
- TkWindow *parentPtr));
+EXTERN TkWindow ** TkWmStackorderToplevel(TkWindow *parentPtr);
+#endif
+#ifndef TkFocusFree_TCL_DECLARED
+#define TkFocusFree_TCL_DECLARED
/* 142 */
-EXTERN void TkFocusFree _ANSI_ARGS_((TkMainInfo *mainPtr));
+EXTERN void TkFocusFree(TkMainInfo *mainPtr);
+#endif
+#ifndef TkClipCleanup_TCL_DECLARED
+#define TkClipCleanup_TCL_DECLARED
/* 143 */
-EXTERN void TkClipCleanup _ANSI_ARGS_((TkDisplay *dispPtr));
+EXTERN void TkClipCleanup(TkDisplay *dispPtr);
+#endif
+#ifndef TkGCCleanup_TCL_DECLARED
+#define TkGCCleanup_TCL_DECLARED
/* 144 */
-EXTERN void TkGCCleanup _ANSI_ARGS_((TkDisplay *dispPtr));
+EXTERN void TkGCCleanup(TkDisplay *dispPtr);
+#endif
+#ifndef TkSubtractRegion_TCL_DECLARED
+#define TkSubtractRegion_TCL_DECLARED
/* 145 */
-EXTERN void TkSubtractRegion _ANSI_ARGS_((TkRegion sra,
- TkRegion srcb, TkRegion dr_return));
+EXTERN void TkSubtractRegion(TkRegion sra, TkRegion srcb,
+ TkRegion dr_return);
+#endif
+#ifndef TkStylePkgInit_TCL_DECLARED
+#define TkStylePkgInit_TCL_DECLARED
/* 146 */
-EXTERN void TkStylePkgInit _ANSI_ARGS_((TkMainInfo *mainPtr));
+EXTERN void TkStylePkgInit(TkMainInfo *mainPtr);
+#endif
+#ifndef TkStylePkgFree_TCL_DECLARED
+#define TkStylePkgFree_TCL_DECLARED
/* 147 */
-EXTERN void TkStylePkgFree _ANSI_ARGS_((TkMainInfo *mainPtr));
+EXTERN void TkStylePkgFree(TkMainInfo *mainPtr);
+#endif
+#ifndef TkToplevelWindowForCommand_TCL_DECLARED
+#define TkToplevelWindowForCommand_TCL_DECLARED
/* 148 */
-EXTERN Tk_Window TkToplevelWindowForCommand _ANSI_ARGS_((
- Tcl_Interp *interp, CONST char *cmdName));
+EXTERN Tk_Window TkToplevelWindowForCommand(Tcl_Interp *interp,
+ CONST char *cmdName);
+#endif
+#ifndef TkGetOptionSpec_TCL_DECLARED
+#define TkGetOptionSpec_TCL_DECLARED
/* 149 */
-EXTERN CONST Tk_OptionSpec * TkGetOptionSpec _ANSI_ARGS_((CONST char *name,
- Tk_OptionTable optionTable));
-/* Slot 150 is reserved */
-/* Slot 151 is reserved */
+EXTERN CONST Tk_OptionSpec * TkGetOptionSpec(CONST char *name,
+ Tk_OptionTable optionTable);
+#endif
+#ifndef TkMakeRawCurve_TCL_DECLARED
+#define TkMakeRawCurve_TCL_DECLARED
+/* 150 */
+EXTERN int TkMakeRawCurve(Tk_Canvas canvas, double *pointPtr,
+ int numPoints, int numSteps,
+ XPoint xPoints[], double dblPoints[]);
+#endif
+#ifndef TkMakeRawCurvePostscript_TCL_DECLARED
+#define TkMakeRawCurvePostscript_TCL_DECLARED
+/* 151 */
+EXTERN void TkMakeRawCurvePostscript(Tcl_Interp *interp,
+ Tk_Canvas canvas, double *pointPtr,
+ int numPoints);
+#endif
+#ifndef TkpDrawFrame_TCL_DECLARED
+#define TkpDrawFrame_TCL_DECLARED
/* 152 */
-EXTERN void TkpDrawFrame _ANSI_ARGS_((Tk_Window tkwin,
- Tk_3DBorder border, int highlightWidth,
- int borderWidth, int relief));
+EXTERN void TkpDrawFrame(Tk_Window tkwin, Tk_3DBorder border,
+ int highlightWidth, int borderWidth,
+ int relief);
+#endif
+#ifndef TkCreateThreadExitHandler_TCL_DECLARED
+#define TkCreateThreadExitHandler_TCL_DECLARED
+/* 153 */
+EXTERN void TkCreateThreadExitHandler(Tcl_ExitProc *proc,
+ ClientData clientData);
+#endif
+#ifndef TkDeleteThreadExitHandler_TCL_DECLARED
+#define TkDeleteThreadExitHandler_TCL_DECLARED
+/* 154 */
+EXTERN void TkDeleteThreadExitHandler(Tcl_ExitProc *proc,
+ ClientData clientData);
+#endif
+/* Slot 155 is reserved */
+#ifndef TkpTestembedCmd_TCL_DECLARED
+#define TkpTestembedCmd_TCL_DECLARED
+/* 156 */
+EXTERN int TkpTestembedCmd(ClientData clientData,
+ Tcl_Interp *interp, int argc,
+ CONST char **argv);
+#endif
+#ifndef TkpTesttextCmd_TCL_DECLARED
+#define TkpTesttextCmd_TCL_DECLARED
+/* 157 */
+EXTERN int TkpTesttextCmd(ClientData dummy, Tcl_Interp *interp,
+ int argc, CONST char **argv);
+#endif
+/* Slot 158 is reserved */
+/* Slot 159 is reserved */
+/* Slot 160 is reserved */
+/* Slot 161 is reserved */
+/* Slot 162 is reserved */
+/* Slot 163 is reserved */
+/* Slot 164 is reserved */
+/* Slot 165 is reserved */
+/* Slot 166 is reserved */
+/* Slot 167 is reserved */
+/* Slot 168 is reserved */
+#ifndef TkStateParseProc_TCL_DECLARED
+#define TkStateParseProc_TCL_DECLARED
+/* 169 */
+EXTERN int TkStateParseProc(ClientData clientData,
+ Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *value, char *widgRec, int offset);
+#endif
+#ifndef TkStatePrintProc_TCL_DECLARED
+#define TkStatePrintProc_TCL_DECLARED
+/* 170 */
+EXTERN char * TkStatePrintProc(ClientData clientData,
+ Tk_Window tkwin, char *widgRec, int offset,
+ Tcl_FreeProc **freeProcPtr);
+#endif
+#ifndef TkCanvasDashParseProc_TCL_DECLARED
+#define TkCanvasDashParseProc_TCL_DECLARED
+/* 171 */
+EXTERN int TkCanvasDashParseProc(ClientData clientData,
+ Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *value, char *widgRec, int offset);
+#endif
+#ifndef TkCanvasDashPrintProc_TCL_DECLARED
+#define TkCanvasDashPrintProc_TCL_DECLARED
+/* 172 */
+EXTERN char * TkCanvasDashPrintProc(ClientData clientData,
+ Tk_Window tkwin, char *widgRec, int offset,
+ Tcl_FreeProc **freeProcPtr);
+#endif
+#ifndef TkOffsetParseProc_TCL_DECLARED
+#define TkOffsetParseProc_TCL_DECLARED
+/* 173 */
+EXTERN int TkOffsetParseProc(ClientData clientData,
+ Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *value, char *widgRec, int offset);
+#endif
+#ifndef TkOffsetPrintProc_TCL_DECLARED
+#define TkOffsetPrintProc_TCL_DECLARED
+/* 174 */
+EXTERN char * TkOffsetPrintProc(ClientData clientData,
+ Tk_Window tkwin, char *widgRec, int offset,
+ Tcl_FreeProc **freeProcPtr);
+#endif
+#ifndef TkPixelParseProc_TCL_DECLARED
+#define TkPixelParseProc_TCL_DECLARED
+/* 175 */
+EXTERN int TkPixelParseProc(ClientData clientData,
+ Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *value, char *widgRec, int offset);
+#endif
+#ifndef TkPixelPrintProc_TCL_DECLARED
+#define TkPixelPrintProc_TCL_DECLARED
+/* 176 */
+EXTERN char * TkPixelPrintProc(ClientData clientData,
+ Tk_Window tkwin, char *widgRec, int offset,
+ Tcl_FreeProc **freeProcPtr);
+#endif
+#ifndef TkOrientParseProc_TCL_DECLARED
+#define TkOrientParseProc_TCL_DECLARED
+/* 177 */
+EXTERN int TkOrientParseProc(ClientData clientData,
+ Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *value, char *widgRec, int offset);
+#endif
+#ifndef TkOrientPrintProc_TCL_DECLARED
+#define TkOrientPrintProc_TCL_DECLARED
+/* 178 */
+EXTERN char * TkOrientPrintProc(ClientData clientData,
+ Tk_Window tkwin, char *widgRec, int offset,
+ Tcl_FreeProc **freeProcPtr);
+#endif
+#ifndef TkSmoothParseProc_TCL_DECLARED
+#define TkSmoothParseProc_TCL_DECLARED
+/* 179 */
+EXTERN int TkSmoothParseProc(ClientData clientData,
+ Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *value, char *widgRec, int offset);
+#endif
+#ifndef TkSmoothPrintProc_TCL_DECLARED
+#define TkSmoothPrintProc_TCL_DECLARED
+/* 180 */
+EXTERN char * TkSmoothPrintProc(ClientData clientData,
+ Tk_Window tkwin, char *widgRec, int offset,
+ Tcl_FreeProc **freeProcPtr);
+#endif
typedef struct TkIntStubs {
int magic;
struct TkIntStubHooks *hooks;
- TkWindow * (*tkAllocWindow) _ANSI_ARGS_((TkDisplay *dispPtr, int screenNum, TkWindow *parentPtr)); /* 0 */
- void (*tkBezierPoints) _ANSI_ARGS_((double control[], int numSteps, double *coordPtr)); /* 1 */
- void (*tkBezierScreenPoints) _ANSI_ARGS_((Tk_Canvas canvas, double control[], int numSteps, XPoint *xPointPtr)); /* 2 */
- void (*tkBindDeadWindow) _ANSI_ARGS_((TkWindow *winPtr)); /* 3 */
- void (*tkBindEventProc) _ANSI_ARGS_((TkWindow *winPtr, XEvent *eventPtr)); /* 4 */
- void (*tkBindFree) _ANSI_ARGS_((TkMainInfo *mainPtr)); /* 5 */
- void (*tkBindInit) _ANSI_ARGS_((TkMainInfo *mainPtr)); /* 6 */
- void (*tkChangeEventWindow) _ANSI_ARGS_((XEvent *eventPtr, TkWindow *winPtr)); /* 7 */
- int (*tkClipInit) _ANSI_ARGS_((Tcl_Interp *interp, TkDisplay *dispPtr)); /* 8 */
- void (*tkComputeAnchor) _ANSI_ARGS_((Tk_Anchor anchor, Tk_Window tkwin, int padX, int padY, int innerWidth, int innerHeight, int *xPtr, int *yPtr)); /* 9 */
- int (*tkCopyAndGlobalEval) _ANSI_ARGS_((Tcl_Interp *interp, char *script)); /* 10 */
- unsigned long (*tkCreateBindingProcedure) _ANSI_ARGS_((Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, CONST char *eventString, TkBindEvalProc *evalProc, TkBindFreeProc *freeProc, ClientData clientData)); /* 11 */
- TkCursor * (*tkCreateCursorFromData) _ANSI_ARGS_((Tk_Window tkwin, CONST char *source, CONST char *mask, int width, int height, int xHot, int yHot, XColor fg, XColor bg)); /* 12 */
- int (*tkCreateFrame) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv, int toplevel, char *appName)); /* 13 */
- Tk_Window (*tkCreateMainWindow) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *screenName, char *baseName)); /* 14 */
- Time (*tkCurrentTime) _ANSI_ARGS_((TkDisplay *dispPtr)); /* 15 */
- void (*tkDeleteAllImages) _ANSI_ARGS_((TkMainInfo *mainPtr)); /* 16 */
- void (*tkDoConfigureNotify) _ANSI_ARGS_((TkWindow *winPtr)); /* 17 */
- void (*tkDrawInsetFocusHighlight) _ANSI_ARGS_((Tk_Window tkwin, GC gc, int width, Drawable drawable, int padding)); /* 18 */
- void (*tkEventDeadWindow) _ANSI_ARGS_((TkWindow *winPtr)); /* 19 */
- void (*tkFillPolygon) _ANSI_ARGS_((Tk_Canvas canvas, double *coordPtr, int numPoints, Display *display, Drawable drawable, GC gc, GC outlineGC)); /* 20 */
- int (*tkFindStateNum) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *option, CONST TkStateMap *mapPtr, CONST char *strKey)); /* 21 */
- char * (*tkFindStateString) _ANSI_ARGS_((CONST TkStateMap *mapPtr, int numKey)); /* 22 */
- void (*tkFocusDeadWindow) _ANSI_ARGS_((TkWindow *winPtr)); /* 23 */
- int (*tkFocusFilterEvent) _ANSI_ARGS_((TkWindow *winPtr, XEvent *eventPtr)); /* 24 */
- TkWindow * (*tkFocusKeyEvent) _ANSI_ARGS_((TkWindow *winPtr, XEvent *eventPtr)); /* 25 */
- void (*tkFontPkgInit) _ANSI_ARGS_((TkMainInfo *mainPtr)); /* 26 */
- void (*tkFontPkgFree) _ANSI_ARGS_((TkMainInfo *mainPtr)); /* 27 */
- void (*tkFreeBindingTags) _ANSI_ARGS_((TkWindow *winPtr)); /* 28 */
- 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 */
- CONST84_RETURN char * (*tkGetDefaultScreenName) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *screenName)); /* 33 */
- TkDisplay * (*tkGetDisplay) _ANSI_ARGS_((Display *display)); /* 34 */
- int (*tkGetDisplayOf) _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tk_Window *tkwinPtr)); /* 35 */
- TkWindow * (*tkGetFocusWin) _ANSI_ARGS_((TkWindow *winPtr)); /* 36 */
- int (*tkGetInterpNames) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin)); /* 37 */
- int (*tkGetMiterPoints) _ANSI_ARGS_((double p1[], double p2[], double p3[], double width, double m1[], double m2[])); /* 38 */
- void (*tkGetPointerCoords) _ANSI_ARGS_((Tk_Window tkwin, int *xPtr, int *yPtr)); /* 39 */
- void (*tkGetServerInfo) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin)); /* 40 */
- void (*tkGrabDeadWindow) _ANSI_ARGS_((TkWindow *winPtr)); /* 41 */
- int (*tkGrabState) _ANSI_ARGS_((TkWindow *winPtr)); /* 42 */
- void (*tkIncludePoint) _ANSI_ARGS_((Tk_Item *itemPtr, double *pointPtr)); /* 43 */
- 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_((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_((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 */
- void (*tkpDisplayWarning) _ANSI_ARGS_((CONST char *msg, CONST char *title)); /* 58 */
- void (*tkpGetAppName) _ANSI_ARGS_((Tcl_Interp *interp, Tcl_DString *name)); /* 59 */
- TkWindow * (*tkpGetOtherWindow) _ANSI_ARGS_((TkWindow *winPtr)); /* 60 */
- TkWindow * (*tkpGetWrapperWindow) _ANSI_ARGS_((TkWindow *winPtr)); /* 61 */
- int (*tkpInit) _ANSI_ARGS_((Tcl_Interp *interp)); /* 62 */
- void (*tkpInitializeMenuBindings) _ANSI_ARGS_((Tcl_Interp *interp, Tk_BindingTable bindingTable)); /* 63 */
- void (*tkpMakeContainer) _ANSI_ARGS_((Tk_Window tkwin)); /* 64 */
- void (*tkpMakeMenuWindow) _ANSI_ARGS_((Tk_Window tkwin, int transient)); /* 65 */
- Window (*tkpMakeWindow) _ANSI_ARGS_((TkWindow *winPtr, Window parent)); /* 66 */
- void (*tkpMenuNotifyToplevelCreate) _ANSI_ARGS_((Tcl_Interp *interp, char *menuName)); /* 67 */
- TkDisplay * (*tkpOpenDisplay) _ANSI_ARGS_((CONST char *display_name)); /* 68 */
- int (*tkPointerEvent) _ANSI_ARGS_((XEvent *eventPtr, TkWindow *winPtr)); /* 69 */
- int (*tkPolygonToArea) _ANSI_ARGS_((double *polyPtr, int numPoints, double *rectPtr)); /* 70 */
- double (*tkPolygonToPoint) _ANSI_ARGS_((double *polyPtr, int numPoints, double *pointPtr)); /* 71 */
- int (*tkPositionInTree) _ANSI_ARGS_((TkWindow *winPtr, TkWindow *treePtr)); /* 72 */
- void (*tkpRedirectKeyEvent) _ANSI_ARGS_((TkWindow *winPtr, XEvent *eventPtr)); /* 73 */
- void (*tkpSetMainMenubar) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, char *menuName)); /* 74 */
- int (*tkpUseWindow) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, CONST char *string)); /* 75 */
- int (*tkpWindowWasRecentlyDeleted) _ANSI_ARGS_((Window win, TkDisplay *dispPtr)); /* 76 */
- void (*tkQueueEventForAllChildren) _ANSI_ARGS_((TkWindow *winPtr, XEvent *eventPtr)); /* 77 */
- int (*tkReadBitmapFile) _ANSI_ARGS_((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)); /* 78 */
- int (*tkScrollWindow) _ANSI_ARGS_((Tk_Window tkwin, GC gc, int x, int y, int width, int height, int dx, int dy, TkRegion damageRgn)); /* 79 */
- void (*tkSelDeadWindow) _ANSI_ARGS_((TkWindow *winPtr)); /* 80 */
- void (*tkSelEventProc) _ANSI_ARGS_((Tk_Window tkwin, XEvent *eventPtr)); /* 81 */
- void (*tkSelInit) _ANSI_ARGS_((Tk_Window tkwin)); /* 82 */
- void (*tkSelPropProc) _ANSI_ARGS_((XEvent *eventPtr)); /* 83 */
+ TkWindow * (*tkAllocWindow) (TkDisplay *dispPtr, int screenNum, TkWindow *parentPtr); /* 0 */
+ void (*tkBezierPoints) (double control[], int numSteps, double *coordPtr); /* 1 */
+ void (*tkBezierScreenPoints) (Tk_Canvas canvas, double control[], int numSteps, XPoint *xPointPtr); /* 2 */
+ void (*tkBindDeadWindow) (TkWindow *winPtr); /* 3 */
+ void (*tkBindEventProc) (TkWindow *winPtr, XEvent *eventPtr); /* 4 */
+ void (*tkBindFree) (TkMainInfo *mainPtr); /* 5 */
+ void (*tkBindInit) (TkMainInfo *mainPtr); /* 6 */
+ void (*tkChangeEventWindow) (XEvent *eventPtr, TkWindow *winPtr); /* 7 */
+ int (*tkClipInit) (Tcl_Interp *interp, TkDisplay *dispPtr); /* 8 */
+ void (*tkComputeAnchor) (Tk_Anchor anchor, Tk_Window tkwin, int padX, int padY, int innerWidth, int innerHeight, int *xPtr, int *yPtr); /* 9 */
+ int (*tkCopyAndGlobalEval) (Tcl_Interp *interp, char *script); /* 10 */
+ unsigned long (*tkCreateBindingProcedure) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, CONST char *eventString, TkBindEvalProc *evalProc, TkBindFreeProc *freeProc, ClientData clientData); /* 11 */
+ TkCursor * (*tkCreateCursorFromData) (Tk_Window tkwin, CONST char *source, CONST char *mask, int width, int height, int xHot, int yHot, XColor fg, XColor bg); /* 12 */
+ int (*tkCreateFrame) (ClientData clientData, Tcl_Interp *interp, int argc, char **argv, int toplevel, char *appName); /* 13 */
+ Tk_Window (*tkCreateMainWindow) (Tcl_Interp *interp, CONST char *screenName, char *baseName); /* 14 */
+ Time (*tkCurrentTime) (TkDisplay *dispPtr); /* 15 */
+ void (*tkDeleteAllImages) (TkMainInfo *mainPtr); /* 16 */
+ void (*tkDoConfigureNotify) (TkWindow *winPtr); /* 17 */
+ void (*tkDrawInsetFocusHighlight) (Tk_Window tkwin, GC gc, int width, Drawable drawable, int padding); /* 18 */
+ void (*tkEventDeadWindow) (TkWindow *winPtr); /* 19 */
+ void (*tkFillPolygon) (Tk_Canvas canvas, double *coordPtr, int numPoints, Display *display, Drawable drawable, GC gc, GC outlineGC); /* 20 */
+ int (*tkFindStateNum) (Tcl_Interp *interp, CONST char *option, CONST TkStateMap *mapPtr, CONST char *strKey); /* 21 */
+ char * (*tkFindStateString) (CONST TkStateMap *mapPtr, int numKey); /* 22 */
+ void (*tkFocusDeadWindow) (TkWindow *winPtr); /* 23 */
+ int (*tkFocusFilterEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 24 */
+ TkWindow * (*tkFocusKeyEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 25 */
+ void (*tkFontPkgInit) (TkMainInfo *mainPtr); /* 26 */
+ void (*tkFontPkgFree) (TkMainInfo *mainPtr); /* 27 */
+ void (*tkFreeBindingTags) (TkWindow *winPtr); /* 28 */
+ void (*tkpFreeCursor) (TkCursor *cursorPtr); /* 29 */
+ char * (*tkGetBitmapData) (Tcl_Interp *interp, char *string, char *fileName, int *widthPtr, int *heightPtr, int *hotXPtr, int *hotYPtr); /* 30 */
+ void (*tkGetButtPoints) (double p1[], double p2[], double width, int project, double m1[], double m2[]); /* 31 */
+ TkCursor * (*tkGetCursorByName) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid string); /* 32 */
+ CONST84_RETURN char * (*tkGetDefaultScreenName) (Tcl_Interp *interp, CONST char *screenName); /* 33 */
+ TkDisplay * (*tkGetDisplay) (Display *display); /* 34 */
+ int (*tkGetDisplayOf) (Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tk_Window *tkwinPtr); /* 35 */
+ TkWindow * (*tkGetFocusWin) (TkWindow *winPtr); /* 36 */
+ int (*tkGetInterpNames) (Tcl_Interp *interp, Tk_Window tkwin); /* 37 */
+ int (*tkGetMiterPoints) (double p1[], double p2[], double p3[], double width, double m1[], double m2[]); /* 38 */
+ void (*tkGetPointerCoords) (Tk_Window tkwin, int *xPtr, int *yPtr); /* 39 */
+ void (*tkGetServerInfo) (Tcl_Interp *interp, Tk_Window tkwin); /* 40 */
+ void (*tkGrabDeadWindow) (TkWindow *winPtr); /* 41 */
+ int (*tkGrabState) (TkWindow *winPtr); /* 42 */
+ void (*tkIncludePoint) (Tk_Item *itemPtr, double *pointPtr); /* 43 */
+ void (*tkInOutEvents) (XEvent *eventPtr, TkWindow *sourcePtr, TkWindow *destPtr, int leaveType, int enterType, Tcl_QueuePosition position); /* 44 */
+ void (*tkInstallFrameMenu) (Tk_Window tkwin); /* 45 */
+ char * (*tkKeysymToString) (KeySym keysym); /* 46 */
+ int (*tkLineToArea) (double end1Ptr[], double end2Ptr[], double rectPtr[]); /* 47 */
+ double (*tkLineToPoint) (double end1Ptr[], double end2Ptr[], double pointPtr[]); /* 48 */
+ int (*tkMakeBezierCurve) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); /* 49 */
+ void (*tkMakeBezierPostscript) (Tcl_Interp *interp, Tk_Canvas canvas, double *pointPtr, int numPoints); /* 50 */
+ void (*tkOptionClassChanged) (TkWindow *winPtr); /* 51 */
+ void (*tkOptionDeadWindow) (TkWindow *winPtr); /* 52 */
+ int (*tkOvalToArea) (double *ovalPtr, double *rectPtr); /* 53 */
+ double (*tkOvalToPoint) (double ovalPtr[], double width, int filled, double pointPtr[]); /* 54 */
+ int (*tkpChangeFocus) (TkWindow *winPtr, int force); /* 55 */
+ void (*tkpCloseDisplay) (TkDisplay *dispPtr); /* 56 */
+ void (*tkpClaimFocus) (TkWindow *topLevelPtr, int force); /* 57 */
+ void (*tkpDisplayWarning) (CONST char *msg, CONST char *title); /* 58 */
+ void (*tkpGetAppName) (Tcl_Interp *interp, Tcl_DString *name); /* 59 */
+ TkWindow * (*tkpGetOtherWindow) (TkWindow *winPtr); /* 60 */
+ TkWindow * (*tkpGetWrapperWindow) (TkWindow *winPtr); /* 61 */
+ int (*tkpInit) (Tcl_Interp *interp); /* 62 */
+ void (*tkpInitializeMenuBindings) (Tcl_Interp *interp, Tk_BindingTable bindingTable); /* 63 */
+ void (*tkpMakeContainer) (Tk_Window tkwin); /* 64 */
+ void (*tkpMakeMenuWindow) (Tk_Window tkwin, int transient); /* 65 */
+ Window (*tkpMakeWindow) (TkWindow *winPtr, Window parent); /* 66 */
+ void (*tkpMenuNotifyToplevelCreate) (Tcl_Interp *interp, char *menuName); /* 67 */
+ TkDisplay * (*tkpOpenDisplay) (CONST char *display_name); /* 68 */
+ int (*tkPointerEvent) (XEvent *eventPtr, TkWindow *winPtr); /* 69 */
+ int (*tkPolygonToArea) (double *polyPtr, int numPoints, double *rectPtr); /* 70 */
+ double (*tkPolygonToPoint) (double *polyPtr, int numPoints, double *pointPtr); /* 71 */
+ int (*tkPositionInTree) (TkWindow *winPtr, TkWindow *treePtr); /* 72 */
+ void (*tkpRedirectKeyEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 73 */
+ void (*tkpSetMainMenubar) (Tcl_Interp *interp, Tk_Window tkwin, char *menuName); /* 74 */
+ int (*tkpUseWindow) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *string); /* 75 */
+ int (*tkpWindowWasRecentlyDeleted) (Window win, TkDisplay *dispPtr); /* 76 */
+ void (*tkQueueEventForAllChildren) (TkWindow *winPtr, XEvent *eventPtr); /* 77 */
+ int (*tkReadBitmapFile) (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); /* 78 */
+ int (*tkScrollWindow) (Tk_Window tkwin, GC gc, int x, int y, int width, int height, int dx, int dy, TkRegion damageRgn); /* 79 */
+ void (*tkSelDeadWindow) (TkWindow *winPtr); /* 80 */
+ void (*tkSelEventProc) (Tk_Window tkwin, XEvent *eventPtr); /* 81 */
+ void (*tkSelInit) (Tk_Window tkwin); /* 82 */
+ void (*tkSelPropProc) (XEvent *eventPtr); /* 83 */
VOID *reserved84;
- void (*tkSetWindowMenuBar) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, char *oldMenuName, char *menuName)); /* 85 */
- KeySym (*tkStringToKeysym) _ANSI_ARGS_((char *name)); /* 86 */
- int (*tkThickPolyLineToArea) _ANSI_ARGS_((double *coordPtr, int numPoints, double width, int capStyle, int joinStyle, double *rectPtr)); /* 87 */
- void (*tkWmAddToColormapWindows) _ANSI_ARGS_((TkWindow *winPtr)); /* 88 */
- void (*tkWmDeadWindow) _ANSI_ARGS_((TkWindow *winPtr)); /* 89 */
- TkWindow * (*tkWmFocusToplevel) _ANSI_ARGS_((TkWindow *winPtr)); /* 90 */
- void (*tkWmMapWindow) _ANSI_ARGS_((TkWindow *winPtr)); /* 91 */
- void (*tkWmNewWindow) _ANSI_ARGS_((TkWindow *winPtr)); /* 92 */
- void (*tkWmProtocolEventProc) _ANSI_ARGS_((TkWindow *winPtr, XEvent *evenvPtr)); /* 93 */
- void (*tkWmRemoveFromColormapWindows) _ANSI_ARGS_((TkWindow *winPtr)); /* 94 */
- 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, CONST char *dbName, CONST char *className)); /* 111 */
- void (*tkpMenuThreadInit) _ANSI_ARGS_((void)); /* 112 */
- void (*tkClipBox) _ANSI_ARGS_((TkRegion rgn, XRectangle *rect_return)); /* 113 */
- TkRegion (*tkCreateRegion) _ANSI_ARGS_((void)); /* 114 */
- void (*tkDestroyRegion) _ANSI_ARGS_((TkRegion rgn)); /* 115 */
- void (*tkIntersectRegion) _ANSI_ARGS_((TkRegion sra, TkRegion srcb, TkRegion dr_return)); /* 116 */
- int (*tkRectInRegion) _ANSI_ARGS_((TkRegion rgn, int x, int y, unsigned int width, unsigned int height)); /* 117 */
- void (*tkSetRegion) _ANSI_ARGS_((Display *display, GC gc, TkRegion rgn)); /* 118 */
- void (*tkUnionRectWithRegion) _ANSI_ARGS_((XRectangle *rect, TkRegion src, TkRegion dr_return)); /* 119 */
+ void (*tkSetWindowMenuBar) (Tcl_Interp *interp, Tk_Window tkwin, char *oldMenuName, char *menuName); /* 85 */
+ KeySym (*tkStringToKeysym) (char *name); /* 86 */
+ int (*tkThickPolyLineToArea) (double *coordPtr, int numPoints, double width, int capStyle, int joinStyle, double *rectPtr); /* 87 */
+ void (*tkWmAddToColormapWindows) (TkWindow *winPtr); /* 88 */
+ void (*tkWmDeadWindow) (TkWindow *winPtr); /* 89 */
+ TkWindow * (*tkWmFocusToplevel) (TkWindow *winPtr); /* 90 */
+ void (*tkWmMapWindow) (TkWindow *winPtr); /* 91 */
+ void (*tkWmNewWindow) (TkWindow *winPtr); /* 92 */
+ void (*tkWmProtocolEventProc) (TkWindow *winPtr, XEvent *evenvPtr); /* 93 */
+ void (*tkWmRemoveFromColormapWindows) (TkWindow *winPtr); /* 94 */
+ void (*tkWmRestackToplevel) (TkWindow *winPtr, int aboveBelow, TkWindow *otherPtr); /* 95 */
+ void (*tkWmSetClass) (TkWindow *winPtr); /* 96 */
+ void (*tkWmUnmapWindow) (TkWindow *winPtr); /* 97 */
+ Tcl_Obj * (*tkDebugBitmap) (Tk_Window tkwin, char *name); /* 98 */
+ Tcl_Obj * (*tkDebugBorder) (Tk_Window tkwin, char *name); /* 99 */
+ Tcl_Obj * (*tkDebugCursor) (Tk_Window tkwin, char *name); /* 100 */
+ Tcl_Obj * (*tkDebugColor) (Tk_Window tkwin, char *name); /* 101 */
+ Tcl_Obj * (*tkDebugConfig) (Tcl_Interp *interp, Tk_OptionTable table); /* 102 */
+ Tcl_Obj * (*tkDebugFont) (Tk_Window tkwin, char *name); /* 103 */
+ int (*tkFindStateNumObj) (Tcl_Interp *interp, Tcl_Obj *optionPtr, CONST TkStateMap *mapPtr, Tcl_Obj *keyPtr); /* 104 */
+ Tcl_HashTable * (*tkGetBitmapPredefTable) (void); /* 105 */
+ TkDisplay * (*tkGetDisplayList) (void); /* 106 */
+ TkMainInfo * (*tkGetMainInfoList) (void); /* 107 */
+ int (*tkGetWindowFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Tk_Window *windowPtr); /* 108 */
+ char * (*tkpGetString) (TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr); /* 109 */
+ void (*tkpGetSubFonts) (Tcl_Interp *interp, Tk_Font tkfont); /* 110 */
+ Tcl_Obj * (*tkpGetSystemDefault) (Tk_Window tkwin, CONST char *dbName, CONST char *className); /* 111 */
+ void (*tkpMenuThreadInit) (void); /* 112 */
+ void (*tkClipBox) (TkRegion rgn, XRectangle *rect_return); /* 113 */
+ TkRegion (*tkCreateRegion) (void); /* 114 */
+ void (*tkDestroyRegion) (TkRegion rgn); /* 115 */
+ void (*tkIntersectRegion) (TkRegion sra, TkRegion srcb, TkRegion dr_return); /* 116 */
+ int (*tkRectInRegion) (TkRegion rgn, int x, int y, unsigned int width, unsigned int height); /* 117 */
+ void (*tkSetRegion) (Display *display, GC gc, TkRegion rgn); /* 118 */
+ void (*tkUnionRectWithRegion) (XRectangle *rect, TkRegion src, TkRegion dr_return); /* 119 */
VOID *reserved120;
#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */
VOID *reserved121;
@@ -588,7 +1096,7 @@ typedef struct TkIntStubs {
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
VOID *reserved121; /* Dummy entry for stubs table backwards compatibility */
- Pixmap (*tkpCreateNativeBitmap) _ANSI_ARGS_((Display *display, CONST char *source)); /* 121 */
+ Pixmap (*tkpCreateNativeBitmap) (Display *display, CONST char *source); /* 121 */
#endif /* AQUA */
#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */
VOID *reserved122;
@@ -598,7 +1106,7 @@ typedef struct TkIntStubs {
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
VOID *reserved122; /* Dummy entry for stubs table backwards compatibility */
- void (*tkpDefineNativeBitmaps) _ANSI_ARGS_((void)); /* 122 */
+ void (*tkpDefineNativeBitmaps) (void); /* 122 */
#endif /* AQUA */
VOID *reserved123;
#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */
@@ -609,7 +1117,7 @@ typedef struct TkIntStubs {
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
VOID *reserved124; /* Dummy entry for stubs table backwards compatibility */
- Pixmap (*tkpGetNativeAppBitmap) _ANSI_ARGS_((Display *display, CONST char *name, int *width, int *height)); /* 124 */
+ Pixmap (*tkpGetNativeAppBitmap) (Display *display, CONST char *name, int *width, int *height); /* 124 */
#endif /* AQUA */
VOID *reserved125;
VOID *reserved126;
@@ -621,24 +1129,52 @@ typedef struct TkIntStubs {
VOID *reserved132;
VOID *reserved133;
VOID *reserved134;
- void (*tkpDrawHighlightBorder) _ANSI_ARGS_((Tk_Window tkwin, GC fgGC, GC bgGC, int highlightWidth, Drawable drawable)); /* 135 */
- void (*tkSetFocusWin) _ANSI_ARGS_((TkWindow *winPtr, int force)); /* 136 */
- void (*tkpSetKeycodeAndState) _ANSI_ARGS_((Tk_Window tkwin, KeySym keySym, XEvent *eventPtr)); /* 137 */
- KeySym (*tkpGetKeySym) _ANSI_ARGS_((TkDisplay *dispPtr, XEvent *eventPtr)); /* 138 */
- void (*tkpInitKeymapInfo) _ANSI_ARGS_((TkDisplay *dispPtr)); /* 139 */
- TkRegion (*tkPhotoGetValidRegion) _ANSI_ARGS_((Tk_PhotoHandle handle)); /* 140 */
- TkWindow ** (*tkWmStackorderToplevel) _ANSI_ARGS_((TkWindow *parentPtr)); /* 141 */
- void (*tkFocusFree) _ANSI_ARGS_((TkMainInfo *mainPtr)); /* 142 */
- void (*tkClipCleanup) _ANSI_ARGS_((TkDisplay *dispPtr)); /* 143 */
- void (*tkGCCleanup) _ANSI_ARGS_((TkDisplay *dispPtr)); /* 144 */
- void (*tkSubtractRegion) _ANSI_ARGS_((TkRegion sra, TkRegion srcb, TkRegion dr_return)); /* 145 */
- void (*tkStylePkgInit) _ANSI_ARGS_((TkMainInfo *mainPtr)); /* 146 */
- void (*tkStylePkgFree) _ANSI_ARGS_((TkMainInfo *mainPtr)); /* 147 */
- Tk_Window (*tkToplevelWindowForCommand) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *cmdName)); /* 148 */
- CONST Tk_OptionSpec * (*tkGetOptionSpec) _ANSI_ARGS_((CONST char *name, Tk_OptionTable optionTable)); /* 149 */
- VOID *reserved150;
- VOID *reserved151;
- void (*tkpDrawFrame) _ANSI_ARGS_((Tk_Window tkwin, Tk_3DBorder border, int highlightWidth, int borderWidth, int relief)); /* 152 */
+ void (*tkpDrawHighlightBorder) (Tk_Window tkwin, GC fgGC, GC bgGC, int highlightWidth, Drawable drawable); /* 135 */
+ void (*tkSetFocusWin) (TkWindow *winPtr, int force); /* 136 */
+ void (*tkpSetKeycodeAndState) (Tk_Window tkwin, KeySym keySym, XEvent *eventPtr); /* 137 */
+ KeySym (*tkpGetKeySym) (TkDisplay *dispPtr, XEvent *eventPtr); /* 138 */
+ void (*tkpInitKeymapInfo) (TkDisplay *dispPtr); /* 139 */
+ TkRegion (*tkPhotoGetValidRegion) (Tk_PhotoHandle handle); /* 140 */
+ TkWindow ** (*tkWmStackorderToplevel) (TkWindow *parentPtr); /* 141 */
+ void (*tkFocusFree) (TkMainInfo *mainPtr); /* 142 */
+ void (*tkClipCleanup) (TkDisplay *dispPtr); /* 143 */
+ void (*tkGCCleanup) (TkDisplay *dispPtr); /* 144 */
+ void (*tkSubtractRegion) (TkRegion sra, TkRegion srcb, TkRegion dr_return); /* 145 */
+ void (*tkStylePkgInit) (TkMainInfo *mainPtr); /* 146 */
+ void (*tkStylePkgFree) (TkMainInfo *mainPtr); /* 147 */
+ Tk_Window (*tkToplevelWindowForCommand) (Tcl_Interp *interp, CONST char *cmdName); /* 148 */
+ CONST Tk_OptionSpec * (*tkGetOptionSpec) (CONST char *name, Tk_OptionTable optionTable); /* 149 */
+ int (*tkMakeRawCurve) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); /* 150 */
+ void (*tkMakeRawCurvePostscript) (Tcl_Interp *interp, Tk_Canvas canvas, double *pointPtr, int numPoints); /* 151 */
+ void (*tkpDrawFrame) (Tk_Window tkwin, Tk_3DBorder border, int highlightWidth, int borderWidth, int relief); /* 152 */
+ void (*tkCreateThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 153 */
+ void (*tkDeleteThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 154 */
+ VOID *reserved155;
+ int (*tkpTestembedCmd) (ClientData clientData, Tcl_Interp *interp, int argc, CONST char **argv); /* 156 */
+ int (*tkpTesttextCmd) (ClientData dummy, Tcl_Interp *interp, int argc, CONST char **argv); /* 157 */
+ VOID *reserved158;
+ VOID *reserved159;
+ VOID *reserved160;
+ VOID *reserved161;
+ VOID *reserved162;
+ VOID *reserved163;
+ VOID *reserved164;
+ VOID *reserved165;
+ VOID *reserved166;
+ VOID *reserved167;
+ VOID *reserved168;
+ int (*tkStateParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset); /* 169 */
+ char * (*tkStatePrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 170 */
+ int (*tkCanvasDashParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset); /* 171 */
+ char * (*tkCanvasDashPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 172 */
+ int (*tkOffsetParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset); /* 173 */
+ char * (*tkOffsetPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 174 */
+ int (*tkPixelParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset); /* 175 */
+ char * (*tkPixelPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 176 */
+ int (*tkOrientParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset); /* 177 */
+ char * (*tkOrientPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 178 */
+ int (*tkSmoothParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset); /* 179 */
+ char * (*tkSmoothPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 180 */
} TkIntStubs;
#ifdef __cplusplus
@@ -1222,12 +1758,94 @@ extern TkIntStubs *tkIntStubsPtr;
#define TkGetOptionSpec \
(tkIntStubsPtr->tkGetOptionSpec) /* 149 */
#endif
-/* Slot 150 is reserved */
-/* Slot 151 is reserved */
+#ifndef TkMakeRawCurve
+#define TkMakeRawCurve \
+ (tkIntStubsPtr->tkMakeRawCurve) /* 150 */
+#endif
+#ifndef TkMakeRawCurvePostscript
+#define TkMakeRawCurvePostscript \
+ (tkIntStubsPtr->tkMakeRawCurvePostscript) /* 151 */
+#endif
#ifndef TkpDrawFrame
#define TkpDrawFrame \
(tkIntStubsPtr->tkpDrawFrame) /* 152 */
#endif
+#ifndef TkCreateThreadExitHandler
+#define TkCreateThreadExitHandler \
+ (tkIntStubsPtr->tkCreateThreadExitHandler) /* 153 */
+#endif
+#ifndef TkDeleteThreadExitHandler
+#define TkDeleteThreadExitHandler \
+ (tkIntStubsPtr->tkDeleteThreadExitHandler) /* 154 */
+#endif
+/* Slot 155 is reserved */
+#ifndef TkpTestembedCmd
+#define TkpTestembedCmd \
+ (tkIntStubsPtr->tkpTestembedCmd) /* 156 */
+#endif
+#ifndef TkpTesttextCmd
+#define TkpTesttextCmd \
+ (tkIntStubsPtr->tkpTesttextCmd) /* 157 */
+#endif
+/* Slot 158 is reserved */
+/* Slot 159 is reserved */
+/* Slot 160 is reserved */
+/* Slot 161 is reserved */
+/* Slot 162 is reserved */
+/* Slot 163 is reserved */
+/* Slot 164 is reserved */
+/* Slot 165 is reserved */
+/* Slot 166 is reserved */
+/* Slot 167 is reserved */
+/* Slot 168 is reserved */
+#ifndef TkStateParseProc
+#define TkStateParseProc \
+ (tkIntStubsPtr->tkStateParseProc) /* 169 */
+#endif
+#ifndef TkStatePrintProc
+#define TkStatePrintProc \
+ (tkIntStubsPtr->tkStatePrintProc) /* 170 */
+#endif
+#ifndef TkCanvasDashParseProc
+#define TkCanvasDashParseProc \
+ (tkIntStubsPtr->tkCanvasDashParseProc) /* 171 */
+#endif
+#ifndef TkCanvasDashPrintProc
+#define TkCanvasDashPrintProc \
+ (tkIntStubsPtr->tkCanvasDashPrintProc) /* 172 */
+#endif
+#ifndef TkOffsetParseProc
+#define TkOffsetParseProc \
+ (tkIntStubsPtr->tkOffsetParseProc) /* 173 */
+#endif
+#ifndef TkOffsetPrintProc
+#define TkOffsetPrintProc \
+ (tkIntStubsPtr->tkOffsetPrintProc) /* 174 */
+#endif
+#ifndef TkPixelParseProc
+#define TkPixelParseProc \
+ (tkIntStubsPtr->tkPixelParseProc) /* 175 */
+#endif
+#ifndef TkPixelPrintProc
+#define TkPixelPrintProc \
+ (tkIntStubsPtr->tkPixelPrintProc) /* 176 */
+#endif
+#ifndef TkOrientParseProc
+#define TkOrientParseProc \
+ (tkIntStubsPtr->tkOrientParseProc) /* 177 */
+#endif
+#ifndef TkOrientPrintProc
+#define TkOrientPrintProc \
+ (tkIntStubsPtr->tkOrientPrintProc) /* 178 */
+#endif
+#ifndef TkSmoothParseProc
+#define TkSmoothParseProc \
+ (tkIntStubsPtr->tkSmoothParseProc) /* 179 */
+#endif
+#ifndef TkSmoothPrintProc
+#define TkSmoothPrintProc \
+ (tkIntStubsPtr->tkSmoothPrintProc) /* 180 */
+#endif
#endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */
@@ -1236,6 +1854,33 @@ extern TkIntStubs *tkIntStubsPtr;
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
+#if !defined(__WIN32__) && !defined(__CYGWIN__) && !defined(MAC_OSX_TK)
+
+/*
+ * These macros are just wrappers for the equivalent X Region calls.
+ */
+# undef TkClipBox
+# undef TkCreateRegion
+# undef TkDestroyRegion
+# undef TkIntersectRegion
+# undef TkRectInRegion
+# undef TkSetRegion
+# undef TkSubtractRegion
+# undef TkUnionRectWithRegion
+
+# define TkClipBox(rgn, rect) XClipBox((Region) (rgn), (rect))
+# define TkCreateRegion() (TkRegion) XCreateRegion()
+# define TkDestroyRegion(rgn) XDestroyRegion((Region) (rgn))
+# define TkIntersectRegion(a, b, r) XIntersectRegion((Region) (a), \
+(Region) (b), (Region) (r))
+# define TkRectInRegion(r, x, y, w, h) XRectInRegion((Region) (r), (x), (y), (w), (h))
+# define TkSetRegion(d, gc, rgn) XSetRegion((d), (gc), (Region) (rgn))
+# define TkSubtractRegion(a, b, r) XSubtractRegion((Region) (a), \
+(Region) (b), (Region) (r))
+# define TkUnionRectWithRegion(rect, src, ret) XUnionRectWithRegion((rect), \
+(Region) (src), (Region) (ret))
+#endif /* !__CYGWIN__*/
+
#if defined(__CYGWIN__) && defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS)
# undef TkBindDeadWindow
# define TkBindDeadWindow(winPtr) /* Removed from Cygwins stub table, just do nothing */
diff --git a/generic/tkIntPlatDecls.h b/generic/tkIntPlatDecls.h
index eb05c02..a181073 100644
--- a/generic/tkIntPlatDecls.h
+++ b/generic/tkIntPlatDecls.h
@@ -31,277 +31,577 @@
*/
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#ifndef TkAlignImageData_TCL_DECLARED
+#define TkAlignImageData_TCL_DECLARED
/* 0 */
-EXTERN char * TkAlignImageData _ANSI_ARGS_((XImage *image,
- int alignment, int bitOrder));
+EXTERN char * TkAlignImageData(XImage *image, int alignment,
+ int bitOrder);
+#endif
/* Slot 1 is reserved */
+#ifndef TkGenerateActivateEvents_TCL_DECLARED
+#define TkGenerateActivateEvents_TCL_DECLARED
/* 2 */
-EXTERN void TkGenerateActivateEvents _ANSI_ARGS_((
- TkWindow *winPtr, int active));
+EXTERN void TkGenerateActivateEvents(TkWindow *winPtr,
+ int active);
+#endif
+#ifndef TkpGetMS_TCL_DECLARED
+#define TkpGetMS_TCL_DECLARED
/* 3 */
-EXTERN unsigned long TkpGetMS _ANSI_ARGS_((void));
+EXTERN unsigned long TkpGetMS(void);
+#endif
+#ifndef TkPointerDeadWindow_TCL_DECLARED
+#define TkPointerDeadWindow_TCL_DECLARED
/* 4 */
-EXTERN void TkPointerDeadWindow _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkPointerDeadWindow(TkWindow *winPtr);
+#endif
+#ifndef TkpPrintWindowId_TCL_DECLARED
+#define TkpPrintWindowId_TCL_DECLARED
/* 5 */
-EXTERN void TkpPrintWindowId _ANSI_ARGS_((char *buf,
- Window window));
+EXTERN void TkpPrintWindowId(char *buf, Window window);
+#endif
+#ifndef TkpScanWindowId_TCL_DECLARED
+#define TkpScanWindowId_TCL_DECLARED
/* 6 */
-EXTERN int TkpScanWindowId _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *string, Window *idPtr));
+EXTERN int TkpScanWindowId(Tcl_Interp *interp,
+ CONST char *string, Window *idPtr);
+#endif
+#ifndef TkpSetCapture_TCL_DECLARED
+#define TkpSetCapture_TCL_DECLARED
/* 7 */
-EXTERN void TkpSetCapture _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkpSetCapture(TkWindow *winPtr);
+#endif
+#ifndef TkpSetCursor_TCL_DECLARED
+#define TkpSetCursor_TCL_DECLARED
/* 8 */
-EXTERN void TkpSetCursor _ANSI_ARGS_((TkpCursor cursor));
+EXTERN void TkpSetCursor(TkpCursor cursor);
+#endif
+#ifndef TkpWmSetState_TCL_DECLARED
+#define TkpWmSetState_TCL_DECLARED
/* 9 */
-EXTERN int TkpWmSetState _ANSI_ARGS_((TkWindow *winPtr,
- int state));
+EXTERN int TkpWmSetState(TkWindow *winPtr, int state);
+#endif
+#ifndef TkSetPixmapColormap_TCL_DECLARED
+#define TkSetPixmapColormap_TCL_DECLARED
/* 10 */
-EXTERN void TkSetPixmapColormap _ANSI_ARGS_((Pixmap pixmap,
- Colormap colormap));
+EXTERN void TkSetPixmapColormap(Pixmap pixmap, Colormap colormap);
+#endif
+#ifndef TkWinCancelMouseTimer_TCL_DECLARED
+#define TkWinCancelMouseTimer_TCL_DECLARED
/* 11 */
-EXTERN void TkWinCancelMouseTimer _ANSI_ARGS_((void));
+EXTERN void TkWinCancelMouseTimer(void);
+#endif
+#ifndef TkWinClipboardRender_TCL_DECLARED
+#define TkWinClipboardRender_TCL_DECLARED
/* 12 */
-EXTERN void TkWinClipboardRender _ANSI_ARGS_((TkDisplay *dispPtr,
- UINT format));
+EXTERN void TkWinClipboardRender(TkDisplay *dispPtr, UINT format);
+#endif
+#ifndef TkWinEmbeddedEventProc_TCL_DECLARED
+#define TkWinEmbeddedEventProc_TCL_DECLARED
/* 13 */
-EXTERN LRESULT TkWinEmbeddedEventProc _ANSI_ARGS_((HWND hwnd,
- UINT message, WPARAM wParam, LPARAM lParam));
+EXTERN LRESULT TkWinEmbeddedEventProc(HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
+#endif
+#ifndef TkWinFillRect_TCL_DECLARED
+#define TkWinFillRect_TCL_DECLARED
/* 14 */
-EXTERN void TkWinFillRect _ANSI_ARGS_((HDC dc, int x, int y,
- int width, int height, int pixel));
+EXTERN void TkWinFillRect(HDC dc, int x, int y, int width,
+ int height, int pixel);
+#endif
+#ifndef TkWinGetBorderPixels_TCL_DECLARED
+#define TkWinGetBorderPixels_TCL_DECLARED
/* 15 */
-EXTERN COLORREF TkWinGetBorderPixels _ANSI_ARGS_((Tk_Window tkwin,
- Tk_3DBorder border, int which));
+EXTERN COLORREF TkWinGetBorderPixels(Tk_Window tkwin,
+ Tk_3DBorder border, int which);
+#endif
+#ifndef TkWinGetDrawableDC_TCL_DECLARED
+#define TkWinGetDrawableDC_TCL_DECLARED
/* 16 */
-EXTERN HDC TkWinGetDrawableDC _ANSI_ARGS_((Display *display,
- Drawable d, TkWinDCState *state));
+EXTERN HDC TkWinGetDrawableDC(Display *display, Drawable d,
+ TkWinDCState *state);
+#endif
+#ifndef TkWinGetModifierState_TCL_DECLARED
+#define TkWinGetModifierState_TCL_DECLARED
/* 17 */
-EXTERN int TkWinGetModifierState _ANSI_ARGS_((void));
+EXTERN int TkWinGetModifierState(void);
+#endif
+#ifndef TkWinGetSystemPalette_TCL_DECLARED
+#define TkWinGetSystemPalette_TCL_DECLARED
/* 18 */
-EXTERN HPALETTE TkWinGetSystemPalette _ANSI_ARGS_((void));
+EXTERN HPALETTE TkWinGetSystemPalette(void);
+#endif
+#ifndef TkWinGetWrapperWindow_TCL_DECLARED
+#define TkWinGetWrapperWindow_TCL_DECLARED
/* 19 */
-EXTERN HWND TkWinGetWrapperWindow _ANSI_ARGS_((Tk_Window tkwin));
+EXTERN HWND TkWinGetWrapperWindow(Tk_Window tkwin);
+#endif
+#ifndef TkWinHandleMenuEvent_TCL_DECLARED
+#define TkWinHandleMenuEvent_TCL_DECLARED
/* 20 */
-EXTERN int TkWinHandleMenuEvent _ANSI_ARGS_((HWND *phwnd,
- UINT *pMessage, WPARAM *pwParam,
- LPARAM *plParam, LRESULT *plResult));
+EXTERN int TkWinHandleMenuEvent(HWND *phwnd, UINT *pMessage,
+ WPARAM *pwParam, LPARAM *plParam,
+ LRESULT *plResult);
+#endif
+#ifndef TkWinIndexOfColor_TCL_DECLARED
+#define TkWinIndexOfColor_TCL_DECLARED
/* 21 */
-EXTERN int TkWinIndexOfColor _ANSI_ARGS_((XColor *colorPtr));
+EXTERN int TkWinIndexOfColor(XColor *colorPtr);
+#endif
+#ifndef TkWinReleaseDrawableDC_TCL_DECLARED
+#define TkWinReleaseDrawableDC_TCL_DECLARED
/* 22 */
-EXTERN void TkWinReleaseDrawableDC _ANSI_ARGS_((Drawable d,
- HDC hdc, TkWinDCState *state));
+EXTERN void TkWinReleaseDrawableDC(Drawable d, HDC hdc,
+ TkWinDCState *state);
+#endif
+#ifndef TkWinResendEvent_TCL_DECLARED
+#define TkWinResendEvent_TCL_DECLARED
/* 23 */
-EXTERN LRESULT TkWinResendEvent _ANSI_ARGS_((WNDPROC wndproc,
- HWND hwnd, XEvent *eventPtr));
+EXTERN LRESULT TkWinResendEvent(WNDPROC wndproc, HWND hwnd,
+ XEvent *eventPtr);
+#endif
+#ifndef TkWinSelectPalette_TCL_DECLARED
+#define TkWinSelectPalette_TCL_DECLARED
/* 24 */
-EXTERN HPALETTE TkWinSelectPalette _ANSI_ARGS_((HDC dc,
- Colormap colormap));
+EXTERN HPALETTE TkWinSelectPalette(HDC dc, Colormap colormap);
+#endif
+#ifndef TkWinSetMenu_TCL_DECLARED
+#define TkWinSetMenu_TCL_DECLARED
/* 25 */
-EXTERN void TkWinSetMenu _ANSI_ARGS_((Tk_Window tkwin,
- HMENU hMenu));
+EXTERN void TkWinSetMenu(Tk_Window tkwin, HMENU hMenu);
+#endif
+#ifndef TkWinSetWindowPos_TCL_DECLARED
+#define TkWinSetWindowPos_TCL_DECLARED
/* 26 */
-EXTERN void TkWinSetWindowPos _ANSI_ARGS_((HWND hwnd,
- HWND siblingHwnd, int pos));
+EXTERN void TkWinSetWindowPos(HWND hwnd, HWND siblingHwnd,
+ int pos);
+#endif
+#ifndef TkWinWmCleanup_TCL_DECLARED
+#define TkWinWmCleanup_TCL_DECLARED
/* 27 */
-EXTERN void TkWinWmCleanup _ANSI_ARGS_((HINSTANCE hInstance));
+EXTERN void TkWinWmCleanup(HINSTANCE hInstance);
+#endif
+#ifndef TkWinXCleanup_TCL_DECLARED
+#define TkWinXCleanup_TCL_DECLARED
/* 28 */
-EXTERN void TkWinXCleanup _ANSI_ARGS_((ClientData clientData));
+EXTERN void TkWinXCleanup(ClientData clientData);
+#endif
+#ifndef TkWinXInit_TCL_DECLARED
+#define TkWinXInit_TCL_DECLARED
/* 29 */
-EXTERN void TkWinXInit _ANSI_ARGS_((HINSTANCE hInstance));
+EXTERN void TkWinXInit(HINSTANCE hInstance);
+#endif
+#ifndef TkWinSetForegroundWindow_TCL_DECLARED
+#define TkWinSetForegroundWindow_TCL_DECLARED
/* 30 */
-EXTERN void TkWinSetForegroundWindow _ANSI_ARGS_((
- TkWindow *winPtr));
+EXTERN void TkWinSetForegroundWindow(TkWindow *winPtr);
+#endif
+#ifndef TkWinDialogDebug_TCL_DECLARED
+#define TkWinDialogDebug_TCL_DECLARED
/* 31 */
-EXTERN void TkWinDialogDebug _ANSI_ARGS_((int debug));
+EXTERN void TkWinDialogDebug(int debug);
+#endif
+#ifndef TkWinGetMenuSystemDefault_TCL_DECLARED
+#define TkWinGetMenuSystemDefault_TCL_DECLARED
/* 32 */
-EXTERN Tcl_Obj * TkWinGetMenuSystemDefault _ANSI_ARGS_((
- Tk_Window tkwin, CONST char *dbName,
- CONST char *className));
+EXTERN Tcl_Obj * TkWinGetMenuSystemDefault(Tk_Window tkwin,
+ CONST char *dbName, CONST char *className);
+#endif
+#ifndef TkWinGetPlatformId_TCL_DECLARED
+#define TkWinGetPlatformId_TCL_DECLARED
/* 33 */
-EXTERN int TkWinGetPlatformId _ANSI_ARGS_((void));
+EXTERN int TkWinGetPlatformId(void);
+#endif
+#ifndef TkWinSetHINSTANCE_TCL_DECLARED
+#define TkWinSetHINSTANCE_TCL_DECLARED
/* 34 */
-EXTERN void TkWinSetHINSTANCE _ANSI_ARGS_((HINSTANCE hInstance));
+EXTERN void TkWinSetHINSTANCE(HINSTANCE hInstance);
+#endif
+#ifndef TkWinGetPlatformTheme_TCL_DECLARED
+#define TkWinGetPlatformTheme_TCL_DECLARED
/* 35 */
-EXTERN int TkWinGetPlatformTheme _ANSI_ARGS_((void));
+EXTERN int TkWinGetPlatformTheme(void);
+#endif
+#ifndef TkWinChildProc_TCL_DECLARED
+#define TkWinChildProc_TCL_DECLARED
/* 36 */
-EXTERN LRESULT __stdcall TkWinChildProc _ANSI_ARGS_((HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam));
+EXTERN LRESULT __stdcall TkWinChildProc(HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
+#endif
+#ifndef TkCreateXEventSource_TCL_DECLARED
+#define TkCreateXEventSource_TCL_DECLARED
/* 37 */
-EXTERN void TkCreateXEventSource _ANSI_ARGS_((void));
+EXTERN void TkCreateXEventSource(void);
+#endif
+#ifndef TkpCmapStressed_TCL_DECLARED
+#define TkpCmapStressed_TCL_DECLARED
/* 38 */
-EXTERN int TkpCmapStressed _ANSI_ARGS_((Tk_Window tkwin,
- Colormap colormap));
+EXTERN int TkpCmapStressed(Tk_Window tkwin, Colormap colormap);
+#endif
+#ifndef TkpSync_TCL_DECLARED
+#define TkpSync_TCL_DECLARED
/* 39 */
-EXTERN void TkpSync _ANSI_ARGS_((Display *display));
+EXTERN void TkpSync(Display *display);
+#endif
+#ifndef TkUnixContainerId_TCL_DECLARED
+#define TkUnixContainerId_TCL_DECLARED
/* 40 */
-EXTERN Window TkUnixContainerId _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN Window TkUnixContainerId(TkWindow *winPtr);
+#endif
+#ifndef TkUnixDoOneXEvent_TCL_DECLARED
+#define TkUnixDoOneXEvent_TCL_DECLARED
/* 41 */
-EXTERN int TkUnixDoOneXEvent _ANSI_ARGS_((Tcl_Time *timePtr));
+EXTERN int TkUnixDoOneXEvent(Tcl_Time *timePtr);
+#endif
+#ifndef TkUnixSetMenubar_TCL_DECLARED
+#define TkUnixSetMenubar_TCL_DECLARED
/* 42 */
-EXTERN void TkUnixSetMenubar _ANSI_ARGS_((Tk_Window tkwin,
- Tk_Window menubar));
+EXTERN void TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar);
+#endif
+#ifndef TkWmCleanup_TCL_DECLARED
+#define TkWmCleanup_TCL_DECLARED
/* 43 */
-EXTERN void TkWmCleanup _ANSI_ARGS_((TkDisplay *dispPtr));
+EXTERN void TkWmCleanup(TkDisplay *dispPtr);
+#endif
+#ifndef TkSendCleanup_TCL_DECLARED
+#define TkSendCleanup_TCL_DECLARED
/* 44 */
-EXTERN void TkSendCleanup _ANSI_ARGS_((TkDisplay *dispPtr));
+EXTERN void TkSendCleanup(TkDisplay *dispPtr);
+#endif
+#ifndef TkpTestsendCmd_TCL_DECLARED
+#define TkpTestsendCmd_TCL_DECLARED
+/* 45 */
+EXTERN int TkpTestsendCmd(ClientData clientData,
+ Tcl_Interp *interp, int argc,
+ CONST char **argv);
+#endif
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
+#ifndef TkGenerateActivateEvents_TCL_DECLARED
+#define TkGenerateActivateEvents_TCL_DECLARED
/* 0 */
-EXTERN void TkGenerateActivateEvents _ANSI_ARGS_((
- TkWindow *winPtr, int active));
+EXTERN void TkGenerateActivateEvents(TkWindow *winPtr,
+ int active);
+#endif
/* Slot 1 is reserved */
/* Slot 2 is reserved */
+#ifndef TkPointerDeadWindow_TCL_DECLARED
+#define TkPointerDeadWindow_TCL_DECLARED
/* 3 */
-EXTERN void TkPointerDeadWindow _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkPointerDeadWindow(TkWindow *winPtr);
+#endif
+#ifndef TkpSetCapture_TCL_DECLARED
+#define TkpSetCapture_TCL_DECLARED
/* 4 */
-EXTERN void TkpSetCapture _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkpSetCapture(TkWindow *winPtr);
+#endif
+#ifndef TkpSetCursor_TCL_DECLARED
+#define TkpSetCursor_TCL_DECLARED
/* 5 */
-EXTERN void TkpSetCursor _ANSI_ARGS_((TkpCursor cursor));
+EXTERN void TkpSetCursor(TkpCursor cursor);
+#endif
+#ifndef TkpWmSetState_TCL_DECLARED
+#define TkpWmSetState_TCL_DECLARED
/* 6 */
-EXTERN void TkpWmSetState _ANSI_ARGS_((TkWindow *winPtr,
- int state));
+EXTERN void TkpWmSetState(TkWindow *winPtr, int state);
+#endif
+#ifndef TkAboutDlg_TCL_DECLARED
+#define TkAboutDlg_TCL_DECLARED
/* 7 */
-EXTERN void TkAboutDlg _ANSI_ARGS_((void));
+EXTERN void TkAboutDlg(void);
+#endif
+#ifndef TkMacOSXButtonKeyState_TCL_DECLARED
+#define TkMacOSXButtonKeyState_TCL_DECLARED
/* 8 */
-EXTERN unsigned int TkMacOSXButtonKeyState _ANSI_ARGS_((void));
+EXTERN unsigned int TkMacOSXButtonKeyState(void);
+#endif
+#ifndef TkMacOSXClearMenubarActive_TCL_DECLARED
+#define TkMacOSXClearMenubarActive_TCL_DECLARED
/* 9 */
-EXTERN void TkMacOSXClearMenubarActive _ANSI_ARGS_((void));
+EXTERN void TkMacOSXClearMenubarActive(void);
+#endif
+#ifndef TkMacOSXDispatchMenuEvent_TCL_DECLARED
+#define TkMacOSXDispatchMenuEvent_TCL_DECLARED
/* 10 */
-EXTERN int TkMacOSXDispatchMenuEvent _ANSI_ARGS_((int menuID,
- int index));
+EXTERN int TkMacOSXDispatchMenuEvent(int menuID, int index);
+#endif
+#ifndef TkMacOSXInstallCursor_TCL_DECLARED
+#define TkMacOSXInstallCursor_TCL_DECLARED
/* 11 */
-EXTERN void TkMacOSXInstallCursor _ANSI_ARGS_((
- int resizeOverride));
+EXTERN void TkMacOSXInstallCursor(int resizeOverride);
+#endif
+#ifndef TkMacOSXHandleTearoffMenu_TCL_DECLARED
+#define TkMacOSXHandleTearoffMenu_TCL_DECLARED
/* 12 */
-EXTERN void TkMacOSXHandleTearoffMenu _ANSI_ARGS_((void));
+EXTERN void TkMacOSXHandleTearoffMenu(void);
+#endif
/* Slot 13 is reserved */
+#ifndef TkMacOSXDoHLEvent_TCL_DECLARED
+#define TkMacOSXDoHLEvent_TCL_DECLARED
/* 14 */
-EXTERN int TkMacOSXDoHLEvent _ANSI_ARGS_((EventRecord *theEvent));
+EXTERN int TkMacOSXDoHLEvent(VOID *theEvent);
+#endif
/* Slot 15 is reserved */
+#ifndef TkMacOSXGetXWindow_TCL_DECLARED
+#define TkMacOSXGetXWindow_TCL_DECLARED
/* 16 */
-EXTERN Window TkMacOSXGetXWindow _ANSI_ARGS_((WindowRef macWinPtr));
+EXTERN Window TkMacOSXGetXWindow(VOID *macWinPtr);
+#endif
+#ifndef TkMacOSXGrowToplevel_TCL_DECLARED
+#define TkMacOSXGrowToplevel_TCL_DECLARED
/* 17 */
-EXTERN int TkMacOSXGrowToplevel _ANSI_ARGS_((
- WindowRef whichWindow, Point start));
+EXTERN int TkMacOSXGrowToplevel(VOID *whichWindow, XPoint start);
+#endif
+#ifndef TkMacOSXHandleMenuSelect_TCL_DECLARED
+#define TkMacOSXHandleMenuSelect_TCL_DECLARED
/* 18 */
-EXTERN void TkMacOSXHandleMenuSelect _ANSI_ARGS_((MenuID theMenu,
- MenuItemIndex theItem, int optionKeyPressed));
+EXTERN void TkMacOSXHandleMenuSelect(short theMenu,
+ unsigned short theItem, int optionKeyPressed);
+#endif
/* Slot 19 is reserved */
/* Slot 20 is reserved */
+#ifndef TkMacOSXInvalidateWindow_TCL_DECLARED
+#define TkMacOSXInvalidateWindow_TCL_DECLARED
/* 21 */
-EXTERN void TkMacOSXInvalidateWindow _ANSI_ARGS_((
- MacDrawable *macWin, int flag));
+EXTERN void TkMacOSXInvalidateWindow(MacDrawable *macWin,
+ int flag);
+#endif
+#ifndef TkMacOSXIsCharacterMissing_TCL_DECLARED
+#define TkMacOSXIsCharacterMissing_TCL_DECLARED
/* 22 */
-EXTERN int TkMacOSXIsCharacterMissing _ANSI_ARGS_((
- Tk_Font tkfont, unsigned int searchChar));
+EXTERN int TkMacOSXIsCharacterMissing(Tk_Font tkfont,
+ unsigned int searchChar);
+#endif
+#ifndef TkMacOSXMakeRealWindowExist_TCL_DECLARED
+#define TkMacOSXMakeRealWindowExist_TCL_DECLARED
/* 23 */
-EXTERN void TkMacOSXMakeRealWindowExist _ANSI_ARGS_((
- TkWindow *winPtr));
+EXTERN void TkMacOSXMakeRealWindowExist(TkWindow *winPtr);
+#endif
+#ifndef TkMacOSXMakeStippleMap_TCL_DECLARED
+#define TkMacOSXMakeStippleMap_TCL_DECLARED
/* 24 */
-EXTERN BitMapPtr TkMacOSXMakeStippleMap _ANSI_ARGS_((Drawable d1,
- Drawable d2));
+EXTERN VOID * TkMacOSXMakeStippleMap(Drawable d1, Drawable d2);
+#endif
+#ifndef TkMacOSXMenuClick_TCL_DECLARED
+#define TkMacOSXMenuClick_TCL_DECLARED
/* 25 */
-EXTERN void TkMacOSXMenuClick _ANSI_ARGS_((void));
+EXTERN void TkMacOSXMenuClick(void);
+#endif
+#ifndef TkMacOSXRegisterOffScreenWindow_TCL_DECLARED
+#define TkMacOSXRegisterOffScreenWindow_TCL_DECLARED
/* 26 */
-EXTERN void TkMacOSXRegisterOffScreenWindow _ANSI_ARGS_((
- Window window, GWorldPtr portPtr));
+EXTERN void TkMacOSXRegisterOffScreenWindow(Window window,
+ VOID *portPtr);
+#endif
+#ifndef TkMacOSXResizable_TCL_DECLARED
+#define TkMacOSXResizable_TCL_DECLARED
/* 27 */
-EXTERN int TkMacOSXResizable _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN int TkMacOSXResizable(TkWindow *winPtr);
+#endif
+#ifndef TkMacOSXSetHelpMenuItemCount_TCL_DECLARED
+#define TkMacOSXSetHelpMenuItemCount_TCL_DECLARED
/* 28 */
-EXTERN void TkMacOSXSetHelpMenuItemCount _ANSI_ARGS_((void));
+EXTERN void TkMacOSXSetHelpMenuItemCount(void);
+#endif
+#ifndef TkMacOSXSetScrollbarGrow_TCL_DECLARED
+#define TkMacOSXSetScrollbarGrow_TCL_DECLARED
/* 29 */
-EXTERN void TkMacOSXSetScrollbarGrow _ANSI_ARGS_((
- TkWindow *winPtr, int flag));
+EXTERN void TkMacOSXSetScrollbarGrow(TkWindow *winPtr, int flag);
+#endif
+#ifndef TkMacOSXSetUpClippingRgn_TCL_DECLARED
+#define TkMacOSXSetUpClippingRgn_TCL_DECLARED
/* 30 */
-EXTERN void TkMacOSXSetUpClippingRgn _ANSI_ARGS_((
- Drawable drawable));
+EXTERN void TkMacOSXSetUpClippingRgn(Drawable drawable);
+#endif
+#ifndef TkMacOSXSetUpGraphicsPort_TCL_DECLARED
+#define TkMacOSXSetUpGraphicsPort_TCL_DECLARED
/* 31 */
-EXTERN void TkMacOSXSetUpGraphicsPort _ANSI_ARGS_((GC gc,
- GWorldPtr destPort));
+EXTERN void TkMacOSXSetUpGraphicsPort(GC gc, VOID *destPort);
+#endif
+#ifndef TkMacOSXUpdateClipRgn_TCL_DECLARED
+#define TkMacOSXUpdateClipRgn_TCL_DECLARED
/* 32 */
-EXTERN void TkMacOSXUpdateClipRgn _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN void TkMacOSXUpdateClipRgn(TkWindow *winPtr);
+#endif
+#ifndef TkMacOSXUnregisterMacWindow_TCL_DECLARED
+#define TkMacOSXUnregisterMacWindow_TCL_DECLARED
/* 33 */
-EXTERN void TkMacOSXUnregisterMacWindow _ANSI_ARGS_((
- WindowRef portPtr));
+EXTERN void TkMacOSXUnregisterMacWindow(VOID *portPtr);
+#endif
+#ifndef TkMacOSXUseMenuID_TCL_DECLARED
+#define TkMacOSXUseMenuID_TCL_DECLARED
/* 34 */
-EXTERN int TkMacOSXUseMenuID _ANSI_ARGS_((short macID));
+EXTERN int TkMacOSXUseMenuID(short macID);
+#endif
+#ifndef TkMacOSXVisableClipRgn_TCL_DECLARED
+#define TkMacOSXVisableClipRgn_TCL_DECLARED
/* 35 */
-EXTERN RgnHandle TkMacOSXVisableClipRgn _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN TkRegion TkMacOSXVisableClipRgn(TkWindow *winPtr);
+#endif
+#ifndef TkMacOSXWinBounds_TCL_DECLARED
+#define TkMacOSXWinBounds_TCL_DECLARED
/* 36 */
-EXTERN void TkMacOSXWinBounds _ANSI_ARGS_((TkWindow *winPtr,
- Rect *geometry));
+EXTERN void TkMacOSXWinBounds(TkWindow *winPtr, VOID *geometry);
+#endif
+#ifndef TkMacOSXWindowOffset_TCL_DECLARED
+#define TkMacOSXWindowOffset_TCL_DECLARED
/* 37 */
-EXTERN void TkMacOSXWindowOffset _ANSI_ARGS_((WindowRef wRef,
- int *xOffset, int *yOffset));
+EXTERN void TkMacOSXWindowOffset(VOID *wRef, int *xOffset,
+ int *yOffset);
+#endif
+#ifndef TkSetMacColor_TCL_DECLARED
+#define TkSetMacColor_TCL_DECLARED
/* 38 */
-EXTERN int TkSetMacColor _ANSI_ARGS_((unsigned long pixel,
- RGBColor *macColor));
+EXTERN int TkSetMacColor(unsigned long pixel, VOID *macColor);
+#endif
+#ifndef TkSetWMName_TCL_DECLARED
+#define TkSetWMName_TCL_DECLARED
/* 39 */
-EXTERN void TkSetWMName _ANSI_ARGS_((TkWindow *winPtr,
- Tk_Uid titleUid));
+EXTERN void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid);
+#endif
+#ifndef TkSuspendClipboard_TCL_DECLARED
+#define TkSuspendClipboard_TCL_DECLARED
/* 40 */
-EXTERN void TkSuspendClipboard _ANSI_ARGS_((void));
+EXTERN void TkSuspendClipboard(void);
+#endif
+#ifndef TkMacOSXZoomToplevel_TCL_DECLARED
+#define TkMacOSXZoomToplevel_TCL_DECLARED
/* 41 */
-EXTERN int TkMacOSXZoomToplevel _ANSI_ARGS_((
- WindowPtr whichWindow, short zoomPart));
+EXTERN int TkMacOSXZoomToplevel(VOID *whichWindow,
+ short zoomPart);
+#endif
+#ifndef Tk_TopCoordsToWindow_TCL_DECLARED
+#define Tk_TopCoordsToWindow_TCL_DECLARED
/* 42 */
-EXTERN Tk_Window Tk_TopCoordsToWindow _ANSI_ARGS_((Tk_Window tkwin,
- int rootX, int rootY, int *newX, int *newY));
+EXTERN Tk_Window Tk_TopCoordsToWindow(Tk_Window tkwin, int rootX,
+ int rootY, int *newX, int *newY);
+#endif
+#ifndef TkMacOSXContainerId_TCL_DECLARED
+#define TkMacOSXContainerId_TCL_DECLARED
/* 43 */
-EXTERN MacDrawable * TkMacOSXContainerId _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN MacDrawable * TkMacOSXContainerId(TkWindow *winPtr);
+#endif
+#ifndef TkMacOSXGetHostToplevel_TCL_DECLARED
+#define TkMacOSXGetHostToplevel_TCL_DECLARED
/* 44 */
-EXTERN MacDrawable * TkMacOSXGetHostToplevel _ANSI_ARGS_((
- TkWindow *winPtr));
+EXTERN MacDrawable * TkMacOSXGetHostToplevel(TkWindow *winPtr);
+#endif
+#ifndef TkMacOSXPreprocessMenu_TCL_DECLARED
+#define TkMacOSXPreprocessMenu_TCL_DECLARED
/* 45 */
-EXTERN void TkMacOSXPreprocessMenu _ANSI_ARGS_((void));
+EXTERN void TkMacOSXPreprocessMenu(void);
+#endif
+#ifndef TkpIsWindowFloating_TCL_DECLARED
+#define TkpIsWindowFloating_TCL_DECLARED
/* 46 */
-EXTERN int TkpIsWindowFloating _ANSI_ARGS_((WindowRef window));
+EXTERN int TkpIsWindowFloating(VOID *window);
+#endif
+#ifndef TkMacOSXGetCapture_TCL_DECLARED
+#define TkMacOSXGetCapture_TCL_DECLARED
/* 47 */
-EXTERN Tk_Window TkMacOSXGetCapture _ANSI_ARGS_((void));
+EXTERN Tk_Window TkMacOSXGetCapture(void);
+#endif
/* Slot 48 is reserved */
+#ifndef TkGetTransientMaster_TCL_DECLARED
+#define TkGetTransientMaster_TCL_DECLARED
/* 49 */
-EXTERN Window TkGetTransientMaster _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN Window TkGetTransientMaster(TkWindow *winPtr);
+#endif
+#ifndef TkGenerateButtonEvent_TCL_DECLARED
+#define TkGenerateButtonEvent_TCL_DECLARED
/* 50 */
-EXTERN int TkGenerateButtonEvent _ANSI_ARGS_((int x, int y,
- Window window, unsigned int state));
+EXTERN int TkGenerateButtonEvent(int x, int y, Window window,
+ unsigned int state);
+#endif
+#ifndef TkGenWMDestroyEvent_TCL_DECLARED
+#define TkGenWMDestroyEvent_TCL_DECLARED
/* 51 */
-EXTERN void TkGenWMDestroyEvent _ANSI_ARGS_((Tk_Window tkwin));
+EXTERN void TkGenWMDestroyEvent(Tk_Window tkwin);
+#endif
/* Slot 52 is reserved */
+#ifndef TkpGetMS_TCL_DECLARED
+#define TkpGetMS_TCL_DECLARED
/* 53 */
-EXTERN unsigned long TkpGetMS _ANSI_ARGS_((void));
+EXTERN unsigned long TkpGetMS(void);
+#endif
+#ifndef TkMacOSXDrawable_TCL_DECLARED
+#define TkMacOSXDrawable_TCL_DECLARED
+/* 54 */
+EXTERN VOID * TkMacOSXDrawable(Drawable drawable);
+#endif
#endif /* AQUA */
#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
+#ifndef TkCreateXEventSource_TCL_DECLARED
+#define TkCreateXEventSource_TCL_DECLARED
/* 0 */
-EXTERN void TkCreateXEventSource _ANSI_ARGS_((void));
+EXTERN void TkCreateXEventSource(void);
+#endif
+#ifndef TkFreeWindowId_TCL_DECLARED
+#define TkFreeWindowId_TCL_DECLARED
/* 1 */
-EXTERN void TkFreeWindowId _ANSI_ARGS_((TkDisplay *dispPtr,
- Window w));
+EXTERN void TkFreeWindowId(TkDisplay *dispPtr, Window w);
+#endif
+#ifndef TkInitXId_TCL_DECLARED
+#define TkInitXId_TCL_DECLARED
/* 2 */
-EXTERN void TkInitXId _ANSI_ARGS_((TkDisplay *dispPtr));
+EXTERN void TkInitXId(TkDisplay *dispPtr);
+#endif
+#ifndef TkpCmapStressed_TCL_DECLARED
+#define TkpCmapStressed_TCL_DECLARED
/* 3 */
-EXTERN int TkpCmapStressed _ANSI_ARGS_((Tk_Window tkwin,
- Colormap colormap));
+EXTERN int TkpCmapStressed(Tk_Window tkwin, Colormap colormap);
+#endif
+#ifndef TkpSync_TCL_DECLARED
+#define TkpSync_TCL_DECLARED
/* 4 */
-EXTERN void TkpSync _ANSI_ARGS_((Display *display));
+EXTERN void TkpSync(Display *display);
+#endif
+#ifndef TkUnixContainerId_TCL_DECLARED
+#define TkUnixContainerId_TCL_DECLARED
/* 5 */
-EXTERN Window TkUnixContainerId _ANSI_ARGS_((TkWindow *winPtr));
+EXTERN Window TkUnixContainerId(TkWindow *winPtr);
+#endif
+#ifndef TkUnixDoOneXEvent_TCL_DECLARED
+#define TkUnixDoOneXEvent_TCL_DECLARED
/* 6 */
-EXTERN int TkUnixDoOneXEvent _ANSI_ARGS_((Tcl_Time *timePtr));
+EXTERN int TkUnixDoOneXEvent(Tcl_Time *timePtr);
+#endif
+#ifndef TkUnixSetMenubar_TCL_DECLARED
+#define TkUnixSetMenubar_TCL_DECLARED
/* 7 */
-EXTERN void TkUnixSetMenubar _ANSI_ARGS_((Tk_Window tkwin,
- Tk_Window menubar));
+EXTERN void TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar);
+#endif
+#ifndef TkpScanWindowId_TCL_DECLARED
+#define TkpScanWindowId_TCL_DECLARED
/* 8 */
-EXTERN int TkpScanWindowId _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *string, Window *idPtr));
+EXTERN int TkpScanWindowId(Tcl_Interp *interp,
+ CONST char *string, Window *idPtr);
+#endif
+#ifndef TkWmCleanup_TCL_DECLARED
+#define TkWmCleanup_TCL_DECLARED
/* 9 */
-EXTERN void TkWmCleanup _ANSI_ARGS_((TkDisplay *dispPtr));
+EXTERN void TkWmCleanup(TkDisplay *dispPtr);
+#endif
+#ifndef TkSendCleanup_TCL_DECLARED
+#define TkSendCleanup_TCL_DECLARED
/* 10 */
-EXTERN void TkSendCleanup _ANSI_ARGS_((TkDisplay *dispPtr));
+EXTERN void TkSendCleanup(TkDisplay *dispPtr);
+#endif
+#ifndef TkFreeXId_TCL_DECLARED
+#define TkFreeXId_TCL_DECLARED
/* 11 */
-EXTERN void TkFreeXId _ANSI_ARGS_((TkDisplay *dispPtr));
+EXTERN void TkFreeXId(TkDisplay *dispPtr);
+#endif
+#ifndef TkpWmSetState_TCL_DECLARED
+#define TkpWmSetState_TCL_DECLARED
/* 12 */
-EXTERN int TkpWmSetState _ANSI_ARGS_((TkWindow *winPtr,
- int state));
+EXTERN int TkpWmSetState(TkWindow *winPtr, int state);
+#endif
+#ifndef TkpTestsendCmd_TCL_DECLARED
+#define TkpTestsendCmd_TCL_DECLARED
+/* 13 */
+EXTERN int TkpTestsendCmd(ClientData clientData,
+ Tcl_Interp *interp, int argc,
+ CONST char **argv);
+#endif
#endif /* X11 */
typedef struct TkIntPlatStubs {
@@ -309,122 +609,125 @@ typedef struct TkIntPlatStubs {
struct TkIntPlatStubHooks *hooks;
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
- char * (*tkAlignImageData) _ANSI_ARGS_((XImage *image, int alignment, int bitOrder)); /* 0 */
+ char * (*tkAlignImageData) (XImage *image, int alignment, int bitOrder); /* 0 */
VOID *reserved1;
- void (*tkGenerateActivateEvents) _ANSI_ARGS_((TkWindow *winPtr, int active)); /* 2 */
- unsigned long (*tkpGetMS) _ANSI_ARGS_((void)); /* 3 */
- void (*tkPointerDeadWindow) _ANSI_ARGS_((TkWindow *winPtr)); /* 4 */
- void (*tkpPrintWindowId) _ANSI_ARGS_((char *buf, Window window)); /* 5 */
- int (*tkpScanWindowId) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *string, Window *idPtr)); /* 6 */
- void (*tkpSetCapture) _ANSI_ARGS_((TkWindow *winPtr)); /* 7 */
- void (*tkpSetCursor) _ANSI_ARGS_((TkpCursor cursor)); /* 8 */
- int (*tkpWmSetState) _ANSI_ARGS_((TkWindow *winPtr, int state)); /* 9 */
- void (*tkSetPixmapColormap) _ANSI_ARGS_((Pixmap pixmap, Colormap colormap)); /* 10 */
- void (*tkWinCancelMouseTimer) _ANSI_ARGS_((void)); /* 11 */
- void (*tkWinClipboardRender) _ANSI_ARGS_((TkDisplay *dispPtr, UINT format)); /* 12 */
- LRESULT (*tkWinEmbeddedEventProc) _ANSI_ARGS_((HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)); /* 13 */
- void (*tkWinFillRect) _ANSI_ARGS_((HDC dc, int x, int y, int width, int height, int pixel)); /* 14 */
- COLORREF (*tkWinGetBorderPixels) _ANSI_ARGS_((Tk_Window tkwin, Tk_3DBorder border, int which)); /* 15 */
- HDC (*tkWinGetDrawableDC) _ANSI_ARGS_((Display *display, Drawable d, TkWinDCState *state)); /* 16 */
- int (*tkWinGetModifierState) _ANSI_ARGS_((void)); /* 17 */
- HPALETTE (*tkWinGetSystemPalette) _ANSI_ARGS_((void)); /* 18 */
- HWND (*tkWinGetWrapperWindow) _ANSI_ARGS_((Tk_Window tkwin)); /* 19 */
- int (*tkWinHandleMenuEvent) _ANSI_ARGS_((HWND *phwnd, UINT *pMessage, WPARAM *pwParam, LPARAM *plParam, LRESULT *plResult)); /* 20 */
- int (*tkWinIndexOfColor) _ANSI_ARGS_((XColor *colorPtr)); /* 21 */
- void (*tkWinReleaseDrawableDC) _ANSI_ARGS_((Drawable d, HDC hdc, TkWinDCState *state)); /* 22 */
- LRESULT (*tkWinResendEvent) _ANSI_ARGS_((WNDPROC wndproc, HWND hwnd, XEvent *eventPtr)); /* 23 */
- HPALETTE (*tkWinSelectPalette) _ANSI_ARGS_((HDC dc, Colormap colormap)); /* 24 */
- void (*tkWinSetMenu) _ANSI_ARGS_((Tk_Window tkwin, HMENU hMenu)); /* 25 */
- void (*tkWinSetWindowPos) _ANSI_ARGS_((HWND hwnd, HWND siblingHwnd, int pos)); /* 26 */
- void (*tkWinWmCleanup) _ANSI_ARGS_((HINSTANCE hInstance)); /* 27 */
- void (*tkWinXCleanup) _ANSI_ARGS_((ClientData clientData)); /* 28 */
- void (*tkWinXInit) _ANSI_ARGS_((HINSTANCE hInstance)); /* 29 */
- void (*tkWinSetForegroundWindow) _ANSI_ARGS_((TkWindow *winPtr)); /* 30 */
- void (*tkWinDialogDebug) _ANSI_ARGS_((int debug)); /* 31 */
- Tcl_Obj * (*tkWinGetMenuSystemDefault) _ANSI_ARGS_((Tk_Window tkwin, CONST char *dbName, CONST char *className)); /* 32 */
- int (*tkWinGetPlatformId) _ANSI_ARGS_((void)); /* 33 */
- void (*tkWinSetHINSTANCE) _ANSI_ARGS_((HINSTANCE hInstance)); /* 34 */
- int (*tkWinGetPlatformTheme) _ANSI_ARGS_((void)); /* 35 */
- LRESULT (__stdcall *tkWinChildProc) _ANSI_ARGS_((HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)); /* 36 */
- void (*tkCreateXEventSource) _ANSI_ARGS_((void)); /* 37 */
- int (*tkpCmapStressed) _ANSI_ARGS_((Tk_Window tkwin, Colormap colormap)); /* 38 */
- void (*tkpSync) _ANSI_ARGS_((Display *display)); /* 39 */
- Window (*tkUnixContainerId) _ANSI_ARGS_((TkWindow *winPtr)); /* 40 */
- int (*tkUnixDoOneXEvent) _ANSI_ARGS_((Tcl_Time *timePtr)); /* 41 */
- void (*tkUnixSetMenubar) _ANSI_ARGS_((Tk_Window tkwin, Tk_Window menubar)); /* 42 */
- void (*tkWmCleanup) _ANSI_ARGS_((TkDisplay *dispPtr)); /* 43 */
- void (*tkSendCleanup) _ANSI_ARGS_((TkDisplay *dispPtr)); /* 44 */
+ void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 2 */
+ unsigned long (*tkpGetMS) (void); /* 3 */
+ void (*tkPointerDeadWindow) (TkWindow *winPtr); /* 4 */
+ void (*tkpPrintWindowId) (char *buf, Window window); /* 5 */
+ int (*tkpScanWindowId) (Tcl_Interp *interp, CONST char *string, Window *idPtr); /* 6 */
+ void (*tkpSetCapture) (TkWindow *winPtr); /* 7 */
+ void (*tkpSetCursor) (TkpCursor cursor); /* 8 */
+ int (*tkpWmSetState) (TkWindow *winPtr, int state); /* 9 */
+ void (*tkSetPixmapColormap) (Pixmap pixmap, Colormap colormap); /* 10 */
+ void (*tkWinCancelMouseTimer) (void); /* 11 */
+ void (*tkWinClipboardRender) (TkDisplay *dispPtr, UINT format); /* 12 */
+ LRESULT (*tkWinEmbeddedEventProc) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); /* 13 */
+ void (*tkWinFillRect) (HDC dc, int x, int y, int width, int height, int pixel); /* 14 */
+ COLORREF (*tkWinGetBorderPixels) (Tk_Window tkwin, Tk_3DBorder border, int which); /* 15 */
+ HDC (*tkWinGetDrawableDC) (Display *display, Drawable d, TkWinDCState *state); /* 16 */
+ int (*tkWinGetModifierState) (void); /* 17 */
+ HPALETTE (*tkWinGetSystemPalette) (void); /* 18 */
+ HWND (*tkWinGetWrapperWindow) (Tk_Window tkwin); /* 19 */
+ int (*tkWinHandleMenuEvent) (HWND *phwnd, UINT *pMessage, WPARAM *pwParam, LPARAM *plParam, LRESULT *plResult); /* 20 */
+ int (*tkWinIndexOfColor) (XColor *colorPtr); /* 21 */
+ void (*tkWinReleaseDrawableDC) (Drawable d, HDC hdc, TkWinDCState *state); /* 22 */
+ LRESULT (*tkWinResendEvent) (WNDPROC wndproc, HWND hwnd, XEvent *eventPtr); /* 23 */
+ HPALETTE (*tkWinSelectPalette) (HDC dc, Colormap colormap); /* 24 */
+ void (*tkWinSetMenu) (Tk_Window tkwin, HMENU hMenu); /* 25 */
+ void (*tkWinSetWindowPos) (HWND hwnd, HWND siblingHwnd, int pos); /* 26 */
+ void (*tkWinWmCleanup) (HINSTANCE hInstance); /* 27 */
+ void (*tkWinXCleanup) (ClientData clientData); /* 28 */
+ void (*tkWinXInit) (HINSTANCE hInstance); /* 29 */
+ void (*tkWinSetForegroundWindow) (TkWindow *winPtr); /* 30 */
+ void (*tkWinDialogDebug) (int debug); /* 31 */
+ Tcl_Obj * (*tkWinGetMenuSystemDefault) (Tk_Window tkwin, CONST char *dbName, CONST char *className); /* 32 */
+ int (*tkWinGetPlatformId) (void); /* 33 */
+ void (*tkWinSetHINSTANCE) (HINSTANCE hInstance); /* 34 */
+ int (*tkWinGetPlatformTheme) (void); /* 35 */
+ LRESULT (__stdcall *tkWinChildProc) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); /* 36 */
+ void (*tkCreateXEventSource) (void); /* 37 */
+ int (*tkpCmapStressed) (Tk_Window tkwin, Colormap colormap); /* 38 */
+ void (*tkpSync) (Display *display); /* 39 */
+ Window (*tkUnixContainerId) (TkWindow *winPtr); /* 40 */
+ int (*tkUnixDoOneXEvent) (Tcl_Time *timePtr); /* 41 */
+ void (*tkUnixSetMenubar) (Tk_Window tkwin, Tk_Window menubar); /* 42 */
+ void (*tkWmCleanup) (TkDisplay *dispPtr); /* 43 */
+ void (*tkSendCleanup) (TkDisplay *dispPtr); /* 44 */
+ int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int argc, CONST char **argv); /* 45 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
- void (*tkGenerateActivateEvents) _ANSI_ARGS_((TkWindow *winPtr, int active)); /* 0 */
+ void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 0 */
VOID *reserved1;
VOID *reserved2;
- void (*tkPointerDeadWindow) _ANSI_ARGS_((TkWindow *winPtr)); /* 3 */
- void (*tkpSetCapture) _ANSI_ARGS_((TkWindow *winPtr)); /* 4 */
- void (*tkpSetCursor) _ANSI_ARGS_((TkpCursor cursor)); /* 5 */
- void (*tkpWmSetState) _ANSI_ARGS_((TkWindow *winPtr, int state)); /* 6 */
- void (*tkAboutDlg) _ANSI_ARGS_((void)); /* 7 */
- unsigned int (*tkMacOSXButtonKeyState) _ANSI_ARGS_((void)); /* 8 */
- void (*tkMacOSXClearMenubarActive) _ANSI_ARGS_((void)); /* 9 */
- int (*tkMacOSXDispatchMenuEvent) _ANSI_ARGS_((int menuID, int index)); /* 10 */
- void (*tkMacOSXInstallCursor) _ANSI_ARGS_((int resizeOverride)); /* 11 */
- void (*tkMacOSXHandleTearoffMenu) _ANSI_ARGS_((void)); /* 12 */
+ void (*tkPointerDeadWindow) (TkWindow *winPtr); /* 3 */
+ void (*tkpSetCapture) (TkWindow *winPtr); /* 4 */
+ void (*tkpSetCursor) (TkpCursor cursor); /* 5 */
+ void (*tkpWmSetState) (TkWindow *winPtr, int state); /* 6 */
+ void (*tkAboutDlg) (void); /* 7 */
+ unsigned int (*tkMacOSXButtonKeyState) (void); /* 8 */
+ void (*tkMacOSXClearMenubarActive) (void); /* 9 */
+ int (*tkMacOSXDispatchMenuEvent) (int menuID, int index); /* 10 */
+ void (*tkMacOSXInstallCursor) (int resizeOverride); /* 11 */
+ void (*tkMacOSXHandleTearoffMenu) (void); /* 12 */
VOID *reserved13;
- int (*tkMacOSXDoHLEvent) _ANSI_ARGS_((EventRecord *theEvent)); /* 14 */
+ int (*tkMacOSXDoHLEvent) (VOID *theEvent); /* 14 */
VOID *reserved15;
- Window (*tkMacOSXGetXWindow) _ANSI_ARGS_((WindowRef macWinPtr)); /* 16 */
- int (*tkMacOSXGrowToplevel) _ANSI_ARGS_((WindowRef whichWindow, Point start)); /* 17 */
- void (*tkMacOSXHandleMenuSelect) _ANSI_ARGS_((MenuID theMenu, MenuItemIndex theItem, int optionKeyPressed)); /* 18 */
+ Window (*tkMacOSXGetXWindow) (VOID *macWinPtr); /* 16 */
+ int (*tkMacOSXGrowToplevel) (VOID *whichWindow, XPoint start); /* 17 */
+ void (*tkMacOSXHandleMenuSelect) (short theMenu, unsigned short theItem, int optionKeyPressed); /* 18 */
VOID *reserved19;
VOID *reserved20;
- void (*tkMacOSXInvalidateWindow) _ANSI_ARGS_((MacDrawable *macWin, int flag)); /* 21 */
- int (*tkMacOSXIsCharacterMissing) _ANSI_ARGS_((Tk_Font tkfont, unsigned int searchChar)); /* 22 */
- void (*tkMacOSXMakeRealWindowExist) _ANSI_ARGS_((TkWindow *winPtr)); /* 23 */
- BitMapPtr (*tkMacOSXMakeStippleMap) _ANSI_ARGS_((Drawable d1, Drawable d2)); /* 24 */
- void (*tkMacOSXMenuClick) _ANSI_ARGS_((void)); /* 25 */
- void (*tkMacOSXRegisterOffScreenWindow) _ANSI_ARGS_((Window window, GWorldPtr portPtr)); /* 26 */
- int (*tkMacOSXResizable) _ANSI_ARGS_((TkWindow *winPtr)); /* 27 */
- void (*tkMacOSXSetHelpMenuItemCount) _ANSI_ARGS_((void)); /* 28 */
- void (*tkMacOSXSetScrollbarGrow) _ANSI_ARGS_((TkWindow *winPtr, int flag)); /* 29 */
- void (*tkMacOSXSetUpClippingRgn) _ANSI_ARGS_((Drawable drawable)); /* 30 */
- void (*tkMacOSXSetUpGraphicsPort) _ANSI_ARGS_((GC gc, GWorldPtr destPort)); /* 31 */
- void (*tkMacOSXUpdateClipRgn) _ANSI_ARGS_((TkWindow *winPtr)); /* 32 */
- void (*tkMacOSXUnregisterMacWindow) _ANSI_ARGS_((WindowRef portPtr)); /* 33 */
- int (*tkMacOSXUseMenuID) _ANSI_ARGS_((short macID)); /* 34 */
- RgnHandle (*tkMacOSXVisableClipRgn) _ANSI_ARGS_((TkWindow *winPtr)); /* 35 */
- void (*tkMacOSXWinBounds) _ANSI_ARGS_((TkWindow *winPtr, Rect *geometry)); /* 36 */
- void (*tkMacOSXWindowOffset) _ANSI_ARGS_((WindowRef wRef, int *xOffset, int *yOffset)); /* 37 */
- int (*tkSetMacColor) _ANSI_ARGS_((unsigned long pixel, RGBColor *macColor)); /* 38 */
- void (*tkSetWMName) _ANSI_ARGS_((TkWindow *winPtr, Tk_Uid titleUid)); /* 39 */
- void (*tkSuspendClipboard) _ANSI_ARGS_((void)); /* 40 */
- int (*tkMacOSXZoomToplevel) _ANSI_ARGS_((WindowPtr whichWindow, short zoomPart)); /* 41 */
- Tk_Window (*tk_TopCoordsToWindow) _ANSI_ARGS_((Tk_Window tkwin, int rootX, int rootY, int *newX, int *newY)); /* 42 */
- MacDrawable * (*tkMacOSXContainerId) _ANSI_ARGS_((TkWindow *winPtr)); /* 43 */
- MacDrawable * (*tkMacOSXGetHostToplevel) _ANSI_ARGS_((TkWindow *winPtr)); /* 44 */
- void (*tkMacOSXPreprocessMenu) _ANSI_ARGS_((void)); /* 45 */
- int (*tkpIsWindowFloating) _ANSI_ARGS_((WindowRef window)); /* 46 */
- Tk_Window (*tkMacOSXGetCapture) _ANSI_ARGS_((void)); /* 47 */
+ void (*tkMacOSXInvalidateWindow) (MacDrawable *macWin, int flag); /* 21 */
+ int (*tkMacOSXIsCharacterMissing) (Tk_Font tkfont, unsigned int searchChar); /* 22 */
+ void (*tkMacOSXMakeRealWindowExist) (TkWindow *winPtr); /* 23 */
+ VOID * (*tkMacOSXMakeStippleMap) (Drawable d1, Drawable d2); /* 24 */
+ void (*tkMacOSXMenuClick) (void); /* 25 */
+ void (*tkMacOSXRegisterOffScreenWindow) (Window window, VOID *portPtr); /* 26 */
+ int (*tkMacOSXResizable) (TkWindow *winPtr); /* 27 */
+ void (*tkMacOSXSetHelpMenuItemCount) (void); /* 28 */
+ void (*tkMacOSXSetScrollbarGrow) (TkWindow *winPtr, int flag); /* 29 */
+ void (*tkMacOSXSetUpClippingRgn) (Drawable drawable); /* 30 */
+ void (*tkMacOSXSetUpGraphicsPort) (GC gc, VOID *destPort); /* 31 */
+ void (*tkMacOSXUpdateClipRgn) (TkWindow *winPtr); /* 32 */
+ void (*tkMacOSXUnregisterMacWindow) (VOID *portPtr); /* 33 */
+ int (*tkMacOSXUseMenuID) (short macID); /* 34 */
+ TkRegion (*tkMacOSXVisableClipRgn) (TkWindow *winPtr); /* 35 */
+ void (*tkMacOSXWinBounds) (TkWindow *winPtr, VOID *geometry); /* 36 */
+ void (*tkMacOSXWindowOffset) (VOID *wRef, int *xOffset, int *yOffset); /* 37 */
+ int (*tkSetMacColor) (unsigned long pixel, VOID *macColor); /* 38 */
+ void (*tkSetWMName) (TkWindow *winPtr, Tk_Uid titleUid); /* 39 */
+ void (*tkSuspendClipboard) (void); /* 40 */
+ int (*tkMacOSXZoomToplevel) (VOID *whichWindow, short zoomPart); /* 41 */
+ Tk_Window (*tk_TopCoordsToWindow) (Tk_Window tkwin, int rootX, int rootY, int *newX, int *newY); /* 42 */
+ MacDrawable * (*tkMacOSXContainerId) (TkWindow *winPtr); /* 43 */
+ MacDrawable * (*tkMacOSXGetHostToplevel) (TkWindow *winPtr); /* 44 */
+ void (*tkMacOSXPreprocessMenu) (void); /* 45 */
+ int (*tkpIsWindowFloating) (VOID *window); /* 46 */
+ Tk_Window (*tkMacOSXGetCapture) (void); /* 47 */
VOID *reserved48;
- Window (*tkGetTransientMaster) _ANSI_ARGS_((TkWindow *winPtr)); /* 49 */
- int (*tkGenerateButtonEvent) _ANSI_ARGS_((int x, int y, Window window, unsigned int state)); /* 50 */
- void (*tkGenWMDestroyEvent) _ANSI_ARGS_((Tk_Window tkwin)); /* 51 */
+ Window (*tkGetTransientMaster) (TkWindow *winPtr); /* 49 */
+ int (*tkGenerateButtonEvent) (int x, int y, Window window, unsigned int state); /* 50 */
+ void (*tkGenWMDestroyEvent) (Tk_Window tkwin); /* 51 */
VOID *reserved52;
- unsigned long (*tkpGetMS) _ANSI_ARGS_((void)); /* 53 */
+ unsigned long (*tkpGetMS) (void); /* 53 */
+ VOID * (*tkMacOSXDrawable) (Drawable drawable); /* 54 */
#endif /* AQUA */
#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
- void (*tkCreateXEventSource) _ANSI_ARGS_((void)); /* 0 */
- void (*tkFreeWindowId) _ANSI_ARGS_((TkDisplay *dispPtr, Window w)); /* 1 */
- void (*tkInitXId) _ANSI_ARGS_((TkDisplay *dispPtr)); /* 2 */
- int (*tkpCmapStressed) _ANSI_ARGS_((Tk_Window tkwin, Colormap colormap)); /* 3 */
- void (*tkpSync) _ANSI_ARGS_((Display *display)); /* 4 */
- Window (*tkUnixContainerId) _ANSI_ARGS_((TkWindow *winPtr)); /* 5 */
- int (*tkUnixDoOneXEvent) _ANSI_ARGS_((Tcl_Time *timePtr)); /* 6 */
- void (*tkUnixSetMenubar) _ANSI_ARGS_((Tk_Window tkwin, Tk_Window menubar)); /* 7 */
- int (*tkpScanWindowId) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *string, Window *idPtr)); /* 8 */
- void (*tkWmCleanup) _ANSI_ARGS_((TkDisplay *dispPtr)); /* 9 */
- void (*tkSendCleanup) _ANSI_ARGS_((TkDisplay *dispPtr)); /* 10 */
- void (*tkFreeXId) _ANSI_ARGS_((TkDisplay *dispPtr)); /* 11 */
- int (*tkpWmSetState) _ANSI_ARGS_((TkWindow *winPtr, int state)); /* 12 */
+ void (*tkCreateXEventSource) (void); /* 0 */
+ void (*tkFreeWindowId) (TkDisplay *dispPtr, Window w); /* 1 */
+ void (*tkInitXId) (TkDisplay *dispPtr); /* 2 */
+ int (*tkpCmapStressed) (Tk_Window tkwin, Colormap colormap); /* 3 */
+ void (*tkpSync) (Display *display); /* 4 */
+ Window (*tkUnixContainerId) (TkWindow *winPtr); /* 5 */
+ int (*tkUnixDoOneXEvent) (Tcl_Time *timePtr); /* 6 */
+ void (*tkUnixSetMenubar) (Tk_Window tkwin, Tk_Window menubar); /* 7 */
+ int (*tkpScanWindowId) (Tcl_Interp *interp, CONST char *string, Window *idPtr); /* 8 */
+ void (*tkWmCleanup) (TkDisplay *dispPtr); /* 9 */
+ void (*tkSendCleanup) (TkDisplay *dispPtr); /* 10 */
+ void (*tkFreeXId) (TkDisplay *dispPtr); /* 11 */
+ int (*tkpWmSetState) (TkWindow *winPtr, int state); /* 12 */
+ int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int argc, CONST char **argv); /* 13 */
#endif /* X11 */
} TkIntPlatStubs;
@@ -620,6 +923,10 @@ extern TkIntPlatStubs *tkIntPlatStubsPtr;
#define TkSendCleanup \
(tkIntPlatStubsPtr->tkSendCleanup) /* 44 */
#endif
+#ifndef TkpTestsendCmd
+#define TkpTestsendCmd \
+ (tkIntPlatStubsPtr->tkpTestsendCmd) /* 45 */
+#endif
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
#ifndef TkGenerateActivateEvents
@@ -814,6 +1121,10 @@ extern TkIntPlatStubs *tkIntPlatStubsPtr;
#define TkpGetMS \
(tkIntPlatStubsPtr->tkpGetMS) /* 53 */
#endif
+#ifndef TkMacOSXDrawable
+#define TkMacOSXDrawable \
+ (tkIntPlatStubsPtr->tkMacOSXDrawable) /* 54 */
+#endif
#endif /* AQUA */
#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
#ifndef TkCreateXEventSource
@@ -868,6 +1179,10 @@ extern TkIntPlatStubs *tkIntPlatStubsPtr;
#define TkpWmSetState \
(tkIntPlatStubsPtr->tkpWmSetState) /* 12 */
#endif
+#ifndef TkpTestsendCmd
+#define TkpTestsendCmd \
+ (tkIntPlatStubsPtr->tkpTestsendCmd) /* 13 */
+#endif
#endif /* X11 */
#endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */
@@ -883,5 +1198,11 @@ extern TkIntPlatStubs *tkIntPlatStubsPtr;
void TkInitXId(TkDisplay *dispPtr);
#endif
+#ifdef __WIN32__
+#undef TkpCmapStressed
+#undef TkpSync
+#define TkpCmapStressed(tkwin,colormap) (0)
+#define TkpSync(display)
+#endif
#endif /* _TKINTPLATDECLS */
diff --git a/generic/tkIntXlibDecls.h b/generic/tkIntXlibDecls.h
index fc12521..1357ceb 100644
--- a/generic/tkIntXlibDecls.h
+++ b/generic/tkIntXlibDecls.h
@@ -19,7 +19,11 @@
* in the generic/tkInt.decls script.
*/
+#ifdef MAC_TCL
+#include "Xutil.h"
+#else
#include "X11/Xutil.h"
+#endif
#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
@@ -37,641 +41,1199 @@ typedef int (*XAfterFunction) ( /* WARNING, this type not in Xlib spec */
*/
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#ifndef XSetDashes_TCL_DECLARED
+#define XSetDashes_TCL_DECLARED
/* 0 */
-EXTERN int XSetDashes _ANSI_ARGS_((Display *display, GC gc,
- int dash_offset, _Xconst char *dash_list,
- int n));
+EXTERN int XSetDashes(Display *display, GC gc, int dash_offset,
+ _Xconst char *dash_list, int n);
+#endif
+#ifndef XGetModifierMapping_TCL_DECLARED
+#define XGetModifierMapping_TCL_DECLARED
/* 1 */
-EXTERN XModifierKeymap * XGetModifierMapping _ANSI_ARGS_((Display *d));
+EXTERN XModifierKeymap * XGetModifierMapping(Display *d);
+#endif
+#ifndef XCreateImage_TCL_DECLARED
+#define XCreateImage_TCL_DECLARED
/* 2 */
-EXTERN XImage * XCreateImage _ANSI_ARGS_((Display *d, Visual *v,
- unsigned int ui1, int i1, int i2, char *cp,
- unsigned int ui2, unsigned int ui3, int i3,
- int i4));
+EXTERN XImage * XCreateImage(Display *d, Visual *v, unsigned int ui1,
+ int i1, int i2, char *cp, unsigned int ui2,
+ unsigned int ui3, int i3, int i4);
+#endif
+#ifndef XGetImage_TCL_DECLARED
+#define XGetImage_TCL_DECLARED
/* 3 */
-EXTERN XImage * XGetImage _ANSI_ARGS_((Display *d, Drawable dr,
- int i1, int i2, unsigned int ui1,
- unsigned int ui2, unsigned long ul, int i3));
+EXTERN XImage * XGetImage(Display *d, Drawable dr, int i1, int i2,
+ unsigned int ui1, unsigned int ui2,
+ unsigned long ul, int i3);
+#endif
+#ifndef XGetAtomName_TCL_DECLARED
+#define XGetAtomName_TCL_DECLARED
/* 4 */
-EXTERN char * XGetAtomName _ANSI_ARGS_((Display *d, Atom a));
+EXTERN char * XGetAtomName(Display *d, Atom a);
+#endif
+#ifndef XKeysymToString_TCL_DECLARED
+#define XKeysymToString_TCL_DECLARED
/* 5 */
-EXTERN char * XKeysymToString _ANSI_ARGS_((KeySym k));
+EXTERN char * XKeysymToString(KeySym k);
+#endif
+#ifndef XCreateColormap_TCL_DECLARED
+#define XCreateColormap_TCL_DECLARED
/* 6 */
-EXTERN Colormap XCreateColormap _ANSI_ARGS_((Display *d, Window w,
- Visual *v, int i));
+EXTERN Colormap XCreateColormap(Display *d, Window w, Visual *v,
+ int i);
+#endif
+#ifndef XCreatePixmapCursor_TCL_DECLARED
+#define XCreatePixmapCursor_TCL_DECLARED
/* 7 */
-EXTERN Cursor XCreatePixmapCursor _ANSI_ARGS_((Display *d,
- Pixmap p1, Pixmap p2, XColor *x1, XColor *x2,
- unsigned int ui1, unsigned int ui2));
+EXTERN Cursor XCreatePixmapCursor(Display *d, Pixmap p1, Pixmap p2,
+ XColor *x1, XColor *x2, unsigned int ui1,
+ unsigned int ui2);
+#endif
+#ifndef XCreateGlyphCursor_TCL_DECLARED
+#define XCreateGlyphCursor_TCL_DECLARED
/* 8 */
-EXTERN Cursor XCreateGlyphCursor _ANSI_ARGS_((Display *d, Font f1,
- Font f2, unsigned int ui1, unsigned int ui2,
- XColor _Xconst *x1, XColor _Xconst *x2));
+EXTERN Cursor XCreateGlyphCursor(Display *d, Font f1, Font f2,
+ unsigned int ui1, unsigned int ui2,
+ XColor _Xconst *x1, XColor _Xconst *x2);
+#endif
+#ifndef XGContextFromGC_TCL_DECLARED
+#define XGContextFromGC_TCL_DECLARED
/* 9 */
-EXTERN GContext XGContextFromGC _ANSI_ARGS_((GC g));
+EXTERN GContext XGContextFromGC(GC g);
+#endif
+#ifndef XListHosts_TCL_DECLARED
+#define XListHosts_TCL_DECLARED
/* 10 */
-EXTERN XHostAddress * XListHosts _ANSI_ARGS_((Display *d, int *i, Bool *b));
+EXTERN XHostAddress * XListHosts(Display *d, int *i, Bool *b);
+#endif
+#ifndef XKeycodeToKeysym_TCL_DECLARED
+#define XKeycodeToKeysym_TCL_DECLARED
/* 11 */
-EXTERN KeySym XKeycodeToKeysym _ANSI_ARGS_((Display *d,
- unsigned int k, int i));
+EXTERN KeySym XKeycodeToKeysym(Display *d, unsigned int k, int i);
+#endif
+#ifndef XStringToKeysym_TCL_DECLARED
+#define XStringToKeysym_TCL_DECLARED
/* 12 */
-EXTERN KeySym XStringToKeysym _ANSI_ARGS_((_Xconst char *c));
+EXTERN KeySym XStringToKeysym(_Xconst char *c);
+#endif
+#ifndef XRootWindow_TCL_DECLARED
+#define XRootWindow_TCL_DECLARED
/* 13 */
-EXTERN Window XRootWindow _ANSI_ARGS_((Display *d, int i));
+EXTERN Window XRootWindow(Display *d, int i);
+#endif
+#ifndef XSetErrorHandler_TCL_DECLARED
+#define XSetErrorHandler_TCL_DECLARED
/* 14 */
-EXTERN XErrorHandler XSetErrorHandler _ANSI_ARGS_((XErrorHandler x));
+EXTERN XErrorHandler XSetErrorHandler(XErrorHandler x);
+#endif
+#ifndef XIconifyWindow_TCL_DECLARED
+#define XIconifyWindow_TCL_DECLARED
/* 15 */
-EXTERN Status XIconifyWindow _ANSI_ARGS_((Display *d, Window w,
- int i));
+EXTERN Status XIconifyWindow(Display *d, Window w, int i);
+#endif
+#ifndef XWithdrawWindow_TCL_DECLARED
+#define XWithdrawWindow_TCL_DECLARED
/* 16 */
-EXTERN Status XWithdrawWindow _ANSI_ARGS_((Display *d, Window w,
- int i));
+EXTERN Status XWithdrawWindow(Display *d, Window w, int i);
+#endif
+#ifndef XGetWMColormapWindows_TCL_DECLARED
+#define XGetWMColormapWindows_TCL_DECLARED
/* 17 */
-EXTERN Status XGetWMColormapWindows _ANSI_ARGS_((Display *d,
- Window w, Window **wpp, int *ip));
+EXTERN Status XGetWMColormapWindows(Display *d, Window w,
+ Window **wpp, int *ip);
+#endif
+#ifndef XAllocColor_TCL_DECLARED
+#define XAllocColor_TCL_DECLARED
/* 18 */
-EXTERN Status XAllocColor _ANSI_ARGS_((Display *d, Colormap c,
- XColor *xp));
+EXTERN Status XAllocColor(Display *d, Colormap c, XColor *xp);
+#endif
+#ifndef XBell_TCL_DECLARED
+#define XBell_TCL_DECLARED
/* 19 */
-EXTERN int XBell _ANSI_ARGS_((Display *d, int i));
+EXTERN int XBell(Display *d, int i);
+#endif
+#ifndef XChangeProperty_TCL_DECLARED
+#define XChangeProperty_TCL_DECLARED
/* 20 */
-EXTERN int XChangeProperty _ANSI_ARGS_((Display *d, Window w,
- Atom a1, Atom a2, int i1, int i2,
- _Xconst unsigned char *c, int i3));
+EXTERN int XChangeProperty(Display *d, Window w, Atom a1,
+ Atom a2, int i1, int i2,
+ _Xconst unsigned char *c, int i3);
+#endif
+#ifndef XChangeWindowAttributes_TCL_DECLARED
+#define XChangeWindowAttributes_TCL_DECLARED
/* 21 */
-EXTERN int XChangeWindowAttributes _ANSI_ARGS_((Display *d,
- Window w, unsigned long ul,
- XSetWindowAttributes *x));
+EXTERN int XChangeWindowAttributes(Display *d, Window w,
+ unsigned long ul, XSetWindowAttributes *x);
+#endif
+#ifndef XClearWindow_TCL_DECLARED
+#define XClearWindow_TCL_DECLARED
/* 22 */
-EXTERN int XClearWindow _ANSI_ARGS_((Display *d, Window w));
+EXTERN int XClearWindow(Display *d, Window w);
+#endif
+#ifndef XConfigureWindow_TCL_DECLARED
+#define XConfigureWindow_TCL_DECLARED
/* 23 */
-EXTERN int XConfigureWindow _ANSI_ARGS_((Display *d, Window w,
- unsigned int i, XWindowChanges *x));
+EXTERN int XConfigureWindow(Display *d, Window w,
+ unsigned int i, XWindowChanges *x);
+#endif
+#ifndef XCopyArea_TCL_DECLARED
+#define XCopyArea_TCL_DECLARED
/* 24 */
-EXTERN int XCopyArea _ANSI_ARGS_((Display *d, Drawable dr1,
- Drawable dr2, GC g, int i1, int i2,
- unsigned int ui1, unsigned int ui2, int i3,
- int i4));
+EXTERN int XCopyArea(Display *d, Drawable dr1, Drawable dr2,
+ GC g, int i1, int i2, unsigned int ui1,
+ unsigned int ui2, int i3, int i4);
+#endif
+#ifndef XCopyPlane_TCL_DECLARED
+#define XCopyPlane_TCL_DECLARED
/* 25 */
-EXTERN int XCopyPlane _ANSI_ARGS_((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));
+EXTERN int XCopyPlane(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);
+#endif
+#ifndef XCreateBitmapFromData_TCL_DECLARED
+#define XCreateBitmapFromData_TCL_DECLARED
/* 26 */
-EXTERN Pixmap XCreateBitmapFromData _ANSI_ARGS_((Display *display,
- Drawable d, _Xconst char *data,
- unsigned int width, unsigned int height));
+EXTERN Pixmap XCreateBitmapFromData(Display *display, Drawable d,
+ _Xconst char *data, unsigned int width,
+ unsigned int height);
+#endif
+#ifndef XDefineCursor_TCL_DECLARED
+#define XDefineCursor_TCL_DECLARED
/* 27 */
-EXTERN int XDefineCursor _ANSI_ARGS_((Display *d, Window w,
- Cursor c));
+EXTERN int XDefineCursor(Display *d, Window w, Cursor c);
+#endif
+#ifndef XDeleteProperty_TCL_DECLARED
+#define XDeleteProperty_TCL_DECLARED
/* 28 */
-EXTERN int XDeleteProperty _ANSI_ARGS_((Display *d, Window w,
- Atom a));
+EXTERN int XDeleteProperty(Display *d, Window w, Atom a);
+#endif
+#ifndef XDestroyWindow_TCL_DECLARED
+#define XDestroyWindow_TCL_DECLARED
/* 29 */
-EXTERN int XDestroyWindow _ANSI_ARGS_((Display *d, Window w));
+EXTERN int XDestroyWindow(Display *d, Window w);
+#endif
+#ifndef XDrawArc_TCL_DECLARED
+#define XDrawArc_TCL_DECLARED
/* 30 */
-EXTERN int XDrawArc _ANSI_ARGS_((Display *d, Drawable dr, GC g,
- int i1, int i2, unsigned int ui1,
- unsigned int ui2, int i3, int i4));
+EXTERN int XDrawArc(Display *d, Drawable dr, GC g, int i1,
+ int i2, unsigned int ui1, unsigned int ui2,
+ int i3, int i4);
+#endif
+#ifndef XDrawLines_TCL_DECLARED
+#define XDrawLines_TCL_DECLARED
/* 31 */
-EXTERN int XDrawLines _ANSI_ARGS_((Display *d, Drawable dr,
- GC g, XPoint *x, int i1, int i2));
+EXTERN int XDrawLines(Display *d, Drawable dr, GC g, XPoint *x,
+ int i1, int i2);
+#endif
+#ifndef XDrawRectangle_TCL_DECLARED
+#define XDrawRectangle_TCL_DECLARED
/* 32 */
-EXTERN int XDrawRectangle _ANSI_ARGS_((Display *d, Drawable dr,
- GC g, int i1, int i2, unsigned int ui1,
- unsigned int ui2));
+EXTERN int XDrawRectangle(Display *d, Drawable dr, GC g, int i1,
+ int i2, unsigned int ui1, unsigned int ui2);
+#endif
+#ifndef XFillArc_TCL_DECLARED
+#define XFillArc_TCL_DECLARED
/* 33 */
-EXTERN int XFillArc _ANSI_ARGS_((Display *d, Drawable dr, GC g,
- int i1, int i2, unsigned int ui1,
- unsigned int ui2, int i3, int i4));
+EXTERN int XFillArc(Display *d, Drawable dr, GC g, int i1,
+ int i2, unsigned int ui1, unsigned int ui2,
+ int i3, int i4);
+#endif
+#ifndef XFillPolygon_TCL_DECLARED
+#define XFillPolygon_TCL_DECLARED
/* 34 */
-EXTERN int XFillPolygon _ANSI_ARGS_((Display *d, Drawable dr,
- GC g, XPoint *x, int i1, int i2, int i3));
+EXTERN int XFillPolygon(Display *d, Drawable dr, GC g,
+ XPoint *x, int i1, int i2, int i3);
+#endif
+#ifndef XFillRectangles_TCL_DECLARED
+#define XFillRectangles_TCL_DECLARED
/* 35 */
-EXTERN int XFillRectangles _ANSI_ARGS_((Display *d, Drawable dr,
- GC g, XRectangle *x, int i));
+EXTERN int XFillRectangles(Display *d, Drawable dr, GC g,
+ XRectangle *x, int i);
+#endif
+#ifndef XForceScreenSaver_TCL_DECLARED
+#define XForceScreenSaver_TCL_DECLARED
/* 36 */
-EXTERN int XForceScreenSaver _ANSI_ARGS_((Display *d, int i));
+EXTERN int XForceScreenSaver(Display *d, int i);
+#endif
+#ifndef XFreeColormap_TCL_DECLARED
+#define XFreeColormap_TCL_DECLARED
/* 37 */
-EXTERN int XFreeColormap _ANSI_ARGS_((Display *d, Colormap c));
+EXTERN int XFreeColormap(Display *d, Colormap c);
+#endif
+#ifndef XFreeColors_TCL_DECLARED
+#define XFreeColors_TCL_DECLARED
/* 38 */
-EXTERN int XFreeColors _ANSI_ARGS_((Display *d, Colormap c,
- unsigned long *ulp, int i, unsigned long ul));
+EXTERN int XFreeColors(Display *d, Colormap c,
+ unsigned long *ulp, int i, unsigned long ul);
+#endif
+#ifndef XFreeCursor_TCL_DECLARED
+#define XFreeCursor_TCL_DECLARED
/* 39 */
-EXTERN int XFreeCursor _ANSI_ARGS_((Display *d, Cursor c));
+EXTERN int XFreeCursor(Display *d, Cursor c);
+#endif
+#ifndef XFreeModifiermap_TCL_DECLARED
+#define XFreeModifiermap_TCL_DECLARED
/* 40 */
-EXTERN int XFreeModifiermap _ANSI_ARGS_((XModifierKeymap *x));
+EXTERN int XFreeModifiermap(XModifierKeymap *x);
+#endif
+#ifndef XGetGeometry_TCL_DECLARED
+#define XGetGeometry_TCL_DECLARED
/* 41 */
-EXTERN Status XGetGeometry _ANSI_ARGS_((Display *d, Drawable dr,
- Window *w, int *i1, int *i2,
- unsigned int *ui1, unsigned int *ui2,
- unsigned int *ui3, unsigned int *ui4));
+EXTERN Status XGetGeometry(Display *d, Drawable dr, Window *w,
+ int *i1, int *i2, unsigned int *ui1,
+ unsigned int *ui2, unsigned int *ui3,
+ unsigned int *ui4);
+#endif
+#ifndef XGetInputFocus_TCL_DECLARED
+#define XGetInputFocus_TCL_DECLARED
/* 42 */
-EXTERN int XGetInputFocus _ANSI_ARGS_((Display *d, Window *w,
- int *i));
+EXTERN int XGetInputFocus(Display *d, Window *w, int *i);
+#endif
+#ifndef XGetWindowProperty_TCL_DECLARED
+#define XGetWindowProperty_TCL_DECLARED
/* 43 */
-EXTERN int XGetWindowProperty _ANSI_ARGS_((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));
+EXTERN int XGetWindowProperty(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);
+#endif
+#ifndef XGetWindowAttributes_TCL_DECLARED
+#define XGetWindowAttributes_TCL_DECLARED
/* 44 */
-EXTERN Status XGetWindowAttributes _ANSI_ARGS_((Display *d,
- Window w, XWindowAttributes *x));
+EXTERN Status XGetWindowAttributes(Display *d, Window w,
+ XWindowAttributes *x);
+#endif
+#ifndef XGrabKeyboard_TCL_DECLARED
+#define XGrabKeyboard_TCL_DECLARED
/* 45 */
-EXTERN int XGrabKeyboard _ANSI_ARGS_((Display *d, Window w,
- Bool b, int i1, int i2, Time t));
+EXTERN int XGrabKeyboard(Display *d, Window w, Bool b, int i1,
+ int i2, Time t);
+#endif
+#ifndef XGrabPointer_TCL_DECLARED
+#define XGrabPointer_TCL_DECLARED
/* 46 */
-EXTERN int XGrabPointer _ANSI_ARGS_((Display *d, Window w1,
- Bool b, unsigned int ui, int i1, int i2,
- Window w2, Cursor c, Time t));
+EXTERN int XGrabPointer(Display *d, Window w1, Bool b,
+ unsigned int ui, int i1, int i2, Window w2,
+ Cursor c, Time t);
+#endif
+#ifndef XKeysymToKeycode_TCL_DECLARED
+#define XKeysymToKeycode_TCL_DECLARED
/* 47 */
-EXTERN KeyCode XKeysymToKeycode _ANSI_ARGS_((Display *d, KeySym k));
+EXTERN KeyCode XKeysymToKeycode(Display *d, KeySym k);
+#endif
+#ifndef XLookupColor_TCL_DECLARED
+#define XLookupColor_TCL_DECLARED
/* 48 */
-EXTERN Status XLookupColor _ANSI_ARGS_((Display *d, Colormap c1,
- _Xconst char *c2, XColor *x1, XColor *x2));
+EXTERN Status XLookupColor(Display *d, Colormap c1,
+ _Xconst char *c2, XColor *x1, XColor *x2);
+#endif
+#ifndef XMapWindow_TCL_DECLARED
+#define XMapWindow_TCL_DECLARED
/* 49 */
-EXTERN int XMapWindow _ANSI_ARGS_((Display *d, Window w));
+EXTERN int XMapWindow(Display *d, Window w);
+#endif
+#ifndef XMoveResizeWindow_TCL_DECLARED
+#define XMoveResizeWindow_TCL_DECLARED
/* 50 */
-EXTERN int XMoveResizeWindow _ANSI_ARGS_((Display *d, Window w,
- int i1, int i2, unsigned int ui1,
- unsigned int ui2));
+EXTERN int XMoveResizeWindow(Display *d, Window w, int i1,
+ int i2, unsigned int ui1, unsigned int ui2);
+#endif
+#ifndef XMoveWindow_TCL_DECLARED
+#define XMoveWindow_TCL_DECLARED
/* 51 */
-EXTERN int XMoveWindow _ANSI_ARGS_((Display *d, Window w,
- int i1, int i2));
+EXTERN int XMoveWindow(Display *d, Window w, int i1, int i2);
+#endif
+#ifndef XNextEvent_TCL_DECLARED
+#define XNextEvent_TCL_DECLARED
/* 52 */
-EXTERN int XNextEvent _ANSI_ARGS_((Display *d, XEvent *x));
+EXTERN int XNextEvent(Display *d, XEvent *x);
+#endif
+#ifndef XPutBackEvent_TCL_DECLARED
+#define XPutBackEvent_TCL_DECLARED
/* 53 */
-EXTERN int XPutBackEvent _ANSI_ARGS_((Display *d, XEvent *x));
+EXTERN int XPutBackEvent(Display *d, XEvent *x);
+#endif
+#ifndef XQueryColors_TCL_DECLARED
+#define XQueryColors_TCL_DECLARED
/* 54 */
-EXTERN int XQueryColors _ANSI_ARGS_((Display *d, Colormap c,
- XColor *x, int i));
+EXTERN int XQueryColors(Display *d, Colormap c, XColor *x,
+ int i);
+#endif
+#ifndef XQueryPointer_TCL_DECLARED
+#define XQueryPointer_TCL_DECLARED
/* 55 */
-EXTERN Bool XQueryPointer _ANSI_ARGS_((Display *d, Window w1,
- Window *w2, Window *w3, int *i1, int *i2,
- int *i3, int *i4, unsigned int *ui));
+EXTERN Bool XQueryPointer(Display *d, Window w1, Window *w2,
+ Window *w3, int *i1, int *i2, int *i3,
+ int *i4, unsigned int *ui);
+#endif
+#ifndef XQueryTree_TCL_DECLARED
+#define XQueryTree_TCL_DECLARED
/* 56 */
-EXTERN Status XQueryTree _ANSI_ARGS_((Display *d, Window w1,
- Window *w2, Window *w3, Window **w4,
- unsigned int *ui));
+EXTERN Status XQueryTree(Display *d, Window w1, Window *w2,
+ Window *w3, Window **w4, unsigned int *ui);
+#endif
+#ifndef XRaiseWindow_TCL_DECLARED
+#define XRaiseWindow_TCL_DECLARED
/* 57 */
-EXTERN int XRaiseWindow _ANSI_ARGS_((Display *d, Window w));
+EXTERN int XRaiseWindow(Display *d, Window w);
+#endif
+#ifndef XRefreshKeyboardMapping_TCL_DECLARED
+#define XRefreshKeyboardMapping_TCL_DECLARED
/* 58 */
-EXTERN int XRefreshKeyboardMapping _ANSI_ARGS_((
- XMappingEvent *x));
+EXTERN int XRefreshKeyboardMapping(XMappingEvent *x);
+#endif
+#ifndef XResizeWindow_TCL_DECLARED
+#define XResizeWindow_TCL_DECLARED
/* 59 */
-EXTERN int XResizeWindow _ANSI_ARGS_((Display *d, Window w,
- unsigned int ui1, unsigned int ui2));
+EXTERN int XResizeWindow(Display *d, Window w, unsigned int ui1,
+ unsigned int ui2);
+#endif
+#ifndef XSelectInput_TCL_DECLARED
+#define XSelectInput_TCL_DECLARED
/* 60 */
-EXTERN int XSelectInput _ANSI_ARGS_((Display *d, Window w,
- long l));
+EXTERN int XSelectInput(Display *d, Window w, long l);
+#endif
+#ifndef XSendEvent_TCL_DECLARED
+#define XSendEvent_TCL_DECLARED
/* 61 */
-EXTERN Status XSendEvent _ANSI_ARGS_((Display *d, Window w, Bool b,
- long l, XEvent *x));
+EXTERN Status XSendEvent(Display *d, Window w, Bool b, long l,
+ XEvent *x);
+#endif
+#ifndef XSetCommand_TCL_DECLARED
+#define XSetCommand_TCL_DECLARED
/* 62 */
-EXTERN int XSetCommand _ANSI_ARGS_((Display *d, Window w,
- char **c, int i));
+EXTERN int XSetCommand(Display *d, Window w, char **c, int i);
+#endif
+#ifndef XSetIconName_TCL_DECLARED
+#define XSetIconName_TCL_DECLARED
/* 63 */
-EXTERN int XSetIconName _ANSI_ARGS_((Display *d, Window w,
- _Xconst char *c));
+EXTERN int XSetIconName(Display *d, Window w, _Xconst char *c);
+#endif
+#ifndef XSetInputFocus_TCL_DECLARED
+#define XSetInputFocus_TCL_DECLARED
/* 64 */
-EXTERN int XSetInputFocus _ANSI_ARGS_((Display *d, Window w,
- int i, Time t));
+EXTERN int XSetInputFocus(Display *d, Window w, int i, Time t);
+#endif
+#ifndef XSetSelectionOwner_TCL_DECLARED
+#define XSetSelectionOwner_TCL_DECLARED
/* 65 */
-EXTERN int XSetSelectionOwner _ANSI_ARGS_((Display *d, Atom a,
- Window w, Time t));
+EXTERN int XSetSelectionOwner(Display *d, Atom a, Window w,
+ Time t);
+#endif
+#ifndef XSetWindowBackground_TCL_DECLARED
+#define XSetWindowBackground_TCL_DECLARED
/* 66 */
-EXTERN int XSetWindowBackground _ANSI_ARGS_((Display *d,
- Window w, unsigned long ul));
+EXTERN int XSetWindowBackground(Display *d, Window w,
+ unsigned long ul);
+#endif
+#ifndef XSetWindowBackgroundPixmap_TCL_DECLARED
+#define XSetWindowBackgroundPixmap_TCL_DECLARED
/* 67 */
-EXTERN int XSetWindowBackgroundPixmap _ANSI_ARGS_((Display *d,
- Window w, Pixmap p));
+EXTERN int XSetWindowBackgroundPixmap(Display *d, Window w,
+ Pixmap p);
+#endif
+#ifndef XSetWindowBorder_TCL_DECLARED
+#define XSetWindowBorder_TCL_DECLARED
/* 68 */
-EXTERN int XSetWindowBorder _ANSI_ARGS_((Display *d, Window w,
- unsigned long ul));
+EXTERN int XSetWindowBorder(Display *d, Window w,
+ unsigned long ul);
+#endif
+#ifndef XSetWindowBorderPixmap_TCL_DECLARED
+#define XSetWindowBorderPixmap_TCL_DECLARED
/* 69 */
-EXTERN int XSetWindowBorderPixmap _ANSI_ARGS_((Display *d,
- Window w, Pixmap p));
+EXTERN int XSetWindowBorderPixmap(Display *d, Window w,
+ Pixmap p);
+#endif
+#ifndef XSetWindowBorderWidth_TCL_DECLARED
+#define XSetWindowBorderWidth_TCL_DECLARED
/* 70 */
-EXTERN int XSetWindowBorderWidth _ANSI_ARGS_((Display *d,
- Window w, unsigned int ui));
+EXTERN int XSetWindowBorderWidth(Display *d, Window w,
+ unsigned int ui);
+#endif
+#ifndef XSetWindowColormap_TCL_DECLARED
+#define XSetWindowColormap_TCL_DECLARED
/* 71 */
-EXTERN int XSetWindowColormap _ANSI_ARGS_((Display *d, Window w,
- Colormap c));
+EXTERN int XSetWindowColormap(Display *d, Window w, Colormap c);
+#endif
+#ifndef XTranslateCoordinates_TCL_DECLARED
+#define XTranslateCoordinates_TCL_DECLARED
/* 72 */
-EXTERN Bool XTranslateCoordinates _ANSI_ARGS_((Display *d,
- Window w1, Window w2, int i1, int i2,
- int *i3, int *i4, Window *w3));
+EXTERN Bool XTranslateCoordinates(Display *d, Window w1,
+ Window w2, int i1, int i2, int *i3, int *i4,
+ Window *w3);
+#endif
+#ifndef XUngrabKeyboard_TCL_DECLARED
+#define XUngrabKeyboard_TCL_DECLARED
/* 73 */
-EXTERN int XUngrabKeyboard _ANSI_ARGS_((Display *d, Time t));
+EXTERN int XUngrabKeyboard(Display *d, Time t);
+#endif
+#ifndef XUngrabPointer_TCL_DECLARED
+#define XUngrabPointer_TCL_DECLARED
/* 74 */
-EXTERN int XUngrabPointer _ANSI_ARGS_((Display *d, Time t));
+EXTERN int XUngrabPointer(Display *d, Time t);
+#endif
+#ifndef XUnmapWindow_TCL_DECLARED
+#define XUnmapWindow_TCL_DECLARED
/* 75 */
-EXTERN int XUnmapWindow _ANSI_ARGS_((Display *d, Window w));
+EXTERN int XUnmapWindow(Display *d, Window w);
+#endif
+#ifndef XWindowEvent_TCL_DECLARED
+#define XWindowEvent_TCL_DECLARED
/* 76 */
-EXTERN int XWindowEvent _ANSI_ARGS_((Display *d, Window w,
- long l, XEvent *x));
+EXTERN int XWindowEvent(Display *d, Window w, long l, XEvent *x);
+#endif
+#ifndef XDestroyIC_TCL_DECLARED
+#define XDestroyIC_TCL_DECLARED
/* 77 */
-EXTERN void XDestroyIC _ANSI_ARGS_((XIC x));
+EXTERN void XDestroyIC(XIC x);
+#endif
+#ifndef XFilterEvent_TCL_DECLARED
+#define XFilterEvent_TCL_DECLARED
/* 78 */
-EXTERN Bool XFilterEvent _ANSI_ARGS_((XEvent *x, Window w));
+EXTERN Bool XFilterEvent(XEvent *x, Window w);
+#endif
+#ifndef XmbLookupString_TCL_DECLARED
+#define XmbLookupString_TCL_DECLARED
/* 79 */
-EXTERN int XmbLookupString _ANSI_ARGS_((XIC xi,
- XKeyPressedEvent *xk, char *c, int i,
- KeySym *k, Status *s));
+EXTERN int XmbLookupString(XIC xi, XKeyPressedEvent *xk,
+ char *c, int i, KeySym *k, Status *s);
+#endif
+#ifndef TkPutImage_TCL_DECLARED
+#define TkPutImage_TCL_DECLARED
/* 80 */
-EXTERN int TkPutImage _ANSI_ARGS_((unsigned long *colors,
- int ncolors, Display *display, Drawable d,
- GC gc, XImage *image, int src_x, int src_y,
+EXTERN int TkPutImage(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));
+ unsigned int height);
+#endif
/* Slot 81 is reserved */
+#ifndef XParseColor_TCL_DECLARED
+#define XParseColor_TCL_DECLARED
/* 82 */
-EXTERN Status XParseColor _ANSI_ARGS_((Display *display,
- Colormap map, _Xconst char *spec,
- XColor *colorPtr));
+EXTERN Status XParseColor(Display *display, Colormap map,
+ _Xconst char *spec, XColor *colorPtr);
+#endif
+#ifndef XCreateGC_TCL_DECLARED
+#define XCreateGC_TCL_DECLARED
/* 83 */
-EXTERN GC XCreateGC _ANSI_ARGS_((Display *display, Drawable d,
- unsigned long valuemask, XGCValues *values));
+EXTERN GC XCreateGC(Display *display, Drawable d,
+ unsigned long valuemask, XGCValues *values);
+#endif
+#ifndef XFreeGC_TCL_DECLARED
+#define XFreeGC_TCL_DECLARED
/* 84 */
-EXTERN int XFreeGC _ANSI_ARGS_((Display *display, GC gc));
+EXTERN int XFreeGC(Display *display, GC gc);
+#endif
+#ifndef XInternAtom_TCL_DECLARED
+#define XInternAtom_TCL_DECLARED
/* 85 */
-EXTERN Atom XInternAtom _ANSI_ARGS_((Display *display,
- _Xconst char *atom_name, Bool only_if_exists));
+EXTERN Atom XInternAtom(Display *display,
+ _Xconst char *atom_name, Bool only_if_exists);
+#endif
+#ifndef XSetBackground_TCL_DECLARED
+#define XSetBackground_TCL_DECLARED
/* 86 */
-EXTERN int XSetBackground _ANSI_ARGS_((Display *display, GC gc,
- unsigned long foreground));
+EXTERN int XSetBackground(Display *display, GC gc,
+ unsigned long foreground);
+#endif
+#ifndef XSetForeground_TCL_DECLARED
+#define XSetForeground_TCL_DECLARED
/* 87 */
-EXTERN int XSetForeground _ANSI_ARGS_((Display *display, GC gc,
- unsigned long foreground));
+EXTERN int XSetForeground(Display *display, GC gc,
+ unsigned long foreground);
+#endif
+#ifndef XSetClipMask_TCL_DECLARED
+#define XSetClipMask_TCL_DECLARED
/* 88 */
-EXTERN int XSetClipMask _ANSI_ARGS_((Display *display, GC gc,
- Pixmap pixmap));
+EXTERN int XSetClipMask(Display *display, GC gc, Pixmap pixmap);
+#endif
+#ifndef XSetClipOrigin_TCL_DECLARED
+#define XSetClipOrigin_TCL_DECLARED
/* 89 */
-EXTERN int XSetClipOrigin _ANSI_ARGS_((Display *display, GC gc,
- int clip_x_origin, int clip_y_origin));
+EXTERN int XSetClipOrigin(Display *display, GC gc,
+ int clip_x_origin, int clip_y_origin);
+#endif
+#ifndef XSetTSOrigin_TCL_DECLARED
+#define XSetTSOrigin_TCL_DECLARED
/* 90 */
-EXTERN int XSetTSOrigin _ANSI_ARGS_((Display *display, GC gc,
- int ts_x_origin, int ts_y_origin));
+EXTERN int XSetTSOrigin(Display *display, GC gc,
+ int ts_x_origin, int ts_y_origin);
+#endif
+#ifndef XChangeGC_TCL_DECLARED
+#define XChangeGC_TCL_DECLARED
/* 91 */
-EXTERN int XChangeGC _ANSI_ARGS_((Display *d, GC gc,
- unsigned long mask, XGCValues *values));
+EXTERN int XChangeGC(Display *d, GC gc, unsigned long mask,
+ XGCValues *values);
+#endif
+#ifndef XSetFont_TCL_DECLARED
+#define XSetFont_TCL_DECLARED
/* 92 */
-EXTERN int XSetFont _ANSI_ARGS_((Display *display, GC gc,
- Font font));
+EXTERN int XSetFont(Display *display, GC gc, Font font);
+#endif
+#ifndef XSetArcMode_TCL_DECLARED
+#define XSetArcMode_TCL_DECLARED
/* 93 */
-EXTERN int XSetArcMode _ANSI_ARGS_((Display *display, GC gc,
- int arc_mode));
+EXTERN int XSetArcMode(Display *display, GC gc, int arc_mode);
+#endif
+#ifndef XSetStipple_TCL_DECLARED
+#define XSetStipple_TCL_DECLARED
/* 94 */
-EXTERN int XSetStipple _ANSI_ARGS_((Display *display, GC gc,
- Pixmap stipple));
+EXTERN int XSetStipple(Display *display, GC gc, Pixmap stipple);
+#endif
+#ifndef XSetFillRule_TCL_DECLARED
+#define XSetFillRule_TCL_DECLARED
/* 95 */
-EXTERN int XSetFillRule _ANSI_ARGS_((Display *display, GC gc,
- int fill_rule));
+EXTERN int XSetFillRule(Display *display, GC gc, int fill_rule);
+#endif
+#ifndef XSetFillStyle_TCL_DECLARED
+#define XSetFillStyle_TCL_DECLARED
/* 96 */
-EXTERN int XSetFillStyle _ANSI_ARGS_((Display *display, GC gc,
- int fill_style));
+EXTERN int XSetFillStyle(Display *display, GC gc,
+ int fill_style);
+#endif
+#ifndef XSetFunction_TCL_DECLARED
+#define XSetFunction_TCL_DECLARED
/* 97 */
-EXTERN int XSetFunction _ANSI_ARGS_((Display *display, GC gc,
- int function));
+EXTERN int XSetFunction(Display *display, GC gc, int function);
+#endif
+#ifndef XSetLineAttributes_TCL_DECLARED
+#define XSetLineAttributes_TCL_DECLARED
/* 98 */
-EXTERN int XSetLineAttributes _ANSI_ARGS_((Display *display,
- GC gc, unsigned int line_width,
- int line_style, int cap_style,
- int join_style));
+EXTERN int XSetLineAttributes(Display *display, GC gc,
+ unsigned int line_width, int line_style,
+ int cap_style, int join_style);
+#endif
+#ifndef _XInitImageFuncPtrs_TCL_DECLARED
+#define _XInitImageFuncPtrs_TCL_DECLARED
/* 99 */
-EXTERN int _XInitImageFuncPtrs _ANSI_ARGS_((XImage *image));
+EXTERN int _XInitImageFuncPtrs(XImage *image);
+#endif
+#ifndef XCreateIC_TCL_DECLARED
+#define XCreateIC_TCL_DECLARED
/* 100 */
-EXTERN XIC XCreateIC _ANSI_ARGS_(TCL_VARARGS(XIM,xim));
+EXTERN XIC XCreateIC(XIM xim, ...);
+#endif
+#ifndef XGetVisualInfo_TCL_DECLARED
+#define XGetVisualInfo_TCL_DECLARED
/* 101 */
-EXTERN XVisualInfo * XGetVisualInfo _ANSI_ARGS_((Display *display,
- long vinfo_mask, XVisualInfo *vinfo_template,
- int *nitems_return));
+EXTERN XVisualInfo * XGetVisualInfo(Display *display, long vinfo_mask,
+ XVisualInfo *vinfo_template,
+ int *nitems_return);
+#endif
+#ifndef XSetWMClientMachine_TCL_DECLARED
+#define XSetWMClientMachine_TCL_DECLARED
/* 102 */
-EXTERN void XSetWMClientMachine _ANSI_ARGS_((Display *display,
- Window w, XTextProperty *text_prop));
+EXTERN void XSetWMClientMachine(Display *display, Window w,
+ XTextProperty *text_prop);
+#endif
+#ifndef XStringListToTextProperty_TCL_DECLARED
+#define XStringListToTextProperty_TCL_DECLARED
/* 103 */
-EXTERN Status XStringListToTextProperty _ANSI_ARGS_((char **list,
- int count, XTextProperty *text_prop_return));
+EXTERN Status XStringListToTextProperty(char **list, int count,
+ XTextProperty *text_prop_return);
+#endif
+#ifndef XDrawLine_TCL_DECLARED
+#define XDrawLine_TCL_DECLARED
/* 104 */
-EXTERN int XDrawLine _ANSI_ARGS_((Display *d, Drawable dr, GC g,
- int x1, int y1, int x2, int y2));
+EXTERN int XDrawLine(Display *d, Drawable dr, GC g, int x1,
+ int y1, int x2, int y2);
+#endif
+#ifndef XWarpPointer_TCL_DECLARED
+#define XWarpPointer_TCL_DECLARED
/* 105 */
-EXTERN int XWarpPointer _ANSI_ARGS_((Display *d, Window s,
- Window dw, int sx, int sy, unsigned int sw,
- unsigned int sh, int dx, int dy));
+EXTERN int XWarpPointer(Display *d, Window s, Window dw, int sx,
+ int sy, unsigned int sw, unsigned int sh,
+ int dx, int dy);
+#endif
+#ifndef XFillRectangle_TCL_DECLARED
+#define XFillRectangle_TCL_DECLARED
/* 106 */
-EXTERN int XFillRectangle _ANSI_ARGS_((Display *display,
- Drawable d, GC gc, int x, int y,
- unsigned int width, unsigned int height));
+EXTERN int XFillRectangle(Display *display, Drawable d, GC gc,
+ int x, int y, unsigned int width,
+ unsigned int height);
+#endif
+#ifndef XFlush_TCL_DECLARED
+#define XFlush_TCL_DECLARED
/* 107 */
-EXTERN int XFlush _ANSI_ARGS_((Display *display));
+EXTERN int XFlush(Display *display);
+#endif
+#ifndef XGrabServer_TCL_DECLARED
+#define XGrabServer_TCL_DECLARED
/* 108 */
-EXTERN int XGrabServer _ANSI_ARGS_((Display *display));
+EXTERN int XGrabServer(Display *display);
+#endif
+#ifndef XUngrabServer_TCL_DECLARED
+#define XUngrabServer_TCL_DECLARED
/* 109 */
-EXTERN int XUngrabServer _ANSI_ARGS_((Display *display));
+EXTERN int XUngrabServer(Display *display);
+#endif
+#ifndef XFree_TCL_DECLARED
+#define XFree_TCL_DECLARED
/* 110 */
-EXTERN int XFree _ANSI_ARGS_((VOID *data));
+EXTERN int XFree(VOID *data);
+#endif
+#ifndef XNoOp_TCL_DECLARED
+#define XNoOp_TCL_DECLARED
/* 111 */
-EXTERN int XNoOp _ANSI_ARGS_((Display *display));
+EXTERN int XNoOp(Display *display);
+#endif
+#ifndef XSynchronize_TCL_DECLARED
+#define XSynchronize_TCL_DECLARED
/* 112 */
-EXTERN XAfterFunction XSynchronize _ANSI_ARGS_((Display *display,
- Bool onoff));
+EXTERN XAfterFunction XSynchronize(Display *display, Bool onoff);
+#endif
+#ifndef XSync_TCL_DECLARED
+#define XSync_TCL_DECLARED
/* 113 */
-EXTERN int XSync _ANSI_ARGS_((Display *display, Bool discard));
+EXTERN int XSync(Display *display, Bool discard);
+#endif
+#ifndef XVisualIDFromVisual_TCL_DECLARED
+#define XVisualIDFromVisual_TCL_DECLARED
/* 114 */
-EXTERN VisualID XVisualIDFromVisual _ANSI_ARGS_((Visual *visual));
+EXTERN VisualID XVisualIDFromVisual(Visual *visual);
+#endif
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
+#ifndef XSetDashes_TCL_DECLARED
+#define XSetDashes_TCL_DECLARED
/* 0 */
-EXTERN int XSetDashes _ANSI_ARGS_((Display *display, GC gc,
- int dash_offset, _Xconst char *dash_list,
- int n));
+EXTERN int XSetDashes(Display *display, GC gc, int dash_offset,
+ _Xconst char *dash_list, int n);
+#endif
+#ifndef XGetModifierMapping_TCL_DECLARED
+#define XGetModifierMapping_TCL_DECLARED
/* 1 */
-EXTERN XModifierKeymap * XGetModifierMapping _ANSI_ARGS_((Display *d));
+EXTERN XModifierKeymap * XGetModifierMapping(Display *d);
+#endif
+#ifndef XCreateImage_TCL_DECLARED
+#define XCreateImage_TCL_DECLARED
/* 2 */
-EXTERN XImage * XCreateImage _ANSI_ARGS_((Display *d, Visual *v,
- unsigned int ui1, int i1, int i2, char *cp,
- unsigned int ui2, unsigned int ui3, int i3,
- int i4));
+EXTERN XImage * XCreateImage(Display *d, Visual *v, unsigned int ui1,
+ int i1, int i2, char *cp, unsigned int ui2,
+ unsigned int ui3, int i3, int i4);
+#endif
+#ifndef XGetImage_TCL_DECLARED
+#define XGetImage_TCL_DECLARED
/* 3 */
-EXTERN XImage * XGetImage _ANSI_ARGS_((Display *d, Drawable dr,
- int i1, int i2, unsigned int ui1,
- unsigned int ui2, unsigned long ul, int i3));
+EXTERN XImage * XGetImage(Display *d, Drawable dr, int i1, int i2,
+ unsigned int ui1, unsigned int ui2,
+ unsigned long ul, int i3);
+#endif
+#ifndef XGetAtomName_TCL_DECLARED
+#define XGetAtomName_TCL_DECLARED
/* 4 */
-EXTERN char * XGetAtomName _ANSI_ARGS_((Display *d, Atom a));
+EXTERN char * XGetAtomName(Display *d, Atom a);
+#endif
+#ifndef XKeysymToString_TCL_DECLARED
+#define XKeysymToString_TCL_DECLARED
/* 5 */
-EXTERN char * XKeysymToString _ANSI_ARGS_((KeySym k));
+EXTERN char * XKeysymToString(KeySym k);
+#endif
+#ifndef XCreateColormap_TCL_DECLARED
+#define XCreateColormap_TCL_DECLARED
/* 6 */
-EXTERN Colormap XCreateColormap _ANSI_ARGS_((Display *d, Window w,
- Visual *v, int i));
+EXTERN Colormap XCreateColormap(Display *d, Window w, Visual *v,
+ int i);
+#endif
+#ifndef XGContextFromGC_TCL_DECLARED
+#define XGContextFromGC_TCL_DECLARED
/* 7 */
-EXTERN GContext XGContextFromGC _ANSI_ARGS_((GC g));
+EXTERN GContext XGContextFromGC(GC g);
+#endif
+#ifndef XKeycodeToKeysym_TCL_DECLARED
+#define XKeycodeToKeysym_TCL_DECLARED
/* 8 */
-EXTERN KeySym XKeycodeToKeysym _ANSI_ARGS_((Display *d, KeyCode k,
- int i));
+EXTERN KeySym XKeycodeToKeysym(Display *d, KeyCode k, int i);
+#endif
+#ifndef XStringToKeysym_TCL_DECLARED
+#define XStringToKeysym_TCL_DECLARED
/* 9 */
-EXTERN KeySym XStringToKeysym _ANSI_ARGS_((_Xconst char *c));
+EXTERN KeySym XStringToKeysym(_Xconst char *c);
+#endif
+#ifndef XRootWindow_TCL_DECLARED
+#define XRootWindow_TCL_DECLARED
/* 10 */
-EXTERN Window XRootWindow _ANSI_ARGS_((Display *d, int i));
+EXTERN Window XRootWindow(Display *d, int i);
+#endif
+#ifndef XSetErrorHandler_TCL_DECLARED
+#define XSetErrorHandler_TCL_DECLARED
/* 11 */
-EXTERN XErrorHandler XSetErrorHandler _ANSI_ARGS_((XErrorHandler x));
+EXTERN XErrorHandler XSetErrorHandler(XErrorHandler x);
+#endif
+#ifndef XAllocColor_TCL_DECLARED
+#define XAllocColor_TCL_DECLARED
/* 12 */
-EXTERN Status XAllocColor _ANSI_ARGS_((Display *d, Colormap c,
- XColor *xp));
+EXTERN Status XAllocColor(Display *d, Colormap c, XColor *xp);
+#endif
+#ifndef XBell_TCL_DECLARED
+#define XBell_TCL_DECLARED
/* 13 */
-EXTERN int XBell _ANSI_ARGS_((Display *d, int i));
+EXTERN int XBell(Display *d, int i);
+#endif
+#ifndef XChangeProperty_TCL_DECLARED
+#define XChangeProperty_TCL_DECLARED
/* 14 */
-EXTERN void XChangeProperty _ANSI_ARGS_((Display *d, Window w,
- Atom a1, Atom a2, int i1, int i2,
- _Xconst unsigned char *c, int i3));
+EXTERN void XChangeProperty(Display *d, Window w, Atom a1,
+ Atom a2, int i1, int i2,
+ _Xconst unsigned char *c, int i3);
+#endif
+#ifndef XChangeWindowAttributes_TCL_DECLARED
+#define XChangeWindowAttributes_TCL_DECLARED
/* 15 */
-EXTERN void XChangeWindowAttributes _ANSI_ARGS_((Display *d,
- Window w, unsigned long ul,
- XSetWindowAttributes *x));
+EXTERN void XChangeWindowAttributes(Display *d, Window w,
+ unsigned long ul, XSetWindowAttributes *x);
+#endif
+#ifndef XConfigureWindow_TCL_DECLARED
+#define XConfigureWindow_TCL_DECLARED
/* 16 */
-EXTERN void XConfigureWindow _ANSI_ARGS_((Display *d, Window w,
- unsigned int i, XWindowChanges *x));
+EXTERN void XConfigureWindow(Display *d, Window w,
+ unsigned int i, XWindowChanges *x);
+#endif
+#ifndef XCopyArea_TCL_DECLARED
+#define XCopyArea_TCL_DECLARED
/* 17 */
-EXTERN void XCopyArea _ANSI_ARGS_((Display *d, Drawable dr1,
- Drawable dr2, GC g, int i1, int i2,
- unsigned int ui1, unsigned int ui2, int i3,
- int i4));
+EXTERN void XCopyArea(Display *d, Drawable dr1, Drawable dr2,
+ GC g, int i1, int i2, unsigned int ui1,
+ unsigned int ui2, int i3, int i4);
+#endif
+#ifndef XCopyPlane_TCL_DECLARED
+#define XCopyPlane_TCL_DECLARED
/* 18 */
-EXTERN void XCopyPlane _ANSI_ARGS_((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));
+EXTERN void XCopyPlane(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);
+#endif
+#ifndef XCreateBitmapFromData_TCL_DECLARED
+#define XCreateBitmapFromData_TCL_DECLARED
/* 19 */
-EXTERN Pixmap XCreateBitmapFromData _ANSI_ARGS_((Display *display,
- Drawable d, _Xconst char *data,
- unsigned int width, unsigned int height));
+EXTERN Pixmap XCreateBitmapFromData(Display *display, Drawable d,
+ _Xconst char *data, unsigned int width,
+ unsigned int height);
+#endif
+#ifndef XDefineCursor_TCL_DECLARED
+#define XDefineCursor_TCL_DECLARED
/* 20 */
-EXTERN int XDefineCursor _ANSI_ARGS_((Display *d, Window w,
- Cursor c));
+EXTERN int XDefineCursor(Display *d, Window w, Cursor c);
+#endif
+#ifndef XDestroyWindow_TCL_DECLARED
+#define XDestroyWindow_TCL_DECLARED
/* 21 */
-EXTERN void XDestroyWindow _ANSI_ARGS_((Display *d, Window w));
+EXTERN void XDestroyWindow(Display *d, Window w);
+#endif
+#ifndef XDrawArc_TCL_DECLARED
+#define XDrawArc_TCL_DECLARED
/* 22 */
-EXTERN void XDrawArc _ANSI_ARGS_((Display *d, Drawable dr, GC g,
- int i1, int i2, unsigned int ui1,
- unsigned int ui2, int i3, int i4));
+EXTERN void XDrawArc(Display *d, Drawable dr, GC g, int i1,
+ int i2, unsigned int ui1, unsigned int ui2,
+ int i3, int i4);
+#endif
+#ifndef XDrawLines_TCL_DECLARED
+#define XDrawLines_TCL_DECLARED
/* 23 */
-EXTERN int XDrawLines _ANSI_ARGS_((Display *d, Drawable dr,
- GC g, XPoint *x, int i1, int i2));
+EXTERN int XDrawLines(Display *d, Drawable dr, GC g, XPoint *x,
+ int i1, int i2);
+#endif
+#ifndef XDrawRectangle_TCL_DECLARED
+#define XDrawRectangle_TCL_DECLARED
/* 24 */
-EXTERN void XDrawRectangle _ANSI_ARGS_((Display *d, Drawable dr,
- GC g, int i1, int i2, unsigned int ui1,
- unsigned int ui2));
+EXTERN void XDrawRectangle(Display *d, Drawable dr, GC g, int i1,
+ int i2, unsigned int ui1, unsigned int ui2);
+#endif
+#ifndef XFillArc_TCL_DECLARED
+#define XFillArc_TCL_DECLARED
/* 25 */
-EXTERN void XFillArc _ANSI_ARGS_((Display *d, Drawable dr, GC g,
- int i1, int i2, unsigned int ui1,
- unsigned int ui2, int i3, int i4));
+EXTERN void XFillArc(Display *d, Drawable dr, GC g, int i1,
+ int i2, unsigned int ui1, unsigned int ui2,
+ int i3, int i4);
+#endif
+#ifndef XFillPolygon_TCL_DECLARED
+#define XFillPolygon_TCL_DECLARED
/* 26 */
-EXTERN void XFillPolygon _ANSI_ARGS_((Display *d, Drawable dr,
- GC g, XPoint *x, int i1, int i2, int i3));
+EXTERN void XFillPolygon(Display *d, Drawable dr, GC g,
+ XPoint *x, int i1, int i2, int i3);
+#endif
+#ifndef XFillRectangles_TCL_DECLARED
+#define XFillRectangles_TCL_DECLARED
/* 27 */
-EXTERN int XFillRectangles _ANSI_ARGS_((Display *d, Drawable dr,
- GC g, XRectangle *x, int i));
+EXTERN int XFillRectangles(Display *d, Drawable dr, GC g,
+ XRectangle *x, int i);
+#endif
+#ifndef XFreeColormap_TCL_DECLARED
+#define XFreeColormap_TCL_DECLARED
/* 28 */
-EXTERN int XFreeColormap _ANSI_ARGS_((Display *d, Colormap c));
+EXTERN int XFreeColormap(Display *d, Colormap c);
+#endif
+#ifndef XFreeColors_TCL_DECLARED
+#define XFreeColors_TCL_DECLARED
/* 29 */
-EXTERN int XFreeColors _ANSI_ARGS_((Display *d, Colormap c,
- unsigned long *ulp, int i, unsigned long ul));
+EXTERN int XFreeColors(Display *d, Colormap c,
+ unsigned long *ulp, int i, unsigned long ul);
+#endif
+#ifndef XFreeModifiermap_TCL_DECLARED
+#define XFreeModifiermap_TCL_DECLARED
/* 30 */
-EXTERN int XFreeModifiermap _ANSI_ARGS_((XModifierKeymap *x));
+EXTERN int XFreeModifiermap(XModifierKeymap *x);
+#endif
+#ifndef XGetGeometry_TCL_DECLARED
+#define XGetGeometry_TCL_DECLARED
/* 31 */
-EXTERN Status XGetGeometry _ANSI_ARGS_((Display *d, Drawable dr,
- Window *w, int *i1, int *i2,
- unsigned int *ui1, unsigned int *ui2,
- unsigned int *ui3, unsigned int *ui4));
+EXTERN Status XGetGeometry(Display *d, Drawable dr, Window *w,
+ int *i1, int *i2, unsigned int *ui1,
+ unsigned int *ui2, unsigned int *ui3,
+ unsigned int *ui4);
+#endif
+#ifndef XGetWindowProperty_TCL_DECLARED
+#define XGetWindowProperty_TCL_DECLARED
/* 32 */
-EXTERN int XGetWindowProperty _ANSI_ARGS_((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));
+EXTERN int XGetWindowProperty(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);
+#endif
+#ifndef XGrabKeyboard_TCL_DECLARED
+#define XGrabKeyboard_TCL_DECLARED
/* 33 */
-EXTERN int XGrabKeyboard _ANSI_ARGS_((Display *d, Window w,
- Bool b, int i1, int i2, Time t));
+EXTERN int XGrabKeyboard(Display *d, Window w, Bool b, int i1,
+ int i2, Time t);
+#endif
+#ifndef XGrabPointer_TCL_DECLARED
+#define XGrabPointer_TCL_DECLARED
/* 34 */
-EXTERN int XGrabPointer _ANSI_ARGS_((Display *d, Window w1,
- Bool b, unsigned int ui, int i1, int i2,
- Window w2, Cursor c, Time t));
+EXTERN int XGrabPointer(Display *d, Window w1, Bool b,
+ unsigned int ui, int i1, int i2, Window w2,
+ Cursor c, Time t);
+#endif
+#ifndef XKeysymToKeycode_TCL_DECLARED
+#define XKeysymToKeycode_TCL_DECLARED
/* 35 */
-EXTERN KeyCode XKeysymToKeycode _ANSI_ARGS_((Display *d, KeySym k));
+EXTERN KeyCode XKeysymToKeycode(Display *d, KeySym k);
+#endif
+#ifndef XMapWindow_TCL_DECLARED
+#define XMapWindow_TCL_DECLARED
/* 36 */
-EXTERN void XMapWindow _ANSI_ARGS_((Display *d, Window w));
+EXTERN void XMapWindow(Display *d, Window w);
+#endif
+#ifndef XMoveResizeWindow_TCL_DECLARED
+#define XMoveResizeWindow_TCL_DECLARED
/* 37 */
-EXTERN void XMoveResizeWindow _ANSI_ARGS_((Display *d, Window w,
- int i1, int i2, unsigned int ui1,
- unsigned int ui2));
+EXTERN void XMoveResizeWindow(Display *d, Window w, int i1,
+ int i2, unsigned int ui1, unsigned int ui2);
+#endif
+#ifndef XMoveWindow_TCL_DECLARED
+#define XMoveWindow_TCL_DECLARED
/* 38 */
-EXTERN void XMoveWindow _ANSI_ARGS_((Display *d, Window w,
- int i1, int i2));
+EXTERN void XMoveWindow(Display *d, Window w, int i1, int i2);
+#endif
+#ifndef XQueryPointer_TCL_DECLARED
+#define XQueryPointer_TCL_DECLARED
/* 39 */
-EXTERN Bool XQueryPointer _ANSI_ARGS_((Display *d, Window w1,
- Window *w2, Window *w3, int *i1, int *i2,
- int *i3, int *i4, unsigned int *ui));
+EXTERN Bool XQueryPointer(Display *d, Window w1, Window *w2,
+ Window *w3, int *i1, int *i2, int *i3,
+ int *i4, unsigned int *ui);
+#endif
+#ifndef XRaiseWindow_TCL_DECLARED
+#define XRaiseWindow_TCL_DECLARED
/* 40 */
-EXTERN void XRaiseWindow _ANSI_ARGS_((Display *d, Window w));
+EXTERN void XRaiseWindow(Display *d, Window w);
+#endif
+#ifndef XRefreshKeyboardMapping_TCL_DECLARED
+#define XRefreshKeyboardMapping_TCL_DECLARED
/* 41 */
-EXTERN void XRefreshKeyboardMapping _ANSI_ARGS_((
- XMappingEvent *x));
+EXTERN void XRefreshKeyboardMapping(XMappingEvent *x);
+#endif
+#ifndef XResizeWindow_TCL_DECLARED
+#define XResizeWindow_TCL_DECLARED
/* 42 */
-EXTERN void XResizeWindow _ANSI_ARGS_((Display *d, Window w,
- unsigned int ui1, unsigned int ui2));
+EXTERN void XResizeWindow(Display *d, Window w, unsigned int ui1,
+ unsigned int ui2);
+#endif
+#ifndef XSelectInput_TCL_DECLARED
+#define XSelectInput_TCL_DECLARED
/* 43 */
-EXTERN void XSelectInput _ANSI_ARGS_((Display *d, Window w,
- long l));
+EXTERN void XSelectInput(Display *d, Window w, long l);
+#endif
+#ifndef XSendEvent_TCL_DECLARED
+#define XSendEvent_TCL_DECLARED
/* 44 */
-EXTERN Status XSendEvent _ANSI_ARGS_((Display *d, Window w, Bool b,
- long l, XEvent *x));
+EXTERN Status XSendEvent(Display *d, Window w, Bool b, long l,
+ XEvent *x);
+#endif
+#ifndef XSetIconName_TCL_DECLARED
+#define XSetIconName_TCL_DECLARED
/* 45 */
-EXTERN void XSetIconName _ANSI_ARGS_((Display *d, Window w,
- _Xconst char *c));
+EXTERN void XSetIconName(Display *d, Window w, _Xconst char *c);
+#endif
+#ifndef XSetInputFocus_TCL_DECLARED
+#define XSetInputFocus_TCL_DECLARED
/* 46 */
-EXTERN void XSetInputFocus _ANSI_ARGS_((Display *d, Window w,
- int i, Time t));
+EXTERN void XSetInputFocus(Display *d, Window w, int i, Time t);
+#endif
+#ifndef XSetSelectionOwner_TCL_DECLARED
+#define XSetSelectionOwner_TCL_DECLARED
/* 47 */
-EXTERN int XSetSelectionOwner _ANSI_ARGS_((Display *d, Atom a,
- Window w, Time t));
+EXTERN int XSetSelectionOwner(Display *d, Atom a, Window w,
+ Time t);
+#endif
+#ifndef XSetWindowBackground_TCL_DECLARED
+#define XSetWindowBackground_TCL_DECLARED
/* 48 */
-EXTERN void XSetWindowBackground _ANSI_ARGS_((Display *d,
- Window w, unsigned long ul));
+EXTERN void XSetWindowBackground(Display *d, Window w,
+ unsigned long ul);
+#endif
+#ifndef XSetWindowBackgroundPixmap_TCL_DECLARED
+#define XSetWindowBackgroundPixmap_TCL_DECLARED
/* 49 */
-EXTERN void XSetWindowBackgroundPixmap _ANSI_ARGS_((Display *d,
- Window w, Pixmap p));
+EXTERN void XSetWindowBackgroundPixmap(Display *d, Window w,
+ Pixmap p);
+#endif
+#ifndef XSetWindowBorder_TCL_DECLARED
+#define XSetWindowBorder_TCL_DECLARED
/* 50 */
-EXTERN void XSetWindowBorder _ANSI_ARGS_((Display *d, Window w,
- unsigned long ul));
+EXTERN void XSetWindowBorder(Display *d, Window w,
+ unsigned long ul);
+#endif
+#ifndef XSetWindowBorderPixmap_TCL_DECLARED
+#define XSetWindowBorderPixmap_TCL_DECLARED
/* 51 */
-EXTERN void XSetWindowBorderPixmap _ANSI_ARGS_((Display *d,
- Window w, Pixmap p));
+EXTERN void XSetWindowBorderPixmap(Display *d, Window w,
+ Pixmap p);
+#endif
+#ifndef XSetWindowBorderWidth_TCL_DECLARED
+#define XSetWindowBorderWidth_TCL_DECLARED
/* 52 */
-EXTERN void XSetWindowBorderWidth _ANSI_ARGS_((Display *d,
- Window w, unsigned int ui));
+EXTERN void XSetWindowBorderWidth(Display *d, Window w,
+ unsigned int ui);
+#endif
+#ifndef XSetWindowColormap_TCL_DECLARED
+#define XSetWindowColormap_TCL_DECLARED
/* 53 */
-EXTERN void XSetWindowColormap _ANSI_ARGS_((Display *d, Window w,
- Colormap c));
+EXTERN void XSetWindowColormap(Display *d, Window w, Colormap c);
+#endif
+#ifndef XUngrabKeyboard_TCL_DECLARED
+#define XUngrabKeyboard_TCL_DECLARED
/* 54 */
-EXTERN void XUngrabKeyboard _ANSI_ARGS_((Display *d, Time t));
+EXTERN void XUngrabKeyboard(Display *d, Time t);
+#endif
+#ifndef XUngrabPointer_TCL_DECLARED
+#define XUngrabPointer_TCL_DECLARED
/* 55 */
-EXTERN int XUngrabPointer _ANSI_ARGS_((Display *d, Time t));
+EXTERN int XUngrabPointer(Display *d, Time t);
+#endif
+#ifndef XUnmapWindow_TCL_DECLARED
+#define XUnmapWindow_TCL_DECLARED
/* 56 */
-EXTERN void XUnmapWindow _ANSI_ARGS_((Display *d, Window w));
+EXTERN void XUnmapWindow(Display *d, Window w);
+#endif
+#ifndef TkPutImage_TCL_DECLARED
+#define TkPutImage_TCL_DECLARED
/* 57 */
-EXTERN int TkPutImage _ANSI_ARGS_((unsigned long *colors,
- int ncolors, Display *display, Drawable d,
- GC gc, XImage *image, int src_x, int src_y,
+EXTERN int TkPutImage(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));
+ unsigned int height);
+#endif
+#ifndef XParseColor_TCL_DECLARED
+#define XParseColor_TCL_DECLARED
/* 58 */
-EXTERN Status XParseColor _ANSI_ARGS_((Display *display,
- Colormap map, _Xconst char *spec,
- XColor *colorPtr));
+EXTERN Status XParseColor(Display *display, Colormap map,
+ _Xconst char *spec, XColor *colorPtr);
+#endif
+#ifndef XCreateGC_TCL_DECLARED
+#define XCreateGC_TCL_DECLARED
/* 59 */
-EXTERN GC XCreateGC _ANSI_ARGS_((Display *display, Drawable d,
- unsigned long valuemask, XGCValues *values));
+EXTERN GC XCreateGC(Display *display, Drawable d,
+ unsigned long valuemask, XGCValues *values);
+#endif
+#ifndef XFreeGC_TCL_DECLARED
+#define XFreeGC_TCL_DECLARED
/* 60 */
-EXTERN int XFreeGC _ANSI_ARGS_((Display *display, GC gc));
+EXTERN int XFreeGC(Display *display, GC gc);
+#endif
+#ifndef XInternAtom_TCL_DECLARED
+#define XInternAtom_TCL_DECLARED
/* 61 */
-EXTERN Atom XInternAtom _ANSI_ARGS_((Display *display,
- _Xconst char *atom_name, Bool only_if_exists));
+EXTERN Atom XInternAtom(Display *display,
+ _Xconst char *atom_name, Bool only_if_exists);
+#endif
+#ifndef XSetBackground_TCL_DECLARED
+#define XSetBackground_TCL_DECLARED
/* 62 */
-EXTERN int XSetBackground _ANSI_ARGS_((Display *display, GC gc,
- unsigned long foreground));
+EXTERN int XSetBackground(Display *display, GC gc,
+ unsigned long foreground);
+#endif
+#ifndef XSetForeground_TCL_DECLARED
+#define XSetForeground_TCL_DECLARED
/* 63 */
-EXTERN int XSetForeground _ANSI_ARGS_((Display *display, GC gc,
- unsigned long foreground));
+EXTERN int XSetForeground(Display *display, GC gc,
+ unsigned long foreground);
+#endif
+#ifndef XSetClipMask_TCL_DECLARED
+#define XSetClipMask_TCL_DECLARED
/* 64 */
-EXTERN int XSetClipMask _ANSI_ARGS_((Display *display, GC gc,
- Pixmap pixmap));
+EXTERN int XSetClipMask(Display *display, GC gc, Pixmap pixmap);
+#endif
+#ifndef XSetClipOrigin_TCL_DECLARED
+#define XSetClipOrigin_TCL_DECLARED
/* 65 */
-EXTERN int XSetClipOrigin _ANSI_ARGS_((Display *display, GC gc,
- int clip_x_origin, int clip_y_origin));
+EXTERN int XSetClipOrigin(Display *display, GC gc,
+ int clip_x_origin, int clip_y_origin);
+#endif
+#ifndef XSetTSOrigin_TCL_DECLARED
+#define XSetTSOrigin_TCL_DECLARED
/* 66 */
-EXTERN int XSetTSOrigin _ANSI_ARGS_((Display *display, GC gc,
- int ts_x_origin, int ts_y_origin));
+EXTERN int XSetTSOrigin(Display *display, GC gc,
+ int ts_x_origin, int ts_y_origin);
+#endif
+#ifndef XChangeGC_TCL_DECLARED
+#define XChangeGC_TCL_DECLARED
/* 67 */
-EXTERN int XChangeGC _ANSI_ARGS_((Display *d, GC gc,
- unsigned long mask, XGCValues *values));
+EXTERN int XChangeGC(Display *d, GC gc, unsigned long mask,
+ XGCValues *values);
+#endif
+#ifndef XSetFont_TCL_DECLARED
+#define XSetFont_TCL_DECLARED
/* 68 */
-EXTERN int XSetFont _ANSI_ARGS_((Display *display, GC gc,
- Font font));
+EXTERN int XSetFont(Display *display, GC gc, Font font);
+#endif
+#ifndef XSetArcMode_TCL_DECLARED
+#define XSetArcMode_TCL_DECLARED
/* 69 */
-EXTERN int XSetArcMode _ANSI_ARGS_((Display *display, GC gc,
- int arc_mode));
+EXTERN int XSetArcMode(Display *display, GC gc, int arc_mode);
+#endif
+#ifndef XSetStipple_TCL_DECLARED
+#define XSetStipple_TCL_DECLARED
/* 70 */
-EXTERN int XSetStipple _ANSI_ARGS_((Display *display, GC gc,
- Pixmap stipple));
+EXTERN int XSetStipple(Display *display, GC gc, Pixmap stipple);
+#endif
+#ifndef XSetFillRule_TCL_DECLARED
+#define XSetFillRule_TCL_DECLARED
/* 71 */
-EXTERN int XSetFillRule _ANSI_ARGS_((Display *display, GC gc,
- int fill_rule));
+EXTERN int XSetFillRule(Display *display, GC gc, int fill_rule);
+#endif
+#ifndef XSetFillStyle_TCL_DECLARED
+#define XSetFillStyle_TCL_DECLARED
/* 72 */
-EXTERN int XSetFillStyle _ANSI_ARGS_((Display *display, GC gc,
- int fill_style));
+EXTERN int XSetFillStyle(Display *display, GC gc,
+ int fill_style);
+#endif
+#ifndef XSetFunction_TCL_DECLARED
+#define XSetFunction_TCL_DECLARED
/* 73 */
-EXTERN int XSetFunction _ANSI_ARGS_((Display *display, GC gc,
- int function));
+EXTERN int XSetFunction(Display *display, GC gc, int function);
+#endif
+#ifndef XSetLineAttributes_TCL_DECLARED
+#define XSetLineAttributes_TCL_DECLARED
/* 74 */
-EXTERN int XSetLineAttributes _ANSI_ARGS_((Display *display,
- GC gc, unsigned int line_width,
- int line_style, int cap_style,
- int join_style));
+EXTERN int XSetLineAttributes(Display *display, GC gc,
+ unsigned int line_width, int line_style,
+ int cap_style, int join_style);
+#endif
+#ifndef _XInitImageFuncPtrs_TCL_DECLARED
+#define _XInitImageFuncPtrs_TCL_DECLARED
/* 75 */
-EXTERN int _XInitImageFuncPtrs _ANSI_ARGS_((XImage *image));
+EXTERN int _XInitImageFuncPtrs(XImage *image);
+#endif
+#ifndef XCreateIC_TCL_DECLARED
+#define XCreateIC_TCL_DECLARED
/* 76 */
-EXTERN XIC XCreateIC _ANSI_ARGS_((void));
+EXTERN XIC XCreateIC(void);
+#endif
+#ifndef XGetVisualInfo_TCL_DECLARED
+#define XGetVisualInfo_TCL_DECLARED
/* 77 */
-EXTERN XVisualInfo * XGetVisualInfo _ANSI_ARGS_((Display *display,
- long vinfo_mask, XVisualInfo *vinfo_template,
- int *nitems_return));
+EXTERN XVisualInfo * XGetVisualInfo(Display *display, long vinfo_mask,
+ XVisualInfo *vinfo_template,
+ int *nitems_return);
+#endif
+#ifndef XSetWMClientMachine_TCL_DECLARED
+#define XSetWMClientMachine_TCL_DECLARED
/* 78 */
-EXTERN void XSetWMClientMachine _ANSI_ARGS_((Display *display,
- Window w, XTextProperty *text_prop));
+EXTERN void XSetWMClientMachine(Display *display, Window w,
+ XTextProperty *text_prop);
+#endif
+#ifndef XStringListToTextProperty_TCL_DECLARED
+#define XStringListToTextProperty_TCL_DECLARED
/* 79 */
-EXTERN Status XStringListToTextProperty _ANSI_ARGS_((char **list,
- int count, XTextProperty *text_prop_return));
+EXTERN Status XStringListToTextProperty(char **list, int count,
+ XTextProperty *text_prop_return);
+#endif
+#ifndef XDrawSegments_TCL_DECLARED
+#define XDrawSegments_TCL_DECLARED
/* 80 */
-EXTERN void XDrawSegments _ANSI_ARGS_((Display *display,
- Drawable d, GC gc, XSegment *segments,
- int nsegments));
+EXTERN void XDrawSegments(Display *display, Drawable d, GC gc,
+ XSegment *segments, int nsegments);
+#endif
+#ifndef XForceScreenSaver_TCL_DECLARED
+#define XForceScreenSaver_TCL_DECLARED
/* 81 */
-EXTERN void XForceScreenSaver _ANSI_ARGS_((Display *display,
- int mode));
+EXTERN void XForceScreenSaver(Display *display, int mode);
+#endif
+#ifndef XDrawLine_TCL_DECLARED
+#define XDrawLine_TCL_DECLARED
/* 82 */
-EXTERN int XDrawLine _ANSI_ARGS_((Display *d, Drawable dr, GC g,
- int x1, int y1, int x2, int y2));
+EXTERN int XDrawLine(Display *d, Drawable dr, GC g, int x1,
+ int y1, int x2, int y2);
+#endif
+#ifndef XFillRectangle_TCL_DECLARED
+#define XFillRectangle_TCL_DECLARED
/* 83 */
-EXTERN int XFillRectangle _ANSI_ARGS_((Display *display,
- Drawable d, GC gc, int x, int y,
- unsigned int width, unsigned int height));
+EXTERN int XFillRectangle(Display *display, Drawable d, GC gc,
+ int x, int y, unsigned int width,
+ unsigned int height);
+#endif
+#ifndef XClearWindow_TCL_DECLARED
+#define XClearWindow_TCL_DECLARED
/* 84 */
-EXTERN void XClearWindow _ANSI_ARGS_((Display *d, Window w));
+EXTERN void XClearWindow(Display *d, Window w);
+#endif
+#ifndef XDrawPoint_TCL_DECLARED
+#define XDrawPoint_TCL_DECLARED
/* 85 */
-EXTERN void XDrawPoint _ANSI_ARGS_((Display *display, Drawable d,
- GC gc, int x, int y));
+EXTERN void XDrawPoint(Display *display, Drawable d, GC gc,
+ int x, int y);
+#endif
+#ifndef XDrawPoints_TCL_DECLARED
+#define XDrawPoints_TCL_DECLARED
/* 86 */
-EXTERN void XDrawPoints _ANSI_ARGS_((Display *display,
- Drawable d, GC gc, XPoint *points,
- int npoints, int mode));
+EXTERN void XDrawPoints(Display *display, Drawable d, GC gc,
+ XPoint *points, int npoints, int mode);
+#endif
+#ifndef XWarpPointer_TCL_DECLARED
+#define XWarpPointer_TCL_DECLARED
/* 87 */
-EXTERN int XWarpPointer _ANSI_ARGS_((Display *display,
- Window src_w, Window dest_w, int src_x,
- int src_y, unsigned int src_width,
+EXTERN int XWarpPointer(Display *display, Window src_w,
+ Window dest_w, int src_x, int src_y,
+ unsigned int src_width,
unsigned int src_height, int dest_x,
- int dest_y));
+ int dest_y);
+#endif
+#ifndef XQueryColor_TCL_DECLARED
+#define XQueryColor_TCL_DECLARED
/* 88 */
-EXTERN void XQueryColor _ANSI_ARGS_((Display *display,
- Colormap colormap, XColor *def_in_out));
+EXTERN void XQueryColor(Display *display, Colormap colormap,
+ XColor *def_in_out);
+#endif
+#ifndef XQueryColors_TCL_DECLARED
+#define XQueryColors_TCL_DECLARED
/* 89 */
-EXTERN void XQueryColors _ANSI_ARGS_((Display *display,
- Colormap colormap, XColor *defs_in_out,
- int ncolors));
+EXTERN void XQueryColors(Display *display, Colormap colormap,
+ XColor *defs_in_out, int ncolors);
+#endif
+#ifndef XQueryTree_TCL_DECLARED
+#define XQueryTree_TCL_DECLARED
/* 90 */
-EXTERN Status XQueryTree _ANSI_ARGS_((Display *d, Window w1,
- Window *w2, Window *w3, Window **w4,
- unsigned int *ui));
+EXTERN Status XQueryTree(Display *d, Window w1, Window *w2,
+ Window *w3, Window **w4, unsigned int *ui);
+#endif
+#ifndef XSync_TCL_DECLARED
+#define XSync_TCL_DECLARED
/* 91 */
-EXTERN int XSync _ANSI_ARGS_((Display *display, Bool flag));
+EXTERN int XSync(Display *display, Bool flag);
+#endif
#endif /* AQUA */
typedef struct TkIntXlibStubs {
@@ -679,215 +1241,215 @@ typedef struct TkIntXlibStubs {
struct TkIntXlibStubHooks *hooks;
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
- int (*xSetDashes) _ANSI_ARGS_((Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n)); /* 0 */
- XModifierKeymap * (*xGetModifierMapping) _ANSI_ARGS_((Display *d)); /* 1 */
- XImage * (*xCreateImage) _ANSI_ARGS_((Display *d, Visual *v, unsigned int ui1, int i1, int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3, int i4)); /* 2 */
- XImage * (*xGetImage) _ANSI_ARGS_((Display *d, Drawable dr, int i1, int i2, unsigned int ui1, unsigned int ui2, unsigned long ul, int i3)); /* 3 */
- char * (*xGetAtomName) _ANSI_ARGS_((Display *d, Atom a)); /* 4 */
- char * (*xKeysymToString) _ANSI_ARGS_((KeySym k)); /* 5 */
- Colormap (*xCreateColormap) _ANSI_ARGS_((Display *d, Window w, Visual *v, int i)); /* 6 */
- Cursor (*xCreatePixmapCursor) _ANSI_ARGS_((Display *d, Pixmap p1, Pixmap p2, XColor *x1, XColor *x2, unsigned int ui1, unsigned int ui2)); /* 7 */
- Cursor (*xCreateGlyphCursor) _ANSI_ARGS_((Display *d, Font f1, Font f2, unsigned int ui1, unsigned int ui2, XColor _Xconst *x1, XColor _Xconst *x2)); /* 8 */
- GContext (*xGContextFromGC) _ANSI_ARGS_((GC g)); /* 9 */
- XHostAddress * (*xListHosts) _ANSI_ARGS_((Display *d, int *i, Bool *b)); /* 10 */
- KeySym (*xKeycodeToKeysym) _ANSI_ARGS_((Display *d, unsigned int k, int i)); /* 11 */
- KeySym (*xStringToKeysym) _ANSI_ARGS_((_Xconst char *c)); /* 12 */
- Window (*xRootWindow) _ANSI_ARGS_((Display *d, int i)); /* 13 */
- XErrorHandler (*xSetErrorHandler) _ANSI_ARGS_((XErrorHandler x)); /* 14 */
- Status (*xIconifyWindow) _ANSI_ARGS_((Display *d, Window w, int i)); /* 15 */
- Status (*xWithdrawWindow) _ANSI_ARGS_((Display *d, Window w, int i)); /* 16 */
- Status (*xGetWMColormapWindows) _ANSI_ARGS_((Display *d, Window w, Window **wpp, int *ip)); /* 17 */
- Status (*xAllocColor) _ANSI_ARGS_((Display *d, Colormap c, XColor *xp)); /* 18 */
- int (*xBell) _ANSI_ARGS_((Display *d, int i)); /* 19 */
- int (*xChangeProperty) _ANSI_ARGS_((Display *d, Window w, Atom a1, Atom a2, int i1, int i2, _Xconst unsigned char *c, int i3)); /* 20 */
- int (*xChangeWindowAttributes) _ANSI_ARGS_((Display *d, Window w, unsigned long ul, XSetWindowAttributes *x)); /* 21 */
- int (*xClearWindow) _ANSI_ARGS_((Display *d, Window w)); /* 22 */
- int (*xConfigureWindow) _ANSI_ARGS_((Display *d, Window w, unsigned int i, XWindowChanges *x)); /* 23 */
- int (*xCopyArea) _ANSI_ARGS_((Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4)); /* 24 */
- int (*xCopyPlane) _ANSI_ARGS_((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)); /* 25 */
- Pixmap (*xCreateBitmapFromData) _ANSI_ARGS_((Display *display, Drawable d, _Xconst char *data, unsigned int width, unsigned int height)); /* 26 */
- int (*xDefineCursor) _ANSI_ARGS_((Display *d, Window w, Cursor c)); /* 27 */
- int (*xDeleteProperty) _ANSI_ARGS_((Display *d, Window w, Atom a)); /* 28 */
- int (*xDestroyWindow) _ANSI_ARGS_((Display *d, Window w)); /* 29 */
- int (*xDrawArc) _ANSI_ARGS_((Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4)); /* 30 */
- int (*xDrawLines) _ANSI_ARGS_((Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2)); /* 31 */
- int (*xDrawRectangle) _ANSI_ARGS_((Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2)); /* 32 */
- int (*xFillArc) _ANSI_ARGS_((Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4)); /* 33 */
- int (*xFillPolygon) _ANSI_ARGS_((Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2, int i3)); /* 34 */
- int (*xFillRectangles) _ANSI_ARGS_((Display *d, Drawable dr, GC g, XRectangle *x, int i)); /* 35 */
- int (*xForceScreenSaver) _ANSI_ARGS_((Display *d, int i)); /* 36 */
- int (*xFreeColormap) _ANSI_ARGS_((Display *d, Colormap c)); /* 37 */
- int (*xFreeColors) _ANSI_ARGS_((Display *d, Colormap c, unsigned long *ulp, int i, unsigned long ul)); /* 38 */
- int (*xFreeCursor) _ANSI_ARGS_((Display *d, Cursor c)); /* 39 */
- int (*xFreeModifiermap) _ANSI_ARGS_((XModifierKeymap *x)); /* 40 */
- Status (*xGetGeometry) _ANSI_ARGS_((Display *d, Drawable dr, Window *w, int *i1, int *i2, unsigned int *ui1, unsigned int *ui2, unsigned int *ui3, unsigned int *ui4)); /* 41 */
- int (*xGetInputFocus) _ANSI_ARGS_((Display *d, Window *w, int *i)); /* 42 */
- int (*xGetWindowProperty) _ANSI_ARGS_((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)); /* 43 */
- Status (*xGetWindowAttributes) _ANSI_ARGS_((Display *d, Window w, XWindowAttributes *x)); /* 44 */
- int (*xGrabKeyboard) _ANSI_ARGS_((Display *d, Window w, Bool b, int i1, int i2, Time t)); /* 45 */
- int (*xGrabPointer) _ANSI_ARGS_((Display *d, Window w1, Bool b, unsigned int ui, int i1, int i2, Window w2, Cursor c, Time t)); /* 46 */
- KeyCode (*xKeysymToKeycode) _ANSI_ARGS_((Display *d, KeySym k)); /* 47 */
- Status (*xLookupColor) _ANSI_ARGS_((Display *d, Colormap c1, _Xconst char *c2, XColor *x1, XColor *x2)); /* 48 */
- int (*xMapWindow) _ANSI_ARGS_((Display *d, Window w)); /* 49 */
- int (*xMoveResizeWindow) _ANSI_ARGS_((Display *d, Window w, int i1, int i2, unsigned int ui1, unsigned int ui2)); /* 50 */
- int (*xMoveWindow) _ANSI_ARGS_((Display *d, Window w, int i1, int i2)); /* 51 */
- int (*xNextEvent) _ANSI_ARGS_((Display *d, XEvent *x)); /* 52 */
- int (*xPutBackEvent) _ANSI_ARGS_((Display *d, XEvent *x)); /* 53 */
- int (*xQueryColors) _ANSI_ARGS_((Display *d, Colormap c, XColor *x, int i)); /* 54 */
- Bool (*xQueryPointer) _ANSI_ARGS_((Display *d, Window w1, Window *w2, Window *w3, int *i1, int *i2, int *i3, int *i4, unsigned int *ui)); /* 55 */
- Status (*xQueryTree) _ANSI_ARGS_((Display *d, Window w1, Window *w2, Window *w3, Window **w4, unsigned int *ui)); /* 56 */
- int (*xRaiseWindow) _ANSI_ARGS_((Display *d, Window w)); /* 57 */
- int (*xRefreshKeyboardMapping) _ANSI_ARGS_((XMappingEvent *x)); /* 58 */
- int (*xResizeWindow) _ANSI_ARGS_((Display *d, Window w, unsigned int ui1, unsigned int ui2)); /* 59 */
- int (*xSelectInput) _ANSI_ARGS_((Display *d, Window w, long l)); /* 60 */
- Status (*xSendEvent) _ANSI_ARGS_((Display *d, Window w, Bool b, long l, XEvent *x)); /* 61 */
- int (*xSetCommand) _ANSI_ARGS_((Display *d, Window w, char **c, int i)); /* 62 */
- int (*xSetIconName) _ANSI_ARGS_((Display *d, Window w, _Xconst char *c)); /* 63 */
- int (*xSetInputFocus) _ANSI_ARGS_((Display *d, Window w, int i, Time t)); /* 64 */
- int (*xSetSelectionOwner) _ANSI_ARGS_((Display *d, Atom a, Window w, Time t)); /* 65 */
- int (*xSetWindowBackground) _ANSI_ARGS_((Display *d, Window w, unsigned long ul)); /* 66 */
- int (*xSetWindowBackgroundPixmap) _ANSI_ARGS_((Display *d, Window w, Pixmap p)); /* 67 */
- int (*xSetWindowBorder) _ANSI_ARGS_((Display *d, Window w, unsigned long ul)); /* 68 */
- int (*xSetWindowBorderPixmap) _ANSI_ARGS_((Display *d, Window w, Pixmap p)); /* 69 */
- int (*xSetWindowBorderWidth) _ANSI_ARGS_((Display *d, Window w, unsigned int ui)); /* 70 */
- int (*xSetWindowColormap) _ANSI_ARGS_((Display *d, Window w, Colormap c)); /* 71 */
- Bool (*xTranslateCoordinates) _ANSI_ARGS_((Display *d, Window w1, Window w2, int i1, int i2, int *i3, int *i4, Window *w3)); /* 72 */
- int (*xUngrabKeyboard) _ANSI_ARGS_((Display *d, Time t)); /* 73 */
- int (*xUngrabPointer) _ANSI_ARGS_((Display *d, Time t)); /* 74 */
- int (*xUnmapWindow) _ANSI_ARGS_((Display *d, Window w)); /* 75 */
- int (*xWindowEvent) _ANSI_ARGS_((Display *d, Window w, long l, XEvent *x)); /* 76 */
- void (*xDestroyIC) _ANSI_ARGS_((XIC x)); /* 77 */
- 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 */
- int (*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 */
+ int (*xSetDashes) (Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); /* 0 */
+ XModifierKeymap * (*xGetModifierMapping) (Display *d); /* 1 */
+ XImage * (*xCreateImage) (Display *d, Visual *v, unsigned int ui1, int i1, int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3, int i4); /* 2 */
+ XImage * (*xGetImage) (Display *d, Drawable dr, int i1, int i2, unsigned int ui1, unsigned int ui2, unsigned long ul, int i3); /* 3 */
+ char * (*xGetAtomName) (Display *d, Atom a); /* 4 */
+ char * (*xKeysymToString) (KeySym k); /* 5 */
+ Colormap (*xCreateColormap) (Display *d, Window w, Visual *v, int i); /* 6 */
+ Cursor (*xCreatePixmapCursor) (Display *d, Pixmap p1, Pixmap p2, XColor *x1, XColor *x2, unsigned int ui1, unsigned int ui2); /* 7 */
+ Cursor (*xCreateGlyphCursor) (Display *d, Font f1, Font f2, unsigned int ui1, unsigned int ui2, XColor _Xconst *x1, XColor _Xconst *x2); /* 8 */
+ GContext (*xGContextFromGC) (GC g); /* 9 */
+ XHostAddress * (*xListHosts) (Display *d, int *i, Bool *b); /* 10 */
+ KeySym (*xKeycodeToKeysym) (Display *d, unsigned int k, int i); /* 11 */
+ KeySym (*xStringToKeysym) (_Xconst char *c); /* 12 */
+ Window (*xRootWindow) (Display *d, int i); /* 13 */
+ XErrorHandler (*xSetErrorHandler) (XErrorHandler x); /* 14 */
+ Status (*xIconifyWindow) (Display *d, Window w, int i); /* 15 */
+ Status (*xWithdrawWindow) (Display *d, Window w, int i); /* 16 */
+ Status (*xGetWMColormapWindows) (Display *d, Window w, Window **wpp, int *ip); /* 17 */
+ Status (*xAllocColor) (Display *d, Colormap c, XColor *xp); /* 18 */
+ int (*xBell) (Display *d, int i); /* 19 */
+ int (*xChangeProperty) (Display *d, Window w, Atom a1, Atom a2, int i1, int i2, _Xconst unsigned char *c, int i3); /* 20 */
+ int (*xChangeWindowAttributes) (Display *d, Window w, unsigned long ul, XSetWindowAttributes *x); /* 21 */
+ int (*xClearWindow) (Display *d, Window w); /* 22 */
+ int (*xConfigureWindow) (Display *d, Window w, unsigned int i, XWindowChanges *x); /* 23 */
+ int (*xCopyArea) (Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); /* 24 */
+ int (*xCopyPlane) (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); /* 25 */
+ Pixmap (*xCreateBitmapFromData) (Display *display, Drawable d, _Xconst char *data, unsigned int width, unsigned int height); /* 26 */
+ int (*xDefineCursor) (Display *d, Window w, Cursor c); /* 27 */
+ int (*xDeleteProperty) (Display *d, Window w, Atom a); /* 28 */
+ int (*xDestroyWindow) (Display *d, Window w); /* 29 */
+ int (*xDrawArc) (Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); /* 30 */
+ int (*xDrawLines) (Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2); /* 31 */
+ int (*xDrawRectangle) (Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2); /* 32 */
+ int (*xFillArc) (Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); /* 33 */
+ int (*xFillPolygon) (Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2, int i3); /* 34 */
+ int (*xFillRectangles) (Display *d, Drawable dr, GC g, XRectangle *x, int i); /* 35 */
+ int (*xForceScreenSaver) (Display *d, int i); /* 36 */
+ int (*xFreeColormap) (Display *d, Colormap c); /* 37 */
+ int (*xFreeColors) (Display *d, Colormap c, unsigned long *ulp, int i, unsigned long ul); /* 38 */
+ int (*xFreeCursor) (Display *d, Cursor c); /* 39 */
+ int (*xFreeModifiermap) (XModifierKeymap *x); /* 40 */
+ Status (*xGetGeometry) (Display *d, Drawable dr, Window *w, int *i1, int *i2, unsigned int *ui1, unsigned int *ui2, unsigned int *ui3, unsigned int *ui4); /* 41 */
+ int (*xGetInputFocus) (Display *d, Window *w, int *i); /* 42 */
+ int (*xGetWindowProperty) (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); /* 43 */
+ Status (*xGetWindowAttributes) (Display *d, Window w, XWindowAttributes *x); /* 44 */
+ int (*xGrabKeyboard) (Display *d, Window w, Bool b, int i1, int i2, Time t); /* 45 */
+ int (*xGrabPointer) (Display *d, Window w1, Bool b, unsigned int ui, int i1, int i2, Window w2, Cursor c, Time t); /* 46 */
+ KeyCode (*xKeysymToKeycode) (Display *d, KeySym k); /* 47 */
+ Status (*xLookupColor) (Display *d, Colormap c1, _Xconst char *c2, XColor *x1, XColor *x2); /* 48 */
+ int (*xMapWindow) (Display *d, Window w); /* 49 */
+ int (*xMoveResizeWindow) (Display *d, Window w, int i1, int i2, unsigned int ui1, unsigned int ui2); /* 50 */
+ int (*xMoveWindow) (Display *d, Window w, int i1, int i2); /* 51 */
+ int (*xNextEvent) (Display *d, XEvent *x); /* 52 */
+ int (*xPutBackEvent) (Display *d, XEvent *x); /* 53 */
+ int (*xQueryColors) (Display *d, Colormap c, XColor *x, int i); /* 54 */
+ Bool (*xQueryPointer) (Display *d, Window w1, Window *w2, Window *w3, int *i1, int *i2, int *i3, int *i4, unsigned int *ui); /* 55 */
+ Status (*xQueryTree) (Display *d, Window w1, Window *w2, Window *w3, Window **w4, unsigned int *ui); /* 56 */
+ int (*xRaiseWindow) (Display *d, Window w); /* 57 */
+ int (*xRefreshKeyboardMapping) (XMappingEvent *x); /* 58 */
+ int (*xResizeWindow) (Display *d, Window w, unsigned int ui1, unsigned int ui2); /* 59 */
+ int (*xSelectInput) (Display *d, Window w, long l); /* 60 */
+ Status (*xSendEvent) (Display *d, Window w, Bool b, long l, XEvent *x); /* 61 */
+ int (*xSetCommand) (Display *d, Window w, char **c, int i); /* 62 */
+ int (*xSetIconName) (Display *d, Window w, _Xconst char *c); /* 63 */
+ int (*xSetInputFocus) (Display *d, Window w, int i, Time t); /* 64 */
+ int (*xSetSelectionOwner) (Display *d, Atom a, Window w, Time t); /* 65 */
+ int (*xSetWindowBackground) (Display *d, Window w, unsigned long ul); /* 66 */
+ int (*xSetWindowBackgroundPixmap) (Display *d, Window w, Pixmap p); /* 67 */
+ int (*xSetWindowBorder) (Display *d, Window w, unsigned long ul); /* 68 */
+ int (*xSetWindowBorderPixmap) (Display *d, Window w, Pixmap p); /* 69 */
+ int (*xSetWindowBorderWidth) (Display *d, Window w, unsigned int ui); /* 70 */
+ int (*xSetWindowColormap) (Display *d, Window w, Colormap c); /* 71 */
+ Bool (*xTranslateCoordinates) (Display *d, Window w1, Window w2, int i1, int i2, int *i3, int *i4, Window *w3); /* 72 */
+ int (*xUngrabKeyboard) (Display *d, Time t); /* 73 */
+ int (*xUngrabPointer) (Display *d, Time t); /* 74 */
+ int (*xUnmapWindow) (Display *d, Window w); /* 75 */
+ int (*xWindowEvent) (Display *d, Window w, long l, XEvent *x); /* 76 */
+ void (*xDestroyIC) (XIC x); /* 77 */
+ Bool (*xFilterEvent) (XEvent *x, Window w); /* 78 */
+ int (*xmbLookupString) (XIC xi, XKeyPressedEvent *xk, char *c, int i, KeySym *k, Status *s); /* 79 */
+ int (*tkPutImage) (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 */
- int (*xFreeGC) _ANSI_ARGS_((Display *display, GC gc)); /* 84 */
- Atom (*xInternAtom) _ANSI_ARGS_((Display *display, _Xconst char *atom_name, Bool only_if_exists)); /* 85 */
- int (*xSetBackground) _ANSI_ARGS_((Display *display, GC gc, unsigned long foreground)); /* 86 */
- int (*xSetForeground) _ANSI_ARGS_((Display *display, GC gc, unsigned long foreground)); /* 87 */
- int (*xSetClipMask) _ANSI_ARGS_((Display *display, GC gc, Pixmap pixmap)); /* 88 */
- int (*xSetClipOrigin) _ANSI_ARGS_((Display *display, GC gc, int clip_x_origin, int clip_y_origin)); /* 89 */
- int (*xSetTSOrigin) _ANSI_ARGS_((Display *display, GC gc, int ts_x_origin, int ts_y_origin)); /* 90 */
- int (*xChangeGC) _ANSI_ARGS_((Display *d, GC gc, unsigned long mask, XGCValues *values)); /* 91 */
- int (*xSetFont) _ANSI_ARGS_((Display *display, GC gc, Font font)); /* 92 */
- int (*xSetArcMode) _ANSI_ARGS_((Display *display, GC gc, int arc_mode)); /* 93 */
- int (*xSetStipple) _ANSI_ARGS_((Display *display, GC gc, Pixmap stipple)); /* 94 */
- int (*xSetFillRule) _ANSI_ARGS_((Display *display, GC gc, int fill_rule)); /* 95 */
- int (*xSetFillStyle) _ANSI_ARGS_((Display *display, GC gc, int fill_style)); /* 96 */
- int (*xSetFunction) _ANSI_ARGS_((Display *display, GC gc, int function)); /* 97 */
- int (*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_((XIM xim, ...)); /* 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 */
- int (*xDrawLine) _ANSI_ARGS_((Display *d, Drawable dr, GC g, int x1, int y1, int x2, int y2)); /* 104 */
- int (*xWarpPointer) _ANSI_ARGS_((Display *d, Window s, Window dw, int sx, int sy, unsigned int sw, unsigned int sh, int dx, int dy)); /* 105 */
- int (*xFillRectangle) _ANSI_ARGS_((Display *display, Drawable d, GC gc, int x, int y, unsigned int width, unsigned int height)); /* 106 */
- int (*xFlush) _ANSI_ARGS_((Display *display)); /* 107 */
- int (*xGrabServer) _ANSI_ARGS_((Display *display)); /* 108 */
- int (*xUngrabServer) _ANSI_ARGS_((Display *display)); /* 109 */
- int (*xFree) _ANSI_ARGS_((VOID *data)); /* 110 */
- int (*xNoOp) _ANSI_ARGS_((Display *display)); /* 111 */
- XAfterFunction (*xSynchronize) _ANSI_ARGS_((Display *display, Bool onoff)); /* 112 */
- int (*xSync) _ANSI_ARGS_((Display *display, Bool discard)); /* 113 */
- VisualID (*xVisualIDFromVisual) _ANSI_ARGS_((Visual *visual)); /* 114 */
+ Status (*xParseColor) (Display *display, Colormap map, _Xconst char *spec, XColor *colorPtr); /* 82 */
+ GC (*xCreateGC) (Display *display, Drawable d, unsigned long valuemask, XGCValues *values); /* 83 */
+ int (*xFreeGC) (Display *display, GC gc); /* 84 */
+ Atom (*xInternAtom) (Display *display, _Xconst char *atom_name, Bool only_if_exists); /* 85 */
+ int (*xSetBackground) (Display *display, GC gc, unsigned long foreground); /* 86 */
+ int (*xSetForeground) (Display *display, GC gc, unsigned long foreground); /* 87 */
+ int (*xSetClipMask) (Display *display, GC gc, Pixmap pixmap); /* 88 */
+ int (*xSetClipOrigin) (Display *display, GC gc, int clip_x_origin, int clip_y_origin); /* 89 */
+ int (*xSetTSOrigin) (Display *display, GC gc, int ts_x_origin, int ts_y_origin); /* 90 */
+ int (*xChangeGC) (Display *d, GC gc, unsigned long mask, XGCValues *values); /* 91 */
+ int (*xSetFont) (Display *display, GC gc, Font font); /* 92 */
+ int (*xSetArcMode) (Display *display, GC gc, int arc_mode); /* 93 */
+ int (*xSetStipple) (Display *display, GC gc, Pixmap stipple); /* 94 */
+ int (*xSetFillRule) (Display *display, GC gc, int fill_rule); /* 95 */
+ int (*xSetFillStyle) (Display *display, GC gc, int fill_style); /* 96 */
+ int (*xSetFunction) (Display *display, GC gc, int function); /* 97 */
+ int (*xSetLineAttributes) (Display *display, GC gc, unsigned int line_width, int line_style, int cap_style, int join_style); /* 98 */
+ int (*_XInitImageFuncPtrs) (XImage *image); /* 99 */
+ XIC (*xCreateIC) (XIM xim, ...); /* 100 */
+ XVisualInfo * (*xGetVisualInfo) (Display *display, long vinfo_mask, XVisualInfo *vinfo_template, int *nitems_return); /* 101 */
+ void (*xSetWMClientMachine) (Display *display, Window w, XTextProperty *text_prop); /* 102 */
+ Status (*xStringListToTextProperty) (char **list, int count, XTextProperty *text_prop_return); /* 103 */
+ int (*xDrawLine) (Display *d, Drawable dr, GC g, int x1, int y1, int x2, int y2); /* 104 */
+ int (*xWarpPointer) (Display *d, Window s, Window dw, int sx, int sy, unsigned int sw, unsigned int sh, int dx, int dy); /* 105 */
+ int (*xFillRectangle) (Display *display, Drawable d, GC gc, int x, int y, unsigned int width, unsigned int height); /* 106 */
+ int (*xFlush) (Display *display); /* 107 */
+ int (*xGrabServer) (Display *display); /* 108 */
+ int (*xUngrabServer) (Display *display); /* 109 */
+ int (*xFree) (VOID *data); /* 110 */
+ int (*xNoOp) (Display *display); /* 111 */
+ XAfterFunction (*xSynchronize) (Display *display, Bool onoff); /* 112 */
+ int (*xSync) (Display *display, Bool discard); /* 113 */
+ VisualID (*xVisualIDFromVisual) (Visual *visual); /* 114 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
- int (*xSetDashes) _ANSI_ARGS_((Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n)); /* 0 */
- XModifierKeymap * (*xGetModifierMapping) _ANSI_ARGS_((Display *d)); /* 1 */
- XImage * (*xCreateImage) _ANSI_ARGS_((Display *d, Visual *v, unsigned int ui1, int i1, int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3, int i4)); /* 2 */
- XImage * (*xGetImage) _ANSI_ARGS_((Display *d, Drawable dr, int i1, int i2, unsigned int ui1, unsigned int ui2, unsigned long ul, int i3)); /* 3 */
- char * (*xGetAtomName) _ANSI_ARGS_((Display *d, Atom a)); /* 4 */
- char * (*xKeysymToString) _ANSI_ARGS_((KeySym k)); /* 5 */
- Colormap (*xCreateColormap) _ANSI_ARGS_((Display *d, Window w, Visual *v, int i)); /* 6 */
- GContext (*xGContextFromGC) _ANSI_ARGS_((GC g)); /* 7 */
- KeySym (*xKeycodeToKeysym) _ANSI_ARGS_((Display *d, KeyCode k, int i)); /* 8 */
- KeySym (*xStringToKeysym) _ANSI_ARGS_((_Xconst char *c)); /* 9 */
- Window (*xRootWindow) _ANSI_ARGS_((Display *d, int i)); /* 10 */
- XErrorHandler (*xSetErrorHandler) _ANSI_ARGS_((XErrorHandler x)); /* 11 */
- Status (*xAllocColor) _ANSI_ARGS_((Display *d, Colormap c, XColor *xp)); /* 12 */
- int (*xBell) _ANSI_ARGS_((Display *d, int i)); /* 13 */
- void (*xChangeProperty) _ANSI_ARGS_((Display *d, Window w, Atom a1, Atom a2, int i1, int i2, _Xconst unsigned char *c, int i3)); /* 14 */
- void (*xChangeWindowAttributes) _ANSI_ARGS_((Display *d, Window w, unsigned long ul, XSetWindowAttributes *x)); /* 15 */
- void (*xConfigureWindow) _ANSI_ARGS_((Display *d, Window w, unsigned int i, XWindowChanges *x)); /* 16 */
- void (*xCopyArea) _ANSI_ARGS_((Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4)); /* 17 */
- void (*xCopyPlane) _ANSI_ARGS_((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)); /* 18 */
- Pixmap (*xCreateBitmapFromData) _ANSI_ARGS_((Display *display, Drawable d, _Xconst char *data, unsigned int width, unsigned int height)); /* 19 */
- int (*xDefineCursor) _ANSI_ARGS_((Display *d, Window w, Cursor c)); /* 20 */
- void (*xDestroyWindow) _ANSI_ARGS_((Display *d, Window w)); /* 21 */
- void (*xDrawArc) _ANSI_ARGS_((Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4)); /* 22 */
- int (*xDrawLines) _ANSI_ARGS_((Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2)); /* 23 */
- void (*xDrawRectangle) _ANSI_ARGS_((Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2)); /* 24 */
- void (*xFillArc) _ANSI_ARGS_((Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4)); /* 25 */
- void (*xFillPolygon) _ANSI_ARGS_((Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2, int i3)); /* 26 */
- int (*xFillRectangles) _ANSI_ARGS_((Display *d, Drawable dr, GC g, XRectangle *x, int i)); /* 27 */
- int (*xFreeColormap) _ANSI_ARGS_((Display *d, Colormap c)); /* 28 */
- int (*xFreeColors) _ANSI_ARGS_((Display *d, Colormap c, unsigned long *ulp, int i, unsigned long ul)); /* 29 */
- int (*xFreeModifiermap) _ANSI_ARGS_((XModifierKeymap *x)); /* 30 */
- Status (*xGetGeometry) _ANSI_ARGS_((Display *d, Drawable dr, Window *w, int *i1, int *i2, unsigned int *ui1, unsigned int *ui2, unsigned int *ui3, unsigned int *ui4)); /* 31 */
- int (*xGetWindowProperty) _ANSI_ARGS_((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)); /* 32 */
- int (*xGrabKeyboard) _ANSI_ARGS_((Display *d, Window w, Bool b, int i1, int i2, Time t)); /* 33 */
- int (*xGrabPointer) _ANSI_ARGS_((Display *d, Window w1, Bool b, unsigned int ui, int i1, int i2, Window w2, Cursor c, Time t)); /* 34 */
- KeyCode (*xKeysymToKeycode) _ANSI_ARGS_((Display *d, KeySym k)); /* 35 */
- void (*xMapWindow) _ANSI_ARGS_((Display *d, Window w)); /* 36 */
- void (*xMoveResizeWindow) _ANSI_ARGS_((Display *d, Window w, int i1, int i2, unsigned int ui1, unsigned int ui2)); /* 37 */
- void (*xMoveWindow) _ANSI_ARGS_((Display *d, Window w, int i1, int i2)); /* 38 */
- Bool (*xQueryPointer) _ANSI_ARGS_((Display *d, Window w1, Window *w2, Window *w3, int *i1, int *i2, int *i3, int *i4, unsigned int *ui)); /* 39 */
- void (*xRaiseWindow) _ANSI_ARGS_((Display *d, Window w)); /* 40 */
- void (*xRefreshKeyboardMapping) _ANSI_ARGS_((XMappingEvent *x)); /* 41 */
- void (*xResizeWindow) _ANSI_ARGS_((Display *d, Window w, unsigned int ui1, unsigned int ui2)); /* 42 */
- void (*xSelectInput) _ANSI_ARGS_((Display *d, Window w, long l)); /* 43 */
- Status (*xSendEvent) _ANSI_ARGS_((Display *d, Window w, Bool b, long l, XEvent *x)); /* 44 */
- void (*xSetIconName) _ANSI_ARGS_((Display *d, Window w, _Xconst char *c)); /* 45 */
- void (*xSetInputFocus) _ANSI_ARGS_((Display *d, Window w, int i, Time t)); /* 46 */
- int (*xSetSelectionOwner) _ANSI_ARGS_((Display *d, Atom a, Window w, Time t)); /* 47 */
- void (*xSetWindowBackground) _ANSI_ARGS_((Display *d, Window w, unsigned long ul)); /* 48 */
- void (*xSetWindowBackgroundPixmap) _ANSI_ARGS_((Display *d, Window w, Pixmap p)); /* 49 */
- void (*xSetWindowBorder) _ANSI_ARGS_((Display *d, Window w, unsigned long ul)); /* 50 */
- void (*xSetWindowBorderPixmap) _ANSI_ARGS_((Display *d, Window w, Pixmap p)); /* 51 */
- void (*xSetWindowBorderWidth) _ANSI_ARGS_((Display *d, Window w, unsigned int ui)); /* 52 */
- void (*xSetWindowColormap) _ANSI_ARGS_((Display *d, Window w, Colormap c)); /* 53 */
- void (*xUngrabKeyboard) _ANSI_ARGS_((Display *d, Time t)); /* 54 */
- int (*xUngrabPointer) _ANSI_ARGS_((Display *d, Time t)); /* 55 */
- void (*xUnmapWindow) _ANSI_ARGS_((Display *d, Window w)); /* 56 */
- int (*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 */
- int (*xFreeGC) _ANSI_ARGS_((Display *display, GC gc)); /* 60 */
- Atom (*xInternAtom) _ANSI_ARGS_((Display *display, _Xconst char *atom_name, Bool only_if_exists)); /* 61 */
- int (*xSetBackground) _ANSI_ARGS_((Display *display, GC gc, unsigned long foreground)); /* 62 */
- int (*xSetForeground) _ANSI_ARGS_((Display *display, GC gc, unsigned long foreground)); /* 63 */
- int (*xSetClipMask) _ANSI_ARGS_((Display *display, GC gc, Pixmap pixmap)); /* 64 */
- int (*xSetClipOrigin) _ANSI_ARGS_((Display *display, GC gc, int clip_x_origin, int clip_y_origin)); /* 65 */
- int (*xSetTSOrigin) _ANSI_ARGS_((Display *display, GC gc, int ts_x_origin, int ts_y_origin)); /* 66 */
- int (*xChangeGC) _ANSI_ARGS_((Display *d, GC gc, unsigned long mask, XGCValues *values)); /* 67 */
- int (*xSetFont) _ANSI_ARGS_((Display *display, GC gc, Font font)); /* 68 */
- int (*xSetArcMode) _ANSI_ARGS_((Display *display, GC gc, int arc_mode)); /* 69 */
- int (*xSetStipple) _ANSI_ARGS_((Display *display, GC gc, Pixmap stipple)); /* 70 */
- int (*xSetFillRule) _ANSI_ARGS_((Display *display, GC gc, int fill_rule)); /* 71 */
- int (*xSetFillStyle) _ANSI_ARGS_((Display *display, GC gc, int fill_style)); /* 72 */
- int (*xSetFunction) _ANSI_ARGS_((Display *display, GC gc, int function)); /* 73 */
- int (*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 */
- void (*xDrawSegments) _ANSI_ARGS_((Display *display, Drawable d, GC gc, XSegment *segments, int nsegments)); /* 80 */
- void (*xForceScreenSaver) _ANSI_ARGS_((Display *display, int mode)); /* 81 */
- int (*xDrawLine) _ANSI_ARGS_((Display *d, Drawable dr, GC g, int x1, int y1, int x2, int y2)); /* 82 */
- int (*xFillRectangle) _ANSI_ARGS_((Display *display, Drawable d, GC gc, int x, int y, unsigned int width, unsigned int height)); /* 83 */
- void (*xClearWindow) _ANSI_ARGS_((Display *d, Window w)); /* 84 */
- void (*xDrawPoint) _ANSI_ARGS_((Display *display, Drawable d, GC gc, int x, int y)); /* 85 */
- void (*xDrawPoints) _ANSI_ARGS_((Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode)); /* 86 */
- int (*xWarpPointer) _ANSI_ARGS_((Display *display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y)); /* 87 */
- void (*xQueryColor) _ANSI_ARGS_((Display *display, Colormap colormap, XColor *def_in_out)); /* 88 */
- void (*xQueryColors) _ANSI_ARGS_((Display *display, Colormap colormap, XColor *defs_in_out, int ncolors)); /* 89 */
- Status (*xQueryTree) _ANSI_ARGS_((Display *d, Window w1, Window *w2, Window *w3, Window **w4, unsigned int *ui)); /* 90 */
- int (*xSync) _ANSI_ARGS_((Display *display, Bool flag)); /* 91 */
+ int (*xSetDashes) (Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); /* 0 */
+ XModifierKeymap * (*xGetModifierMapping) (Display *d); /* 1 */
+ XImage * (*xCreateImage) (Display *d, Visual *v, unsigned int ui1, int i1, int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3, int i4); /* 2 */
+ XImage * (*xGetImage) (Display *d, Drawable dr, int i1, int i2, unsigned int ui1, unsigned int ui2, unsigned long ul, int i3); /* 3 */
+ char * (*xGetAtomName) (Display *d, Atom a); /* 4 */
+ char * (*xKeysymToString) (KeySym k); /* 5 */
+ Colormap (*xCreateColormap) (Display *d, Window w, Visual *v, int i); /* 6 */
+ GContext (*xGContextFromGC) (GC g); /* 7 */
+ KeySym (*xKeycodeToKeysym) (Display *d, KeyCode k, int i); /* 8 */
+ KeySym (*xStringToKeysym) (_Xconst char *c); /* 9 */
+ Window (*xRootWindow) (Display *d, int i); /* 10 */
+ XErrorHandler (*xSetErrorHandler) (XErrorHandler x); /* 11 */
+ Status (*xAllocColor) (Display *d, Colormap c, XColor *xp); /* 12 */
+ int (*xBell) (Display *d, int i); /* 13 */
+ void (*xChangeProperty) (Display *d, Window w, Atom a1, Atom a2, int i1, int i2, _Xconst unsigned char *c, int i3); /* 14 */
+ void (*xChangeWindowAttributes) (Display *d, Window w, unsigned long ul, XSetWindowAttributes *x); /* 15 */
+ void (*xConfigureWindow) (Display *d, Window w, unsigned int i, XWindowChanges *x); /* 16 */
+ void (*xCopyArea) (Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); /* 17 */
+ void (*xCopyPlane) (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); /* 18 */
+ Pixmap (*xCreateBitmapFromData) (Display *display, Drawable d, _Xconst char *data, unsigned int width, unsigned int height); /* 19 */
+ int (*xDefineCursor) (Display *d, Window w, Cursor c); /* 20 */
+ void (*xDestroyWindow) (Display *d, Window w); /* 21 */
+ void (*xDrawArc) (Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); /* 22 */
+ int (*xDrawLines) (Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2); /* 23 */
+ void (*xDrawRectangle) (Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2); /* 24 */
+ void (*xFillArc) (Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); /* 25 */
+ void (*xFillPolygon) (Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2, int i3); /* 26 */
+ int (*xFillRectangles) (Display *d, Drawable dr, GC g, XRectangle *x, int i); /* 27 */
+ int (*xFreeColormap) (Display *d, Colormap c); /* 28 */
+ int (*xFreeColors) (Display *d, Colormap c, unsigned long *ulp, int i, unsigned long ul); /* 29 */
+ int (*xFreeModifiermap) (XModifierKeymap *x); /* 30 */
+ Status (*xGetGeometry) (Display *d, Drawable dr, Window *w, int *i1, int *i2, unsigned int *ui1, unsigned int *ui2, unsigned int *ui3, unsigned int *ui4); /* 31 */
+ int (*xGetWindowProperty) (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); /* 32 */
+ int (*xGrabKeyboard) (Display *d, Window w, Bool b, int i1, int i2, Time t); /* 33 */
+ int (*xGrabPointer) (Display *d, Window w1, Bool b, unsigned int ui, int i1, int i2, Window w2, Cursor c, Time t); /* 34 */
+ KeyCode (*xKeysymToKeycode) (Display *d, KeySym k); /* 35 */
+ void (*xMapWindow) (Display *d, Window w); /* 36 */
+ void (*xMoveResizeWindow) (Display *d, Window w, int i1, int i2, unsigned int ui1, unsigned int ui2); /* 37 */
+ void (*xMoveWindow) (Display *d, Window w, int i1, int i2); /* 38 */
+ Bool (*xQueryPointer) (Display *d, Window w1, Window *w2, Window *w3, int *i1, int *i2, int *i3, int *i4, unsigned int *ui); /* 39 */
+ void (*xRaiseWindow) (Display *d, Window w); /* 40 */
+ void (*xRefreshKeyboardMapping) (XMappingEvent *x); /* 41 */
+ void (*xResizeWindow) (Display *d, Window w, unsigned int ui1, unsigned int ui2); /* 42 */
+ void (*xSelectInput) (Display *d, Window w, long l); /* 43 */
+ Status (*xSendEvent) (Display *d, Window w, Bool b, long l, XEvent *x); /* 44 */
+ void (*xSetIconName) (Display *d, Window w, _Xconst char *c); /* 45 */
+ void (*xSetInputFocus) (Display *d, Window w, int i, Time t); /* 46 */
+ int (*xSetSelectionOwner) (Display *d, Atom a, Window w, Time t); /* 47 */
+ void (*xSetWindowBackground) (Display *d, Window w, unsigned long ul); /* 48 */
+ void (*xSetWindowBackgroundPixmap) (Display *d, Window w, Pixmap p); /* 49 */
+ void (*xSetWindowBorder) (Display *d, Window w, unsigned long ul); /* 50 */
+ void (*xSetWindowBorderPixmap) (Display *d, Window w, Pixmap p); /* 51 */
+ void (*xSetWindowBorderWidth) (Display *d, Window w, unsigned int ui); /* 52 */
+ void (*xSetWindowColormap) (Display *d, Window w, Colormap c); /* 53 */
+ void (*xUngrabKeyboard) (Display *d, Time t); /* 54 */
+ int (*xUngrabPointer) (Display *d, Time t); /* 55 */
+ void (*xUnmapWindow) (Display *d, Window w); /* 56 */
+ int (*tkPutImage) (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) (Display *display, Colormap map, _Xconst char *spec, XColor *colorPtr); /* 58 */
+ GC (*xCreateGC) (Display *display, Drawable d, unsigned long valuemask, XGCValues *values); /* 59 */
+ int (*xFreeGC) (Display *display, GC gc); /* 60 */
+ Atom (*xInternAtom) (Display *display, _Xconst char *atom_name, Bool only_if_exists); /* 61 */
+ int (*xSetBackground) (Display *display, GC gc, unsigned long foreground); /* 62 */
+ int (*xSetForeground) (Display *display, GC gc, unsigned long foreground); /* 63 */
+ int (*xSetClipMask) (Display *display, GC gc, Pixmap pixmap); /* 64 */
+ int (*xSetClipOrigin) (Display *display, GC gc, int clip_x_origin, int clip_y_origin); /* 65 */
+ int (*xSetTSOrigin) (Display *display, GC gc, int ts_x_origin, int ts_y_origin); /* 66 */
+ int (*xChangeGC) (Display *d, GC gc, unsigned long mask, XGCValues *values); /* 67 */
+ int (*xSetFont) (Display *display, GC gc, Font font); /* 68 */
+ int (*xSetArcMode) (Display *display, GC gc, int arc_mode); /* 69 */
+ int (*xSetStipple) (Display *display, GC gc, Pixmap stipple); /* 70 */
+ int (*xSetFillRule) (Display *display, GC gc, int fill_rule); /* 71 */
+ int (*xSetFillStyle) (Display *display, GC gc, int fill_style); /* 72 */
+ int (*xSetFunction) (Display *display, GC gc, int function); /* 73 */
+ int (*xSetLineAttributes) (Display *display, GC gc, unsigned int line_width, int line_style, int cap_style, int join_style); /* 74 */
+ int (*_XInitImageFuncPtrs) (XImage *image); /* 75 */
+ XIC (*xCreateIC) (void); /* 76 */
+ XVisualInfo * (*xGetVisualInfo) (Display *display, long vinfo_mask, XVisualInfo *vinfo_template, int *nitems_return); /* 77 */
+ void (*xSetWMClientMachine) (Display *display, Window w, XTextProperty *text_prop); /* 78 */
+ Status (*xStringListToTextProperty) (char **list, int count, XTextProperty *text_prop_return); /* 79 */
+ void (*xDrawSegments) (Display *display, Drawable d, GC gc, XSegment *segments, int nsegments); /* 80 */
+ void (*xForceScreenSaver) (Display *display, int mode); /* 81 */
+ int (*xDrawLine) (Display *d, Drawable dr, GC g, int x1, int y1, int x2, int y2); /* 82 */
+ int (*xFillRectangle) (Display *display, Drawable d, GC gc, int x, int y, unsigned int width, unsigned int height); /* 83 */
+ void (*xClearWindow) (Display *d, Window w); /* 84 */
+ void (*xDrawPoint) (Display *display, Drawable d, GC gc, int x, int y); /* 85 */
+ void (*xDrawPoints) (Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode); /* 86 */
+ int (*xWarpPointer) (Display *display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y); /* 87 */
+ void (*xQueryColor) (Display *display, Colormap colormap, XColor *def_in_out); /* 88 */
+ void (*xQueryColors) (Display *display, Colormap colormap, XColor *defs_in_out, int ncolors); /* 89 */
+ Status (*xQueryTree) (Display *d, Window w1, Window *w2, Window *w3, Window **w4, unsigned int *ui); /* 90 */
+ int (*xSync) (Display *display, Bool flag); /* 91 */
#endif /* AQUA */
} TkIntXlibStubs;
diff --git a/generic/tkListbox.c b/generic/tkListbox.c
index 103cd9d..d803d7b 100644
--- a/generic/tkListbox.c
+++ b/generic/tkListbox.c
@@ -1,18 +1,17 @@
-/*
+/*
* tkListbox.c --
*
- * This module implements listbox widgets for the Tk
- * toolkit. A listbox displays a collection of strings,
- * one per line, and provides scrolling and selection.
+ * This module implements listbox widgets for the Tk toolkit. A listbox
+ * displays a collection of strings, one per line, and provides scrolling
+ * and selection.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "default.h"
#include "tkInt.h"
@@ -21,38 +20,40 @@
#endif
typedef struct {
- Tk_OptionTable listboxOptionTable; /* Table defining configuration options
- * available for the listbox */
- Tk_OptionTable itemAttrOptionTable; /* Table definining configuration
- * options available for listbox
- * items */
+ Tk_OptionTable listboxOptionTable;
+ /* Table defining configuration options
+ * available for the listbox. */
+ Tk_OptionTable itemAttrOptionTable;
+ /* Table definining configuration options
+ * available for listbox items. */
} ListboxOptionTables;
/*
- * A data structure of the following type is kept for each listbox
- * widget managed by this file:
+ * A data structure of the following type is kept for each listbox widget
+ * managed by this file:
*/
typedef struct {
- Tk_Window tkwin; /* Window that embodies the listbox. NULL
+ Tk_Window tkwin; /* Window that embodies the listbox. NULL
* means that the window has been destroyed
* but the data structures haven't yet been
- * cleaned up.*/
- Display *display; /* Display containing widget. Used, among
+ * cleaned up. */
+ Display *display; /* Display containing widget. Used, among
* other things, so that resources can be
* freed even after tkwin has gone away. */
Tcl_Interp *interp; /* Interpreter associated with listbox. */
Tcl_Command widgetCmd; /* Token for listbox's widget command. */
Tk_OptionTable optionTable; /* Table that defines configuration options
* available for this widget. */
- Tk_OptionTable itemAttrOptionTable; /* Table that defines configuration
- * options available for listbox
- * items */
- char *listVarName; /* List variable name */
- Tcl_Obj *listObj; /* Pointer to the list object being used */
- int nElements; /* Holds the current count of elements */
- Tcl_HashTable *selection; /* Tracks selection */
- Tcl_HashTable *itemAttrTable; /* Tracks item attributes */
+ Tk_OptionTable itemAttrOptionTable;
+ /* Table that defines configuration options
+ * available for listbox items. */
+ char *listVarName; /* List variable name */
+ Tcl_Obj *listObj; /* Pointer to the list object being used */
+ int nElements; /* Holds the current count of elements */
+ Tcl_HashTable *selection; /* Tracks selection */
+ Tcl_HashTable *itemAttrTable;
+ /* Tracks item attributes */
/*
* Information used when displaying widget:
@@ -62,18 +63,18 @@ typedef struct {
* window, plus used for background. */
int borderWidth; /* Width of 3-D border around window. */
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.
- * <= 0 means don't draw a highlight. */
+ 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. */
+ /* Color for drawing traversal 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.
- * Indicates how much interior stuff must
- * be offset from outside edges to leave
- * room for borders. */
+ * 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 *fgColorPtr; /* Text color in normal mode. */
XColor *dfgColorPtr; /* Text color in disabled mode. */
@@ -85,20 +86,20 @@ typedef struct {
GC selTextGC; /* For drawing selected text. */
int width; /* Desired width of window, in characters. */
int height; /* Desired height of window, in lines. */
- int lineHeight; /* Number of pixels allocated for each line
- * in display. */
+ int lineHeight; /* Number of pixels allocated for each line in
+ * display. */
int topIndex; /* Index of top-most element visible in
* window. */
int fullLines; /* Number of lines that fit are completely
- * visible in window. There may be one
+ * visible in window. There may be one
* additional line at the bottom that is
* partially visible. */
int partialLine; /* 0 means that the window holds exactly
- * fullLines lines. 1 means that there is
- * one additional line that is partially
+ * fullLines lines. 1 means that there is one
+ * additional line that is partially
* visble. */
- int setGrid; /* Non-zero means pass gridding information
- * to window manager. */
+ int setGrid; /* Non-zero means pass gridding information to
+ * window manager. */
/*
* Information to support horizontal scrolling:
@@ -110,26 +111,26 @@ typedef struct {
* horizontal scrolling (window scrolls
* horizontally in increments of this size).
* This is an average character size. */
- int xOffset; /* The left edge of each string in the
- * listbox is offset to the left by this
- * many pixels (0 means no offset, positive
- * means there is an offset). */
+ int xOffset; /* The left edge of each string in the listbox
+ * is offset to the left by this many pixels
+ * (0 means no offset, positive means there is
+ * an offset). */
/*
* Information about what's selected or active, if any.
*/
Tk_Uid selectMode; /* Selection style: single, browse, multiple,
- * or extended. This value isn't used in C
+ * or extended. This value isn't used in C
* code, but the Tcl bindings use it. */
int numSelected; /* Number of elements currently selected. */
- int selectAnchor; /* Fixed end of selection (i.e. element
- * at which selection was started.) */
- int exportSelection; /* Non-zero means tie internal listbox
- * to X selection. */
- int active; /* Index of "active" element (the one that
- * has been selected by keyboard traversal).
- * -1 means none. */
+ int selectAnchor; /* Fixed end of selection (i.e. element at
+ * which selection was started.) */
+ int exportSelection; /* Non-zero means tie internal listbox to X
+ * selection. */
+ int active; /* Index of "active" element (the one that has
+ * been selected by keyboard traversal). -1
+ * means none. */
int activeStyle; /* style in which to draw the active element.
* One of: underline, none, dotbox */
@@ -151,18 +152,18 @@ typedef struct {
*/
Tk_Cursor cursor; /* Current cursor for window, or None. */
- char *takeFocus; /* Value of -takefocus option; not used in
- * the C code, but used by keyboard traversal
- * scripts. Malloc'ed, but may be NULL. */
+ char *takeFocus; /* Value of -takefocus option; not used in the
+ * C code, but used by keyboard traversal
+ * scripts. Malloc'ed, but may be NULL. */
char *yScrollCmd; /* Command prefix for communicating with
- * vertical scrollbar. NULL means no command
- * to issue. Malloc'ed. */
+ * vertical scrollbar. NULL means no command
+ * to issue. Malloc'ed. */
char *xScrollCmd; /* Command prefix for communicating with
- * horizontal scrollbar. NULL means no command
- * to issue. Malloc'ed. */
+ * horizontal scrollbar. NULL means no command
+ * to issue. Malloc'ed. */
int state; /* Listbox state. */
Pixmap gray; /* Pixmap for displaying disabled text. */
- int flags; /* Various flag bits: see below for
+ int flags; /* Various flag bits: see below for
* definitions. */
} Listbox;
@@ -170,26 +171,26 @@ typedef struct {
* ItemAttr structures are used to store item configuration information for
* the items in a listbox
*/
+
typedef struct {
Tk_3DBorder border; /* Used for drawing background around text */
Tk_3DBorder selBorder; /* Used for selected text */
XColor *fgColor; /* Text color in normal mode. */
XColor *selFgColor; /* Text color in selected mode. */
-} ItemAttr;
+} ItemAttr;
/*
* Flag bits for listboxes:
*
- * REDRAW_PENDING: Non-zero means a DoWhenIdle handler
- * has already been queued to redraw
- * this window.
- * UPDATE_V_SCROLLBAR: Non-zero means vertical scrollbar needs
- * to be updated.
- * UPDATE_H_SCROLLBAR: Non-zero means horizontal scrollbar needs
- * to be updated.
- * GOT_FOCUS: Non-zero means this widget currently
- * has the input focus.
- * MAXWIDTH_IS_STALE: Stored maxWidth may be out-of-date
+ * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has
+ * already been queued to redraw this window.
+ * UPDATE_V_SCROLLBAR: Non-zero means vertical scrollbar needs to be
+ * updated.
+ * UPDATE_H_SCROLLBAR: Non-zero means horizontal scrollbar needs to
+ * be updated.
+ * GOT_FOCUS: Non-zero means this widget currently has the
+ * input focus.
+ * MAXWIDTH_IS_STALE: Stored maxWidth may be out-of-date
* LISTBOX_DELETED: This listbox has been effectively destroyed.
*/
@@ -201,42 +202,43 @@ typedef struct {
#define LISTBOX_DELETED 32
/*
- * 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.
+ * The following enum is used to define a type for the -state option of the
+ * Listbox widget. These values are used as indices into the string table
+ * below.
*/
enum state {
STATE_DISABLED, STATE_NORMAL
};
-static CONST char *CONST stateStrings[] = {
- "disabled", "normal", (char *) NULL
+static const char *const stateStrings[] = {
+ "disabled", "normal", NULL
};
enum activeStyle {
ACTIVE_STYLE_DOTBOX, ACTIVE_STYLE_NONE, ACTIVE_STYLE_UNDERLINE
};
-static CONST char *CONST activeStyleStrings[] = {
- "dotbox", "none", "underline", (char *) NULL
+static const char *const activeStyleStrings[] = {
+ "dotbox", "none", "underline", NULL
};
/*
* The optionSpecs table defines the valid configuration options for the
- * listbox widget
+ * listbox widget.
*/
-static CONST Tk_OptionSpec optionSpecs[] = {
+
+static const Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_STRING_TABLE, "-activestyle", "activeStyle", "ActiveStyle",
DEF_LISTBOX_ACTIVE_STYLE, -1, Tk_Offset(Listbox, activeStyle),
- 0, (ClientData) activeStyleStrings, 0},
+ 0, (ClientData) activeStyleStrings, 0},
{TK_OPTION_BORDER, "-background", "background", "Background",
DEF_LISTBOX_BG_COLOR, -1, Tk_Offset(Listbox, normalBorder),
0, (ClientData) DEF_LISTBOX_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_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-background", 0},
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
DEF_LISTBOX_BORDER_WIDTH, -1, Tk_Offset(Listbox, borderWidth),
0, 0, 0},
@@ -249,8 +251,8 @@ static CONST Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
"ExportSelection", DEF_LISTBOX_EXPORT_SELECTION, -1,
Tk_Offset(Listbox, exportSelection), 0, 0, 0},
- {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0},
+ {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
+ NULL, 0, -1, 0, (ClientData) "-foreground", 0},
{TK_OPTION_FONT, "-font", "font", "Font",
DEF_LISTBOX_FONT, -1, Tk_Offset(Listbox, tkfont), 0, 0, 0},
{TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
@@ -258,7 +260,7 @@ static CONST Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_INT, "-height", "height", "Height",
DEF_LISTBOX_HEIGHT, -1, Tk_Offset(Listbox, height), 0, 0, 0},
{TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
- "HighlightBackground", DEF_LISTBOX_HIGHLIGHT_BG, -1,
+ "HighlightBackground", DEF_LISTBOX_HIGHLIGHT_BG, -1,
Tk_Offset(Listbox, highlightBgColorPtr), 0, 0, 0},
{TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
DEF_LISTBOX_HIGHLIGHT, -1, Tk_Offset(Listbox, highlightColorPtr),
@@ -283,8 +285,8 @@ static CONST Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_BOOLEAN, "-setgrid", "setGrid", "SetGrid",
DEF_LISTBOX_SET_GRID, -1, Tk_Offset(Listbox, setGrid), 0, 0, 0},
{TK_OPTION_STRING_TABLE, "-state", "state", "State",
- DEF_LISTBOX_STATE, -1, Tk_Offset(Listbox, state),
- 0, (ClientData) stateStrings, 0},
+ DEF_LISTBOX_STATE, -1, Tk_Offset(Listbox, state),
+ 0, (ClientData) stateStrings, 0},
{TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
DEF_LISTBOX_TAKE_FOCUS, -1, Tk_Offset(Listbox, takeFocus),
TK_OPTION_NULL_OK, 0, 0},
@@ -299,50 +301,48 @@ static CONST Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_STRING, "-listvariable", "listVariable", "Variable",
DEF_LISTBOX_LIST_VARIABLE, -1, Tk_Offset(Listbox, listVarName),
TK_OPTION_NULL_OK, 0, 0},
- {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, 0, 0}
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};
/*
* The itemAttrOptionSpecs table defines the valid configuration options for
* listbox items
*/
-static CONST Tk_OptionSpec itemAttrOptionSpecs[] = {
+
+static const Tk_OptionSpec itemAttrOptionSpecs[] = {
{TK_OPTION_BORDER, "-background", "background", "Background",
- (char *)NULL, -1, Tk_Offset(ItemAttr, border),
+ NULL, -1, Tk_Offset(ItemAttr, border),
TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
(ClientData) DEF_LISTBOX_BG_MONO, 0},
- {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-background", 0},
- {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-background", 0},
+ {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
+ NULL, 0, -1, 0, (ClientData) "-foreground", 0},
{TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
- (char *) NULL, -1, Tk_Offset(ItemAttr, fgColor),
+ NULL, -1, Tk_Offset(ItemAttr, fgColor),
TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
{TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
- (char *) NULL, -1, Tk_Offset(ItemAttr, selBorder),
+ NULL, -1, Tk_Offset(ItemAttr, selBorder),
TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
(ClientData) DEF_LISTBOX_SELECT_MONO, 0},
{TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
- (char *) NULL, -1, Tk_Offset(ItemAttr, selFgColor),
+ NULL, -1, Tk_Offset(ItemAttr, selFgColor),
TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
(ClientData) DEF_LISTBOX_SELECT_FG_MONO, 0},
- {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, 0, 0}
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};
/*
- * The following tables define the listbox widget commands (and sub-
- * commands) and map the indexes into the string tables into
- * enumerated types used to dispatch the listbox widget command.
+ * The following tables define the listbox widget commands (and sub- commands)
+ * and map the indexes into the string tables into enumerated types used to
+ * dispatch the listbox widget command.
*/
-static CONST char *commandNames[] = {
+
+static const char *commandNames[] = {
"activate", "bbox", "cget", "configure", "curselection", "delete", "get",
"index", "insert", "itemcget", "itemconfigure", "nearest", "scan",
- "see", "selection", "size", "xview", "yview",
- (char *) NULL
+ "see", "selection", "size", "xview", "yview", NULL
};
-
enum command {
COMMAND_ACTIVATE, COMMAND_BBOX, COMMAND_CGET, COMMAND_CONFIGURE,
COMMAND_CURSELECTION, COMMAND_DELETE, COMMAND_GET, COMMAND_INDEX,
@@ -351,99 +351,84 @@ enum command {
COMMAND_SIZE, COMMAND_XVIEW, COMMAND_YVIEW
};
-static CONST char *selCommandNames[] = {
- "anchor", "clear", "includes", "set", (char *) NULL
+static const char *selCommandNames[] = {
+ "anchor", "clear", "includes", "set", NULL
};
-
enum selcommand {
SELECTION_ANCHOR, SELECTION_CLEAR, SELECTION_INCLUDES, SELECTION_SET
};
-static CONST char *scanCommandNames[] = {
- "mark", "dragto", (char *) NULL
+static const char *scanCommandNames[] = {
+ "mark", "dragto", NULL
};
-
enum scancommand {
SCAN_MARK, SCAN_DRAGTO
};
-static CONST char *indexNames[] = {
- "active", "anchor", "end", (char *)NULL
+static const char *indexNames[] = {
+ "active", "anchor", "end", NULL
};
-
enum indices {
INDEX_ACTIVE, INDEX_ANCHOR, INDEX_END
};
+/*
+ * Declarations for procedures defined later in this file.
+ */
-/* Declarations for procedures defined later in this file */
-static void ChangeListboxOffset _ANSI_ARGS_((Listbox *listPtr,
- int offset));
-static void ChangeListboxView _ANSI_ARGS_((Listbox *listPtr,
- int index));
-static int ConfigureListbox _ANSI_ARGS_((Tcl_Interp *interp,
- Listbox *listPtr, int objc, Tcl_Obj *CONST objv[],
- int flags));
-static int ConfigureListboxItem _ANSI_ARGS_ ((Tcl_Interp *interp,
+static void ChangeListboxOffset(Listbox *listPtr, int offset);
+static void ChangeListboxView(Listbox *listPtr, int index);
+static int ConfigureListbox(Tcl_Interp *interp, Listbox *listPtr,
+ int objc, Tcl_Obj *const objv[], int flags);
+static int ConfigureListboxItem(Tcl_Interp *interp,
Listbox *listPtr, ItemAttr *attrs, int objc,
- Tcl_Obj *CONST objv[], int index));
-static int ListboxDeleteSubCmd _ANSI_ARGS_((Listbox *listPtr,
- int first, int last));
-static void DestroyListbox _ANSI_ARGS_((char *memPtr));
-static void DestroyListboxOptionTables _ANSI_ARGS_ (
- (ClientData clientData, Tcl_Interp *interp));
-static void DisplayListbox _ANSI_ARGS_((ClientData clientData));
-static int GetListboxIndex _ANSI_ARGS_((Tcl_Interp *interp,
- Listbox *listPtr, Tcl_Obj *index, int endIsSize,
- int *indexPtr));
-static int ListboxInsertSubCmd _ANSI_ARGS_((Listbox *listPtr,
- int index, int objc, Tcl_Obj *CONST objv[]));
-static void ListboxCmdDeletedProc _ANSI_ARGS_((
- ClientData clientData));
-static void ListboxComputeGeometry _ANSI_ARGS_((Listbox *listPtr,
- int fontChanged, int maxIsStale, int updateGrid));
-static void ListboxEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static int ListboxFetchSelection _ANSI_ARGS_((
- ClientData clientData, int offset, char *buffer,
- int maxBytes));
-static void ListboxLostSelection _ANSI_ARGS_((
- ClientData clientData));
-static void EventuallyRedrawRange _ANSI_ARGS_((Listbox *listPtr,
- int first, int last));
-static void ListboxScanTo _ANSI_ARGS_((Listbox *listPtr,
- int x, int y));
-static int ListboxSelect _ANSI_ARGS_((Listbox *listPtr,
- int first, int last, int select));
-static void ListboxUpdateHScrollbar _ANSI_ARGS_(
- (Listbox *listPtr));
-static void ListboxUpdateVScrollbar _ANSI_ARGS_(
- (Listbox *listPtr));
-static int ListboxWidgetObjCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int ListboxBboxSubCmd _ANSI_ARGS_ ((Tcl_Interp *interp,
- Listbox *listPtr, int index));
-static int ListboxSelectionSubCmd _ANSI_ARGS_ (
- (Tcl_Interp *interp, Listbox *listPtr, int objc,
- Tcl_Obj *CONST objv[]));
-static int ListboxXviewSubCmd _ANSI_ARGS_ ((Tcl_Interp *interp,
- Listbox *listPtr, int objc,
- Tcl_Obj *CONST objv[]));
-static int ListboxYviewSubCmd _ANSI_ARGS_ ((Tcl_Interp *interp,
- Listbox *listPtr, int objc,
- Tcl_Obj *CONST objv[]));
-static ItemAttr * ListboxGetItemAttributes _ANSI_ARGS_ (
- (Tcl_Interp *interp, Listbox *listPtr, int index));
-static void ListboxWorldChanged _ANSI_ARGS_((
- ClientData instanceData));
-static int NearestListboxElement _ANSI_ARGS_((Listbox *listPtr,
- int y));
-static char * ListboxListVarProc _ANSI_ARGS_ ((ClientData clientData,
- Tcl_Interp *interp, CONST char *name1,
- CONST char *name2, int flags));
-static void MigrateHashEntries _ANSI_ARGS_ ((Tcl_HashTable *table,
- int first, int last, int offset));
+ Tcl_Obj *const objv[], int index);
+static int ListboxDeleteSubCmd(Listbox *listPtr,
+ int first, int last);
+static void DestroyListbox(char *memPtr);
+static void DestroyListboxOptionTables(ClientData clientData,
+ Tcl_Interp *interp);
+static void DisplayListbox(ClientData clientData);
+static int GetListboxIndex(Tcl_Interp *interp, Listbox *listPtr,
+ Tcl_Obj *index, int endIsSize, int *indexPtr);
+static int ListboxInsertSubCmd(Listbox *listPtr,
+ int index, int objc, Tcl_Obj *const objv[]);
+static void ListboxCmdDeletedProc(ClientData clientData);
+static void ListboxComputeGeometry(Listbox *listPtr,
+ int fontChanged, int maxIsStale, int updateGrid);
+static void ListboxEventProc(ClientData clientData,
+ XEvent *eventPtr);
+static int ListboxFetchSelection(ClientData clientData,
+ int offset, char *buffer, int maxBytes);
+static void ListboxLostSelection(ClientData clientData);
+static void EventuallyRedrawRange(Listbox *listPtr,
+ int first, int last);
+static void ListboxScanTo(Listbox *listPtr, int x, int y);
+static int ListboxSelect(Listbox *listPtr,
+ int first, int last, int select);
+static void ListboxUpdateHScrollbar(Listbox *listPtr);
+static void ListboxUpdateVScrollbar(Listbox *listPtr);
+static int ListboxWidgetObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+static int ListboxBboxSubCmd(Tcl_Interp *interp,
+ Listbox *listPtr, int index);
+static int ListboxSelectionSubCmd(Tcl_Interp *interp,
+ Listbox *listPtr, int objc, Tcl_Obj *const objv[]);
+static int ListboxXviewSubCmd(Tcl_Interp *interp,
+ Listbox *listPtr, int objc, Tcl_Obj *const objv[]);
+static int ListboxYviewSubCmd(Tcl_Interp *interp,
+ Listbox *listPtr, int objc, Tcl_Obj *const objv[]);
+static ItemAttr * ListboxGetItemAttributes(Tcl_Interp *interp,
+ Listbox *listPtr, int index);
+static void ListboxWorldChanged(ClientData instanceData);
+static int NearestListboxElement(Listbox *listPtr, int y);
+static char * ListboxListVarProc(ClientData clientData,
+ Tcl_Interp *interp, const char *name1,
+ const char *name2, int flags);
+static void MigrateHashEntries(Tcl_HashTable *table,
+ int first, int last, int offset);
+
/*
* The structure below defines button class behavior by means of procedures
* that can be invoked from generic window code.
@@ -452,17 +437,17 @@ static void MigrateHashEntries _ANSI_ARGS_ ((Tcl_HashTable *table,
static Tk_ClassProcs listboxClass = {
sizeof(Tk_ClassProcs), /* size */
ListboxWorldChanged, /* worldChangedProc */
+ NULL, /* createProc */
+ NULL /* modalProc */
};
-
/*
*--------------------------------------------------------------
*
* Tk_ListboxObjCmd --
*
- * This procedure is invoked to process the "listbox" Tcl
- * command. See the user documentation for details on what
- * it does.
+ * This procedure is invoked to process the "listbox" Tcl command. See
+ * the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -474,11 +459,11 @@ static Tk_ClassProcs listboxClass = {
*/
int
-Tk_ListboxObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* NULL. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_ListboxObjCmd(
+ ClientData clientData, /* NULL. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
register Listbox *listPtr;
Tk_Window tkwin;
@@ -490,7 +475,7 @@ Tk_ListboxObjCmd(clientData, interp, objc, objv)
}
tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
- Tcl_GetString(objv[1]), (char *) NULL);
+ Tcl_GetString(objv[1]), NULL);
if (tkwin == NULL) {
return TCL_ERROR;
}
@@ -499,56 +484,64 @@ Tk_ListboxObjCmd(clientData, interp, objc, objv)
Tcl_GetAssocData(interp, "ListboxOptionTables", NULL);
if (optionTables == NULL) {
/*
- * We haven't created the option tables for this widget class yet.
- * Do it now and save the a pointer to them as the ClientData for
- * the command, so future invocations will have access to it.
+ * We haven't created the option tables for this widget class yet. Do
+ * it now and save the a pointer to them as the ClientData for the
+ * command, so future invocations will have access to it.
*/
optionTables = (ListboxOptionTables *)
- ckalloc(sizeof(ListboxOptionTables));
- /* Set up an exit handler to free the optionTables struct */
+ ckalloc(sizeof(ListboxOptionTables));
+
+ /*
+ * Set up an exit handler to free the optionTables struct.
+ */
+
Tcl_SetAssocData(interp, "ListboxOptionTables",
DestroyListboxOptionTables, (ClientData) optionTables);
- /* Create the listbox option table and the listbox item option table */
+ /*
+ * Create the listbox option table and the listbox item option table.
+ */
+
optionTables->listboxOptionTable =
- Tk_CreateOptionTable(interp, optionSpecs);
+ Tk_CreateOptionTable(interp, optionSpecs);
optionTables->itemAttrOptionTable =
- Tk_CreateOptionTable(interp, itemAttrOptionSpecs);
+ Tk_CreateOptionTable(interp, itemAttrOptionSpecs);
}
/*
- * Initialize the fields of the structure that won't be initialized
- * by ConfigureListbox, or that ConfigureListbox requires to be
- * initialized already (e.g. resource pointers).
+ * Initialize the fields of the structure that won't be initialized by
+ * ConfigureListbox, or that ConfigureListbox requires to be initialized
+ * already (e.g. resource pointers).
*/
- listPtr = (Listbox *) ckalloc(sizeof(Listbox));
- memset((void *) listPtr, 0, (sizeof(Listbox)));
- listPtr->tkwin = tkwin;
- listPtr->display = Tk_Display(tkwin);
- listPtr->interp = interp;
- listPtr->widgetCmd = Tcl_CreateObjCommand(interp,
+ listPtr = (Listbox *) ckalloc(sizeof(Listbox));
+ memset(listPtr, 0, (sizeof(Listbox)));
+
+ listPtr->tkwin = tkwin;
+ listPtr->display = Tk_Display(tkwin);
+ listPtr->interp = interp;
+ listPtr->widgetCmd = Tcl_CreateObjCommand(interp,
Tk_PathName(listPtr->tkwin), ListboxWidgetObjCmd,
(ClientData) listPtr, ListboxCmdDeletedProc);
- listPtr->optionTable = optionTables->listboxOptionTable;
- listPtr->itemAttrOptionTable = optionTables->itemAttrOptionTable;
- listPtr->selection =
- (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
+ listPtr->optionTable = optionTables->listboxOptionTable;
+ listPtr->itemAttrOptionTable = optionTables->itemAttrOptionTable;
+ listPtr->selection = (Tcl_HashTable *)
+ ckalloc(sizeof(Tcl_HashTable));
Tcl_InitHashTable(listPtr->selection, TCL_ONE_WORD_KEYS);
- listPtr->itemAttrTable =
- (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
+ listPtr->itemAttrTable = (Tcl_HashTable *)
+ ckalloc(sizeof(Tcl_HashTable));
Tcl_InitHashTable(listPtr->itemAttrTable, TCL_ONE_WORD_KEYS);
- listPtr->relief = TK_RELIEF_RAISED;
- listPtr->textGC = None;
- listPtr->selFgColorPtr = None;
- listPtr->selTextGC = None;
- listPtr->fullLines = 1;
- listPtr->xScrollUnit = 1;
- listPtr->exportSelection = 1;
- listPtr->cursor = None;
- listPtr->state = STATE_NORMAL;
- listPtr->gray = None;
+ listPtr->relief = TK_RELIEF_RAISED;
+ listPtr->textGC = None;
+ listPtr->selFgColorPtr = None;
+ listPtr->selTextGC = None;
+ listPtr->fullLines = 1;
+ listPtr->xScrollUnit = 1;
+ listPtr->exportSelection = 1;
+ listPtr->cursor = None;
+ listPtr->state = STATE_NORMAL;
+ listPtr->gray = None;
/*
* Keep a hold of the associated tkwin until we destroy the listbox,
@@ -585,8 +578,8 @@ Tk_ListboxObjCmd(clientData, interp, objc, objv)
* ListboxWidgetObjCmd --
*
* This Tcl_Obj based procedure is invoked to process the Tcl command
- * that corresponds to a widget managed by this module. See the user
- * documentation for details on what it does.
+ * that corresponds to a widget managed by this module. See the user
+ * documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -598,25 +591,26 @@ Tk_ListboxObjCmd(clientData, interp, objc, objv)
*/
static int
-ListboxWidgetObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Information about listbox widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Arguments as Tcl_Obj's. */
+ListboxWidgetObjCmd(
+ ClientData clientData, /* Information about listbox widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Arguments as Tcl_Obj's. */
{
register Listbox *listPtr = (Listbox *) clientData;
int cmdIndex, index;
int result = TCL_OK;
-
+
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
return TCL_ERROR;
}
/*
- * Parse the command by looking up the second argument in the list
- * of valid subcommand names
+ * Parse the command by looking up the second argument in the list of
+ * valid subcommand names
*/
+
result = Tcl_GetIndexFromObj(interp, objv[1], commandNames,
"option", 0, &cmdIndex);
if (result != TCL_OK) {
@@ -624,448 +618,436 @@ ListboxWidgetObjCmd(clientData, interp, objc, objv)
}
Tcl_Preserve((ClientData)listPtr);
- /* The subcommand was valid, so continue processing */
- switch (cmdIndex) {
- case COMMAND_ACTIVATE: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "index");
- result = TCL_ERROR;
- break;
- }
- result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
- if (result != TCL_OK) {
- break;
- }
- if (!(listPtr->state & STATE_NORMAL)) {
- break;
- }
+ /*
+ * The subcommand was valid, so continue processing.
+ */
- if (index >= listPtr->nElements) {
- index = listPtr->nElements-1;
- }
- if (index < 0) {
- index = 0;
- }
- listPtr->active = index;
- EventuallyRedrawRange(listPtr, listPtr->active, listPtr->active);
- result = TCL_OK;
+ switch (cmdIndex) {
+ case COMMAND_ACTIVATE:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
+ result = TCL_ERROR;
+ break;
+ }
+ result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
+ if (result != TCL_OK) {
break;
}
- case COMMAND_BBOX: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "index");
- result = TCL_ERROR;
- break;
- }
- result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
- if (result != TCL_OK) {
- break;
- }
-
- result = ListboxBboxSubCmd(interp, listPtr, index);
+ if (!(listPtr->state & STATE_NORMAL)) {
break;
}
- case COMMAND_CGET: {
- Tcl_Obj *objPtr;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "option");
- result = TCL_ERROR;
- break;
- }
+ if (index >= listPtr->nElements) {
+ index = listPtr->nElements-1;
+ }
+ if (index < 0) {
+ index = 0;
+ }
+ listPtr->active = index;
+ EventuallyRedrawRange(listPtr, listPtr->active, listPtr->active);
+ result = TCL_OK;
+ break;
- objPtr = Tk_GetOptionValue(interp, (char *)listPtr,
- listPtr->optionTable, objv[2], listPtr->tkwin);
- if (objPtr == NULL) {
- result = TCL_ERROR;
- break;
- }
- Tcl_SetObjResult(interp, objPtr);
- result = TCL_OK;
+ case COMMAND_BBOX:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
+ result = TCL_ERROR;
break;
}
-
- case COMMAND_CONFIGURE: {
- Tcl_Obj *objPtr;
- if (objc <= 3) {
- objPtr = Tk_GetOptionInfo(interp, (char *) listPtr,
- listPtr->optionTable,
- (objc == 3) ? objv[2] : (Tcl_Obj *) NULL,
- listPtr->tkwin);
- if (objPtr == NULL) {
- result = TCL_ERROR;
- break;
- } else {
- Tcl_SetObjResult(interp, objPtr);
- result = TCL_OK;
- }
- } else {
- result = ConfigureListbox(interp, listPtr, objc-2, objv+2, 0);
- }
+ result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
+ if (result != TCL_OK) {
break;
}
- case COMMAND_CURSELECTION: {
- char indexStringRep[TCL_INTEGER_SPACE];
- int i;
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- result = TCL_ERROR;
- break;
- }
- /*
- * Of course, it would be more efficient to use the Tcl_HashTable
- * search functions (Tcl_FirstHashEntry, Tcl_NextHashEntry), but
- * then the result wouldn't be in sorted order. So instead we
- * loop through the indices in order, adding them to the result
- * if they are selected
- */
- for (i = 0; i < listPtr->nElements; i++) {
- if (Tcl_FindHashEntry(listPtr->selection, (char *)i) != NULL) {
- sprintf(indexStringRep, "%d", i);
- Tcl_AppendElement(interp, indexStringRep);
- }
- }
- result = TCL_OK;
+ result = ListboxBboxSubCmd(interp, listPtr, index);
+ break;
+
+ case COMMAND_CGET: {
+ Tcl_Obj *objPtr;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option");
+ result = TCL_ERROR;
break;
}
-
- case COMMAND_DELETE: {
- int first, last;
- if ((objc < 3) || (objc > 4)) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "firstIndex ?lastIndex?");
- result = TCL_ERROR;
- break;
- }
- result = GetListboxIndex(interp, listPtr, objv[2], 0, &first);
- if (result != TCL_OK) {
- break;
- }
+ objPtr = Tk_GetOptionValue(interp, (char *) listPtr,
+ listPtr->optionTable, objv[2], listPtr->tkwin);
+ if (objPtr == NULL) {
+ result = TCL_ERROR;
+ break;
+ }
+ Tcl_SetObjResult(interp, objPtr);
+ result = TCL_OK;
+ break;
+ }
- if (!(listPtr->state & STATE_NORMAL)) {
- break;
- }
+ case COMMAND_CONFIGURE: {
+ Tcl_Obj *objPtr;
- if (first < listPtr->nElements) {
- /*
- * if a "last index" was given, get it now; otherwise, use the
- * first index as the last index
- */
- if (objc == 4) {
- result = GetListboxIndex(interp, listPtr,
- objv[3], 0, &last);
- if (result != TCL_OK) {
- break;
- }
- } else {
- last = first;
- }
- if (last >= listPtr->nElements) {
- last = listPtr->nElements - 1;
- }
- result = ListboxDeleteSubCmd(listPtr, first, last);
+ if (objc <= 3) {
+ objPtr = Tk_GetOptionInfo(interp, (char *) listPtr,
+ listPtr->optionTable,
+ (objc == 3) ? objv[2] : NULL, listPtr->tkwin);
+ if (objPtr == NULL) {
+ result = TCL_ERROR;
+ break;
} else {
+ Tcl_SetObjResult(interp, objPtr);
result = TCL_OK;
}
+ } else {
+ result = ConfigureListbox(interp, listPtr, objc-2, objv+2, 0);
+ }
+ break;
+ }
+
+ case COMMAND_CURSELECTION: {
+ char indexStringRep[TCL_INTEGER_SPACE];
+ int i;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
break;
}
- case COMMAND_GET: {
- int first, last;
- Tcl_Obj **elemPtrs;
- int listLen;
- if (objc != 3 && objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
- result = TCL_ERROR;
- break;
- }
- result = GetListboxIndex(interp, listPtr, objv[2], 0, &first);
- if (result != TCL_OK) {
- break;
+ /*
+ * Of course, it would be more efficient to use the Tcl_HashTable
+ * search functions (Tcl_FirstHashEntry, Tcl_NextHashEntry), but then
+ * the result wouldn't be in sorted order. So instead we loop through
+ * the indices in order, adding them to the result if they are
+ * selected.
+ */
+
+ for (i = 0; i < listPtr->nElements; i++) {
+ if (Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i))) {
+ sprintf(indexStringRep, "%d", i);
+ Tcl_AppendElement(interp, indexStringRep);
}
- last = first;
+ }
+ result = TCL_OK;
+ break;
+ }
+
+ case COMMAND_DELETE: {
+ int first, last;
+
+ if ((objc < 3) || (objc > 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
+ result = TCL_ERROR;
+ break;
+ }
+
+ result = GetListboxIndex(interp, listPtr, objv[2], 0, &first);
+ if (result != TCL_OK) {
+ break;
+ }
+
+ if (!(listPtr->state & STATE_NORMAL)) {
+ break;
+ }
+
+ if (first < listPtr->nElements) {
+ /*
+ * if a "last index" was given, get it now; otherwise, use the
+ * first index as the last index.
+ */
+
if (objc == 4) {
result = GetListboxIndex(interp, listPtr, objv[3], 0, &last);
if (result != TCL_OK) {
break;
}
- }
- if (first >= listPtr->nElements) {
- result = TCL_OK;
- break;
+ } else {
+ last = first;
}
if (last >= listPtr->nElements) {
last = listPtr->nElements - 1;
}
- if (first < 0) {
- first = 0;
- }
- if (first > last) {
- result = TCL_OK;
- break;
- }
- result = Tcl_ListObjGetElements(interp, listPtr->listObj, &listLen,
- &elemPtrs);
- if (result != TCL_OK) {
- break;
- }
- if (objc == 3) {
- /*
- * One element request - we return a string
- */
- Tcl_SetObjResult(interp, elemPtrs[first]);
- } else {
- Tcl_SetListObj(Tcl_GetObjResult(interp), (last - first + 1),
- &(elemPtrs[first]));
- }
+ result = ListboxDeleteSubCmd(listPtr, first, last);
+ } else {
result = TCL_OK;
- break;
}
+ break;
+ }
- case COMMAND_INDEX:{
- char buf[TCL_INTEGER_SPACE];
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "index");
- result = TCL_ERROR;
- break;
- }
- result = GetListboxIndex(interp, listPtr, objv[2], 1, &index);
+ case COMMAND_GET: {
+ int first, last, listLen;
+ Tcl_Obj **elemPtrs;
+
+ if (objc != 3 && objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
+ result = TCL_ERROR;
+ break;
+ }
+ result = GetListboxIndex(interp, listPtr, objv[2], 0, &first);
+ if (result != TCL_OK) {
+ break;
+ }
+ last = first;
+ if (objc == 4) {
+ result = GetListboxIndex(interp, listPtr, objv[3], 0, &last);
if (result != TCL_OK) {
break;
}
- sprintf(buf, "%d", index);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ if (first >= listPtr->nElements) {
+ result = TCL_OK;
+ break;
+ }
+ if (last >= listPtr->nElements) {
+ last = listPtr->nElements - 1;
+ }
+ if (first < 0) {
+ first = 0;
+ }
+ if (first > last) {
result = TCL_OK;
break;
}
+ result = Tcl_ListObjGetElements(interp, listPtr->listObj, &listLen,
+ &elemPtrs);
+ if (result != TCL_OK) {
+ break;
+ }
+ if (objc == 3) {
+ /*
+ * One element request - we return a string
+ */
- case COMMAND_INSERT: {
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "index ?element element ...?");
- result = TCL_ERROR;
- break;
- }
+ Tcl_SetObjResult(interp, elemPtrs[first]);
+ } else {
+ Tcl_SetListObj(Tcl_GetObjResult(interp), (last - first + 1),
+ &(elemPtrs[first]));
+ }
+ result = TCL_OK;
+ break;
+ }
- result = GetListboxIndex(interp, listPtr, objv[2], 1, &index);
- if (result != TCL_OK) {
- break;
- }
+ case COMMAND_INDEX:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
+ result = TCL_ERROR;
+ break;
+ }
+ result = GetListboxIndex(interp, listPtr, objv[2], 1, &index);
+ if (result != TCL_OK) {
+ break;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
+ result = TCL_OK;
+ break;
- if (!(listPtr->state & STATE_NORMAL)) {
- break;
- }
+ case COMMAND_INSERT:
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index ?element element ...?");
+ result = TCL_ERROR;
+ break;
+ }
- result = ListboxInsertSubCmd(listPtr, index, objc-3, objv+3);
+ result = GetListboxIndex(interp, listPtr, objv[2], 1, &index);
+ if (result != TCL_OK) {
break;
}
- case COMMAND_ITEMCGET: {
- Tcl_Obj *objPtr;
- ItemAttr *attrPtr;
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "index option");
- result = TCL_ERROR;
- break;
- }
+ if (!(listPtr->state & STATE_NORMAL)) {
+ break;
+ }
- result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
- if (result != TCL_OK) {
- break;
- }
+ result = ListboxInsertSubCmd(listPtr, index, objc-3, objv+3);
+ break;
- if (index < 0 || index >= listPtr->nElements) {
- Tcl_AppendResult(interp, "item number \"",
- Tcl_GetString(objv[2]), "\" out of range",
- (char *)NULL);
- result = TCL_ERROR;
- break;
- }
-
- attrPtr = ListboxGetItemAttributes(interp, listPtr, index);
+ case COMMAND_ITEMCGET: {
+ Tcl_Obj *objPtr;
+ ItemAttr *attrPtr;
- objPtr = Tk_GetOptionValue(interp, (char *)attrPtr,
- listPtr->itemAttrOptionTable, objv[3], listPtr->tkwin);
- if (objPtr == NULL) {
- result = TCL_ERROR;
- break;
- }
- Tcl_SetObjResult(interp, objPtr);
- result = TCL_OK;
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index option");
+ result = TCL_ERROR;
break;
}
- case COMMAND_ITEMCONFIGURE: {
- Tcl_Obj *objPtr;
- ItemAttr *attrPtr;
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "index ?option? ?value? ?option value ...?");
- result = TCL_ERROR;
- break;
- }
+ result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
+ if (result != TCL_OK) {
+ break;
+ }
- result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
- if (result != TCL_OK) {
- break;
- }
-
- if (index < 0 || index >= listPtr->nElements) {
- Tcl_AppendResult(interp, "item number \"",
- Tcl_GetString(objv[2]), "\" out of range",
- (char *)NULL);
- result = TCL_ERROR;
- break;
- }
-
- attrPtr = ListboxGetItemAttributes(interp, listPtr, index);
- if (objc <= 4) {
- objPtr = Tk_GetOptionInfo(interp, (char *)attrPtr,
- listPtr->itemAttrOptionTable,
- (objc == 4) ? objv[3] : (Tcl_Obj *) NULL,
- listPtr->tkwin);
- if (objPtr == NULL) {
- result = TCL_ERROR;
- break;
- } else {
- Tcl_SetObjResult(interp, objPtr);
- result = TCL_OK;
- }
- } else {
- result = ConfigureListboxItem(interp, listPtr, attrPtr,
- objc-3, objv+3, index);
- }
+ if (index < 0 || index >= listPtr->nElements) {
+ Tcl_AppendResult(interp, "item number \"",
+ Tcl_GetString(objv[2]), "\" out of range", NULL);
+ result = TCL_ERROR;
break;
}
-
- case COMMAND_NEAREST: {
- char buf[TCL_INTEGER_SPACE];
- int y;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "y");
- result = TCL_ERROR;
- break;
- }
-
- result = Tcl_GetIntFromObj(interp, objv[2], &y);
- if (result != TCL_OK) {
- break;
- }
- index = NearestListboxElement(listPtr, y);
- sprintf(buf, "%d", index);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
- result = TCL_OK;
+
+ attrPtr = ListboxGetItemAttributes(interp, listPtr, index);
+
+ objPtr = Tk_GetOptionValue(interp, (char *) attrPtr,
+ listPtr->itemAttrOptionTable, objv[3], listPtr->tkwin);
+ if (objPtr == NULL) {
+ result = TCL_ERROR;
break;
}
-
- case COMMAND_SCAN: {
- int x, y, scanCmdIndex;
+ Tcl_SetObjResult(interp, objPtr);
+ result = TCL_OK;
+ break;
+ }
- if (objc != 5) {
- Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y");
- result = TCL_ERROR;
- break;
- }
+ case COMMAND_ITEMCONFIGURE: {
+ Tcl_Obj *objPtr;
+ ItemAttr *attrPtr;
- if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK
- || Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) {
- result = TCL_ERROR;
- break;
- }
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "index ?option? ?value? ?option value ...?");
+ result = TCL_ERROR;
+ break;
+ }
- result = Tcl_GetIndexFromObj(interp, objv[2], scanCommandNames,
- "option", 0, &scanCmdIndex);
- if (result != TCL_OK) {
- break;
- }
- switch (scanCmdIndex) {
- case SCAN_MARK: {
- listPtr->scanMarkX = x;
- listPtr->scanMarkY = y;
- listPtr->scanMarkXOffset = listPtr->xOffset;
- listPtr->scanMarkYIndex = listPtr->topIndex;
- break;
- }
- case SCAN_DRAGTO: {
- ListboxScanTo(listPtr, x, y);
- break;
- }
- }
- result = TCL_OK;
+ result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
+ if (result != TCL_OK) {
+ break;
+ }
+
+ if (index < 0 || index >= listPtr->nElements) {
+ Tcl_AppendResult(interp, "item number \"", Tcl_GetString(objv[2]),
+ "\" out of range", NULL);
+ result = TCL_ERROR;
break;
}
- case COMMAND_SEE: {
- int diff;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "index");
+ attrPtr = ListboxGetItemAttributes(interp, listPtr, index);
+ if (objc <= 4) {
+ objPtr = Tk_GetOptionInfo(interp, (char *) attrPtr,
+ listPtr->itemAttrOptionTable,
+ (objc == 4) ? objv[3] : NULL, listPtr->tkwin);
+ if (objPtr == NULL) {
result = TCL_ERROR;
break;
- }
- result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
- if (result != TCL_OK) {
- break;
- }
- if (index >= listPtr->nElements) {
- index = listPtr->nElements - 1;
- }
- if (index < 0) {
- index = 0;
- }
- diff = listPtr->topIndex - index;
- if (diff > 0) {
- if (diff <= (listPtr->fullLines/3)) {
- ChangeListboxView(listPtr, index);
- } else {
- ChangeListboxView(listPtr,
- index - (listPtr->fullLines-1)/2);
- }
} else {
- diff = index - (listPtr->topIndex + listPtr->fullLines - 1);
- if (diff > 0) {
- if (diff <= (listPtr->fullLines/3)) {
- ChangeListboxView(listPtr, listPtr->topIndex + diff);
- } else {
- ChangeListboxView(listPtr,
- index - (listPtr->fullLines-1)/2);
- }
- }
+ Tcl_SetObjResult(interp, objPtr);
+ result = TCL_OK;
}
- result = TCL_OK;
+ } else {
+ result = ConfigureListboxItem(interp, listPtr, attrPtr,
+ objc-3, objv+3, index);
+ }
+ break;
+ }
+
+ case COMMAND_NEAREST: {
+ int y;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "y");
+ result = TCL_ERROR;
break;
}
- case COMMAND_SELECTION: {
- result = ListboxSelectionSubCmd(interp, listPtr, objc, objv);
+ result = Tcl_GetIntFromObj(interp, objv[2], &y);
+ if (result != TCL_OK) {
break;
}
+ index = NearestListboxElement(listPtr, y);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
+ result = TCL_OK;
+ break;
+ }
- case COMMAND_SIZE: {
- char buf[TCL_INTEGER_SPACE];
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- result = TCL_ERROR;
- break;
- }
- sprintf(buf, "%d", listPtr->nElements);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
- result = TCL_OK;
+ case COMMAND_SCAN: {
+ int x, y, scanCmdIndex;
+
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y");
+ result = TCL_ERROR;
+ break;
+ }
+
+ if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK
+ || Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) {
+ result = TCL_ERROR;
+ break;
+ }
+
+ result = Tcl_GetIndexFromObj(interp, objv[2], scanCommandNames,
+ "option", 0, &scanCmdIndex);
+ if (result != TCL_OK) {
break;
}
+ switch (scanCmdIndex) {
+ case SCAN_MARK:
+ listPtr->scanMarkX = x;
+ listPtr->scanMarkY = y;
+ listPtr->scanMarkXOffset = listPtr->xOffset;
+ listPtr->scanMarkYIndex = listPtr->topIndex;
+ break;
+ case SCAN_DRAGTO:
+ ListboxScanTo(listPtr, x, y);
+ break;
+ }
+ result = TCL_OK;
+ break;
+ }
- case COMMAND_XVIEW: {
- result = ListboxXviewSubCmd(interp, listPtr, objc, objv);
+ case COMMAND_SEE: {
+ int diff;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
+ result = TCL_ERROR;
+ break;
+ }
+ result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
+ if (result != TCL_OK) {
break;
}
-
- case COMMAND_YVIEW: {
- result = ListboxYviewSubCmd(interp, listPtr, objc, objv);
+ if (index >= listPtr->nElements) {
+ index = listPtr->nElements - 1;
+ }
+ if (index < 0) {
+ index = 0;
+ }
+ diff = listPtr->topIndex - index;
+ if (diff > 0) {
+ if (diff <= (listPtr->fullLines/3)) {
+ ChangeListboxView(listPtr, index);
+ } else {
+ ChangeListboxView(listPtr, index - (listPtr->fullLines-1)/2);
+ }
+ } else {
+ diff = index - (listPtr->topIndex + listPtr->fullLines - 1);
+ if (diff > 0) {
+ if (diff <= (listPtr->fullLines/3)) {
+ ChangeListboxView(listPtr, listPtr->topIndex + diff);
+ } else {
+ ChangeListboxView(listPtr, index-(listPtr->fullLines-1)/2);
+ }
+ }
+ }
+ result = TCL_OK;
+ break;
+ }
+
+ case COMMAND_SELECTION:
+ result = ListboxSelectionSubCmd(interp, listPtr, objc, objv);
+ break;
+ case COMMAND_SIZE:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
break;
}
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(listPtr->nElements));
+ result = TCL_OK;
+ break;
+ case COMMAND_XVIEW:
+ result = ListboxXviewSubCmd(interp, listPtr, objc, objv);
+ break;
+ case COMMAND_YVIEW:
+ result = ListboxYviewSubCmd(interp, listPtr, objc, objv);
+ break;
}
Tcl_Release((ClientData)listPtr);
return result;
@@ -1076,34 +1058,41 @@ ListboxWidgetObjCmd(clientData, interp, objc, objv)
*
* ListboxBboxSubCmd --
*
- * This procedure is invoked to process a listbox bbox request.
- * See the user documentation for more information.
+ * This procedure is invoked to process a listbox bbox request. See the
+ * user documentation for more information.
*
* Results:
* A standard Tcl result.
*
* Side effects:
- * For valid indices, places the bbox of the requested element in
- * the interpreter's result.
+ * For valid indices, places the bbox of the requested element in the
+ * interpreter's result.
*
*----------------------------------------------------------------------
*/
static int
-ListboxBboxSubCmd(interp, listPtr, index)
- Tcl_Interp *interp; /* Pointer to the calling Tcl interpreter */
- Listbox *listPtr; /* Information about the listbox */
- int index; /* Index of the element to get bbox info on */
+ListboxBboxSubCmd(
+ Tcl_Interp *interp, /* Pointer to the calling Tcl interpreter */
+ Listbox *listPtr, /* Information about the listbox */
+ int index) /* Index of the element to get bbox info on */
{
int lastVisibleIndex;
- /* Determine the index of the last visible item in the listbox */
+
+ /*
+ * Determine the index of the last visible item in the listbox.
+ */
+
lastVisibleIndex = listPtr->topIndex + listPtr->fullLines
- + listPtr->partialLine;
+ + listPtr->partialLine;
if (listPtr->nElements < lastVisibleIndex) {
lastVisibleIndex = listPtr->nElements;
}
- /* Only allow bbox requests for indices that are visible */
+ /*
+ * Only allow bbox requests for indices that are visible.
+ */
+
if ((listPtr->topIndex <= index) && (index < lastVisibleIndex)) {
char buf[TCL_INTEGER_SPACE * 4];
Tcl_Obj *el;
@@ -1111,7 +1100,10 @@ ListboxBboxSubCmd(interp, listPtr, index)
int pixelWidth, stringLen, x, y, result;
Tk_FontMetrics fm;
- /* Compute the pixel width of the requested element */
+ /*
+ * Compute the pixel width of the requested element.
+ */
+
result = Tcl_ListObjIndex(interp, listPtr->listObj, index, &el);
if (result != TCL_OK) {
return result;
@@ -1123,7 +1115,7 @@ ListboxBboxSubCmd(interp, listPtr, index)
x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset;
y = ((index - listPtr->topIndex)*listPtr->lineHeight)
- + listPtr->inset + listPtr->selBorderWidth;
+ + listPtr->inset + listPtr->selBorderWidth;
sprintf(buf, "%d %d %d %d", x, y, pixelWidth, fm.linespace);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
}
@@ -1135,8 +1127,8 @@ ListboxBboxSubCmd(interp, listPtr, index)
*
* ListboxSelectionSubCmd --
*
- * This procedure is invoked to process the selection sub command
- * for listbox widgets.
+ * This procedure is invoked to process the selection sub command for
+ * listbox widgets.
*
* Results:
* Standard Tcl result.
@@ -1148,14 +1140,15 @@ ListboxBboxSubCmd(interp, listPtr, index)
*/
static int
-ListboxSelectionSubCmd(interp, listPtr, objc, objv)
- Tcl_Interp *interp; /* Pointer to the calling Tcl interpreter */
- Listbox *listPtr; /* Information about the listbox */
- int objc; /* Number of arguments in the objv array */
- Tcl_Obj *CONST objv[]; /* Array of arguments to the procedure */
+ListboxSelectionSubCmd(
+ Tcl_Interp *interp, /* Pointer to the calling Tcl interpreter */
+ Listbox *listPtr, /* Information about the listbox */
+ int objc, /* Number of arguments in the objv array */
+ Tcl_Obj *const objv[]) /* Array of arguments to the procedure */
{
int selCmdIndex, first, last;
int result = TCL_OK;
+
if (objc != 4 && objc != 5) {
Tcl_WrongNumArgs(interp, 2, objv, "option index ?index?");
return TCL_ERROR;
@@ -1187,40 +1180,36 @@ ListboxSelectionSubCmd(interp, listPtr, objc, objv)
}
switch (selCmdIndex) {
- case SELECTION_ANCHOR: {
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 3, objv, "index");
- return TCL_ERROR;
- }
- if (first >= listPtr->nElements) {
- first = listPtr->nElements - 1;
- }
- if (first < 0) {
- first = 0;
- }
- listPtr->selectAnchor = first;
- result = TCL_OK;
- break;
+ case SELECTION_ANCHOR:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index");
+ return TCL_ERROR;
}
- case SELECTION_CLEAR: {
- result = ListboxSelect(listPtr, first, last, 0);
- break;
+ if (first >= listPtr->nElements) {
+ first = listPtr->nElements - 1;
}
- case SELECTION_INCLUDES: {
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 3, objv, "index");
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp,
- Tcl_NewBooleanObj((Tcl_FindHashEntry(listPtr->selection,
- (char *)first) != NULL)));
- result = TCL_OK;
- break;
+ if (first < 0) {
+ first = 0;
}
- case SELECTION_SET: {
- result = ListboxSelect(listPtr, first, last, 1);
- break;
+ listPtr->selectAnchor = first;
+ result = TCL_OK;
+ break;
+ case SELECTION_CLEAR:
+ result = ListboxSelect(listPtr, first, last, 0);
+ break;
+ case SELECTION_INCLUDES:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index");
+ return TCL_ERROR;
}
+ Tcl_SetObjResult(interp,
+ Tcl_NewBooleanObj((Tcl_FindHashEntry(listPtr->selection,
+ (char *) INT2PTR(first)) != NULL)));
+ result = TCL_OK;
+ break;
+ case SELECTION_SET:
+ result = ListboxSelect(listPtr, first, last, 1);
+ break;
}
return result;
}
@@ -1242,33 +1231,35 @@ ListboxSelectionSubCmd(interp, listPtr, objc, objv)
*/
static int
-ListboxXviewSubCmd(interp, listPtr, objc, objv)
- Tcl_Interp *interp; /* Pointer to the calling Tcl interpreter */
- Listbox *listPtr; /* Information about the listbox */
- int objc; /* Number of arguments in the objv array */
- Tcl_Obj *CONST objv[]; /* Array of arguments to the procedure */
+ListboxXviewSubCmd(
+ Tcl_Interp *interp, /* Pointer to the calling Tcl interpreter */
+ Listbox *listPtr, /* Information about the listbox */
+ int objc, /* Number of arguments in the objv array */
+ Tcl_Obj *const objv[]) /* Array of arguments to the procedure */
{
int index, count, type, windowWidth, windowUnits;
int offset = 0; /* Initialized to stop gcc warnings. */
double fraction, fraction2;
-
+
windowWidth = Tk_Width(listPtr->tkwin)
- - 2*(listPtr->inset + listPtr->selBorderWidth);
+ - 2*(listPtr->inset + listPtr->selBorderWidth);
if (objc == 2) {
if (listPtr->maxWidth == 0) {
- Tcl_SetResult(interp, "0 1", TCL_STATIC);
+ Tcl_SetResult(interp, "0.0 1.0", TCL_STATIC);
} else {
- char buf[TCL_DOUBLE_SPACE * 2];
-
+ char buf[TCL_DOUBLE_SPACE];
+
fraction = listPtr->xOffset/((double) listPtr->maxWidth);
fraction2 = (listPtr->xOffset + windowWidth)
- /((double) listPtr->maxWidth);
+ / ((double) listPtr->maxWidth);
if (fraction2 > 1.0) {
fraction2 = 1.0;
}
- sprintf(buf, "%g %g", fraction, fraction2);
+ Tcl_PrintDouble(NULL, fraction, buf);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ Tcl_PrintDouble(NULL, fraction2, buf);
+ Tcl_AppendResult(interp, " ", buf, NULL);
}
} else if (objc == 3) {
if (Tcl_GetIntFromObj(interp, objv[2], &index) != TCL_OK) {
@@ -1278,23 +1269,23 @@ ListboxXviewSubCmd(interp, listPtr, objc, objv)
} else {
type = Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count);
switch (type) {
- case TK_SCROLL_ERROR:
- return TCL_ERROR;
- case TK_SCROLL_MOVETO:
- offset = (int) (fraction*listPtr->maxWidth + 0.5);
- break;
- case TK_SCROLL_PAGES:
- windowUnits = windowWidth/listPtr->xScrollUnit;
- if (windowUnits > 2) {
- offset = listPtr->xOffset
+ case TK_SCROLL_ERROR:
+ return TCL_ERROR;
+ case TK_SCROLL_MOVETO:
+ offset = (int) (fraction*listPtr->maxWidth + 0.5);
+ break;
+ case TK_SCROLL_PAGES:
+ windowUnits = windowWidth/listPtr->xScrollUnit;
+ if (windowUnits > 2) {
+ offset = listPtr->xOffset
+ count*listPtr->xScrollUnit*(windowUnits-2);
- } else {
- offset = listPtr->xOffset + count*listPtr->xScrollUnit;
- }
- break;
- case TK_SCROLL_UNITS:
+ } else {
offset = listPtr->xOffset + count*listPtr->xScrollUnit;
- break;
+ }
+ break;
+ case TK_SCROLL_UNITS:
+ offset = listPtr->xOffset + count*listPtr->xScrollUnit;
+ break;
}
ChangeListboxOffset(listPtr, offset);
}
@@ -1318,29 +1309,31 @@ ListboxXviewSubCmd(interp, listPtr, objc, objv)
*/
static int
-ListboxYviewSubCmd(interp, listPtr, objc, objv)
- Tcl_Interp *interp; /* Pointer to the calling Tcl interpreter */
- Listbox *listPtr; /* Information about the listbox */
- int objc; /* Number of arguments in the objv array */
- Tcl_Obj *CONST objv[]; /* Array of arguments to the procedure */
+ListboxYviewSubCmd(
+ Tcl_Interp *interp, /* Pointer to the calling Tcl interpreter */
+ Listbox *listPtr, /* Information about the listbox */
+ int objc, /* Number of arguments in the objv array */
+ Tcl_Obj *const objv[]) /* Array of arguments to the procedure */
{
int index, count, type;
double fraction, fraction2;
-
+
if (objc == 2) {
if (listPtr->nElements == 0) {
- Tcl_SetResult(interp, "0 1", TCL_STATIC);
+ Tcl_SetResult(interp, "0.0 1.0", TCL_STATIC);
} else {
- char buf[TCL_DOUBLE_SPACE * 2];
-
+ char buf[TCL_DOUBLE_SPACE];
+
fraction = listPtr->topIndex/((double) listPtr->nElements);
fraction2 = (listPtr->topIndex+listPtr->fullLines)
- /((double) listPtr->nElements);
+ /((double) listPtr->nElements);
if (fraction2 > 1.0) {
fraction2 = 1.0;
}
- sprintf(buf, "%g %g", fraction, fraction2);
+ Tcl_PrintDouble(NULL, fraction, buf);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ Tcl_PrintDouble(NULL, fraction2, buf);
+ Tcl_AppendResult(interp, " ", buf, NULL);
}
} else if (objc == 3) {
if (GetListboxIndex(interp, listPtr, objv[2], 0, &index) != TCL_OK) {
@@ -1350,22 +1343,22 @@ ListboxYviewSubCmd(interp, listPtr, objc, objv)
} else {
type = Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count);
switch (type) {
- case TK_SCROLL_ERROR:
- return TCL_ERROR;
- case TK_SCROLL_MOVETO:
- index = (int) (listPtr->nElements*fraction + 0.5);
- break;
- case TK_SCROLL_PAGES:
- if (listPtr->fullLines > 2) {
- index = listPtr->topIndex
- + count*(listPtr->fullLines-2);
- } else {
- index = listPtr->topIndex + count;
- }
- break;
- case TK_SCROLL_UNITS:
+ case TK_SCROLL_MOVETO:
+ index = (int) (listPtr->nElements*fraction + 0.5);
+ break;
+ case TK_SCROLL_PAGES:
+ if (listPtr->fullLines > 2) {
+ index = listPtr->topIndex + count*(listPtr->fullLines-2);
+ } else {
index = listPtr->topIndex + count;
- break;
+ }
+ break;
+ case TK_SCROLL_UNITS:
+ index = listPtr->topIndex + count;
+ break;
+ case TK_SCROLL_ERROR:
+ default:
+ return TCL_ERROR;
}
ChangeListboxView(listPtr, index);
}
@@ -1377,8 +1370,8 @@ ListboxYviewSubCmd(interp, listPtr, objc, objv)
*
* ListboxGetItemAttributes --
*
- * Returns a pointer to the ItemAttr record for a given index,
- * creating one if it does not already exist.
+ * Returns a pointer to the ItemAttr record for a given index, creating
+ * one if it does not already exist.
*
* Results:
* Pointer to an ItemAttr record.
@@ -1390,18 +1383,19 @@ ListboxYviewSubCmd(interp, listPtr, objc, objv)
*/
static ItemAttr *
-ListboxGetItemAttributes(interp, listPtr, index)
- Tcl_Interp *interp; /* Pointer to the calling Tcl interpreter */
- Listbox *listPtr; /* Information about the listbox */
- int index; /* Index of the item to retrieve attributes
- * for */
+ListboxGetItemAttributes(
+ Tcl_Interp *interp, /* Pointer to the calling Tcl interpreter */
+ Listbox *listPtr, /* Information about the listbox */
+ int index) /* Index of the item to retrieve attributes
+ * for. */
{
- int new;
+ int isNew;
Tcl_HashEntry *entry;
ItemAttr *attrs;
- entry = Tcl_CreateHashEntry(listPtr->itemAttrTable, (char *)index, &new);
- if (new) {
+ entry = Tcl_CreateHashEntry(listPtr->itemAttrTable,
+ (char *) INT2PTR(index), &isNew);
+ if (isNew) {
attrs = (ItemAttr *) ckalloc(sizeof(ItemAttr));
attrs->border = NULL;
attrs->selBorder = NULL;
@@ -1420,9 +1414,9 @@ ListboxGetItemAttributes(interp, listPtr, index)
*
* DestroyListbox --
*
- * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release
- * to clean up the internal structure of a listbox at a safe time
- * (when no-one is using it anymore).
+ * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to
+ * clean up the internal structure of a listbox at a safe time (when
+ * no-one is using it anymore).
*
* Results:
* None.
@@ -1434,14 +1428,17 @@ ListboxGetItemAttributes(interp, listPtr, index)
*/
static void
-DestroyListbox(memPtr)
- char *memPtr; /* Info about listbox widget. */
+DestroyListbox(
+ char *memPtr) /* Info about listbox widget. */
{
register Listbox *listPtr = (Listbox *) memPtr;
Tcl_HashEntry *entry;
Tcl_HashSearch search;
- /* If we have an internal list object, free it */
+ /*
+ * If we have an internal list object, free it.
+ */
+
if (listPtr->listObj != NULL) {
Tcl_DecrRefCount(listPtr->listObj);
listPtr->listObj = NULL;
@@ -1452,23 +1449,28 @@ DestroyListbox(memPtr)
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ListboxListVarProc, (ClientData) listPtr);
}
-
- /* Free the selection hash table */
+
+ /*
+ * Free the selection hash table.
+ */
+
Tcl_DeleteHashTable(listPtr->selection);
ckfree((char *)listPtr->selection);
- /* Free the item attribute hash table */
+ /*
+ * Free the item attribute hash table.
+ */
+
for (entry = Tcl_FirstHashEntry(listPtr->itemAttrTable, &search);
- entry != NULL; entry = Tcl_NextHashEntry(&search)) {
+ entry != NULL; entry = Tcl_NextHashEntry(&search)) {
ckfree((char *)Tcl_GetHashValue(entry));
}
Tcl_DeleteHashTable(listPtr->itemAttrTable);
ckfree((char *)listPtr->itemAttrTable);
/*
- * Free up all the stuff that requires special handling, then
- * let Tk_FreeOptions handle all the standard option-related
- * stuff.
+ * Free up all the stuff that requires special handling, then let
+ * Tk_FreeOptions handle all the standard option-related stuff.
*/
if (listPtr->textGC != None) {
@@ -1494,7 +1496,7 @@ DestroyListbox(memPtr)
* DestroyListboxOptionTables --
*
* This procedure is registered as an exit callback when the listbox
- * command is first called. It cleans up the OptionTables structure
+ * command is first called. It cleans up the OptionTables structure
* allocated by that command.
*
* Results:
@@ -1507,11 +1509,11 @@ DestroyListbox(memPtr)
*/
static void
-DestroyListboxOptionTables(clientData, interp)
- ClientData clientData; /* Pointer to the OptionTables struct */
- Tcl_Interp *interp; /* Pointer to the calling interp */
+DestroyListboxOptionTables(
+ ClientData clientData, /* Pointer to the OptionTables struct */
+ Tcl_Interp *interp) /* Pointer to the calling interp */
{
- ckfree((char *)clientData);
+ ckfree((char *) clientData);
return;
}
@@ -1520,30 +1522,29 @@ DestroyListboxOptionTables(clientData, interp)
*
* ConfigureListbox --
*
- * This procedure is called to process an objv/objc list, plus
- * the Tk option database, in order to configure (or reconfigure)
- * a listbox widget.
+ * This procedure is called to process an objv/objc list, plus the Tk
+ * option database, in order to configure (or reconfigure) a listbox
+ * widget.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message.
+ * 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 colors, border width,
- * etc. get set for listPtr; old resources get freed,
- * if there were any.
+ * Configuration information, such as colors, border width, etc. get set
+ * for listPtr; old resources get freed, if there were any.
*
*----------------------------------------------------------------------
*/
static int
-ConfigureListbox(interp, listPtr, objc, objv, flags)
- Tcl_Interp *interp; /* Used for error reporting. */
- register Listbox *listPtr; /* Information about widget; may or may
- * not already have values for some fields. */
- int objc; /* Number of valid entries in argv. */
- Tcl_Obj *CONST objv[]; /* Arguments. */
- int flags; /* Flags to pass to Tk_ConfigureWidget. */
+ConfigureListbox(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ register Listbox *listPtr, /* Information about widget; may or may not
+ * already have values for some fields. */
+ int objc, /* Number of valid entries in argv. */
+ Tcl_Obj *const objv[], /* Arguments. */
+ int flags) /* Flags to pass to Tk_ConfigureWidget. */
{
Tk_SavedOptions savedOptions;
Tcl_Obj *oldListObj = NULL;
@@ -1565,7 +1566,7 @@ ConfigureListbox(interp, listPtr, objc, objv, flags)
if (Tk_SetOptions(interp, (char *) listPtr,
listPtr->optionTable, objc, objv,
- listPtr->tkwin, &savedOptions, (int *) NULL) != TCL_OK) {
+ listPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
continue;
}
} else {
@@ -1601,29 +1602,32 @@ ConfigureListbox(interp, listPtr, objc, objv, flags)
(ClientData) listPtr);
}
- /* Verify the current status of the list var.
+ /*
+ * Verify the current status of the list var.
* PREVIOUS STATE | NEW STATE | ACTION
* ---------------+------------+----------------------------------
- * no listvar | listvar | If listvar does not exist, create
- * it and copy the internal list obj's
- * content to the new var. If it does
- * exist, toss the internal list obj.
+ * no listvar | listvar | If listvar does not exist, create it
+ * and copy the internal list obj's
+ * content to the new var. If it does
+ * exist, toss the internal list obj.
*
- * listvar | no listvar | Copy old listvar content to the
- * internal list obj
+ * listvar | no listvar | Copy old listvar content to the
+ * internal list obj
*
- * listvar | listvar | no special action
+ * listvar | listvar | no special action
*
* no listvar | no listvar | no special action
*/
+
oldListObj = listPtr->listObj;
if (listPtr->listVarName != NULL) {
Tcl_Obj *listVarObj = Tcl_GetVar2Ex(interp, listPtr->listVarName,
- (char *) NULL, TCL_GLOBAL_ONLY);
+ NULL, TCL_GLOBAL_ONLY);
int dummy;
+
if (listVarObj == NULL) {
listVarObj = (oldListObj ? oldListObj : Tcl_NewObj());
- if (Tcl_SetVar2Ex(interp, listPtr->listVarName, (char *) NULL,
+ if (Tcl_SetVar2Ex(interp, listPtr->listVarName, NULL,
listVarObj, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
== NULL) {
if (oldListObj == NULL) {
@@ -1632,11 +1636,15 @@ ConfigureListbox(interp, listPtr, objc, objv, flags)
continue;
}
}
- /* Make sure the object is a good list object */
+
+ /*
+ * Make sure the object is a good list object.
+ */
+
if (Tcl_ListObjLength(listPtr->interp, listVarObj, &dummy)
!= TCL_OK) {
Tcl_AppendResult(listPtr->interp,
- ": invalid -listvariable value", (char *) NULL);
+ ": invalid -listvariable value", NULL);
continue;
}
@@ -1657,11 +1665,14 @@ ConfigureListbox(interp, listPtr, objc, objv, flags)
Tk_FreeSavedOptions(&savedOptions);
}
- /* Make sure that the list length is correct */
+ /*
+ * Make sure that the list length is correct.
+ */
+
Tcl_ListObjLength(listPtr->interp, listPtr->listObj, &listPtr->nElements);
-
+
if (error) {
- Tcl_SetObjResult(interp, errorResult);
+ Tcl_SetObjResult(interp, errorResult);
Tcl_DecrRefCount(errorResult);
return TCL_ERROR;
} else {
@@ -1675,45 +1686,46 @@ ConfigureListbox(interp, listPtr, objc, objv, flags)
*
* ConfigureListboxItem --
*
- * This procedure is called to process an objv/objc list, plus
- * the Tk option database, in order to configure (or reconfigure)
- * a listbox item.
+ * This procedure is called to process an objv/objc list, plus the Tk
+ * option database, in order to configure (or reconfigure) a listbox
+ * item.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message.
+ * 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 colors, border width,
- * etc. get set for a listbox item; old resources get freed,
- * if there were any.
+ * Configuration information, such as colors, border width, etc. get set
+ * for a listbox item; old resources get freed, if there were any.
*
*----------------------------------------------------------------------
*/
static int
-ConfigureListboxItem(interp, listPtr, attrs, objc, objv, index)
- Tcl_Interp *interp; /* Used for error reporting. */
- register Listbox *listPtr; /* Information about widget; may or may
- * not already have values for some fields. */
- ItemAttr *attrs; /* Information about the item to configure */
- int objc; /* Number of valid entries in argv. */
- Tcl_Obj *CONST objv[]; /* Arguments. */
- int index; /* Index of the listbox item being configure */
+ConfigureListboxItem(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ register Listbox *listPtr, /* Information about widget; may or may not
+ * already have values for some fields. */
+ ItemAttr *attrs, /* Information about the item to configure */
+ int objc, /* Number of valid entries in argv. */
+ Tcl_Obj *const objv[], /* Arguments. */
+ int index) /* Index of the listbox item being configure */
{
Tk_SavedOptions savedOptions;
if (Tk_SetOptions(interp, (char *)attrs,
listPtr->itemAttrOptionTable, objc, objv, listPtr->tkwin,
- &savedOptions, (int *)NULL) != TCL_OK) {
+ &savedOptions, NULL) != TCL_OK) {
Tk_RestoreSavedOptions(&savedOptions);
return TCL_ERROR;
}
Tk_FreeSavedOptions(&savedOptions);
+
/*
- * Redraw this index - ListboxWorldChanged would need to be called
- * if item attributes were checked in the "world".
+ * Redraw this index - ListboxWorldChanged would need to be called if item
+ * attributes were checked in the "world".
*/
+
EventuallyRedrawRange(listPtr, index, index);
return TCL_OK;
}
@@ -1723,50 +1735,46 @@ ConfigureListboxItem(interp, listPtr, attrs, objc, objv, index)
*
* ListboxWorldChanged --
*
- * This procedure is called when the world has changed in some
- * way and the widget needs to recompute all its graphics contexts
- * and determine its new geometry.
+ * This procedure is called when the world has changed in some way and
+ * the widget needs to recompute all its graphics contexts and determine
+ * its new geometry.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Listbox will be relayed out and redisplayed.
+ * Listbox will be relayed out and redisplayed.
*
*---------------------------------------------------------------------------
*/
-
+
static void
-ListboxWorldChanged(instanceData)
- ClientData instanceData; /* Information about widget. */
+ListboxWorldChanged(
+ ClientData instanceData) /* Information about widget. */
{
XGCValues gcValues;
GC gc;
unsigned long mask;
- Listbox *listPtr;
-
- listPtr = (Listbox *) instanceData;
+ Listbox *listPtr = (Listbox *) instanceData;
if (listPtr->state & STATE_NORMAL) {
gcValues.foreground = listPtr->fgColorPtr->pixel;
gcValues.graphics_exposures = False;
mask = GCForeground | GCFont | GCGraphicsExposures;
+ } else if (listPtr->dfgColorPtr != NULL) {
+ gcValues.foreground = listPtr->dfgColorPtr->pixel;
+ gcValues.graphics_exposures = False;
+ mask = GCForeground | GCFont | GCGraphicsExposures;
} else {
- if (listPtr->dfgColorPtr != NULL) {
- gcValues.foreground = listPtr->dfgColorPtr->pixel;
- gcValues.graphics_exposures = False;
- mask = GCForeground | GCFont | GCGraphicsExposures;
- } else {
- gcValues.foreground = listPtr->fgColorPtr->pixel;
- mask = GCForeground | GCFont;
- if (listPtr->gray == None) {
- listPtr->gray = Tk_GetBitmap(NULL, listPtr->tkwin, "gray50");
- }
- if (listPtr->gray != None) {
- gcValues.fill_style = FillStippled;
- gcValues.stipple = listPtr->gray;
- mask |= GCFillStyle | GCStipple;
- }
+ gcValues.foreground = listPtr->fgColorPtr->pixel;
+ mask = GCForeground | GCFont;
+ if (listPtr->gray == None) {
+ listPtr->gray = Tk_GetBitmap(NULL, listPtr->tkwin, "gray50");
+ }
+ if (listPtr->gray != None) {
+ gcValues.fill_style = FillStippled;
+ gcValues.stipple = listPtr->gray;
+ mask |= GCFillStyle | GCStipple;
}
}
@@ -1789,8 +1797,8 @@ ListboxWorldChanged(instanceData)
listPtr->selTextGC = gc;
/*
- * Register the desired geometry for the window and arrange for
- * the window to be redisplayed.
+ * Register the desired geometry for the window and arrange for the window
+ * to be redisplayed.
*/
ListboxComputeGeometry(listPtr, 1, 1, 1);
@@ -1815,25 +1823,24 @@ ListboxWorldChanged(instanceData)
*/
static void
-DisplayListbox(clientData)
- ClientData clientData; /* Information about window. */
+DisplayListbox(
+ ClientData clientData) /* Information about window. */
{
register Listbox *listPtr = (Listbox *) clientData;
register Tk_Window tkwin = listPtr->tkwin;
GC gc;
- int i, limit, x, y, width = 0, prevSelected, freeGC;
+ int i, limit, x, y, prevSelected, freeGC, stringLen;
Tk_FontMetrics fm;
Tcl_Obj *curElement;
Tcl_HashEntry *entry;
char *stringRep;
- int stringLen;
ItemAttr *attrs;
Tk_3DBorder selectedBg;
XGCValues gcValues;
unsigned long mask;
- int left, right; /* Non-zero values here indicate
- * that the left or right edge of
- * the listbox is off-screen. */
+ int left, right; /* Non-zero values here indicate that the left
+ * or right edge of the listbox is
+ * off-screen. */
Pixmap pixmap;
listPtr->flags &= ~REDRAW_PENDING;
@@ -1867,11 +1874,11 @@ DisplayListbox(clientData)
#ifndef TK_NO_DOUBLE_BUFFERING
/*
- * Redrawing is done in a temporary pixmap that is allocated
- * here and freed at the end of the procedure. All drawing is
- * done to the pixmap, and the pixmap is copied to the screen
- * at the end of the procedure. This provides the smoothest
- * possible visual effects (no flashing on the screen).
+ * Redrawing is done in a temporary pixmap that is allocated here and
+ * freed at the end of the procedure. All drawing is done to the pixmap,
+ * and the pixmap is copied to the screen at the end of the procedure.
+ * This provides the smoothest possible visual effects (no flashing on the
+ * screen).
*/
pixmap = Tk_GetPixmap(listPtr->display, Tk_WindowId(tkwin),
@@ -1882,7 +1889,10 @@ DisplayListbox(clientData)
Tk_Fill3DRectangle(tkwin, pixmap, listPtr->normalBorder, 0, 0,
Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
- /* Display each item in the listbox */
+ /*
+ * Display each item in the listbox.
+ */
+
limit = listPtr->topIndex + listPtr->fullLines + listPtr->partialLine - 1;
if (limit >= listPtr->nElements) {
limit = listPtr->nElements-1;
@@ -1892,40 +1902,54 @@ DisplayListbox(clientData)
left = listPtr->selBorderWidth+1;
}
if ((listPtr->maxWidth - listPtr->xOffset) > (Tk_Width(listPtr->tkwin)
- - 2*(listPtr->inset + listPtr->selBorderWidth))) {
+ - 2*(listPtr->inset + listPtr->selBorderWidth))) {
right = listPtr->selBorderWidth+1;
}
prevSelected = 0;
-
+
for (i = listPtr->topIndex; i <= limit; i++) {
+ int width = Tk_Width(tkwin); /* zeroth approx to silence warning */
+
x = listPtr->inset;
- y = ((i - listPtr->topIndex) * listPtr->lineHeight)
- + listPtr->inset;
+ y = ((i - listPtr->topIndex) * listPtr->lineHeight) + listPtr->inset;
gc = listPtr->textGC;
freeGC = 0;
+
/*
* Lookup this item in the item attributes table, to see if it has
- * special foreground/background colors
+ * special foreground/background colors.
*/
- entry = Tcl_FindHashEntry(listPtr->itemAttrTable, (char *)i);
+
+ entry = Tcl_FindHashEntry(listPtr->itemAttrTable, (char *) INT2PTR(i));
/*
- * If the listbox is enabled, items may be drawn differently;
- * they may be drawn selected, or they may have special foreground
- * or background colors.
+ * If the listbox is enabled, items may be drawn differently; they may
+ * be drawn selected, or they may have special foreground or
+ * background colors.
*/
+
if (listPtr->state & STATE_NORMAL) {
- if (Tcl_FindHashEntry(listPtr->selection, (char *)i) != NULL) {
- /* Selected items are drawn differently. */
+ if (Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i))) {
+ /*
+ * Selected items are drawn differently.
+ */
+
gc = listPtr->selTextGC;
width = Tk_Width(tkwin) - 2*listPtr->inset;
selectedBg = listPtr->selBorder;
-
- /* If there is attribute information for this item,
- * adjust the drawing accordingly */
+
+ /*
+ * If there is attribute information for this item, adjust the
+ * drawing accordingly.
+ */
+
if (entry != NULL) {
attrs = (ItemAttr *)Tcl_GetHashValue(entry);
- /* Default GC has the values from the widget at large */
+
+ /*
+ * Default GC has the values from the widget at large.
+ */
+
if (listPtr->selFgColorPtr) {
gcValues.foreground = listPtr->selFgColorPtr->pixel;
} else {
@@ -1934,11 +1958,11 @@ DisplayListbox(clientData)
gcValues.font = Tk_FontId(listPtr->tkfont);
gcValues.graphics_exposures = False;
mask = GCForeground | GCFont | GCGraphicsExposures;
-
+
if (attrs->selBorder != NULL) {
selectedBg = attrs->selBorder;
}
-
+
if (attrs->selFgColor != NULL) {
gcValues.foreground = attrs->selFgColor->pixel;
gc = Tk_GetGC(listPtr->tkwin, mask, &gcValues);
@@ -1988,7 +2012,7 @@ DisplayListbox(clientData)
/* Draw bottom bevel */
if (i + 1 == listPtr->nElements ||
Tcl_FindHashEntry(listPtr->selection,
- (char *)(i + 1)) == NULL ) {
+ (char *) INT2PTR(i + 1)) == NULL ) {
Tk_3DHorizontalBevel(tkwin, pixmap, selectedBg, x-left,
y + listPtr->lineHeight - listPtr->selBorderWidth,
width+left+right, listPtr->selBorderWidth, 0, 0, 0,
@@ -2000,28 +2024,29 @@ DisplayListbox(clientData)
* If there is an item attributes record for this item, draw
* the background box and set the foreground color accordingly
*/
+
if (entry != NULL) {
attrs = (ItemAttr *)Tcl_GetHashValue(entry);
gcValues.foreground = listPtr->fgColorPtr->pixel;
gcValues.font = Tk_FontId(listPtr->tkfont);
gcValues.graphics_exposures = False;
mask = GCForeground | GCFont | GCGraphicsExposures;
-
+
/*
* If the item has its own background color, draw it now.
*/
-
+
if (attrs->border != NULL) {
width = Tk_Width(tkwin) - 2*listPtr->inset;
Tk_Fill3DRectangle(tkwin, pixmap, attrs->border, x, y,
width, listPtr->lineHeight, 0, TK_RELIEF_FLAT);
}
-
+
/*
* If the item has its own foreground, use it to override
* the value in the gcValues structure.
*/
-
+
if ((listPtr->state & STATE_NORMAL)
&& attrs->fgColor != NULL) {
gcValues.foreground = attrs->fgColor->pixel;
@@ -2033,7 +2058,10 @@ DisplayListbox(clientData)
}
}
- /* Draw the actual text of this item */
+ /*
+ * Draw the actual text of this item.
+ */
+
Tk_GetFontMetrics(listPtr->tkfont, &fm);
y += fm.ascent + listPtr->selBorderWidth;
x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset;
@@ -2042,10 +2070,16 @@ DisplayListbox(clientData)
Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont,
stringRep, stringLen, x, y);
- /* If this is the active element, apply the activestyle to it. */
+ /*
+ * If this is the active element, apply the activestyle to it.
+ */
+
if ((i == listPtr->active) && (listPtr->flags & GOT_FOCUS)) {
if (listPtr->activeStyle == ACTIVE_STYLE_UNDERLINE) {
- /* Underline the text. */
+ /*
+ * Underline the text.
+ */
+
Tk_UnderlineChars(listPtr->display, pixmap, gc,
listPtr->tkfont, stringRep, x, y, 0, stringLen);
} else if (listPtr->activeStyle == ACTIVE_STYLE_DOTBOX) {
@@ -2053,52 +2087,59 @@ DisplayListbox(clientData)
/*
* This provides for exact default look and feel on Windows.
*/
+
TkWinDCState state;
HDC dc;
RECT rect;
dc = TkWinGetDrawableDC(listPtr->display, pixmap, &state);
- rect.left = listPtr->inset;
- rect.top = ((i - listPtr->topIndex) * listPtr->lineHeight)
- + listPtr->inset;
- rect.right = rect.left + width;
+ rect.left = listPtr->inset;
+ rect.top = ((i - listPtr->topIndex) * listPtr->lineHeight)
+ + listPtr->inset;
+ rect.right = rect.left + width;
rect.bottom = rect.top + listPtr->lineHeight;
DrawFocusRect(dc, &rect);
TkWinReleaseDrawableDC(pixmap, dc, &state);
-#else
+#else /* !WIN32 */
/*
* Draw a dotted box around the text.
*/
+
x = listPtr->inset;
y = ((i - listPtr->topIndex) * listPtr->lineHeight)
- + listPtr->inset;
+ + listPtr->inset;
width = Tk_Width(tkwin) - 2*listPtr->inset - 1;
- gcValues.line_style = LineOnOffDash;
- gcValues.line_width = listPtr->selBorderWidth;
+ gcValues.line_style = LineOnOffDash;
+ gcValues.line_width = listPtr->selBorderWidth;
if (gcValues.line_width <= 0) {
gcValues.line_width = 1;
}
gcValues.dash_offset = 0;
- gcValues.dashes = 1;
+ gcValues.dashes = 1;
+
/*
* You would think the XSetDashes was necessary, but it
- * appears that the default dotting for just saying we
- * want dashes appears to work correctly.
+ * appears that the default dotting for just saying we want
+ * dashes appears to work correctly.
static char dashList[] = { 1 };
- static int dashLen = sizeof(dashList);
+ static int dashLen = sizeof(dashList);
XSetDashes(listPtr->display, gc, 0, dashList, dashLen);
*/
+
mask = GCLineWidth | GCLineStyle | GCDashList | GCDashOffset;
XChangeGC(listPtr->display, gc, mask, &gcValues);
XDrawRectangle(listPtr->display, pixmap, gc, x, y,
(unsigned) width, (unsigned) listPtr->lineHeight - 1);
if (!freeGC) {
- /* Don't bother changing if it is about to be freed. */
+ /*
+ * Don't bother changing if it is about to be freed.
+ */
+
gcValues.line_style = LineSolid;
XChangeGC(listPtr->display, gc, GCLineStyle, &gcValues);
}
-#endif
+#endif /* WIN32 */
}
}
@@ -2108,8 +2149,8 @@ DisplayListbox(clientData)
}
/*
- * Redraw the border for the listbox to make sure that it's on top
- * of any of the text of the listbox entries.
+ * Redraw the border for the listbox to make sure that it's on top of any
+ * of the text of the listbox entries.
*/
Tk_Draw3DRectangle(tkwin, pixmap, listPtr->normalBorder,
@@ -2123,11 +2164,11 @@ DisplayListbox(clientData)
bgGC = Tk_GCForColor(listPtr->highlightBgColorPtr, pixmap);
if (listPtr->flags & GOT_FOCUS) {
fgGC = Tk_GCForColor(listPtr->highlightColorPtr, pixmap);
- TkpDrawHighlightBorder(tkwin, fgGC, bgGC,
- listPtr->highlightWidth, pixmap);
+ TkpDrawHighlightBorder(tkwin, fgGC, bgGC,
+ listPtr->highlightWidth, pixmap);
} else {
- TkpDrawHighlightBorder(tkwin, bgGC, bgGC,
- listPtr->highlightWidth, pixmap);
+ TkpDrawHighlightBorder(tkwin, bgGC, bgGC,
+ listPtr->highlightWidth, pixmap);
}
}
#ifndef TK_NO_DOUBLE_BUFFERING
@@ -2143,51 +2184,51 @@ DisplayListbox(clientData)
*
* ListboxComputeGeometry --
*
- * This procedure is invoked to recompute geometry information
- * such as the sizes of the elements and the overall dimensions
- * desired for the listbox.
+ * This procedure is invoked to recompute geometry information such as
+ * the sizes of the elements and the overall dimensions desired for the
+ * listbox.
*
* Results:
* None.
*
* Side effects:
- * Geometry information is updated and a new requested size is
- * registered for the widget. Internal border and gridding
- * information is also set.
+ * Geometry information is updated and a new requested size is registered
+ * for the widget. Internal border and gridding information is also set.
*
*----------------------------------------------------------------------
*/
static void
-ListboxComputeGeometry(listPtr, fontChanged, maxIsStale, updateGrid)
- Listbox *listPtr; /* Listbox whose geometry is to be
+ListboxComputeGeometry(
+ Listbox *listPtr, /* Listbox whose geometry is to be
* recomputed. */
- int fontChanged; /* Non-zero means the font may have changed
- * so per-element width information also
- * has to be computed. */
- int maxIsStale; /* Non-zero means the "maxWidth" field may
- * no longer be up-to-date and must
- * be recomputed. If fontChanged is 1 then
- * this must be 1. */
- int updateGrid; /* Non-zero means call Tk_SetGrid or
- * Tk_UnsetGrid to update gridding for
- * the window. */
+ int fontChanged, /* Non-zero means the font may have changed so
+ * per-element width information also has to
+ * be computed. */
+ int maxIsStale, /* Non-zero means the "maxWidth" field may no
+ * longer be up-to-date and must be
+ * recomputed. If fontChanged is 1 then this
+ * must be 1. */
+ int updateGrid) /* Non-zero means call Tk_SetGrid or
+ * Tk_UnsetGrid to update gridding for the
+ * window. */
{
- int width, height, pixelWidth, pixelHeight;
+ int width, height, pixelWidth, pixelHeight, textLength, i, result;
Tk_FontMetrics fm;
Tcl_Obj *element;
- int textLength;
char *text;
- int i, result;
-
- if (fontChanged || maxIsStale) {
+
+ if (fontChanged || maxIsStale) {
listPtr->xScrollUnit = Tk_TextWidth(listPtr->tkfont, "0", 1);
if (listPtr->xScrollUnit == 0) {
listPtr->xScrollUnit = 1;
}
listPtr->maxWidth = 0;
for (i = 0; i < listPtr->nElements; i++) {
- /* Compute the pixel width of the current element */
+ /*
+ * Compute the pixel width of the current element.
+ */
+
result = Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i,
&element);
if (result != TCL_OK) {
@@ -2239,87 +2280,92 @@ ListboxComputeGeometry(listPtr, fontChanged, maxIsStale, updateGrid)
*
* ListboxInsertSubCmd --
*
- * This procedure is invoked to handle the listbox "insert"
- * subcommand.
+ * This procedure is invoked to handle the listbox "insert" subcommand.
*
* Results:
* Standard Tcl result.
*
* Side effects:
- * New elements are added to the listbox pointed to by listPtr;
- * a refresh callback is registered for the listbox.
+ * New elements are added to the listbox pointed to by listPtr; a refresh
+ * callback is registered for the listbox.
*
*----------------------------------------------------------------------
*/
static int
-ListboxInsertSubCmd(listPtr, index, objc, objv)
- register Listbox *listPtr; /* Listbox that is to get the new
- * elements. */
- int index; /* Add the new elements before this
+ListboxInsertSubCmd(
+ register Listbox *listPtr, /* Listbox that is to get the new elements. */
+ int index, /* Add the new elements before this
* element. */
- int objc; /* Number of new elements to add. */
- Tcl_Obj *CONST objv[]; /* New elements (one per entry). */
+ int objc, /* Number of new elements to add. */
+ Tcl_Obj *const objv[]) /* New elements (one per entry). */
{
- int i, oldMaxWidth;
+ int i, oldMaxWidth, pixelWidth, result, length;
Tcl_Obj *newListObj;
- int pixelWidth;
- int result;
char *stringRep;
- int length;
-
+
oldMaxWidth = listPtr->maxWidth;
for (i = 0; i < objc; i++) {
/*
* Check if any of the new elements are wider than the current widest;
* if so, update our notion of "widest."
*/
+
stringRep = Tcl_GetStringFromObj(objv[i], &length);
pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length);
if (pixelWidth > listPtr->maxWidth) {
listPtr->maxWidth = pixelWidth;
}
}
-
- /* Adjust selection and attribute information for every index after
- * the first index */
+
+ /*
+ * Adjust selection and attribute information for every index after the
+ * first index.
+ */
+
MigrateHashEntries(listPtr->selection, index, listPtr->nElements-1, objc);
MigrateHashEntries(listPtr->itemAttrTable, index, listPtr->nElements-1,
objc);
-
- /* If the object is shared, duplicate it before writing to it */
+
+ /*
+ * If the object is shared, duplicate it before writing to it.
+ */
+
if (Tcl_IsShared(listPtr->listObj)) {
newListObj = Tcl_DuplicateObj(listPtr->listObj);
} else {
newListObj = listPtr->listObj;
}
- result =
- Tcl_ListObjReplace(listPtr->interp, newListObj, index, 0, objc, objv);
+ result = Tcl_ListObjReplace(listPtr->interp, newListObj, index, 0,
+ objc, objv);
if (result != TCL_OK) {
return result;
}
/*
- * Replace the current object and set attached listvar, if any.
- * This may error if listvar points to a var in a deleted namespace, but
- * we ignore those errors. If the namespace is recreated, it will
- * auto-sync with the current value. [Bug 1424513]
+ * Replace the current object and set attached listvar, if any. This may
+ * error if listvar points to a var in a deleted namespace, but we ignore
+ * those errors. If the namespace is recreated, it will auto-sync with the
+ * current value. [Bug 1424513]
*/
Tcl_IncrRefCount(newListObj);
Tcl_DecrRefCount(listPtr->listObj);
listPtr->listObj = newListObj;
if (listPtr->listVarName != NULL) {
- Tcl_SetVar2Ex(listPtr->interp, listPtr->listVarName,
- (char *) NULL, listPtr->listObj, TCL_GLOBAL_ONLY);
+ Tcl_SetVar2Ex(listPtr->interp, listPtr->listVarName, NULL,
+ listPtr->listObj, TCL_GLOBAL_ONLY);
}
- /* Get the new list length */
+ /*
+ * Get the new list length.
+ */
+
Tcl_ListObjLength(listPtr->interp, listPtr->listObj, &listPtr->nElements);
/*
- * Update the "special" indices (anchor, topIndex, active) to account
- * for the renumbering that just occurred. Then arrange for the new
+ * Update the "special" indices (anchor, topIndex, active) to account for
+ * the renumbering that just occurred. Then arrange for the new
* information to be displayed.
*/
@@ -2350,8 +2396,8 @@ ListboxInsertSubCmd(listPtr, index, objc, objv)
*
* ListboxDeleteSubCmd --
*
- * Process a listbox "delete" subcommand by removing one or more
- * elements from a listbox widget.
+ * Process a listbox "delete" subcommand by removing one or more elements
+ * from a listbox widget.
*
* Results:
* Standard Tcl result.
@@ -2363,23 +2409,19 @@ ListboxInsertSubCmd(listPtr, index, objc, objv)
*/
static int
-ListboxDeleteSubCmd(listPtr, first, last)
- register Listbox *listPtr; /* Listbox widget to modify. */
- int first; /* Index of first element to delete. */
- int last; /* Index of last element to delete. */
+ListboxDeleteSubCmd(
+ register Listbox *listPtr, /* Listbox widget to modify. */
+ int first, /* Index of first element to delete. */
+ int last) /* Index of last element to delete. */
{
- int count, i, widthChanged;
- Tcl_Obj *newListObj;
- Tcl_Obj *element;
- int length;
+ int count, i, widthChanged, length, result, pixelWidth;
+ Tcl_Obj *newListObj, *element;
char *stringRep;
- int result;
- int pixelWidth;
Tcl_HashEntry *entry;
-
+
/*
- * Adjust the range to fit within the existing elements of the
- * listbox, and make sure there's something to delete.
+ * Adjust the range to fit within the existing elements of the listbox,
+ * and make sure there's something to delete.
*/
if (first < 0) {
@@ -2395,30 +2437,36 @@ ListboxDeleteSubCmd(listPtr, first, last)
/*
* Foreach deleted index we must:
- * a) remove selection information
+ * a) remove selection information,
* b) check the width of the element; if it is equal to the max, set
* widthChanged to 1, because it may be the only element with that
- * width
+ * width.
*/
+
widthChanged = 0;
for (i = first; i <= last; i++) {
- /* Remove selection information */
- entry = Tcl_FindHashEntry(listPtr->selection, (char *)i);
+ /*
+ * Remove selection information.
+ */
+
+ entry = Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i));
if (entry != NULL) {
listPtr->numSelected--;
Tcl_DeleteHashEntry(entry);
}
- entry = Tcl_FindHashEntry(listPtr->itemAttrTable, (char *)i);
+ entry = Tcl_FindHashEntry(listPtr->itemAttrTable, (char *) INT2PTR(i));
if (entry != NULL) {
ckfree((char *)Tcl_GetHashValue(entry));
Tcl_DeleteHashEntry(entry);
}
-
- /* Check width of the element. We only have to check if widthChanged
+
+ /*
+ * Check width of the element. We only have to check if widthChanged
* has not already been set to 1, because we only need one maxWidth
* element to disappear for us to have to recompute the width
*/
+
if (widthChanged == 0) {
Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &element);
stringRep = Tcl_GetStringFromObj(element, &length);
@@ -2429,13 +2477,19 @@ ListboxDeleteSubCmd(listPtr, first, last)
}
}
- /* Adjust selection and attribute info for indices after lastIndex */
+ /*
+ * Adjust selection and attribute info for indices after lastIndex.
+ */
+
MigrateHashEntries(listPtr->selection, last+1,
listPtr->nElements-1, count*-1);
MigrateHashEntries(listPtr->itemAttrTable, last+1,
listPtr->nElements-1, count*-1);
- /* Delete the requested elements */
+ /*
+ * Delete the requested elements.
+ */
+
if (Tcl_IsShared(listPtr->listObj)) {
newListObj = Tcl_DuplicateObj(listPtr->listObj);
} else {
@@ -2448,27 +2502,30 @@ ListboxDeleteSubCmd(listPtr, first, last)
}
/*
- * Replace the current object and set attached listvar, if any.
- * This may error if listvar points to a var in a deleted namespace, but
- * we ignore those errors. If the namespace is recreated, it will
- * auto-sync with the current value. [Bug 1424513]
+ * Replace the current object and set attached listvar, if any. This may
+ * error if listvar points to a var in a deleted namespace, but we ignore
+ * those errors. If the namespace is recreated, it will auto-sync with the
+ * current value. [Bug 1424513]
*/
Tcl_IncrRefCount(newListObj);
Tcl_DecrRefCount(listPtr->listObj);
listPtr->listObj = newListObj;
if (listPtr->listVarName != NULL) {
- Tcl_SetVar2Ex(listPtr->interp, listPtr->listVarName,
- (char *) NULL, listPtr->listObj, TCL_GLOBAL_ONLY);
+ Tcl_SetVar2Ex(listPtr->interp, listPtr->listVarName, NULL,
+ listPtr->listObj, TCL_GLOBAL_ONLY);
}
- /* Get the new list length */
+ /*
+ * Get the new list length.
+ */
+
Tcl_ListObjLength(listPtr->interp, listPtr->listObj, &listPtr->nElements);
/*
- * Update the selection and viewing information to reflect the change
- * in the element numbering, and redisplay to slide information up over
- * the elements that were deleted.
+ * Update the selection and viewing information to reflect the change in
+ * the element numbering, and redisplay to slide information up over the
+ * elements that were deleted.
*/
if (first <= listPtr->selectAnchor) {
@@ -2512,26 +2569,26 @@ ListboxDeleteSubCmd(listPtr, first, last)
*
* ListboxEventProc --
*
- * This procedure is invoked by the Tk dispatcher for various
- * events on listboxes.
+ * This procedure is invoked by the Tk dispatcher for various events on
+ * listboxes.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up. When
+ * it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-ListboxEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- XEvent *eventPtr; /* Information about event. */
+ListboxEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
Listbox *listPtr = (Listbox *) clientData;
-
+
if (eventPtr->type == Expose) {
EventuallyRedrawRange(listPtr,
NearestListboxElement(listPtr, eventPtr->xexpose.y),
@@ -2564,10 +2621,9 @@ ListboxEventProc(clientData, eventPtr)
ChangeListboxOffset(listPtr, listPtr->xOffset);
/*
- * Redraw the whole listbox. It's hard to tell what needs
- * to be redrawn (e.g. if the listbox has shrunk then we
- * may only need to redraw the borders), so just redraw
- * everything for safety.
+ * Redraw the whole listbox. It's hard to tell what needs to be
+ * redrawn (e.g. if the listbox has shrunk then we may only need to
+ * redraw the borders), so just redraw everything for safety.
*/
EventuallyRedrawRange(listPtr, 0, listPtr->nElements-1);
@@ -2589,9 +2645,9 @@ ListboxEventProc(clientData, eventPtr)
*
* ListboxCmdDeletedProc --
*
- * 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.
+ * 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.
@@ -2603,16 +2659,16 @@ ListboxEventProc(clientData, eventPtr)
*/
static void
-ListboxCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+ListboxCmdDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
Listbox *listPtr = (Listbox *) clientData;
/*
- * 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.
+ * 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.
*/
if (!(listPtr->flags & LISTBOX_DELETED)) {
@@ -2625,13 +2681,12 @@ ListboxCmdDeletedProc(clientData)
*
* GetListboxIndex --
*
- * Parse an index into a listbox and return either its value
- * or an error.
+ * Parse an index into a listbox and return either its value or an error.
*
* 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 the interp's result.
+ * 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 the interp's result.
*
* Side effects:
* None.
@@ -2640,62 +2695,62 @@ ListboxCmdDeletedProc(clientData)
*/
static int
-GetListboxIndex(interp, listPtr, indexObj, endIsSize, indexPtr)
- Tcl_Interp *interp; /* For error messages. */
- Listbox *listPtr; /* Listbox for which the index is being
+GetListboxIndex(
+ Tcl_Interp *interp, /* For error messages. */
+ Listbox *listPtr, /* Listbox for which the index is being
* specified. */
- Tcl_Obj *indexObj; /* Specifies an element in the listbox. */
- int endIsSize; /* If 1, "end" refers to the number of
- * entries in the listbox. If 0, "end"
- * refers to 1 less than the number of
- * entries. */
- int *indexPtr; /* Where to store converted index. */
+ Tcl_Obj *indexObj, /* Specifies an element in the listbox. */
+ int endIsSize, /* If 1, "end" refers to the number of entries
+ * in the listbox. If 0, "end" refers to 1
+ * less than the number of entries. */
+ int *indexPtr) /* Where to store converted index. */
{
- int result;
- int index;
+ int result, index;
char *stringRep;
-
- /* First see if the index is one of the named indices */
+
+ /*
+ * First see if the index is one of the named indices.
+ */
+
result = Tcl_GetIndexFromObj(NULL, indexObj, indexNames, "", 0, &index);
if (result == TCL_OK) {
switch (index) {
- case INDEX_ACTIVE: {
- /* "active" index */
- *indexPtr = listPtr->active;
- break;
- }
-
- case INDEX_ANCHOR: {
- /* "anchor" index */
- *indexPtr = listPtr->selectAnchor;
- break;
- }
-
- case INDEX_END: {
- /* "end" index */
- if (endIsSize) {
- *indexPtr = listPtr->nElements;
- } else {
- *indexPtr = listPtr->nElements - 1;
- }
- break;
+ case INDEX_ACTIVE:
+ /* "active" index */
+ *indexPtr = listPtr->active;
+ break;
+ case INDEX_ANCHOR:
+ /* "anchor" index */
+ *indexPtr = listPtr->selectAnchor;
+ break;
+ case INDEX_END:
+ /* "end" index */
+ if (endIsSize) {
+ *indexPtr = listPtr->nElements;
+ } else {
+ *indexPtr = listPtr->nElements - 1;
}
+ break;
}
return TCL_OK;
}
- /* The index didn't match any of the named indices; maybe it's an @x,y */
+ /*
+ * The index didn't match any of the named indices; maybe it's an @x,y
+ */
+
stringRep = Tcl_GetString(indexObj);
if (stringRep[0] == '@') {
/* @x,y index */
int y;
char *start, *end;
+
start = stringRep + 1;
- strtol(start, &end, 0);
+ y = strtol(start, &end, 0);
if ((start == end) || (*end != ',')) {
Tcl_AppendResult(interp, "bad listbox index \"", stringRep,
"\": must be active, anchor, end, @x,y, or a number",
- (char *)NULL);
+ NULL);
return TCL_ERROR;
}
start = end+1;
@@ -2703,23 +2758,29 @@ GetListboxIndex(interp, listPtr, indexObj, endIsSize, indexPtr)
if ((start == end) || (*end != '\0')) {
Tcl_AppendResult(interp, "bad listbox index \"", stringRep,
"\": must be active, anchor, end, @x,y, or a number",
- (char *)NULL);
+ NULL);
return TCL_ERROR;
}
*indexPtr = NearestListboxElement(listPtr, y);
return TCL_OK;
}
-
- /* Maybe the index is just an integer */
+
+ /*
+ * Maybe the index is just an integer.
+ */
+
if (Tcl_GetIntFromObj(interp, indexObj, indexPtr) == TCL_OK) {
return TCL_OK;
}
- /* Everything failed, nothing matched. Throw up an error message */
+ /*
+ * Everything failed, nothing matched. Throw up an error message.
+ */
+
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "bad listbox index \"",
Tcl_GetString(indexObj), "\": must be active, anchor, ",
- "end, @x,y, or a number", (char *) NULL);
+ "end, @x,y, or a number", NULL);
return TCL_ERROR;
}
@@ -2728,26 +2789,25 @@ GetListboxIndex(interp, listPtr, indexObj, endIsSize, indexPtr)
*
* ChangeListboxView --
*
- * Change the view on a listbox widget so that a given element
- * is displayed at the top.
+ * Change the view on a listbox widget so that a given element is
+ * displayed at the top.
*
* Results:
* None.
*
* Side effects:
- * What's displayed on the screen is changed. If there is a
- * scrollbar associated with this widget, then the scrollbar
- * is instructed to change its display too.
+ * What's displayed on the screen is changed. If there is a scrollbar
+ * associated with this widget, then the scrollbar is instructed to
+ * change its display too.
*
*----------------------------------------------------------------------
*/
static void
-ChangeListboxView(listPtr, index)
- register Listbox *listPtr; /* Information about widget. */
- int index; /* Index of element in listPtr
- * that should now appear at the
- * top of the listbox. */
+ChangeListboxView(
+ register Listbox *listPtr, /* Information about widget. */
+ int index) /* Index of element in listPtr that should now
+ * appear at the top of the listbox. */
{
if (index >= (listPtr->nElements - listPtr->fullLines)) {
index = listPtr->nElements - listPtr->fullLines;
@@ -2773,26 +2833,24 @@ ChangeListboxView(listPtr, index)
* None.
*
* Side effects:
- * The listbox may be redrawn to reflect its new horizontal
- * offset.
+ * The listbox may be redrawn to reflect its new horizontal offset.
*
*----------------------------------------------------------------------
*/
static void
-ChangeListboxOffset(listPtr, offset)
- register Listbox *listPtr; /* Information about widget. */
- int offset; /* Desired new "xOffset" for
- * listbox. */
+ChangeListboxOffset(
+ register Listbox *listPtr, /* Information about widget. */
+ int offset) /* Desired new "xOffset" for listbox. */
{
int maxOffset;
-
+
/*
- * Make sure that the new offset is within the allowable range, and
- * round it off to an even multiple of xScrollUnit.
+ * Make sure that the new offset is within the allowable range, and round
+ * it off to an even multiple of xScrollUnit.
*
- * Add half a scroll unit to do entry/text-like synchronization.
- * [Bug #225025]
+ * Add half a scroll unit to do entry/text-like synchronization. [Bug
+ * #225025]
*/
offset += listPtr->xScrollUnit / 2;
@@ -2818,8 +2876,8 @@ ChangeListboxOffset(listPtr, offset)
*
* ListboxScanTo --
*
- * Given a point (presumably of the curent mouse location)
- * drag the view in the window to implement the scan operation.
+ * Given a point (presumably of the curent mouse location) drag the view
+ * in the window to implement the scan operation.
*
* Results:
* None.
@@ -2831,29 +2889,26 @@ ChangeListboxOffset(listPtr, offset)
*/
static void
-ListboxScanTo(listPtr, x, y)
- register Listbox *listPtr; /* Information about widget. */
- int x; /* X-coordinate to use for scan
- * operation. */
- int y; /* Y-coordinate to use for scan
- * operation. */
+ListboxScanTo(
+ register Listbox *listPtr, /* Information about widget. */
+ int x, /* X-coordinate to use for scan operation. */
+ int y) /* Y-coordinate to use for scan operation. */
{
int newTopIndex, newOffset, maxIndex, maxOffset;
-
+
maxIndex = listPtr->nElements - listPtr->fullLines;
maxOffset = listPtr->maxWidth + (listPtr->xScrollUnit - 1)
- (Tk_Width(listPtr->tkwin) - 2*listPtr->inset
- 2*listPtr->selBorderWidth - listPtr->xScrollUnit);
/*
- * Compute new top line for screen by amplifying the difference
- * between the current position and the place where the scan
- * started (the "mark" position). If we run off the top or bottom
- * of the list, then reset the mark point so that the current
- * position continues to correspond to the edge of the window.
- * This means that the picture will start dragging as soon as the
- * mouse reverses direction (without this reset, might have to slide
- * mouse a long ways back before the picture starts moving again).
+ * Compute new top line for screen by amplifying the difference between
+ * the current position and the place where the scan started (the "mark"
+ * position). If we run off the top or bottom of the list, then reset the
+ * mark point so that the current position continues to correspond to the
+ * edge of the window. This means that the picture will start dragging as
+ * soon as the mouse reverses direction (without this reset, might have to
+ * slide mouse a long ways back before the picture starts moving again).
*/
newTopIndex = listPtr->scanMarkYIndex
@@ -2873,7 +2928,7 @@ ListboxScanTo(listPtr, x, y)
* scan started.
*/
- newOffset = listPtr->scanMarkXOffset - (10*(x - listPtr->scanMarkX));
+ newOffset = listPtr->scanMarkXOffset - 10*(x - listPtr->scanMarkX);
if (newOffset > maxOffset) {
newOffset = listPtr->scanMarkXOffset = maxOffset;
listPtr->scanMarkX = x;
@@ -2889,13 +2944,12 @@ ListboxScanTo(listPtr, x, y)
*
* NearestListboxElement --
*
- * Given a y-coordinate inside a listbox, compute the index of
- * the element under that y-coordinate (or closest to that
- * y-coordinate).
+ * Given a y-coordinate inside a listbox, compute the index of the
+ * element under that y-coordinate (or closest to that y-coordinate).
*
* Results:
- * The return value is an index of an element of listPtr. If
- * listPtr has no elements, then 0 is always returned.
+ * The return value is an index of an element of listPtr. If listPtr has
+ * no elements, then 0 is always returned.
*
* Side effects:
* None.
@@ -2904,9 +2958,9 @@ ListboxScanTo(listPtr, x, y)
*/
static int
-NearestListboxElement(listPtr, y)
- register Listbox *listPtr; /* Information about widget. */
- int y; /* Y-coordinate in listPtr's window. */
+NearestListboxElement(
+ register Listbox *listPtr, /* Information about widget. */
+ int y) /* Y-coordinate in listPtr's window. */
{
int index;
@@ -2935,29 +2989,28 @@ NearestListboxElement(listPtr, y)
* Standard Tcl result.
*
* Side effects:
- * All of the elements in the range between first and last are
- * marked as either selected or deselected, depending on the
- * "select" argument. Any items whose state changes are redisplayed.
- * The selection is claimed from X when the number of selected
- * elements changes from zero to non-zero.
+ * All of the elements in the range between first and last are marked as
+ * either selected or deselected, depending on the "select" argument. Any
+ * items whose state changes are redisplayed. The selection is claimed
+ * from X when the number of selected elements changes from zero to
+ * non-zero.
*
*----------------------------------------------------------------------
*/
static int
-ListboxSelect(listPtr, first, last, select)
- register Listbox *listPtr; /* Information about widget. */
- int first; /* Index of first element to
- * select or deselect. */
- int last; /* Index of last element to
- * select or deselect. */
- int select; /* 1 means select items, 0 means
- * deselect them. */
+ListboxSelect(
+ register Listbox *listPtr, /* Information about widget. */
+ int first, /* Index of first element to select or
+ * deselect. */
+ int last, /* Index of last element to select or
+ * deselect. */
+ int select) /* 1 means select items, 0 means deselect
+ * them. */
{
- int i, firstRedisplay, oldCount;
+ int i, firstRedisplay, oldCount, isNew;
Tcl_HashEntry *entry;
- int new;
-
+
if (last < first) {
i = first;
first = last;
@@ -2976,12 +3029,13 @@ ListboxSelect(listPtr, first, last, select)
firstRedisplay = -1;
/*
- * For each index in the range, find it in our selection hash table.
- * If it's not there but should be, add it. If it's there but shouldn't
- * be, remove it.
+ * For each index in the range, find it in our selection hash table. If
+ * it's not there but should be, add it. If it's there but shouldn't be,
+ * remove it.
*/
+
for (i = first; i <= last; i++) {
- entry = Tcl_FindHashEntry(listPtr->selection, (char *)i);
+ entry = Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i));
if (entry != NULL) {
if (!select) {
Tcl_DeleteHashEntry(entry);
@@ -2993,7 +3047,7 @@ ListboxSelect(listPtr, first, last, select)
} else {
if (select) {
entry = Tcl_CreateHashEntry(listPtr->selection,
- (char *)i, &new);
+ (char *) INT2PTR(i), &isNew);
Tcl_SetHashValue(entry, (ClientData) NULL);
listPtr->numSelected++;
if (firstRedisplay < 0) {
@@ -3019,17 +3073,16 @@ ListboxSelect(listPtr, first, last, select)
*
* ListboxFetchSelection --
*
- * This procedure is called back by Tk when the selection is
- * requested by someone. It returns part or all of the selection
- * in a buffer provided by the caller.
+ * This procedure is called back by Tk when the selection is requested by
+ * someone. It returns part or all of the selection in a buffer provided
+ * by the caller.
*
* Results:
- * The return value is the number of non-NULL bytes stored
- * at buffer. Buffer is filled (or partially filled) with a
- * NULL-terminated string containing part or all of the selection,
- * as given by offset and maxBytes. The selection is returned
- * as a Tcl list with one list element for each element in the
- * listbox.
+ * The return value is the number of non-NULL bytes stored at buffer.
+ * Buffer is filled (or partially filled) with a NULL-terminated string
+ * containing part or all of the selection, as given by offset and
+ * maxBytes. The selection is returned as a Tcl list with one list
+ * element for each element in the listbox.
*
* Side effects:
* None.
@@ -3038,25 +3091,22 @@ ListboxSelect(listPtr, first, last, select)
*/
static int
-ListboxFetchSelection(clientData, offset, buffer, maxBytes)
- ClientData clientData; /* Information about listbox widget. */
- int offset; /* Offset within selection of first
- * byte 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. */
+ListboxFetchSelection(
+ ClientData clientData, /* Information about listbox widget. */
+ int offset, /* Offset within selection of first byte 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. */
{
register Listbox *listPtr = (Listbox *) clientData;
Tcl_DString selection;
- int length, count, needNewline;
+ int length, count, needNewline, stringLen, i;
Tcl_Obj *curElement;
char *stringRep;
- int stringLen;
Tcl_HashEntry *entry;
- int i;
-
+
if (!listPtr->exportSelection) {
return -1;
}
@@ -3068,7 +3118,7 @@ ListboxFetchSelection(clientData, offset, buffer, maxBytes)
needNewline = 0;
Tcl_DStringInit(&selection);
for (i = 0; i < listPtr->nElements; i++) {
- entry = Tcl_FindHashEntry(listPtr->selection, (char *)i);
+ entry = Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i));
if (entry != NULL) {
if (needNewline) {
Tcl_DStringAppend(&selection, "\n", 1);
@@ -3097,9 +3147,7 @@ ListboxFetchSelection(clientData, offset, buffer, maxBytes)
if (count > maxBytes) {
count = maxBytes;
}
- memcpy((VOID *) buffer,
- (VOID *) (Tcl_DStringValue(&selection) + offset),
- (size_t) count);
+ memcpy(buffer, Tcl_DStringValue(&selection) + offset, (size_t) count);
}
buffer[count] = '\0';
Tcl_DStringFree(&selection);
@@ -3111,25 +3159,25 @@ ListboxFetchSelection(clientData, offset, buffer, maxBytes)
*
* ListboxLostSelection --
*
- * This procedure is called back by Tk when the selection is
- * grabbed away from a listbox widget.
+ * This procedure is called back by Tk when the selection is grabbed away
+ * from a listbox widget.
*
* Results:
* None.
*
* Side effects:
- * The existing selection is unhighlighted, and the window is
- * marked as not containing a selection.
+ * The existing selection is unhighlighted, and the window is marked as
+ * not containing a selection.
*
*----------------------------------------------------------------------
*/
static void
-ListboxLostSelection(clientData)
- ClientData clientData; /* Information about listbox widget. */
+ListboxLostSelection(
+ ClientData clientData) /* Information about listbox widget. */
{
register Listbox *listPtr = (Listbox *) clientData;
-
+
if ((listPtr->exportSelection) && (listPtr->nElements > 0)) {
ListboxSelect(listPtr, 0, listPtr->nElements-1, 0);
}
@@ -3140,8 +3188,8 @@ ListboxLostSelection(clientData)
*
* EventuallyRedrawRange --
*
- * Ensure that a given range of elements is eventually redrawn on
- * the display (if those elements in fact appear on the display).
+ * Ensure that a given range of elements is eventually redrawn on the
+ * display (if those elements in fact appear on the display).
*
* Results:
* None.
@@ -3153,17 +3201,19 @@ ListboxLostSelection(clientData)
*/
static void
-EventuallyRedrawRange(listPtr, first, last)
- register Listbox *listPtr; /* Information about widget. */
- int first; /* Index of first element in list
- * that needs to be redrawn. */
- int last; /* Index of last element in list
- * that needs to be redrawn. May
- * be less than first;
- * these just bracket a range. */
+EventuallyRedrawRange(
+ register Listbox *listPtr, /* Information about widget. */
+ int first, /* Index of first element in list that needs
+ * to be redrawn. */
+ int last) /* Index of last element in list that needs to
+ * be redrawn. May be less than first; these
+ * just bracket a range. */
{
- /* We don't have to register a redraw callback if one is already pending,
- * or if the window doesn't exist, or if the window isn't mapped */
+ /*
+ * We don't have to register a redraw callback if one is already pending,
+ * or if the window doesn't exist, or if the window isn't mapped.
+ */
+
if ((listPtr->flags & REDRAW_PENDING)
|| (listPtr->flags & LISTBOX_DELETED)
|| !Tk_IsMapped(listPtr->tkwin)) {
@@ -3178,30 +3228,30 @@ EventuallyRedrawRange(listPtr, first, last)
*
* ListboxUpdateVScrollbar --
*
- * This procedure is invoked whenever information has changed in
- * a listbox in a way that would invalidate a vertical scrollbar
- * display. If there is an associated scrollbar, then this command
- * updates it by invoking a Tcl command.
+ * This procedure is invoked whenever information has changed in a
+ * listbox in a way that would invalidate a vertical scrollbar display.
+ * If there is an associated scrollbar, then this command updates it by
+ * invoking a Tcl command.
*
* Results:
* None.
*
* Side effects:
- * A Tcl command is invoked, and an additional command may be
- * invoked to process errors in the command.
+ * A Tcl command is invoked, and an additional command may be invoked to
+ * process errors in the command.
*
*----------------------------------------------------------------------
*/
static void
-ListboxUpdateVScrollbar(listPtr)
- register Listbox *listPtr; /* Information about widget. */
+ListboxUpdateVScrollbar(
+ register Listbox *listPtr) /* Information about widget. */
{
- char string[TCL_DOUBLE_SPACE * 2];
+ char firstStr[TCL_DOUBLE_SPACE+1], lastStr[TCL_DOUBLE_SPACE+1];
double first, last;
int result;
Tcl_Interp *interp;
-
+
if (listPtr->yScrollCmd == NULL) {
return;
}
@@ -3209,30 +3259,32 @@ ListboxUpdateVScrollbar(listPtr)
first = 0.0;
last = 1.0;
} else {
- first = listPtr->topIndex/((double) listPtr->nElements);
- last = (listPtr->topIndex+listPtr->fullLines)
- /((double) listPtr->nElements);
+ first = listPtr->topIndex / (double) listPtr->nElements;
+ last = (listPtr->topIndex + listPtr->fullLines)
+ / (double) listPtr->nElements;
if (last > 1.0) {
last = 1.0;
}
}
- sprintf(string, " %g %g", first, last);
+ firstStr[0] = lastStr[0] = ' ';
+ Tcl_PrintDouble(NULL, first, firstStr+1);
+ Tcl_PrintDouble(NULL, last, lastStr+1);
/*
- * We must hold onto the interpreter from the listPtr because the data
- * at listPtr might be freed as a result of the Tcl_VarEval.
+ * We must hold onto the interpreter from the listPtr because the data at
+ * listPtr might be freed as a result of the Tcl_VarEval.
*/
-
+
interp = listPtr->interp;
- Tcl_Preserve((ClientData) interp);
- result = Tcl_VarEval(interp, listPtr->yScrollCmd, string,
- (char *) NULL);
+ Tcl_Preserve(interp);
+ result = Tcl_VarEval(interp, listPtr->yScrollCmd, firstStr, lastStr,
+ NULL);
if (result != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (vertical scrolling command executed by listbox)");
Tcl_BackgroundError(interp);
}
- Tcl_Release((ClientData) interp);
+ Tcl_Release(interp);
}
/*
@@ -3240,26 +3292,26 @@ ListboxUpdateVScrollbar(listPtr)
*
* ListboxUpdateHScrollbar --
*
- * This procedure is invoked whenever information has changed in
- * a listbox in a way that would invalidate a horizontal scrollbar
- * display. If there is an associated horizontal scrollbar, then
- * this command updates it by invoking a Tcl command.
+ * This procedure is invoked whenever information has changed in a
+ * listbox in a way that would invalidate a horizontal scrollbar display.
+ * If there is an associated horizontal scrollbar, then this command
+ * updates it by invoking a Tcl command.
*
* Results:
* None.
*
* Side effects:
- * A Tcl command is invoked, and an additional command may be
- * invoked to process errors in the command.
+ * A Tcl command is invoked, and an additional command may be invoked to
+ * process errors in the command.
*
*----------------------------------------------------------------------
*/
static void
-ListboxUpdateHScrollbar(listPtr)
- register Listbox *listPtr; /* Information about widget. */
+ListboxUpdateHScrollbar(
+ register Listbox *listPtr) /* Information about widget. */
{
- char string[TCL_DOUBLE_SPACE * 2];
+ char firstStr[TCL_DOUBLE_SPACE+1], lastStr[TCL_DOUBLE_SPACE+1];
int result, windowWidth;
double first, last;
Tcl_Interp *interp;
@@ -3273,30 +3325,33 @@ ListboxUpdateHScrollbar(listPtr)
first = 0;
last = 1.0;
} else {
- first = listPtr->xOffset/((double) listPtr->maxWidth);
- last = (listPtr->xOffset + windowWidth)
- /((double) listPtr->maxWidth);
+ register double maxWide = (double) listPtr->maxWidth;
+
+ first = listPtr->xOffset / maxWide;
+ last = (listPtr->xOffset + windowWidth) / maxWide;
if (last > 1.0) {
last = 1.0;
}
}
- sprintf(string, " %g %g", first, last);
+ firstStr[0] = lastStr[0] = ' ';
+ Tcl_PrintDouble(NULL, first, firstStr+1);
+ Tcl_PrintDouble(NULL, last, lastStr+1);
/*
* We must hold onto the interpreter because the data referred to at
* listPtr might be freed as a result of the call to Tcl_VarEval.
*/
-
+
interp = listPtr->interp;
- Tcl_Preserve((ClientData) interp);
- result = Tcl_VarEval(interp, listPtr->xScrollCmd, string,
- (char *) NULL);
+ Tcl_Preserve(interp);
+ result = Tcl_VarEval(interp, listPtr->xScrollCmd, firstStr, lastStr,
+ NULL);
if (result != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (horizontal scrolling command executed by listbox)");
Tcl_BackgroundError(interp);
}
- Tcl_Release((ClientData) interp);
+ Tcl_Release(interp);
}
/*
@@ -3304,60 +3359,72 @@ ListboxUpdateHScrollbar(listPtr)
*
* ListboxListVarProc --
*
- * Called whenever the trace on the listbox list var fires.
+ * Called whenever the trace on the listbox list var fires.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
static char *
-ListboxListVarProc(clientData, interp, name1, name2, flags)
- ClientData clientData; /* Information about button. */
- Tcl_Interp *interp; /* Interpreter containing variable. */
- CONST char *name1; /* Not used. */
- CONST char *name2; /* Not used. */
- int flags; /* Information about what happened. */
+ListboxListVarProc(
+ ClientData clientData, /* Information about button. */
+ Tcl_Interp *interp, /* Interpreter containing variable. */
+ const char *name1, /* Not used. */
+ const char *name2, /* Not used. */
+ int flags) /* Information about what happened. */
{
Listbox *listPtr = (Listbox *)clientData;
Tcl_Obj *oldListObj, *varListObj;
- int oldLength;
- int i;
+ int oldLength, i;
Tcl_HashEntry *entry;
-
- /* Bwah hahahaha -- puny mortal, you can't unset a -listvar'd variable! */
+
+ /*
+ * Bwah hahahaha! Puny mortal, you can't unset a -listvar'd variable!
+ */
+
if (flags & TCL_TRACE_UNSETS) {
if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {
- Tcl_SetVar2Ex(interp, listPtr->listVarName,
- (char *)NULL, listPtr->listObj, TCL_GLOBAL_ONLY);
+ Tcl_SetVar2Ex(interp, listPtr->listVarName, NULL,
+ listPtr->listObj, TCL_GLOBAL_ONLY);
Tcl_TraceVar(interp, listPtr->listVarName,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ListboxListVarProc, clientData);
- return (char *)NULL;
+ return NULL;
}
} else {
oldListObj = listPtr->listObj;
varListObj = Tcl_GetVar2Ex(listPtr->interp, listPtr->listVarName,
- (char *)NULL, TCL_GLOBAL_ONLY);
+ NULL, TCL_GLOBAL_ONLY);
+
/*
- * Make sure the new value is a good list; if it's not, disallow
- * the change -- the fact that it is a listvar means that it must
- * always be a valid list -- and return an error message.
+ * Make sure the new value is a good list; if it's not, disallow the
+ * change - the fact that it is a listvar means that it must always be
+ * a valid list - and return an error message.
*/
+
if (Tcl_ListObjLength(listPtr->interp, varListObj, &i) != TCL_OK) {
- Tcl_SetVar2Ex(interp, listPtr->listVarName, (char *)NULL,
- oldListObj, TCL_GLOBAL_ONLY);
- return("invalid listvar value");
+ Tcl_SetVar2Ex(interp, listPtr->listVarName, NULL, oldListObj,
+ TCL_GLOBAL_ONLY);
+ return (char *) "invalid listvar value";
}
-
+
listPtr->listObj = varListObj;
- /* Incr the obj ref count so it doesn't vanish if the var is unset */
+
+ /*
+ * Incr the obj ref count so it doesn't vanish if the var is unset.
+ */
+
Tcl_IncrRefCount(listPtr->listObj);
- /* Clean up the ref to our old list obj */
+
+ /*
+ * Clean up the ref to our old list obj.
+ */
+
Tcl_DecrRefCount(oldListObj);
}
@@ -3365,21 +3432,29 @@ ListboxListVarProc(clientData, interp, name1, name2, flags)
* If the list length has decreased, then we should clean up selection and
* attributes information for elements past the end of the new list
*/
+
oldLength = listPtr->nElements;
Tcl_ListObjLength(listPtr->interp, listPtr->listObj, &listPtr->nElements);
if (listPtr->nElements < oldLength) {
for (i = listPtr->nElements; i < oldLength; i++) {
- /* Clean up selection */
- entry = Tcl_FindHashEntry(listPtr->selection, (char *)i);
+ /*
+ * Clean up selection.
+ */
+
+ entry = Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i));
if (entry != NULL) {
listPtr->numSelected--;
Tcl_DeleteHashEntry(entry);
}
- /* Clean up attributes */
- entry = Tcl_FindHashEntry(listPtr->itemAttrTable, (char *)i);
+ /*
+ * Clean up attributes.
+ */
+
+ entry = Tcl_FindHashEntry(listPtr->itemAttrTable,
+ (char *) INT2PTR(i));
if (entry != NULL) {
- ckfree((char *)Tcl_GetHashValue(entry));
+ ckfree((char *) Tcl_GetHashValue(entry));
Tcl_DeleteHashEntry(entry);
}
}
@@ -3398,14 +3473,15 @@ ListboxListVarProc(clientData, interp, name1, name2, flags)
/*
* The computed maxWidth may have changed as a result of this operation.
* However, we don't want to recompute it every time this trace fires
- * (imagine the user doing 1000 lappends to the listvar). Therefore, set
+ * (imagine the user doing 1000 lappends to the listvar). Therefore, set
* the MAXWIDTH_IS_STALE flag, which will cause the width to be recomputed
* next time the list is redrawn.
*/
+
listPtr->flags |= MAXWIDTH_IS_STALE;
-
+
EventuallyRedrawRange(listPtr, 0, listPtr->nElements-1);
- return (char*)NULL;
+ return NULL;
}
/*
@@ -3413,10 +3489,10 @@ ListboxListVarProc(clientData, interp, name1, name2, flags)
*
* MigrateHashEntries --
*
- * Given a hash table with entries keyed by a single integer value,
- * move all entries in a given range by a fixed amount, so that
- * if in the original table there was an entry with key n and
- * the offset was i, in the new table that entry would have key n + i.
+ * Given a hash table with entries keyed by a single integer value, move
+ * all entries in a given range by a fixed amount, so that if in the
+ * original table there was an entry with key n and the offset was i, in
+ * the new table that entry would have key n + i.
*
* Results:
* None.
@@ -3428,39 +3504,45 @@ ListboxListVarProc(clientData, interp, name1, name2, flags)
*/
static void
-MigrateHashEntries(table, first, last, offset)
- Tcl_HashTable *table;
- int first;
- int last;
- int offset;
+MigrateHashEntries(
+ Tcl_HashTable *table,
+ int first,
+ int last,
+ int offset)
{
- int i, new;
+ int i, isNew;
Tcl_HashEntry *entry;
ClientData clientData;
if (offset == 0) {
return;
}
- /* It's more efficient to do one if/else and nest the for loops inside,
+
+ /*
+ * It's more efficient to do one if/else and nest the for loops inside,
* although we could avoid some code duplication if we nested the if/else
- * inside the for loops */
+ * inside the for loops.
+ */
+
if (offset > 0) {
for (i = last; i >= first; i--) {
- entry = Tcl_FindHashEntry(table, (char *)i);
+ entry = Tcl_FindHashEntry(table, (char *) INT2PTR(i));
if (entry != NULL) {
clientData = Tcl_GetHashValue(entry);
Tcl_DeleteHashEntry(entry);
- entry = Tcl_CreateHashEntry(table, (char *)(i + offset), &new);
+ entry = Tcl_CreateHashEntry(table,
+ (char *) INT2PTR(i + offset), &isNew);
Tcl_SetHashValue(entry, clientData);
}
}
} else {
for (i = first; i <= last; i++) {
- entry = Tcl_FindHashEntry(table, (char *)i);
+ entry = Tcl_FindHashEntry(table, (char *) INT2PTR(i));
if (entry != NULL) {
clientData = Tcl_GetHashValue(entry);
Tcl_DeleteHashEntry(entry);
- entry = Tcl_CreateHashEntry(table, (char *)(i + offset), &new);
+ entry = Tcl_CreateHashEntry(table,
+ (char *) INT2PTR(i + offset), &isNew);
Tcl_SetHashValue(entry, clientData);
}
}
@@ -3468,3 +3550,10 @@ MigrateHashEntries(table, first, last, offset)
return;
}
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkMacWinMenu.c b/generic/tkMacWinMenu.c
index 7138c7d..9351de1 100644
--- a/generic/tkMacWinMenu.c
+++ b/generic/tkMacWinMenu.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkMacWinMenu.c --
*
* This module implements the common elements of the Mac and Windows
@@ -6,10 +6,11 @@
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
+#include "tkInt.h"
#include "tkMenu.h"
typedef struct ThreadSpecificData {
@@ -17,9 +18,7 @@ typedef struct ThreadSpecificData {
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
-
-static int PreprocessMenu _ANSI_ARGS_((TkMenu *menuPtr));
-
+static int PreprocessMenu(TkMenu *menuPtr);
/*
*----------------------------------------------------------------------
@@ -29,8 +28,8 @@ static int PreprocessMenu _ANSI_ARGS_((TkMenu *menuPtr));
* The guts of the preprocessing. Recursive.
*
* Results:
- * The return value is a standard Tcl result (errors can occur
- * while the postcommands are being processed).
+ * The return value is a standard Tcl result (errors can occur while the
+ * postcommands are being processed).
*
* Side effects:
* Since commands can get executed while this routine is being executed,
@@ -40,61 +39,59 @@ static int PreprocessMenu _ANSI_ARGS_((TkMenu *menuPtr));
*/
static int
-PreprocessMenu(menuPtr)
- TkMenu *menuPtr;
+PreprocessMenu(
+ TkMenu *menuPtr)
{
int index, result, finished;
- TkMenu *cascadeMenuPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+
Tcl_Preserve((ClientData) menuPtr);
-
+
/*
* First, let's process the post command on ourselves. If this command
* destroys this menu, or if there was an error, we are done.
*/
-
+
result = TkPostCommand(menuPtr);
if ((result != TCL_OK) || (menuPtr->tkwin == NULL)) {
- goto done;
+ goto done;
}
-
+
/*
- * Now, we go through structure and process all of the commands.
- * Since the structure is changing, we stop after we do one command,
- * and start over. When we get through without doing any, we are done.
+ * Now, we go through structure and process all of the commands. Since the
+ * structure is changing, we stop after we do one command, and start over.
+ * When we get through without doing any, we are done.
*/
-
-
+
do {
- finished = 1;
- for (index = 0; index < menuPtr->numEntries; index++) {
- if ((menuPtr->entries[index]->type == CASCADE_ENTRY)
- && (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 !=
- tsdPtr->postCommandGeneration) {
- cascadeMenuPtr->postCommandGeneration =
- tsdPtr->postCommandGeneration;
- result = PreprocessMenu(cascadeMenuPtr);
- if (result != TCL_OK) {
- goto done;
- }
- finished = 0;
- break;
- }
- }
- }
- }
+ finished = 1;
+ for (index = 0; index < menuPtr->numEntries; index++) {
+ register TkMenuEntry *entryPtr = menuPtr->entries[index];
+
+ if ((entryPtr->type == CASCADE_ENTRY)
+ && (entryPtr->namePtr != NULL)
+ && (entryPtr->childMenuRefPtr != NULL)
+ && (entryPtr->childMenuRefPtr->menuPtr != NULL)) {
+ TkMenu *cascadeMenuPtr = entryPtr->childMenuRefPtr->menuPtr;
+
+ if (cascadeMenuPtr->postCommandGeneration !=
+ tsdPtr->postCommandGeneration) {
+ cascadeMenuPtr->postCommandGeneration =
+ tsdPtr->postCommandGeneration;
+ result = PreprocessMenu(cascadeMenuPtr);
+ if (result != TCL_OK) {
+ goto done;
+ }
+ finished = 0;
+ break;
+ }
+ }
+ }
} while (!finished);
-
- done:
- Tcl_Release((ClientData)menuPtr);
+
+ done:
+ Tcl_Release((ClientData) menuPtr);
return result;
}
@@ -103,23 +100,23 @@ PreprocessMenu(menuPtr)
*
* TkPreprocessMenu --
*
- * On the Mac and on Windows, all of the postcommand processing has
- * to be done on the entire tree underneath the main window to be
- * posted. This means that we have to traverse the menu tree and
- * issue the postcommands for all of the menus that have cascades
- * attached. Since the postcommands can change the menu structure while
- * we are traversing, we have to be extremely careful. Basically, the
- * idea is to traverse the structure until we succesfully process
- * one postcommand. Then we start over, and do it again until
- * we traverse the whole structure without processing any postcommands.
+ * On the Mac and on Windows, all of the postcommand processing has to be
+ * done on the entire tree underneath the main window to be posted. This
+ * means that we have to traverse the menu tree and issue the
+ * postcommands for all of the menus that have cascades attached. Since
+ * the postcommands can change the menu structure while we are
+ * traversing, we have to be extremely careful. Basically, the idea is to
+ * traverse the structure until we succesfully process one postcommand.
+ * Then we start over, and do it again until we traverse the whole
+ * structure without processing any postcommands.
*
- * We are also going to set up the cascade back pointers in here
- * since we have to traverse the entire structure underneath the menu
- * anyway, We can clear the postcommand marks while we do that.
+ * We are also going to set up the cascade back pointers in here since we
+ * have to traverse the entire structure underneath the menu anyway. We
+ * can clear the postcommand marks while we do that.
*
* Results:
- * The return value is a standard Tcl result (errors can occur
- * while the postcommands are being processed).
+ * The return value is a standard Tcl result (errors can occur while the
+ * postcommands are being processed).
*
* Side effects:
* Since commands can get executed while this routine is being executed,
@@ -129,13 +126,21 @@ PreprocessMenu(menuPtr)
*/
int
-TkPreprocessMenu(menuPtr)
- TkMenu *menuPtr;
+TkPreprocessMenu(
+ TkMenu *menuPtr)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
tsdPtr->postCommandGeneration++;
menuPtr->postCommandGeneration = tsdPtr->postCommandGeneration;
return PreprocessMenu(menuPtr);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkMain.c b/generic/tkMain.c
index 5e5ddb7..b794ce0 100644
--- a/generic/tkMain.c
+++ b/generic/tkMain.c
@@ -3,29 +3,19 @@
*
* This file contains a generic main program for Tk-based applications.
* It can be used as-is for many applications, just by supplying a
- * different appInitProc procedure for each specific application.
- * Or, it can be used as a template for creating new main programs
- * for Tk applications.
+ * different appInitProc function for each specific application. Or, it
+ * can be used as a template for creating new main programs for Tk
+ * applications.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <tcl.h>
-#include <tclInt.h>
-#include <tk.h>
+#include "tclInt.h"
#include "tkInt.h"
-#ifdef NO_STDLIB_H
-# include "../compat/stdlib.h"
-#else
-# include <stdlib.h>
-#endif
#ifdef __WIN32__
#include "tkWinInt.h"
#include "../win/tclWinPort.h"
@@ -37,24 +27,23 @@
extern int TkCygwinMainEx(int, char **, Tcl_AppInitProc *, Tcl_Interp *);
typedef struct ThreadSpecificData {
- Tcl_Interp *interp; /* Interpreter for this thread. */
- Tcl_DString command; /* Used to assemble lines of terminal input
+ 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
+ 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. */
+ int tty; /* Non-zero means standard input is a
+ * terminal-like device. Zero means it's a
+ * file. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
/*
- * Declarations for various library procedures and variables (don't want
- * to include tkInt.h or tkPort.h here, because people might copy this
- * file out of the Tk source directory to make their own modified versions).
- * Note: don't declare "exit" here even though a declaration is really
- * needed, because it will conflict with a declaration elsewhere on
- * some systems.
+ * Declarations for various library functions and variables (don't want to
+ * include tkInt.h or tkPort.h here, because people might copy this file out
+ * of the Tk source directory to make their own modified versions). Note: do
+ * not declare "exit" here even though a declaration is really needed, because
+ * it will conflict with a declaration elsewhere on some systems.
*/
#if defined(__WIN32__) || defined(_WIN32)
@@ -96,17 +85,16 @@ static int WinIsTty(int fd) {
}
}
#else
-extern int isatty _ANSI_ARGS_((int fd));
-extern char * strrchr _ANSI_ARGS_((CONST char *string, int c));
+extern int isatty(int fd);
+extern char * strrchr(CONST char *string, int c);
#endif
/*
- * Forward declarations for procedures defined later in this file.
+ * Forward declarations for functions defined later in this file.
*/
-static void Prompt _ANSI_ARGS_((Tcl_Interp *interp, int partial));
-static void StdinProc _ANSI_ARGS_((ClientData clientData,
- int mask));
+static void Prompt(Tcl_Interp *interp, int partial);
+static void StdinProc(ClientData clientData, int mask);
/*
*----------------------------------------------------------------------
@@ -116,39 +104,39 @@ static void StdinProc _ANSI_ARGS_((ClientData clientData,
* Main program for Wish and most other Tk-based applications.
*
* Results:
- * None. This procedure never returns (it exits the process when
- * it's done.
+ * None. This function never returns (it exits the process when it's
+ * done.
*
* Side effects:
- * This procedure initializes the Tk world and then starts
- * interpreting commands; almost anything could happen, depending
- * on the script being interpreted.
+ * This function initializes the Tk world and then starts interpreting
+ * commands; almost anything could happen, depending on the script being
+ * interpreted.
*
*----------------------------------------------------------------------
*/
void
-Tk_MainEx(argc, argv, appInitProc, interp)
- 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. */
- Tcl_Interp *interp;
+Tk_MainEx(
+ int argc, /* Number of arguments. */
+ char **argv, /* Array of argument strings. */
+ Tcl_AppInitProc *appInitProc,
+ /* Application-specific initialization
+ * function to call after most initialization
+ * but before starting to execute commands. */
+ Tcl_Interp *interp)
{
- Tcl_Obj *argvPtr;
+ Tcl_Obj *path, *argvPtr;
+ CONST char *encodingName;
int code, nullStdin = 0;
- size_t length;
Tcl_Channel inChannel, outChannel;
- Tcl_DString appName;
ThreadSpecificData *tsdPtr;
+ Tcl_DString appName;
/*
- * Ensure that we are getting the matching version of Tcl. This is
- * really only an issue when Tk is loaded dynamically.
+ * Ensure that we are getting a compatible version of Tcl. This is really
+ * only an issue when Tk is loaded dynamically.
*/
- if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
+ if (Tcl_InitStubs(interp, "8.5.0", 0) == NULL) {
abort();
}
@@ -178,7 +166,7 @@ Tk_MainEx(argc, argv, appInitProc, interp)
#endif
tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Tcl_FindExecutable(argv[0]);
tsdPtr->interp = interp;
@@ -194,8 +182,8 @@ Tk_MainEx(argc, argv, appInitProc, interp)
#endif
#ifdef MAC_OSX_TK
- if (TclGetStartupScriptFileName() == NULL) {
- TkMacOSXDefaultStartupScript();
+ if (Tcl_GetStartupScript(NULL) == NULL) {
+ TkMacOSXDefaultStartupScript();
}
#endif
@@ -204,37 +192,51 @@ Tk_MainEx(argc, argv, appInitProc, interp)
#endif
/*
- * Parse command-line arguments. A leading "-file" argument is
- * ignored (a historical relic from the distant past). If the
- * next argument doesn't start with a "-" then strip it off and
- * use it as the name of a script file to process.
+ * If the application has not already set a startup script, parse the
+ * first few command line arguments to determine the script path and
+ * encoding.
*/
- if (argc > 1) {
- length = strlen(argv[1]);
- if ((length >= 2) && (strncmp(argv[1], "-file", length) == 0)) {
- argc--;
- argv++;
- }
- }
- if (TclGetStartupScriptFileName() == NULL) {
- if ((argc > 1) && (argv[1][0] != '-')) {
- TclSetStartupScriptFileName(argv[1]);
+ if (NULL == Tcl_GetStartupScript(NULL)) {
+ size_t length;
+
+ /*
+ * Check whether first 3 args (argv[1] - argv[3]) look like
+ * -encoding ENCODING FILENAME
+ * or like
+ * FILENAME
+ * or like
+ * -file FILENAME (ancient history support only)
+ */
+
+ if ((argc > 3) && (0 == strcmp("-encoding", argv[1]))
+ && ('-' != argv[3][0])) {
+ Tcl_SetStartupScript(Tcl_NewStringObj(argv[3], -1), argv[2]);
+ argc -= 3;
+ argv += 3;
+ } else if ((argc > 1) && ('-' != argv[1][0])) {
+ Tcl_SetStartupScript(Tcl_NewStringObj(argv[1], -1), NULL);
argc--;
argv++;
+ } else if ((argc > 2) && (length = strlen(argv[1]))
+ && (length > 1) && (0 == strncmp("-file", argv[1], length))
+ && ('-' != argv[2][0])) {
+ Tcl_SetStartupScript(Tcl_NewStringObj(argv[2], -1), NULL);
+ argc -= 2;
+ argv += 2;
}
}
- /*
- * Make command-line arguments available in the Tcl variables "argc"
- * and "argv".
- */
-
- if (TclGetStartupScriptFileName() == NULL) {
+ path = Tcl_GetStartupScript(&encodingName);
+ if (NULL == path) {
Tcl_ExternalToUtfDString(NULL, argv[0], -1, &appName);
} else {
- TclSetStartupScriptFileName(Tcl_ExternalToUtfDString(NULL,
- TclGetStartupScriptFileName(), -1, &appName));
+ int numBytes;
+ CONST char *pathName = Tcl_GetStringFromObj(path, &numBytes);
+
+ Tcl_ExternalToUtfDString(NULL, pathName, numBytes, &appName);
+ path = Tcl_NewStringObj(Tcl_DStringValue(&appName), -1);
+ Tcl_SetStartupScript(path, encodingName);
}
Tcl_SetVar(interp, "argv0", Tcl_DStringValue(&appName), TCL_GLOBAL_ONLY);
Tcl_DStringFree(&appName);
@@ -246,6 +248,7 @@ Tk_MainEx(argc, argv, appInitProc, interp)
argvPtr = Tcl_NewListObj(0, NULL);
while (argc--) {
Tcl_DString ds;
+
Tcl_ExternalToUtfDString(NULL, *argv++, -1, &ds);
Tcl_ListObjAppendElement(NULL, argvPtr, Tcl_NewStringObj(
Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)));
@@ -265,7 +268,7 @@ Tk_MainEx(argc, argv, appInitProc, interp)
* of length 0, (e.g. /dev/null, which is what Finder sets when double
* clicking Wish) then use the GUI console.
*/
-
+
if (!tsdPtr->tty) {
struct stat st;
@@ -273,8 +276,8 @@ Tk_MainEx(argc, argv, appInitProc, interp)
}
#endif
Tcl_SetVar(interp, "tcl_interactive",
- ((TclGetStartupScriptFileName() == NULL) && (tsdPtr->tty
- || nullStdin)) ? "1" : "0", TCL_GLOBAL_ONLY);
+ ((path == NULL) && (tsdPtr->tty || nullStdin)) ? "1" : "0",
+ TCL_GLOBAL_ONLY);
/*
* Invoke application-specific initialization.
@@ -286,16 +289,18 @@ Tk_MainEx(argc, argv, appInitProc, interp)
}
/*
- * Invoke the script specified on the command line, if any.
+ * Invoke the script specified on the command line, if any. Must fetch it
+ * again, as the appInitProc might have reset it.
*/
- if (TclGetStartupScriptFileName() != NULL) {
+ path = Tcl_GetStartupScript(&encodingName);
+ if (path != NULL) {
Tcl_ResetResult(interp);
- code = Tcl_EvalFile(interp, TclGetStartupScriptFileName());
+ code = Tcl_FSEvalFileEx(interp, path, encodingName);
if (code != TCL_OK) {
/*
- * The following statement guarantees that the errorInfo
- * variable is set properly.
+ * The following statement guarantees that the errorInfo variable
+ * is set properly.
*/
Tcl_AddErrorInfo(interp, "");
@@ -336,13 +341,14 @@ Tk_MainEx(argc, argv, appInitProc, interp)
Tcl_ResetResult(interp);
/*
- * Loop infinitely, waiting for commands to execute. When there
- * are no windows left, Tk_MainLoop returns and we exit.
+ * Loop infinitely, waiting for commands to execute. When there are no
+ * windows left, Tk_MainLoop returns and we exit.
*/
Tk_MainLoop();
Tcl_DeleteInterp(interp);
Tcl_Release((ClientData) interp);
+ Tcl_SetStartupScript(NULL, NULL);
Tcl_Exit(0);
}
@@ -351,64 +357,60 @@ Tk_MainEx(argc, argv, appInitProc, interp)
*
* StdinProc --
*
- * This procedure is invoked by the event dispatcher whenever
- * standard input becomes readable. It grabs the next line of
- * input characters, adds them to a command being assembled, and
- * executes the command if it's complete.
+ * This function is invoked by the event dispatcher whenever standard
+ * input becomes readable. It grabs the next line of input characters,
+ * adds them to a command being assembled, and executes the command if
+ * it's complete.
*
* Results:
* None.
*
* Side effects:
- * Could be almost arbitrary, depending on the command that's
- * typed.
+ * Could be almost arbitrary, depending on the command that's typed.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static void
-StdinProc(clientData, mask)
- ClientData clientData; /* Not used. */
- int mask; /* Not used. */
+StdinProc(
+ ClientData clientData, /* Not used. */
+ int mask) /* Not used. */
{
static int gotPartial = 0;
char *cmd;
int code, count;
Tcl_Channel chan = (Tcl_Channel) clientData;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Tcl_Interp *interp = tsdPtr->interp;
count = Tcl_Gets(chan, &tsdPtr->line);
- if (count < 0) {
- if (!gotPartial) {
- if (tsdPtr->tty) {
- Tcl_Exit(0);
- } else {
- Tcl_DeleteChannelHandler(chan, StdinProc, (ClientData) chan);
- }
- return;
+ if (count < 0 && !gotPartial) {
+ if (tsdPtr->tty) {
+ Tcl_Exit(0);
+ } else {
+ Tcl_DeleteChannelHandler(chan, StdinProc, (ClientData) chan);
}
+ return;
}
(void) Tcl_DStringAppend(&tsdPtr->command, Tcl_DStringValue(
- &tsdPtr->line), -1);
+ &tsdPtr->line), -1);
cmd = Tcl_DStringAppend(&tsdPtr->command, "\n", -1);
Tcl_DStringFree(&tsdPtr->line);
if (!Tcl_CommandComplete(cmd)) {
- gotPartial = 1;
- goto prompt;
+ gotPartial = 1;
+ goto prompt;
}
gotPartial = 0;
/*
* Disable the stdin channel handler while evaluating the command;
- * otherwise if the command re-enters the event loop we might
- * process commands from stdin before the current command is
- * finished. Among other things, this will trash the text of the
- * command being evaluated.
+ * otherwise if the command re-enters the event loop we might process
+ * commands from stdin before the current command is finished. Among other
+ * things, this will trash the text of the command being evaluated.
*/
Tcl_CreateChannelHandler(chan, 0, StdinProc, (ClientData) chan);
@@ -434,7 +436,7 @@ StdinProc(clientData, mask)
* Output a prompt.
*/
- prompt:
+ prompt:
if (tsdPtr->tty) {
Prompt(interp, gotPartial);
}
@@ -446,25 +448,24 @@ StdinProc(clientData, mask)
*
* Prompt --
*
- * Issue a prompt on standard output, or invoke a script
- * to issue the prompt.
+ * Issue a prompt on standard output, or invoke a script to issue the
+ * prompt.
*
* Results:
* None.
*
* Side effects:
- * A prompt gets output, and a Tcl script may be evaluated
- * in interp.
+ * A prompt gets output, and a Tcl script may be evaluated in interp.
*
*----------------------------------------------------------------------
*/
static void
-Prompt(interp, partial)
- Tcl_Interp *interp; /* Interpreter to use for prompting. */
- int partial; /* Non-zero means there already
- * exists a partial command, so use
- * the secondary prompt. */
+Prompt(
+ Tcl_Interp *interp, /* Interpreter to use for prompting. */
+ int partial) /* Non-zero means there already exists a
+ * partial command, so use the secondary
+ * prompt. */
{
Tcl_Obj *promptCmd;
int code;
@@ -473,41 +474,49 @@ Prompt(interp, partial)
promptCmd = Tcl_GetVar2Ex(interp,
partial ? "tcl_prompt2" : "tcl_prompt1", NULL, TCL_GLOBAL_ONLY);
if (promptCmd == NULL) {
-defaultPrompt:
+ defaultPrompt:
if (!partial) {
-
- /*
- * We must check that outChannel is a real channel - it
- * is possible that someone has transferred stdout out of
- * this interpreter with "interp transfer".
- */
+ /*
+ * We must check that outChannel is a real channel - it is
+ * possible that someone has transferred stdout out of this
+ * interpreter with "interp transfer".
+ */
outChannel = Tcl_GetChannel(interp, "stdout", NULL);
- if (outChannel != (Tcl_Channel) NULL) {
- Tcl_WriteChars(outChannel, "% ", 2);
- }
+ if (outChannel != (Tcl_Channel) NULL) {
+ Tcl_WriteChars(outChannel, "% ", 2);
+ }
}
} else {
code = Tcl_EvalObjEx(interp, promptCmd, TCL_EVAL_GLOBAL);
if (code != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (script that generates prompt)");
- /*
- * We must check that errChannel is a real channel - it
- * is possible that someone has transferred stderr out of
- * this interpreter with "interp transfer".
- */
+
+ /*
+ * We must check that errChannel is a real channel - it is
+ * possible that someone has transferred stderr out of this
+ * interpreter with "interp transfer".
+ */
errChannel = Tcl_GetChannel(interp, "stderr", NULL);
- if (errChannel != (Tcl_Channel) NULL) {
- Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp));
- Tcl_WriteChars(errChannel, "\n", 1);
- }
+ if (errChannel != (Tcl_Channel) NULL) {
+ Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp));
+ Tcl_WriteChars(errChannel, "\n", 1);
+ }
goto defaultPrompt;
}
}
outChannel = Tcl_GetChannel(interp, "stdout", NULL);
if (outChannel != (Tcl_Channel) NULL) {
- Tcl_Flush(outChannel);
+ Tcl_Flush(outChannel);
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkMenu.c b/generic/tkMenu.c
index a8fd7ce..064eaca 100755..100644
--- a/generic/tkMenu.c
+++ b/generic/tkMenu.c
@@ -1,16 +1,16 @@
-/*
+/*
* tkMenu.c --
*
* This file contains most of the code for implementing menus in Tk. It takes
- * care of all of the generic (platform-independent) parts of menus, and
- * is supplemented by platform-specific files. The geometry calculation
- * and drawing code for menus is in the file tkMenuDraw.c
+ * care of all of the generic (platform-independent) parts of menus, and is
+ * supplemented by platform-specific files. The geometry calculation 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-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
/*
@@ -18,50 +18,49 @@
*
* Menus can be used in three ways:
* - as a popup menu, either as part of a menubutton or standalone.
- * - as a menubar. The menu's cascade items are arranged according to
- * the specific platform to provide the user access to the menus at all
- * times
+ * - as a menubar. The menu's cascade items are arranged according to the
+ * specific platform to provide the user access to the menus at all times
* - as a tearoff palette. This is a window with the menu's items in it.
*
- * The goal is to provide the Tk developer with a way to use a common
- * set of menus for all of these tasks.
+ * The goal is to provide the Tk developer with a way to use a common set of
+ * menus for all of these tasks.
*
* In order to make the bindings for cascade menus work properly under Unix,
- * the cascade menus' pathnames must be proper children of the menu that
- * they are cascade from. So if there is a menu .m, and it has two
- * cascades labelled "File" and "Edit", the cascade menus might have
- * the pathnames .m.file and .m.edit. Another constraint is that the menus
- * used for menubars must be children of the toplevel widget that they
- * are attached to.
+ * the cascade menus' pathnames must be proper children of the menu that they
+ * are cascade from. So if there is a menu .m, and it has two cascades
+ * labelled "File" and "Edit", the cascade menus might have the pathnames
+ * .m.file and .m.edit. Another constraint is that the menus used for menubars
+ * must be children of the toplevel widget that they are attached to. And on
+ * the Macintosh, the platform specific menu handle for cascades attached to a
+ * menu bar must have a title that matches the label for the cascade menu.
*
* To handle all of the constraints, Tk menubars and tearoff menus are
* implemented using menu clones. Menu clones are full menus in their own
- * right; they have a Tk window and pathname associated with them; they have
- * a TkMenu structure and array of entries. However, they are linked with the
- * original menu that they were cloned from. The reflect the attributes of
- * the original, or "master", menu. So if an item is added to a menu, and
- * that menu has clones, then the item must be added to all of its clones
- * also. Menus are cloned when a menu is torn-off or when a menu is assigned
- * as a menubar using the "-menu" option of the toplevel's pathname configure
+ * right; they have a Tk window and pathname associated with them; they have a
+ * TkMenu structure and array of entries. However, they are linked with the
+ * original menu that they were cloned from. The reflect the attributes of the
+ * original, or "master", menu. So if an item is added to a menu, and that
+ * menu has clones, then the item must be added to all of its clones also.
+ * Menus are cloned when a menu is torn-off or when a menu is assigned as a
+ * menubar using the "-menu" option of the toplevel's pathname configure
* subcommand. When a clone is destroyed, only the clone is destroyed, but
* when the master menu is destroyed, all clones are also destroyed. This
- * allows the developer to just deal with one set of menus when creating
- * and destroying.
+ * allows the developer to just deal with one set of menus when creating and
+ * destroying.
*
* Clones are rather tricky when a menu with cascade entries is cloned (such
* as a menubar). Not only does the menu have to be cloned, but each cascade
* entry's corresponding menu must also be cloned. This maintains the pathname
- * parent-child hierarchy necessary for menubars and toplevels to work.
- * This leads to several special cases:
+ * parent-child hierarchy necessary for menubars and toplevels to work. This
+ * leads to several special cases:
*
* 1. When a new menu is created, and it is pointed to by cascade entries in
* cloned menus, the new menu has to be cloned to parallel the cascade
* structure.
* 2. When a cascade item is added to a menu that has been cloned, and the
* menu that the cascade item points to exists, that menu has to be cloned.
- * 3. When the menu that a cascade entry points to is changed, the old
- * cloned cascade menu has to be discarded, and the new one has to be cloned.
- *
+ * 3. When the menu that a cascade entry points to is changed, the old cloned
+ * cascade menu has to be discarded, and the new one has to be cloned.
*/
#if 0
@@ -73,22 +72,21 @@
#define __NO_OLD_CONFIG
#endif
-#include "tkPort.h"
+#include "tkInt.h"
#include "tkMenu.h"
#define MENU_HASH_KEY "tkMenus"
typedef struct ThreadSpecificData {
- int menusInitialized; /* Flag indicates whether thread-specific
- * elements of the Windows Menu module
- * have been initialized. */
+ 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.
+ * 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;
@@ -99,170 +97,171 @@ TCL_DECLARE_MUTEX(menuMutex)
* to update code in TkpMenuInit that changes the font string entry.
*/
-CONST char *tkMenuStateStrings[] = {"active", "normal", "disabled", (char *) NULL};
+const char *tkMenuStateStrings[] = {"active", "normal", "disabled", NULL};
-static CONST char *menuEntryTypeStrings[] = {
- "cascade", "checkbutton", "command", "radiobutton", "separator",
- (char *) NULL
+static const char *menuEntryTypeStrings[] = {
+ "cascade", "checkbutton", "command", "radiobutton", "separator", NULL
};
/*
- * The following table defines the legal values for the -compound option.
- * It is used with the "enum compound" declaration in tkMenu.h
+ * The following table defines the legal values for the -compound option. It
+ * is used with the "enum compound" declaration in tkMenu.h
*/
-static CONST char *CONST compoundStrings[] = {
- "bottom", "center", "left", "none", "right", "top", (char *) NULL
+static const char *compoundStrings[] = {
+ "bottom", "center", "left", "none", "right", "top", NULL
};
-static CONST Tk_OptionSpec tkBasicMenuEntryConfigSpecs[] = {
- {TK_OPTION_BORDER, "-activebackground", (char *) NULL, (char *) NULL,
- DEF_MENU_ENTRY_ACTIVE_BG, Tk_Offset(TkMenuEntry, activeBorderPtr), -1,
+static const Tk_OptionSpec tkBasicMenuEntryConfigSpecs[] = {
+ {TK_OPTION_BORDER, "-activebackground", NULL, NULL,
+ DEF_MENU_ENTRY_ACTIVE_BG, Tk_Offset(TkMenuEntry, activeBorderPtr), -1,
TK_OPTION_NULL_OK},
- {TK_OPTION_COLOR, "-activeforeground", (char *) NULL, (char *) NULL,
+ {TK_OPTION_COLOR, "-activeforeground", NULL, NULL,
DEF_MENU_ENTRY_ACTIVE_FG,
Tk_Offset(TkMenuEntry, activeFgPtr), -1, TK_OPTION_NULL_OK},
- {TK_OPTION_STRING, "-accelerator", (char *) NULL, (char *) NULL,
+ {TK_OPTION_STRING, "-accelerator", NULL, NULL,
DEF_MENU_ENTRY_ACCELERATOR,
Tk_Offset(TkMenuEntry, accelPtr), -1, TK_OPTION_NULL_OK},
- {TK_OPTION_BORDER, "-background", (char *) NULL, (char *) NULL,
+ {TK_OPTION_BORDER, "-background", NULL, NULL,
DEF_MENU_ENTRY_BG,
Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK},
- {TK_OPTION_BITMAP, "-bitmap", (char *) NULL, (char *) NULL,
+ {TK_OPTION_BITMAP, "-bitmap", NULL, NULL,
DEF_MENU_ENTRY_BITMAP,
Tk_Offset(TkMenuEntry, bitmapPtr), -1, TK_OPTION_NULL_OK},
- {TK_OPTION_BOOLEAN, "-columnbreak", (char *) NULL, (char *) NULL,
+ {TK_OPTION_BOOLEAN, "-columnbreak", NULL, NULL,
DEF_MENU_ENTRY_COLUMN_BREAK,
-1, Tk_Offset(TkMenuEntry, columnBreak)},
- {TK_OPTION_STRING, "-command", (char *) NULL, (char *) NULL,
+ {TK_OPTION_STRING, "-command", NULL, NULL,
DEF_MENU_ENTRY_COMMAND,
Tk_Offset(TkMenuEntry, commandPtr), -1, TK_OPTION_NULL_OK},
{TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
- DEF_MENU_ENTRY_COMPOUND, -1, Tk_Offset(TkMenuEntry, compound), 0,
+ DEF_MENU_ENTRY_COMPOUND, -1, Tk_Offset(TkMenuEntry, compound), 0,
(ClientData) compoundStrings, 0},
- {TK_OPTION_FONT, "-font", (char *) NULL, (char *) NULL,
+ {TK_OPTION_FONT, "-font", NULL, NULL,
DEF_MENU_ENTRY_FONT,
Tk_Offset(TkMenuEntry, fontPtr), -1, TK_OPTION_NULL_OK},
- {TK_OPTION_COLOR, "-foreground", (char *) NULL, (char *) NULL,
+ {TK_OPTION_COLOR, "-foreground", NULL, NULL,
DEF_MENU_ENTRY_FG,
Tk_Offset(TkMenuEntry, fgPtr), -1, TK_OPTION_NULL_OK},
- {TK_OPTION_BOOLEAN, "-hidemargin", (char *) NULL, (char *) NULL,
+ {TK_OPTION_BOOLEAN, "-hidemargin", NULL, NULL,
DEF_MENU_ENTRY_HIDE_MARGIN,
-1, Tk_Offset(TkMenuEntry, hideMargin)},
- {TK_OPTION_STRING, "-image", (char *) NULL, (char *) NULL,
+ {TK_OPTION_STRING, "-image", NULL, NULL,
DEF_MENU_ENTRY_IMAGE,
Tk_Offset(TkMenuEntry, imagePtr), -1, TK_OPTION_NULL_OK},
- {TK_OPTION_STRING, "-label", (char *) NULL, (char *) NULL,
+ {TK_OPTION_STRING, "-label", NULL, NULL,
DEF_MENU_ENTRY_LABEL,
Tk_Offset(TkMenuEntry, labelPtr), -1, 0},
- {TK_OPTION_STRING_TABLE, "-state", (char *) NULL, (char *) NULL,
+ {TK_OPTION_STRING_TABLE, "-state", NULL, NULL,
DEF_MENU_ENTRY_STATE,
-1, Tk_Offset(TkMenuEntry, state), 0,
(ClientData) tkMenuStateStrings},
- {TK_OPTION_INT, "-underline", (char *) NULL, (char *) NULL,
+ {TK_OPTION_INT, "-underline", NULL, NULL,
DEF_MENU_ENTRY_UNDERLINE, -1, Tk_Offset(TkMenuEntry, underline)},
{TK_OPTION_END}
};
-static CONST Tk_OptionSpec tkSeparatorEntryConfigSpecs[] = {
- {TK_OPTION_BORDER, "-background", (char *) NULL, (char *) NULL,
+static const Tk_OptionSpec tkSeparatorEntryConfigSpecs[] = {
+ {TK_OPTION_BORDER, "-background", NULL, NULL,
DEF_MENU_ENTRY_BG,
Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK},
{TK_OPTION_END}
};
-static CONST Tk_OptionSpec tkCheckButtonEntryConfigSpecs[] = {
- {TK_OPTION_BOOLEAN, "-indicatoron", (char *) NULL, (char *) NULL,
+static const Tk_OptionSpec tkCheckButtonEntryConfigSpecs[] = {
+ {TK_OPTION_BOOLEAN, "-indicatoron", NULL, NULL,
DEF_MENU_ENTRY_INDICATOR,
-1, Tk_Offset(TkMenuEntry, indicatorOn)},
- {TK_OPTION_STRING, "-offvalue", (char *) NULL, (char *) NULL,
+ {TK_OPTION_STRING, "-offvalue", NULL, NULL,
DEF_MENU_ENTRY_OFF_VALUE,
Tk_Offset(TkMenuEntry, offValuePtr), -1},
- {TK_OPTION_STRING, "-onvalue", (char *) NULL, (char *) NULL,
+ {TK_OPTION_STRING, "-onvalue", NULL, NULL,
DEF_MENU_ENTRY_ON_VALUE,
Tk_Offset(TkMenuEntry, onValuePtr), -1},
- {TK_OPTION_COLOR, "-selectcolor", (char *) NULL, (char *) NULL,
+ {TK_OPTION_COLOR, "-selectcolor", NULL, NULL,
DEF_MENU_ENTRY_SELECT,
Tk_Offset(TkMenuEntry, indicatorFgPtr), -1, TK_OPTION_NULL_OK},
- {TK_OPTION_STRING, "-selectimage", (char *) NULL, (char *) NULL,
+ {TK_OPTION_STRING, "-selectimage", NULL, NULL,
DEF_MENU_ENTRY_SELECT_IMAGE,
Tk_Offset(TkMenuEntry, selectImagePtr), -1, TK_OPTION_NULL_OK},
- {TK_OPTION_STRING, "-variable", (char *) NULL, (char *) NULL,
+ {TK_OPTION_STRING, "-variable", NULL, 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_OPTION_END, NULL, NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) tkBasicMenuEntryConfigSpecs}
};
-static CONST Tk_OptionSpec tkRadioButtonEntryConfigSpecs[] = {
- {TK_OPTION_BOOLEAN, "-indicatoron", (char *) NULL, (char *) NULL,
+static const Tk_OptionSpec tkRadioButtonEntryConfigSpecs[] = {
+ {TK_OPTION_BOOLEAN, "-indicatoron", NULL, NULL,
DEF_MENU_ENTRY_INDICATOR,
-1, Tk_Offset(TkMenuEntry, indicatorOn)},
- {TK_OPTION_COLOR, "-selectcolor", (char *) NULL, (char *) NULL,
+ {TK_OPTION_COLOR, "-selectcolor", NULL, 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_OPTION_STRING, "-selectimage", NULL, NULL,
+ DEF_MENU_ENTRY_SELECT_IMAGE,
Tk_Offset(TkMenuEntry, selectImagePtr), -1, TK_OPTION_NULL_OK},
- {TK_OPTION_STRING, "-value", (char *) NULL, (char *) NULL,
+ {TK_OPTION_STRING, "-value", NULL, NULL,
DEF_MENU_ENTRY_VALUE,
Tk_Offset(TkMenuEntry, onValuePtr), -1, TK_OPTION_NULL_OK},
- {TK_OPTION_STRING, "-variable", (char *) NULL, (char *) NULL,
+ {TK_OPTION_STRING, "-variable", NULL, 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_OPTION_END, NULL, NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) tkBasicMenuEntryConfigSpecs}
};
-static CONST Tk_OptionSpec tkCascadeEntryConfigSpecs[] = {
- {TK_OPTION_STRING, "-menu", (char *) NULL, (char *) NULL,
+static const Tk_OptionSpec tkCascadeEntryConfigSpecs[] = {
+ {TK_OPTION_STRING, "-menu", NULL, 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_OPTION_END, NULL, NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) tkBasicMenuEntryConfigSpecs}
};
-static CONST Tk_OptionSpec tkTearoffEntryConfigSpecs[] = {
- {TK_OPTION_BORDER, "-background", (char *) NULL, (char *) NULL,
+static const Tk_OptionSpec tkTearoffEntryConfigSpecs[] = {
+ {TK_OPTION_BORDER, "-background", NULL, NULL,
DEF_MENU_ENTRY_BG,
Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK},
- {TK_OPTION_STRING_TABLE, "-state", (char *) NULL, (char *) NULL,
+ {TK_OPTION_STRING_TABLE, "-state", NULL, NULL,
DEF_MENU_ENTRY_STATE, -1, Tk_Offset(TkMenuEntry, state), 0,
(ClientData) tkMenuStateStrings},
{TK_OPTION_END}
};
-static CONST Tk_OptionSpec *CONST specsArray[] = {
+static const Tk_OptionSpec *const specsArray[] = {
tkCascadeEntryConfigSpecs, tkCheckButtonEntryConfigSpecs,
tkBasicMenuEntryConfigSpecs, tkRadioButtonEntryConfigSpecs,
- tkSeparatorEntryConfigSpecs, tkTearoffEntryConfigSpecs};
-
+ tkSeparatorEntryConfigSpecs, tkTearoffEntryConfigSpecs
+};
+
/*
* Menu type strings for use with Tcl_GetIndexFromObj.
*/
-static CONST char *menuTypeStrings[] = {"normal", "tearoff", "menubar",
- (char *) NULL};
+static const char *menuTypeStrings[] = {
+ "normal", "tearoff", "menubar", NULL
+};
-static CONST Tk_OptionSpec tkMenuConfigSpecs[] = {
- {TK_OPTION_BORDER, "-activebackground", "activeBackground",
- "Foreground", DEF_MENU_ACTIVE_BG_COLOR,
+static const 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, activeBorderWidthPtr), -1},
- {TK_OPTION_COLOR, "-activeforeground", "activeForeground",
- "Background", DEF_MENU_ACTIVE_FG_COLOR,
+ "BorderWidth", DEF_MENU_ACTIVE_BORDER_WIDTH,
+ 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_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth"},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-background"},
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
DEF_MENU_BORDER_WIDTH,
Tk_Offset(TkMenu, borderWidthPtr), -1, 0},
@@ -273,14 +272,14 @@ static CONST Tk_OptionSpec tkMenuConfigSpecs[] = {
"DisabledForeground", DEF_MENU_DISABLED_FG_COLOR,
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_SYNONYM, "-fg", NULL, NULL,
+ 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,
+ 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},
@@ -292,11 +291,11 @@ static CONST Tk_OptionSpec tkMenuConfigSpecs[] = {
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",
+ {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,
+ 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,
@@ -305,73 +304,70 @@ static CONST Tk_OptionSpec tkMenuConfigSpecs[] = {
};
/*
- * Command line options. Put here because MenuCmd has to look at them
- * along with MenuWidgetObjCmd.
+ * Command line options. Put here because MenuCmd has to look at them along
+ * with MenuWidgetObjCmd.
*/
-static CONST char *menuOptions[] = {
+static const char *menuOptions[] = {
"activate", "add", "cget", "clone", "configure", "delete", "entrycget",
"entryconfigure", "index", "insert", "invoke", "post", "postcascade",
- "type", "unpost", "yposition", (char *) NULL
+ "type", "unpost", "xposition", "yposition", 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
+ MENU_UNPOST, MENU_XPOSITION, MENU_YPOSITION
};
/*
- * Prototypes for static procedures in this file:
+ * Prototypes for static functions in this file:
*/
-static int CloneMenu _ANSI_ARGS_((TkMenu *menuPtr,
- Tcl_Obj *newMenuName, Tcl_Obj *newMenuTypeString));
-static int ConfigureMenu _ANSI_ARGS_((Tcl_Interp *interp,
- TkMenu *menuPtr, int objc, Tcl_Obj *CONST objv[]));
-static int ConfigureMenuCloneEntries _ANSI_ARGS_((
- Tcl_Interp *interp, TkMenu *menuPtr, int index,
- int objc, Tcl_Obj *CONST objv[]));
-static int ConfigureMenuEntry _ANSI_ARGS_((TkMenuEntry *mePtr,
- int objc, Tcl_Obj *CONST objv[]));
-static void DeleteMenuCloneEntries _ANSI_ARGS_((TkMenu *menuPtr,
- int first, int last));
-static void DestroyMenuHashTable _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp));
-static void DestroyMenuInstance _ANSI_ARGS_((TkMenu *menuPtr));
-static void DestroyMenuEntry _ANSI_ARGS_((char *memPtr));
-static int GetIndexFromCoords
- _ANSI_ARGS_((Tcl_Interp *interp, TkMenu *menuPtr,
- char *string, int *indexPtr));
-static int MenuDoYPosition _ANSI_ARGS_((Tcl_Interp *interp,
- TkMenu *menuPtr, Tcl_Obj *objPtr));
-static int MenuAddOrInsert _ANSI_ARGS_((Tcl_Interp *interp,
+static int CloneMenu(TkMenu *menuPtr, Tcl_Obj *newMenuName,
+ Tcl_Obj *newMenuTypeString);
+static int ConfigureMenu(Tcl_Interp *interp, TkMenu *menuPtr,
+ int objc, Tcl_Obj *const objv[]);
+static int ConfigureMenuCloneEntries(Tcl_Interp *interp,
+ TkMenu *menuPtr, int index,
+ int objc, Tcl_Obj *const objv[]);
+static int ConfigureMenuEntry(TkMenuEntry *mePtr,
+ int objc, Tcl_Obj *const objv[]);
+static void DeleteMenuCloneEntries(TkMenu *menuPtr,
+ int first, int last);
+static void DestroyMenuHashTable(ClientData clientData,
+ Tcl_Interp *interp);
+static void DestroyMenuInstance(TkMenu *menuPtr);
+static void DestroyMenuEntry(char *memPtr);
+static int GetIndexFromCoords(Tcl_Interp *interp, TkMenu *menuPtr,
+ char *string, int *indexPtr);
+static int MenuDoYPosition(Tcl_Interp *interp,
+ TkMenu *menuPtr, Tcl_Obj *objPtr);
+static int MenuDoXPosition(Tcl_Interp *interp,
+ TkMenu *menuPtr, Tcl_Obj *objPtr);
+static int MenuAddOrInsert(Tcl_Interp *interp,
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,
- int type));
-static char * MenuVarProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, CONST char *name1,
- CONST char *name2, int flags));
-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));
-static Tcl_ExitProc TkMenuCleanup;
+ Tcl_Obj *const objv[]);
+static int MenuCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static void MenuCmdDeletedProc(ClientData clientData);
+static TkMenuEntry * MenuNewEntry(TkMenu *menuPtr, int index, int type);
+static char * MenuVarProc(ClientData clientData,
+ Tcl_Interp *interp, const char *name1,
+ const char *name2, int flags);
+static int MenuWidgetObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+static void MenuWorldChanged(ClientData instanceData);
+static int PostProcessEntry(TkMenuEntry *mePtr);
+static void RecursivelyDeleteMenu(TkMenu *menuPtr);
+static void UnhookCascadeEntry(TkMenuEntry *mePtr);
+static void TkMenuCleanup(ClientData unused);
/*
* The structure below is a list of procs that respond to certain window
- * manager events. One of these includes a font change, which forces
- * the geometry proc to be called.
+ * manager events. One of these includes a font change, which forces the
+ * geometry proc to be called.
*/
static Tk_ClassProcs menuClass = {
@@ -384,8 +380,7 @@ static Tk_ClassProcs menuClass = {
*
* TkCreateMenuCmd --
*
- * Called by Tk at initialization time to create the menu
- * command.
+ * Called by Tk at initialization time to create the menu command.
*
* Results:
* A standard Tcl result.
@@ -405,14 +400,14 @@ FreeOptionTables(
}
int
-TkCreateMenuCmd(interp)
- Tcl_Interp *interp; /* Interpreter we are creating the
- * command in. */
+TkCreateMenuCmd(
+ Tcl_Interp *interp) /* Interpreter we are creating the command
+ * in. */
{
- TkMenuOptionTables *optionTablesPtr =
+ TkMenuOptionTables *optionTablesPtr =
(TkMenuOptionTables *) ckalloc(sizeof(TkMenuOptionTables));
- optionTablesPtr->menuOptionTable =
+ optionTablesPtr->menuOptionTable =
Tk_CreateOptionTable(interp, tkMenuConfigSpecs);
optionTablesPtr->entryOptionTables[TEAROFF_ENTRY] =
Tk_CreateOptionTable(interp, specsArray[TEAROFF_ENTRY]);
@@ -442,9 +437,8 @@ TkCreateMenuCmd(interp)
*
* MenuCmd --
*
- * This procedure is invoked to process the "menu" Tcl
- * command. See the user documentation for details on
- * what it does.
+ * This function is invoked to process the "menu" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -456,21 +450,19 @@ TkCreateMenuCmd(interp)
*/
static int
-MenuCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument strings. */
+MenuCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
Tk_Window tkwin = Tk_MainWindow(interp);
- Tk_Window new;
+ Tk_Window newWin;
register TkMenu *menuPtr;
TkMenuReferences *menuRefPtr;
- int i, index;
- int toplevel;
+ int i, index, toplevel;
char *windowName;
- static CONST char *typeStringList[] = {"-type", (char *) NULL};
+ static const char *typeStringList[] = {"-type", NULL};
TkMenuOptionTables *optionTablesPtr = (TkMenuOptionTables *) clientData;
if (objc < 2) {
@@ -492,23 +484,23 @@ MenuCmd(clientData, interp, objc, objv)
}
}
- windowName = Tcl_GetStringFromObj(objv[1], NULL);
- new = Tk_CreateWindowFromPath(interp, tkwin, windowName, toplevel ? ""
- : NULL);
- if (new == NULL) {
+ windowName = Tcl_GetString(objv[1]);
+ newWin = Tk_CreateWindowFromPath(interp, tkwin, windowName,
+ toplevel ? "" : NULL);
+ if (newWin == NULL) {
return TCL_ERROR;
}
/*
- * Initialize the data structure for the menu. Note that the
- * menuPtr is eventually freed in 'TkMenuEventProc' in tkMenuDraw.c,
- * when Tcl_EventuallyFree is called.
+ * Initialize the data structure for the menu. Note that the menuPtr is
+ * eventually freed in 'TkMenuEventProc' in tkMenuDraw.c, when
+ * Tcl_EventuallyFree is called.
*/
menuPtr = (TkMenu *) ckalloc(sizeof(TkMenu));
memset(menuPtr, 0, sizeof(TkMenu));
- menuPtr->tkwin = new;
- menuPtr->display = Tk_Display(new);
+ menuPtr->tkwin = newWin;
+ menuPtr->display = Tk_Display(newWin);
menuPtr->interp = interp;
menuPtr->widgetCmd = Tcl_CreateObjCommand(interp,
Tk_PathName(menuPtr->tkwin), MenuWidgetObjCmd,
@@ -522,7 +514,8 @@ MenuCmd(clientData, interp, objc, objv)
Tk_SetClass(menuPtr->tkwin, "Menu");
Tk_SetClassProcs(menuPtr->tkwin, &menuClass, (ClientData) menuPtr);
- Tk_CreateEventHandler(new, ExposureMask|StructureNotifyMask|ActivateMask,
+ Tk_CreateEventHandler(newWin,
+ ExposureMask|StructureNotifyMask|ActivateMask,
TkMenuEventProc, (ClientData) menuPtr);
if (Tk_InitOptions(interp, (char *) menuPtr,
menuPtr->optionTablesPtr->menuOptionTable, menuPtr->tkwin)
@@ -548,38 +541,36 @@ MenuCmd(clientData, interp, objc, objv)
/*
* If a menu has a parent menu pointing to it as a cascade entry, the
- * parent menu needs to be told that this menu now exists so that
- * the platform-part of the menu is correctly updated.
+ * parent menu needs to be told that this menu now exists so that the
+ * platform-part of the menu is correctly updated.
*
* If a menu has an instance and has cascade entries, then each cascade
- * menu must also have a parallel instance. This is especially true on
- * the Mac, where each menu has to have a separate title everytime it is in
- * a menubar. For instance, say you have a menu .m1 with a cascade entry
- * for .m2, where .m2 does not exist yet. You then put .m1 into a menubar.
+ * menu must also have a parallel instance. This is especially true on the
+ * Mac, where each menu has to have a separate title everytime it is in a
+ * menubar. For instance, say you have a menu .m1 with a cascade entry for
+ * .m2, where .m2 does not exist yet. You then put .m1 into a menubar.
* This creates a menubar instance for .m1, but since .m2 is not there,
* nothing else happens. When we go to create .m2, we hook it up properly
* with .m1. However, we now need to clone .m2 and assign the clone of .m2
- * to be the cascade entry for the clone of .m1. This is special case
- * #1 listed in the introductory comment.
+ * to be the cascade entry for the clone of .m1. This is special case #1
+ * listed in the introductory comment.
*/
if (menuRefPtr->parentEntryPtr != NULL) {
- TkMenuEntry *cascadeListPtr = menuRefPtr->parentEntryPtr;
- TkMenuEntry *nextCascadePtr;
- Tcl_Obj *newMenuName;
- Tcl_Obj *newObjv[2];
-
- while (cascadeListPtr != NULL) {
+ TkMenuEntry *cascadeListPtr = menuRefPtr->parentEntryPtr;
+ TkMenuEntry *nextCascadePtr;
+ Tcl_Obj *newMenuName, *newObjv[2];
+ while (cascadeListPtr != NULL) {
nextCascadePtr = cascadeListPtr->nextCascadePtr;
/*
- * If we have a new master menu, and an existing cloned menu
- * points to this menu in a cascade entry, we have to clone
- * the new menu and point the entry to the clone instead
- * of the menu we are creating. Otherwise, ConfigureMenuEntry
- * will hook up the platform-specific cascade linkages now
- * that the menu we are creating exists.
+ * If we have a new master menu, and an existing cloned menu
+ * points to this menu in a cascade entry, we have to clone the
+ * new menu and point the entry to the clone instead of the menu
+ * we are creating. Otherwise, ConfigureMenuEntry will hook up the
+ * platform-specific cascade linkages now that the menu we are
+ * creating exists.
*/
if ((menuPtr->masterMenuPtr != menuPtr)
@@ -600,50 +591,50 @@ MenuCmd(clientData, interp, objc, objv)
Tcl_IncrRefCount(normalPtr);
Tcl_IncrRefCount(windowNamePtr);
- newMenuName = TkNewMenuName(menuPtr->interp,
+ newMenuName = TkNewMenuName(menuPtr->interp,
windowNamePtr, menuPtr);
Tcl_IncrRefCount(newMenuName);
- CloneMenu(menuPtr, newMenuName, normalPtr);
+ CloneMenu(menuPtr, newMenuName, normalPtr);
- /*
- * Now we can set the new menu instance to be the cascade entry
- * of the parent's instance.
- */
+ /*
+ * Now we can set the new menu instance to be the cascade
+ * entry of the parent's instance.
+ */
newObjv[0] = Tcl_NewStringObj("-menu", -1);
newObjv[1] = newMenuName;
Tcl_IncrRefCount(newObjv[0]);
- ConfigureMenuEntry(cascadeListPtr, 2, newObjv);
+ ConfigureMenuEntry(cascadeListPtr, 2, newObjv);
Tcl_DecrRefCount(normalPtr);
Tcl_DecrRefCount(newObjv[0]);
Tcl_DecrRefCount(newObjv[1]);
Tcl_DecrRefCount(windowNamePtr);
- }
- cascadeListPtr = nextCascadePtr;
- }
+ }
+ cascadeListPtr = nextCascadePtr;
+ }
}
/*
- * If there already exist toplevel widgets that refer to this menu,
- * find them and notify them so that they can reconfigure their
- * geometry to reflect the menu.
+ * If there already exist toplevel widgets that refer to this menu, find
+ * them and notify them so that they can reconfigure their geometry to
+ * reflect the menu.
*/
if (menuRefPtr->topLevelListPtr != NULL) {
TkMenuTopLevelList *topLevelListPtr = menuRefPtr->topLevelListPtr;
TkMenuTopLevelList *nextPtr;
Tk_Window listtkwin;
- while (topLevelListPtr != NULL) {
+ while (topLevelListPtr != NULL) {
/*
- * Need to get the next pointer first. TkSetWindowMenuBar
- * changes the list, so that the next pointer is different
- * after calling it.
+ * Need to get the next pointer first. TkSetWindowMenuBar changes
+ * the list, so that the next pointer is different after calling
+ * it.
*/
nextPtr = topLevelListPtr->nextPtr;
listtkwin = topLevelListPtr->tkwin;
- TkSetWindowMenuBar(menuPtr->interp, listtkwin,
+ TkSetWindowMenuBar(menuPtr->interp, listtkwin,
Tk_PathName(menuPtr->tkwin), Tk_PathName(menuPtr->tkwin));
topLevelListPtr = nextPtr;
}
@@ -658,9 +649,9 @@ MenuCmd(clientData, interp, objc, objv)
*
* MenuWidgetObjCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to a widget managed by this module.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the Tcl command that corresponds
+ * to a widget managed by this module. See the user documentation for
+ * details on what it does.
*
* Results:
* A standard Tcl result.
@@ -672,11 +663,11 @@ MenuCmd(clientData, interp, objc, objv)
*/
static int
-MenuWidgetObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Information about menu widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument strings. */
+MenuWidgetObjCmd(
+ ClientData clientData, /* Information about menu widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
register TkMenu *menuPtr = (TkMenu *) clientData;
register TkMenuEntry *mePtr;
@@ -694,335 +685,331 @@ MenuWidgetObjCmd(clientData, interp, objc, objv)
Tcl_Preserve((ClientData) menuPtr);
switch ((enum options) option) {
- case MENU_ACTIVATE: {
- int index;
+ 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;
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "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;
+ }
+ case MENU_ADD:
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "type ?options?");
+ 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 (MenuAddOrInsert(interp, menuPtr, 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;
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "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;
+ }
+ case MENU_CLONE:
+ if ((objc < 3) || (objc > 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "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, NULL,
+ menuPtr->tkwin);
+ if (resultPtr == NULL) {
+ result = TCL_ERROR;
+ } else {
+ result = TCL_OK;
+ Tcl_SetObjResult(interp, resultPtr);
}
- resultPtr = Tk_GetOptionValue(interp, (char *) menuPtr,
+ } else if (objc == 3) {
+ resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr,
menuPtr->optionTablesPtr->menuOptionTable, objv[2],
menuPtr->tkwin);
if (resultPtr == NULL) {
- goto error;
- }
- Tcl_SetObjResult(interp, resultPtr);
- break;
- }
- 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);
- }
+ result = TCL_ERROR;
} else {
- result = ConfigureMenu(interp, menuPtr, objc - 2, objv + 2);
+ result = TCL_OK;
+ Tcl_SetObjResult(interp, resultPtr);
}
- if (result != TCL_OK) {
- goto error;
- }
- break;
+ } else {
+ result = ConfigureMenu(interp, menuPtr, objc - 2, objv + 2);
}
- 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)) {
+ if (result != TCL_OK) {
+ goto error;
+ }
+ break;
+ }
+ case MENU_DELETE: {
+ int first, last;
- /*
- * Sorry, can't delete the tearoff entry; must reconfigure
- * the menu.
- */
-
- first = 1;
- }
- if ((first < 0) || (last < first)) {
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "first ?last?");
+ goto error;
+ }
+
+ /*
+ * If 'first' explicitly refers to past the end of the menu, we don't
+ * do anything. [Bug 220950]
+ */
+
+ if (isdigit(UCHAR(Tcl_GetString(objv[2])[0]))
+ && Tcl_GetIntFromObj(NULL, objv[2], &first) == TCL_OK) {
+ if (first >= menuPtr->numEntries) {
goto done;
}
- DeleteMenuCloneEntries(menuPtr, first, last);
- break;
+ } else 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;
}
- 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;
+ 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;
+ }
+ case MENU_ENTRYCGET: {
+ int index;
+ Tcl_Obj *resultPtr;
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "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;
+ }
+ case MENU_ENTRYCONFIGURE: {
+ int index;
+ Tcl_Obj *resultPtr;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "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, NULL, menuPtr->tkwin);
+ if (resultPtr == NULL) {
+ result = TCL_ERROR;
+ } else {
+ result = TCL_OK;
+ Tcl_SetObjResult(interp, resultPtr);
}
- mePtr = menuPtr->entries[index];
- Tcl_Preserve((ClientData) mePtr);
- resultPtr = Tk_GetOptionValue(interp, (char *) mePtr,
+ } else if (objc == 4) {
+ resultPtr = Tk_GetOptionInfo(interp, (char *) mePtr,
mePtr->optionTable, objv[3], menuPtr->tkwin);
- Tcl_Release((ClientData) mePtr);
if (resultPtr == NULL) {
- goto error;
+ result = TCL_ERROR;
+ } else {
+ result = TCL_OK;
+ Tcl_SetObjResult(interp, resultPtr);
}
- Tcl_SetObjResult(interp, resultPtr);
- break;
+ } else {
+ result = ConfigureMenuCloneEntries(interp, menuPtr, index,
+ objc-3, objv+3);
}
- case MENU_ENTRYCONFIGURE: {
- int index;
- Tcl_Obj *resultPtr;
+ Tcl_Release((ClientData) mePtr);
+ break;
+ }
+ case MENU_INDEX: {
+ int index;
- 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 (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "string");
+ goto error;
+ }
+ if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
+ goto error;
}
- case MENU_INDEX: {
- int index;
+ if (index < 0) {
+ Tcl_SetResult(interp, "none", TCL_STATIC);
+ } else {
+ Tcl_SetIntObj(Tcl_GetObjResult(interp), index);
+ }
+ break;
+ }
+ case MENU_INSERT:
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "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, "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 (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
+ 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 (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
+ goto error;
+ }
+ if (index < 0) {
+ goto done;
+ }
+ result = TkInvokeMenu(interp, menuPtr, index);
+ break;
+ }
+ case MENU_POST: {
+ int x, y;
- 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 (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ goto error;
+ }
+ if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
+ goto error;
}
- 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;
- }
+ /*
+ * 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.
+ */
- /*
- * 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);
- }
- break;
+ if (menuPtr->menuType != TEAROFF_MENU) {
+ result = TkpPostMenu(interp, menuPtr, x, y);
+ } else {
+ result = TkPostTearoffMenu(interp, menuPtr, x, y);
}
- case MENU_POSTCASCADE: {
- int index;
+ break;
+ }
+ case MENU_POSTCASCADE: {
+ int index;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "postcascade index");
- goto error;
- }
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
+ 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, objv[2], 0, &index) != TCL_OK) {
+ goto error;
+ }
+ if ((index < 0) || (menuPtr->entries[index]->type != CASCADE_ENTRY)) {
+ result = TkPostSubmenu(interp, menuPtr, NULL);
+ } else {
+ result = TkPostSubmenu(interp, menuPtr, menuPtr->entries[index]);
}
- case MENU_TYPE: {
- int index;
+ break;
+ }
+ 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_SetStringObj(Tcl_GetObjResult(interp),
- menuEntryTypeStrings[menuPtr->entries[index]->type],
- -1);
- }
- break;
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
+ goto error;
}
- case MENU_UNPOST:
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "unpost");
- goto error;
- }
- Tk_UnmapWindow(menuPtr->tkwin);
- result = TkPostSubmenu(interp, menuPtr, (TkMenuEntry *) NULL);
- break;
- case MENU_YPOSITION:
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "yposition index");
- goto error;
- }
- result = MenuDoYPosition(interp, menuPtr, objv[2]);
- break;
+ 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_SetStringObj(Tcl_GetObjResult(interp),
+ menuEntryTypeStrings[menuPtr->entries[index]->type], -1);
+ }
+ break;
}
- done:
+ case MENU_UNPOST:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ goto error;
+ }
+ Tk_UnmapWindow(menuPtr->tkwin);
+ result = TkPostSubmenu(interp, menuPtr, NULL);
+ break;
+ case MENU_XPOSITION:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
+ goto error;
+ }
+ result = MenuDoXPosition(interp, menuPtr, objv[2]);
+ break;
+ case MENU_YPOSITION:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
+ goto error;
+ }
+ result = MenuDoYPosition(interp, menuPtr, objv[2]);
+ break;
+ }
+ done:
Tcl_Release((ClientData) menuPtr);
return result;
- error:
+ error:
Tcl_Release((ClientData) menuPtr);
return TCL_ERROR;
}
@@ -1032,29 +1019,29 @@ MenuWidgetObjCmd(clientData, interp, objc, objv)
*
* TkInvokeMenu --
*
- * Given a menu and an index, takes the appropriate action for the
- * entry associated with that index.
+ * Given a menu and an index, takes the appropriate action for the entry
+ * associated with that index.
*
* Results:
* Standard Tcl result.
*
* Side effects:
- * Commands may get excecuted; variables may get set; sub-menus may
- * get posted.
+ * Commands may get excecuted; variables may get set; sub-menus may get
+ * posted.
*
*----------------------------------------------------------------------
*/
int
-TkInvokeMenu(interp, menuPtr, index)
- Tcl_Interp *interp; /* The interp that the menu lives in. */
- TkMenu *menuPtr; /* The menu we are invoking. */
- int index; /* The zero based index of the item we
- * are invoking */
+TkInvokeMenu(
+ Tcl_Interp *interp, /* The interp that the menu lives in. */
+ TkMenu *menuPtr, /* The menu we are invoking. */
+ int index) /* The zero based index of the item we are
+ * invoking. */
{
int result = TCL_OK;
TkMenuEntry *mePtr;
-
+
if (index < 0) {
goto done;
}
@@ -1102,11 +1089,13 @@ TkInvokeMenu(interp, menuPtr, index)
}
Tcl_DecrRefCount(valuePtr);
}
+
/*
- * We check numEntries in addition to whether the menu entry
- * has a command because that goes to zero if the menu gets
- * deleted (e.g., during command evaluation).
+ * We check numEntries in addition to whether the menu entry has a command
+ * because that goes to zero if the menu gets deleted (e.g., during
+ * command evaluation).
*/
+
if ((menuPtr->numEntries != 0) && (result == TCL_OK)
&& (mePtr->commandPtr != NULL)) {
Tcl_Obj *commandPtr = mePtr->commandPtr;
@@ -1116,7 +1105,7 @@ TkInvokeMenu(interp, menuPtr, index)
Tcl_DecrRefCount(commandPtr);
}
Tcl_Release((ClientData) mePtr);
- done:
+ done:
return result;
}
@@ -1125,10 +1114,9 @@ TkInvokeMenu(interp, menuPtr, index)
*
* DestroyMenuInstance --
*
- * This procedure is invoked by TkDestroyMenu
- * to clean up the internal structure of a menu at a safe time
- * (when no-one is using it anymore). Only takes care of one instance
- * of the menu.
+ * This function is invoked by TkDestroyMenu to clean up the internal
+ * structure of a menu at a safe time (when no-one is using it anymore).
+ * Only takes care of one instance of the menu.
*
* Results:
* None.
@@ -1140,8 +1128,8 @@ TkInvokeMenu(interp, menuPtr, index)
*/
static void
-DestroyMenuInstance(menuPtr)
- TkMenu *menuPtr; /* Info about menu widget. */
+DestroyMenuInstance(
+ TkMenu *menuPtr) /* Info about menu widget. */
{
int i;
TkMenu *menuInstancePtr;
@@ -1149,19 +1137,19 @@ DestroyMenuInstance(menuPtr)
Tcl_Obj *newObjv[2];
TkMenu *parentMasterMenuPtr;
TkMenuEntry *parentMasterEntryPtr;
-
+
/*
* If the menu has any cascade menu entries pointing to it, the cascade
* entries need to be told that the menu is going away. We need to clear
- * the menu ptr field in the menu reference at this point in the code
- * so that everything else can forget about this menu properly. We also
- * need to reset -menu field of all entries that are not master menus
- * back to this entry name if this is a master menu pointed to by another
- * master menu. If there is a clone menu that points to this menu,
- * then this menu is itself a clone, so when this menu goes away,
- * the -menu field of the pointing entry must be set back to this
- * menu's master menu name so that later if another menu is created
- * the cascade hierarchy can be maintained.
+ * the menu ptr field in the menu reference at this point in the code so
+ * that everything else can forget about this menu properly. We also need
+ * to reset -menu field of all entries that are not master menus back to
+ * this entry name if this is a master menu pointed to by another master
+ * menu. If there is a clone menu that points to this menu, then this menu
+ * is itself a clone, so when this menu goes away, the -menu field of the
+ * pointing entry must be set back to this menu's master menu name so that
+ * later if another menu is created the cascade hierarchy can be
+ * maintained.
*/
TkpDestroyMenu(menuPtr);
@@ -1176,7 +1164,7 @@ DestroyMenuInstance(menuPtr)
for (; cascadePtr != NULL; cascadePtr = nextCascadePtr) {
nextCascadePtr = cascadePtr->nextCascadePtr;
-
+
if (menuPtr->masterMenuPtr != menuPtr) {
Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1);
@@ -1185,10 +1173,12 @@ DestroyMenuInstance(menuPtr)
parentMasterMenuPtr->entries[cascadePtr->index];
newObjv[0] = menuNamePtr;
newObjv[1] = parentMasterEntryPtr->namePtr;
+
/*
- * It is possible that the menu info is out of sync, and
- * these things point to NULL, so verify existence [Bug: 3402]
+ * It is possible that the menu info is out of sync, and these
+ * things point to NULL, so verify existence [Bug: 3402]
*/
+
if (newObjv[0] && newObjv[1]) {
Tcl_IncrRefCount(newObjv[0]);
Tcl_IncrRefCount(newObjv[1]);
@@ -1197,38 +1187,37 @@ DestroyMenuInstance(menuPtr)
Tcl_DecrRefCount(newObjv[1]);
}
} else {
- ConfigureMenuEntry(cascadePtr, 0, (Tcl_Obj **) NULL);
+ ConfigureMenuEntry(cascadePtr, 0, NULL);
}
}
-
+
if (menuPtr->masterMenuPtr != menuPtr) {
- for (menuInstancePtr = menuPtr->masterMenuPtr;
- menuInstancePtr != NULL;
- menuInstancePtr = menuInstancePtr->nextInstancePtr) {
- if (menuInstancePtr->nextInstancePtr == menuPtr) {
- menuInstancePtr->nextInstancePtr =
- menuInstancePtr->nextInstancePtr->nextInstancePtr;
- break;
- }
- }
- } else if (menuPtr->nextInstancePtr != NULL) {
- panic("Attempting to delete master menu when there are still clones.");
- }
+ for (menuInstancePtr = menuPtr->masterMenuPtr;
+ menuInstancePtr != NULL;
+ menuInstancePtr = menuInstancePtr->nextInstancePtr) {
+ if (menuInstancePtr->nextInstancePtr == menuPtr) {
+ menuInstancePtr->nextInstancePtr =
+ menuInstancePtr->nextInstancePtr->nextInstancePtr;
+ break;
+ }
+ }
+ } else if (menuPtr->nextInstancePtr != NULL) {
+ Tcl_Panic("Attempting to delete master menu when there are still clones.");
+ }
/*
- * Free up all the stuff that requires special handling, then
- * let Tk_FreeConfigOptions handle all the standard option-related
- * stuff.
+ * Free up all the stuff that requires special handling, then let
+ * Tk_FreeConfigOptions handle all the standard option-related stuff.
*/
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.
+ * 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;
}
@@ -1236,7 +1225,7 @@ DestroyMenuInstance(menuPtr)
ckfree((char *) menuPtr->entries);
}
TkMenuFreeDrawOptions(menuPtr);
- Tk_FreeConfigOptions((char *) menuPtr,
+ Tk_FreeConfigOptions((char *) menuPtr,
menuPtr->optionTablesPtr->menuOptionTable, menuPtr->tkwin);
if (menuPtr->tkwin != NULL) {
Tk_Window tkwin = menuPtr->tkwin;
@@ -1250,11 +1239,11 @@ DestroyMenuInstance(menuPtr)
*
* TkDestroyMenu --
*
- * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release
- * to clean up the internal structure of a menu at a safe time
- * (when no-one is using it anymore). If called on a master instance,
- * destroys all of the slave instances. If called on a non-master
- * instance, just destroys that instance.
+ * This function is invoked by Tcl_EventuallyFree or Tcl_Release to clean
+ * up the internal structure of a menu at a safe time (when no-one is
+ * using it anymore). If called on a master instance, destroys all of the
+ * slave instances. If called on a non-master instance, just destroys
+ * that instance.
*
* Results:
* None.
@@ -1266,8 +1255,8 @@ DestroyMenuInstance(menuPtr)
*/
void
-TkDestroyMenu(menuPtr)
- TkMenu *menuPtr; /* Info about menu widget. */
+TkDestroyMenu(
+ TkMenu *menuPtr) /* Info about menu widget. */
{
TkMenu *menuInstancePtr;
TkMenuTopLevelList *topLevelListPtr, *nextTopLevelPtr;
@@ -1277,20 +1266,21 @@ TkDestroyMenu(menuPtr)
}
Tcl_Preserve(menuPtr);
-
+
/*
- * Now destroy all non-tearoff instances of this menu if this is a
- * parent menu. Is this loop safe enough? Are there going to be
- * destroy bindings on child menus which kill the parent? If not,
- * we have to do a slightly more complex scheme.
+ * Now destroy all non-tearoff instances of this menu if this is a parent
+ * menu. Is this loop safe enough? Are there going to be destroy bindings
+ * on child menus which kill the parent? If not, we have to do a slightly
+ * more complex scheme.
*/
menuPtr->menuFlags |= MENU_DELETION_PENDING;
if (menuPtr->menuRefPtr != NULL) {
/*
- * If any toplevel widgets have this menu as their menubar,
- * the geometry of the window may have to be recalculated.
+ * If any toplevel widgets have this menu as their menubar, the
+ * geometry of the window may have to be recalculated.
*/
+
topLevelListPtr = menuPtr->menuRefPtr->topLevelListPtr;
while (topLevelListPtr != NULL) {
nextTopLevelPtr = topLevelListPtr->nextPtr;
@@ -1304,11 +1294,13 @@ TkDestroyMenu(menuPtr)
menuPtr->nextInstancePtr = menuInstancePtr->nextInstancePtr;
if (menuInstancePtr->tkwin != NULL) {
Tk_Window tkwin = menuInstancePtr->tkwin;
- /*
- * Note: it may be desirable to NULL out the tkwin
- * field of menuInstancePtr here:
+
+ /*
+ * Note: it may be desirable to NULL out the tkwin field of
+ * menuInstancePtr here:
* menuInstancePtr->tkwin = NULL;
*/
+
Tk_DestroyWindow(tkwin);
}
}
@@ -1325,12 +1317,12 @@ TkDestroyMenu(menuPtr)
* UnhookCascadeEntry --
*
* This entry is removed from the list of entries that point to the
- * cascade menu. This is done in preparation for changing the menu
- * that this entry points to.
- *
- * At the end of this function, the menu entry no longer contains
- * a reference to a 'TkMenuReferences' structure, and therefore
- * no such structure contains a reference to this menu entry either.
+ * cascade menu. This is done in preparation for changing the menu that
+ * this entry points to.
+ *
+ * At the end of this function, the menu entry no longer contains a
+ * reference to a 'TkMenuReferences' structure, and therefore no such
+ * structure contains a reference to this menu entry either.
*
* Results:
* None
@@ -1342,9 +1334,9 @@ TkDestroyMenu(menuPtr)
*/
static void
-UnhookCascadeEntry(mePtr)
- TkMenuEntry *mePtr; /* The cascade entry we are removing
- * from the cascade list. */
+UnhookCascadeEntry(
+ TkMenuEntry *mePtr) /* The cascade entry we are removing from the
+ * cascade list. */
{
TkMenuEntry *cascadeEntryPtr;
TkMenuEntry *prevCascadePtr;
@@ -1352,35 +1344,34 @@ UnhookCascadeEntry(mePtr)
menuRefPtr = mePtr->childMenuRefPtr;
if (menuRefPtr == NULL) {
- return;
+ return;
}
-
+
cascadeEntryPtr = menuRefPtr->parentEntryPtr;
if (cascadeEntryPtr == NULL) {
TkFreeMenuReferences(menuRefPtr);
mePtr->childMenuRefPtr = NULL;
return;
}
-
+
/*
- * Singularly linked list deletion. The two special cases are
- * 1. one element; 2. The first element is the one we want.
+ * Singularly linked list deletion. The two special cases are 1. one
+ * element; 2. The first element is the one we want.
*/
if (cascadeEntryPtr == mePtr) {
if (cascadeEntryPtr->nextCascadePtr == NULL) {
-
/*
- * This is the last menu entry which points to this
- * menu, so we need to clear out the list pointer in the
- * cascade itself.
+ * This is the last menu entry which points to this menu, so we
+ * need to clear out the list pointer in the cascade itself.
*/
menuRefPtr->parentEntryPtr = NULL;
- /*
- * The original field is set to zero below, after it is
- * freed.
+
+ /*
+ * The original field is set to zero below, after it is freed.
*/
+
TkFreeMenuReferences(menuRefPtr);
} else {
menuRefPtr->parentEntryPtr = cascadeEntryPtr->nextCascadePtr;
@@ -1390,15 +1381,15 @@ UnhookCascadeEntry(mePtr)
for (prevCascadePtr = cascadeEntryPtr,
cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr;
cascadeEntryPtr != NULL;
- prevCascadePtr = cascadeEntryPtr,
+ prevCascadePtr = cascadeEntryPtr,
cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
if (cascadeEntryPtr == mePtr){
prevCascadePtr->nextCascadePtr =
- cascadeEntryPtr->nextCascadePtr;
+ cascadeEntryPtr->nextCascadePtr;
cascadeEntryPtr->nextCascadePtr = NULL;
break;
}
- }
+ }
mePtr->nextCascadePtr = NULL;
}
mePtr->childMenuRefPtr = NULL;
@@ -1409,9 +1400,9 @@ UnhookCascadeEntry(mePtr)
*
* DestroyMenuEntry --
*
- * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release
- * to clean up the internal structure of a menu entry at a safe time
- * (when no-one is using it anymore).
+ * This function is invoked by Tcl_EventuallyFree or Tcl_Release to clean
+ * up the internal structure of a menu entry at a safe time (when no-one
+ * is using it anymore).
*
* Results:
* None.
@@ -1423,56 +1414,57 @@ UnhookCascadeEntry(mePtr)
*/
static void
-DestroyMenuEntry(memPtr)
- char *memPtr; /* Pointer to entry to be freed. */
+DestroyMenuEntry(
+ char *memPtr) /* Pointer to entry to be freed. */
{
register TkMenuEntry *mePtr = (TkMenuEntry *) memPtr;
TkMenu *menuPtr = mePtr->menuPtr;
if (menuPtr->postedCascade == mePtr) {
/*
- * Ignore errors while unposting the menu, since it's possible
- * that the menu has already been deleted and the unpost will
- * generate an error.
+ * Ignore errors while unposting the menu, since it's possible that
+ * the menu has already been deleted and the unpost will generate an
+ * error.
*/
- TkPostSubmenu(menuPtr->interp, menuPtr, (TkMenuEntry *) NULL);
+ TkPostSubmenu(menuPtr->interp, menuPtr, NULL);
}
/*
- * Free up all the stuff that requires special handling, then
- * let Tk_FreeConfigOptions handle all the standard option-related
- * stuff.
+ * Free up all the stuff that requires special handling, then let
+ * Tk_FreeConfigOptions handle all the standard option-related stuff.
*/
if (mePtr->type == CASCADE_ENTRY) {
if (menuPtr->masterMenuPtr != menuPtr) {
TkMenu *destroyThis = NULL;
- /*
- * The menu as a whole is a clone. We must delete the clone
- * of the cascaded menu for the particular entry we are
- * destroying.
+ /*
+ * The menu as a whole is a clone. We must delete the clone of the
+ * cascaded menu for the particular entry we are destroying.
*/
+
TkMenuReferences *menuRefPtr = mePtr->childMenuRefPtr;
+
if (menuRefPtr != NULL) {
destroyThis = menuRefPtr->menuPtr;
- /*
- * But only if it is a clone. What can happen is that
- * we are in the middle of deleting a menu and this
- * menu pointer has already been reset to point to the
- * original menu. In that case we have nothing special
- * to do.
+
+ /*
+ * But only if it is a clone. What can happen is that we are
+ * in the middle of deleting a menu and this menu pointer has
+ * already been reset to point to the original menu. In that
+ * case we have nothing special to do.
*/
- if ((destroyThis != NULL)
- && (destroyThis->masterMenuPtr == destroyThis)) {
+
+ if ((destroyThis != NULL)
+ && (destroyThis->masterMenuPtr == destroyThis)) {
destroyThis = NULL;
}
}
UnhookCascadeEntry(mePtr);
if (menuRefPtr != NULL) {
- if (menuRefPtr->menuPtr == destroyThis) {
- menuRefPtr->menuPtr = NULL;
- }
+ if (menuRefPtr->menuPtr == destroyThis) {
+ menuRefPtr->menuPtr = NULL;
+ }
if (destroyThis != NULL) {
TkDestroyMenu(destroyThis);
}
@@ -1487,10 +1479,11 @@ DestroyMenuEntry(memPtr)
if (mePtr->selectImage != NULL) {
Tk_FreeImage(mePtr->selectImage);
}
- if (((mePtr->type == CHECK_BUTTON_ENTRY)
+ if (((mePtr->type == CHECK_BUTTON_ENTRY)
|| (mePtr->type == RADIO_BUTTON_ENTRY))
&& (mePtr->namePtr != NULL)) {
- char *varName = Tcl_GetStringFromObj(mePtr->namePtr, NULL);
+ char *varName = Tcl_GetString(mePtr->namePtr);
+
Tcl_UntraceVar(menuPtr->interp, varName,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MenuVarProc, (ClientData) mePtr);
@@ -1506,22 +1499,22 @@ DestroyMenuEntry(memPtr)
*
* MenuWorldChanged --
*
- * This procedure is called when the world has changed in some
- * way (such as the fonts in the system changing) and the widget needs
- * to recompute all its graphics contexts and determine its new geometry.
+ * This function is called when the world has changed in some way (such
+ * as the fonts in the system changing) and the widget needs to recompute
+ * all its graphics contexts and determine its new geometry.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Menu will be relayed out and redisplayed.
+ * Menu will be relayed out and redisplayed.
*
*---------------------------------------------------------------------------
*/
static void
-MenuWorldChanged(instanceData)
- ClientData instanceData; /* Information about widget. */
+MenuWorldChanged(
+ ClientData instanceData) /* Information about widget. */
{
TkMenu *menuPtr = (TkMenu *) instanceData;
int i;
@@ -1540,40 +1533,39 @@ MenuWorldChanged(instanceData)
*
* ConfigureMenu --
*
- * This procedure is called to process an argv/argc list, plus
- * the Tk option database, in order to configure (or
- * reconfigure) a menu widget.
+ * This function is called to process an argv/argc list, plus the Tk
+ * option database, in order to configure (or reconfigure) a menu widget.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message.
+ * 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 colors, font, etc. get set
- * for menuPtr; old resources get freed, if there were any.
+ * Configuration information, such as colors, font, etc. get set for
+ * menuPtr; old resources get freed, if there were any.
*
*----------------------------------------------------------------------
*/
static int
-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 objc; /* Number of valid entries in argv. */
- Tcl_Obj *CONST objv[]; /* Arguments. */
+ConfigureMenu(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ register TkMenu *menuPtr, /* Information about widget; may or may not
+ * already have values for some fields. */
+ int objc, /* Number of valid entries in argv. */
+ Tcl_Obj *const objv[]) /* Arguments. */
{
int i;
TkMenu *menuListPtr, *cleanupPtr;
int result;
-
+
for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
menuListPtr = menuListPtr->nextInstancePtr) {
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);
+ menuListPtr->optionTablesPtr->menuOptionTable, objc, objv,
+ menuListPtr->tkwin, menuListPtr->errorStructPtr, NULL);
if (result != TCL_OK) {
for (cleanupPtr = menuPtr->masterMenuPtr;
cleanupPtr != menuListPtr;
@@ -1591,25 +1583,24 @@ ConfigureMenu(interp, menuPtr, objc, objv)
}
/*
- * When a menu is created, the type is in all of the arguments
- * to the menu command. Let Tk_ConfigureWidget take care of
- * parsing them, and then set the type after we can look at
- * the type string. Once set, a menu's type cannot be changed
+ * When a menu is created, the type is in all of the arguments to the
+ * menu command. Let Tk_ConfigureWidget take care of parsing them, and
+ * then set the type after we can look at the type string. Once set, a
+ * menu's type cannot be changed
*/
-
+
if (menuListPtr->menuType == UNKNOWN_TYPE) {
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
+ * 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) {
@@ -1619,10 +1610,10 @@ ConfigureMenu(interp, menuPtr, objc, objv)
/*
- * Depending on the -tearOff option, make sure that there is or
- * isn't an initial tear-off entry at the beginning of the menu.
+ * 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->numEntries == 0)
|| (menuListPtr->entries[0]->type != TEAROFF_ENTRY)) {
@@ -1645,7 +1636,7 @@ ConfigureMenu(interp, menuPtr, objc, objv)
} else if ((menuListPtr->numEntries > 0)
&& (menuListPtr->entries[0]->type == TEAROFF_ENTRY)) {
int i;
-
+
Tcl_EventuallyFree((ClientData) menuListPtr->entries[0],
DestroyMenuEntry);
@@ -1661,21 +1652,21 @@ ConfigureMenu(interp, menuPtr, objc, objv)
}
TkMenuConfigureDrawOptions(menuListPtr);
-
+
/*
* After reconfiguring a menu, we need to reconfigure all of the
- * entries in the menu, since some of the things in the children
- * (such as graphics contexts) may have to change to reflect changes
- * in the parent.
+ * entries in the menu, since some of the things in the children (such
+ * as graphics contexts) may have to change to reflect changes in the
+ * parent.
*/
-
+
for (i = 0; i < menuListPtr->numEntries; i++) {
TkMenuEntry *mePtr;
-
+
mePtr = menuListPtr->entries[i];
- ConfigureMenuEntry(mePtr, 0, (Tcl_Obj **) NULL);
+ ConfigureMenuEntry(mePtr, 0, NULL);
}
-
+
TkEventuallyRecomputeMenu(menuListPtr);
}
@@ -1688,7 +1679,6 @@ ConfigureMenu(interp, menuPtr, objc, objv)
return TCL_OK;
}
-
/*
*----------------------------------------------------------------------
@@ -1696,23 +1686,23 @@ ConfigureMenu(interp, menuPtr, objc, objv)
* PostProcessEntry --
*
* 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.
+ * 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 the interp's result contains an error message.
+ * 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.
+ * Configuration information such as label and accelerator get set for
+ * mePtr; old resources get freed, if there were any.
*
*----------------------------------------------------------------------
*/
static int
-PostProcessEntry(mePtr)
- TkMenuEntry *mePtr; /* The entry we are configuring. */
+PostProcessEntry(
+ TkMenuEntry *mePtr) /* The entry we are configuring. */
{
TkMenu *menuPtr = mePtr->menuPtr;
int index = mePtr->index;
@@ -1720,9 +1710,9 @@ PostProcessEntry(mePtr)
Tk_Image image;
/*
- * 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.
+ * 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->labelPtr == NULL) {
@@ -1750,16 +1740,15 @@ PostProcessEntry(mePtr)
* prevent compiler warning. */
/*
- * This is a cascade entry. If the menu that the cascade entry
- * is pointing to has changed, we need to remove this entry
- * from the list of entries pointing to the old menu, and add a
- * cascade reference to the list of entries pointing to the
- * new menu.
+ * This is a cascade entry. If the menu that the cascade entry is
+ * pointing to has changed, we need to remove this entry from the list
+ * of entries pointing to the old menu, and add a cascade reference to
+ * the list of entries pointing to the new menu.
*
* BUG: We are not recloning for special case #3 yet.
*/
-
- name = Tcl_GetStringFromObj(mePtr->namePtr, NULL);
+
+ name = Tcl_GetString(mePtr->namePtr);
if (mePtr->childMenuRefPtr != NULL) {
oldHashKey = Tcl_GetHashKey(TkGetMenuHashTable(menuPtr->interp),
mePtr->childMenuRefPtr->hashEntryPtr);
@@ -1768,7 +1757,7 @@ PostProcessEntry(mePtr)
}
}
- if ((mePtr->childMenuRefPtr == NULL)
+ if ((mePtr->childMenuRefPtr == NULL)
|| (strcmp(oldHashKey, name) != 0)) {
menuRefPtr = TkCreateMenuReferences(menuPtr->interp, name);
mePtr->childMenuRefPtr = menuRefPtr;
@@ -1786,11 +1775,11 @@ PostProcessEntry(mePtr)
break;
}
}
-
+
/*
* Put the item at the front of the list.
*/
-
+
if (!alreadyThere) {
mePtr->nextCascadePtr = menuRefPtr->parentEntryPtr;
menuRefPtr->parentEntryPtr = mePtr;
@@ -1798,23 +1787,20 @@ PostProcessEntry(mePtr)
}
}
}
-
+
if (TkMenuConfigureEntryDrawOptions(mePtr, index) != TCL_OK) {
return TCL_ERROR;
}
- if (TkpConfigureMenuEntry(mePtr) != TCL_OK) {
- return TCL_ERROR;
- }
-
/*
- * 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.
+ * 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->imagePtr != NULL) {
- char *imageString = Tcl_GetStringFromObj(mePtr->imagePtr, NULL);
+ char *imageString = Tcl_GetString(mePtr->imagePtr);
+
image = Tk_GetImage(menuPtr->interp, menuPtr->tkwin, imageString,
TkMenuImageProc, (ClientData) mePtr);
if (image == NULL) {
@@ -1828,8 +1814,8 @@ PostProcessEntry(mePtr)
}
mePtr->image = image;
if (mePtr->selectImagePtr != NULL) {
- char *selectImageString = Tcl_GetStringFromObj(
- mePtr->selectImagePtr, NULL);
+ char *selectImageString = Tcl_GetString(mePtr->selectImagePtr);
+
image = Tk_GetImage(menuPtr->interp, menuPtr->tkwin, selectImageString,
TkMenuSelectImageProc, (ClientData) mePtr);
if (image == NULL) {
@@ -1866,12 +1852,11 @@ PostProcessEntry(mePtr)
}
/*
- * 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.
+ * 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);
@@ -1881,10 +1866,8 @@ PostProcessEntry(mePtr)
mePtr->entryFlags &= ~ENTRY_SELECTED;
if (valuePtr != NULL) {
if (mePtr->onValuePtr != NULL) {
- char *value = Tcl_GetStringFromObj(valuePtr, NULL);
- char *onValue = Tcl_GetStringFromObj(mePtr->onValuePtr,
- NULL);
-
+ char *value = Tcl_GetString(valuePtr);
+ char *onValue = Tcl_GetString(mePtr->onValuePtr);
if (strcmp(value, onValue) == 0) {
mePtr->entryFlags |= ENTRY_SELECTED;
@@ -1894,19 +1877,21 @@ PostProcessEntry(mePtr)
if (mePtr->namePtr != NULL) {
Tcl_ObjSetVar2(menuPtr->interp, mePtr->namePtr, NULL,
(mePtr->type == CHECK_BUTTON_ENTRY)
- ? mePtr->offValuePtr
- : Tcl_NewObj(),
- TCL_GLOBAL_ONLY);
+ ? mePtr->offValuePtr : Tcl_NewObj(), TCL_GLOBAL_ONLY);
}
}
if (mePtr->namePtr != NULL) {
- name = Tcl_GetStringFromObj(mePtr->namePtr, NULL);
+ name = Tcl_GetString(mePtr->namePtr);
Tcl_TraceVar(menuPtr->interp, name,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MenuVarProc, (ClientData) mePtr);
}
}
-
+
+ if (TkpConfigureMenuEntry(mePtr) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
return TCL_OK;
}
@@ -1915,41 +1900,41 @@ PostProcessEntry(mePtr)
*
* ConfigureMenuEntry --
*
- * This procedure is called to process an argv/argc list in order
- * to configure (or reconfigure) one entry in a menu.
+ * This function 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.
+ * 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.
+ * 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. */
+ConfigureMenuEntry(
+ 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 this entry is a check button or radio button, then remove its old
+ * trace function.
*/
if ((mePtr->namePtr != NULL)
&& ((mePtr->type == CHECK_BUTTON_ENTRY)
|| (mePtr->type == RADIO_BUTTON_ENTRY))) {
- char *name = Tcl_GetStringFromObj(mePtr->namePtr, NULL);
+ char *name = Tcl_GetString(mePtr->namePtr);
+
Tcl_UntraceVar(menuPtr->interp, name,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MenuVarProc, (ClientData) mePtr);
@@ -1959,7 +1944,7 @@ ConfigureMenuEntry(mePtr, objc, objv)
if (menuPtr->tkwin != NULL) {
if (Tk_SetOptions(menuPtr->interp, (char *) mePtr,
mePtr->optionTable, objc, objv, menuPtr->tkwin,
- &errorStruct, (int *) NULL) != TCL_OK) {
+ &errorStruct, NULL) != TCL_OK) {
return TCL_ERROR;
}
result = PostProcessEntry(mePtr);
@@ -1971,7 +1956,7 @@ ConfigureMenuEntry(mePtr, objc, objv)
}
TkEventuallyRecomputeMenu(menuPtr);
-
+
return result;
}
@@ -1983,39 +1968,38 @@ ConfigureMenuEntry(mePtr, objc, objv)
* Calls ConfigureMenuEntry for each menu in the clone chain.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message.
+ * 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.
+ * Configuration information such as label and accelerator get set for
+ * mePtr; old resources get freed, if there were any.
*
*----------------------------------------------------------------------
*/
static int
-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 objc; /* Number of valid entries in argv. */
- Tcl_Obj *CONST objv[]; /* Arguments. */
+ConfigureMenuCloneEntries(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ TkMenu *menuPtr, /* Information about whole menu. */
+ int index, /* Index of mePtr within menuPtr's entries. */
+ int objc, /* Number of valid entries in argv. */
+ Tcl_Obj *const objv[]) /* Arguments. */
{
TkMenuEntry *mePtr;
TkMenu *menuListPtr;
int cascadeEntryChanged = 0;
- TkMenuReferences *oldCascadeMenuRefPtr, *cascadeMenuRefPtr = NULL;
+ 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
- * clone chain, and has an entry with a cascade menu, the clones of
- * the menu will point to clones of the cascade menu. We have
- * to destroy the clones of the cascades, clone the new cascade
- * menu, and configure the entry to point to the new clone.
+ * 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 clone chain, and has an entry with a cascade menu, the clones
+ * of the menu will point to clones of the cascade menu. We have to
+ * destroy the clones of the cascades, clone the new cascade menu, and
+ * configure the entry to point to the new clone.
*/
mePtr = menuPtr->masterMenuPtr->entries[index];
@@ -2034,21 +2018,20 @@ ConfigureMenuCloneEntries(interp, menuPtr, index, objc, objv)
char *oldCascadeName;
if (mePtr->namePtr != NULL) {
- newCascadeName = Tcl_GetStringFromObj(mePtr->namePtr, NULL);
+ newCascadeName = Tcl_GetString(mePtr->namePtr);
} else {
newCascadeName = NULL;
}
-
+
if ((oldCascadePtr == NULL) && (mePtr->namePtr == NULL)) {
cascadeEntryChanged = 0;
} else if (((oldCascadePtr == NULL) && (mePtr->namePtr != NULL))
- || ((oldCascadePtr != NULL)
+ || ((oldCascadePtr != NULL)
&& (mePtr->namePtr == NULL))) {
cascadeEntryChanged = 1;
} else {
- oldCascadeName = Tcl_GetStringFromObj(oldCascadePtr,
- NULL);
- cascadeEntryChanged = (strcmp(oldCascadeName, newCascadeName)
+ oldCascadeName = Tcl_GetString(oldCascadePtr);
+ cascadeEntryChanged = (strcmp(oldCascadeName, newCascadeName)
!= 0);
}
if (oldCascadePtr != NULL) {
@@ -2058,20 +2041,20 @@ ConfigureMenuCloneEntries(interp, menuPtr, index, objc, objv)
if (cascadeEntryChanged) {
if (mePtr->namePtr != NULL) {
- newCascadeName = Tcl_GetStringFromObj(mePtr->namePtr, NULL);
+ newCascadeName = Tcl_GetString(mePtr->namePtr);
cascadeMenuRefPtr = TkFindMenuReferences(menuPtr->interp,
newCascadeName);
}
}
- for (menuListPtr = menuPtr->masterMenuPtr->nextInstancePtr;
+ for (menuListPtr = menuPtr->masterMenuPtr->nextInstancePtr;
menuListPtr != NULL;
menuListPtr = menuListPtr->nextInstancePtr) {
-
+
mePtr = menuListPtr->entries[index];
if (cascadeEntryChanged && (mePtr->namePtr != NULL)) {
- oldCascadeMenuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,
+ oldCascadeMenuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,
mePtr->namePtr);
if ((oldCascadeMenuRefPtr != NULL)
@@ -2083,7 +2066,7 @@ ConfigureMenuCloneEntries(interp, menuPtr, index, objc, objv)
if (ConfigureMenuEntry(mePtr, objc, objv) != TCL_OK) {
return TCL_ERROR;
}
-
+
if (cascadeEntryChanged && (mePtr->namePtr != NULL)) {
if (cascadeMenuRefPtr->menuPtr != NULL) {
Tcl_Obj *newObjv[2];
@@ -2095,7 +2078,7 @@ ConfigureMenuCloneEntries(interp, menuPtr, index, objc, objv)
Tcl_IncrRefCount(pathNamePtr);
newCloneNamePtr = TkNewMenuName(menuPtr->interp,
- pathNamePtr,
+ pathNamePtr,
cascadeMenuRefPtr->menuPtr);
Tcl_IncrRefCount(newCloneNamePtr);
Tcl_IncrRefCount(normalPtr);
@@ -2121,14 +2104,14 @@ ConfigureMenuCloneEntries(interp, menuPtr, index, objc, objv)
*
* TkGetMenuIndex --
*
- * Parse a textual index into a menu and return the numerical
- * index of the indicated entry.
+ * Parse a textual index into a menu and return the numerical index of
+ * the indicated entry.
*
* Results:
- * 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 the interp's result.
+ * 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 the interp's result.
*
* Side effects:
* None.
@@ -2137,18 +2120,18 @@ ConfigureMenuCloneEntries(interp, menuPtr, index, objc, objv)
*/
int
-TkGetMenuIndex(interp, menuPtr, objPtr, lastOK, indexPtr)
- Tcl_Interp *interp; /* For error messages. */
- TkMenu *menuPtr; /* Menu for which the index is being
+TkGetMenuIndex(
+ Tcl_Interp *interp, /* For error messages. */
+ TkMenu *menuPtr, /* Menu for which the index is being
* specified. */
- Tcl_Obj *objPtr; /* 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 index. */
+ int lastOK, /* Non-zero means its OK to return index just
+ * *after* last entry. */
+ int *indexPtr) /* Where to store converted index. */
{
int i;
- char *string = Tcl_GetStringFromObj(objPtr, NULL);
+ char *string = Tcl_GetString(objPtr);
if ((string[0] == 'a') && (strcmp(string, "active") == 0)) {
*indexPtr = menuPtr->active;
@@ -2174,7 +2157,7 @@ TkGetMenuIndex(interp, menuPtr, objPtr, lastOK, indexPtr)
}
if (isdigit(UCHAR(string[0]))) {
- if (Tcl_GetInt(interp, string, &i) == TCL_OK) {
+ if (Tcl_GetInt(interp, string, &i) == TCL_OK) {
if (i >= menuPtr->numEntries) {
if (lastOK) {
i = menuPtr->numEntries;
@@ -2187,26 +2170,23 @@ TkGetMenuIndex(interp, menuPtr, objPtr, lastOK, indexPtr)
*indexPtr = i;
goto success;
}
- Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);
+ Tcl_SetResult(interp, NULL, TCL_STATIC);
}
for (i = 0; i < menuPtr->numEntries; i++) {
Tcl_Obj *labelPtr = menuPtr->entries[i]->labelPtr;
- char *label = (labelPtr == NULL) ? NULL
- : Tcl_GetStringFromObj(labelPtr, NULL);
-
- if ((label != NULL)
- && (Tcl_StringMatch(label, string))) {
+ char *label = (labelPtr == NULL) ? NULL : Tcl_GetString(labelPtr);
+
+ if ((label != NULL) && (Tcl_StringMatch(label, string))) {
*indexPtr = i;
goto success;
}
}
- Tcl_AppendResult(interp, "bad menu entry index \"",
- string, "\"", (char *) NULL);
+ Tcl_AppendResult(interp, "bad menu entry index \"", string, "\"", NULL);
return TCL_ERROR;
-success:
+ success:
return TCL_OK;
}
@@ -2215,9 +2195,9 @@ success:
*
* MenuCmdDeletedProc --
*
- * 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.
+ * This function 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.
@@ -2229,25 +2209,26 @@ success:
*/
static void
-MenuCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+MenuCmdDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
TkMenu *menuPtr = (TkMenu *) clientData;
Tk_Window tkwin = menuPtr->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.
+ * This function 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 function destroys the
+ * widget.
*/
if (tkwin != NULL) {
- /*
- * Note: it may be desirable to NULL out the tkwin
- * field of menuPtr here:
+ /*
+ * Note: it may be desirable to NULL out the tkwin field of menuPtr
+ * here:
* menuPtr->tkwin = NULL;
*/
+
Tk_DestroyWindow(tkwin);
}
}
@@ -2257,12 +2238,12 @@ MenuCmdDeletedProc(clientData)
*
* MenuNewEntry --
*
- * This procedure allocates and initializes a new menu entry.
+ * This function allocates and initializes a new menu entry.
*
* Results:
- * The return value is a pointer to a new menu entry structure,
- * which has been malloc-ed, initialized, and entered into the
- * entry array for the menu.
+ * The return value is a pointer to a new menu entry structure, which has
+ * been malloc-ed, initialized, and entered into the entry array for the
+ * menu.
*
* Side effects:
* Storage gets allocated.
@@ -2271,19 +2252,18 @@ MenuCmdDeletedProc(clientData)
*/
static TkMenuEntry *
-MenuNewEntry(menuPtr, index, type)
- TkMenu *menuPtr; /* Menu that will hold the new entry. */
- int index; /* Where in the menu the new entry is to
+MenuNewEntry(
+ TkMenu *menuPtr, /* Menu that will hold the new entry. */
+ int index, /* Where in the menu the new entry is to
* go. */
- int type; /* The type of the new entry. */
+ int type) /* The type of the new entry. */
{
TkMenuEntry *mePtr;
TkMenuEntry **newEntries;
int i;
/*
- * Create a new array of entries with an empty slot for the
- * new entry.
+ * Create a new array of entries with an empty slot for the new entry.
*/
newEntries = (TkMenuEntry **) ckalloc((unsigned)
@@ -2291,7 +2271,7 @@ MenuNewEntry(menuPtr, index, type)
for (i = 0; i < index; i++) {
newEntries[i] = menuPtr->entries[i];
}
- for ( ; i < menuPtr->numEntries; i++) {
+ for (; i < menuPtr->numEntries; i++) {
newEntries[i+1] = menuPtr->entries[i];
newEntries[i+1]->index = i + 1;
}
@@ -2354,8 +2334,8 @@ MenuNewEntry(menuPtr, index, type)
*
* MenuAddOrInsert --
*
- * This procedure does all of the work of the "add" and "insert"
- * widget commands, allowing the code for these to be shared.
+ * This function does all of the work of the "add" and "insert" widget
+ * commands, allowing the code for these to be shared.
*
* Results:
* A standard Tcl return value.
@@ -2367,34 +2347,29 @@ MenuNewEntry(menuPtr, index, type)
*/
static int
-MenuAddOrInsert(interp, menuPtr, indexPtr, objc, objv)
- Tcl_Interp *interp; /* Used for error reporting. */
- TkMenu *menuPtr; /* Widget in which to create new
- * entry. */
- Tcl_Obj *indexPtr; /* Object describing index at which
- * to insert. NULL means insert at
- * end. */
- int objc; /* Number of elements in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments to command: first arg
- * is type of entry, others are
- * config options. */
+MenuAddOrInsert(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ TkMenu *menuPtr, /* Widget in which to create new entry. */
+ Tcl_Obj *indexPtr, /* Object describing index at which to insert.
+ * NULL means insert at end. */
+ 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 type, index;
TkMenuEntry *mePtr;
TkMenu *menuListPtr;
if (indexPtr != NULL) {
- if (TkGetMenuIndex(interp, menuPtr, indexPtr, 1, &index)
- != TCL_OK) {
+ if (TkGetMenuIndex(interp, menuPtr, indexPtr, 1, &index) != TCL_OK) {
return TCL_ERROR;
}
} else {
index = menuPtr->numEntries;
}
if (index < 0) {
- char *indexString = Tcl_GetStringFromObj(indexPtr, NULL);
- Tcl_AppendResult(interp, "bad index \"", indexString, "\"",
- (char *) NULL);
+ char *indexString = Tcl_GetString(indexPtr);
+ Tcl_AppendResult(interp, "bad index \"", indexString, "\"", NULL);
return TCL_ERROR;
}
if (menuPtr->tearoff && (index == 0)) {
@@ -2414,9 +2389,9 @@ MenuAddOrInsert(interp, menuPtr, indexPtr, objc, objv)
* Now we have to add an entry for every instance related to this menu.
*/
- for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
+ for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
menuListPtr = menuListPtr->nextInstancePtr) {
-
+
mePtr = MenuNewEntry(menuListPtr, index, type);
if (mePtr == NULL) {
return TCL_ERROR;
@@ -2445,48 +2420,46 @@ MenuAddOrInsert(interp, menuPtr, indexPtr, objc, objv)
}
return TCL_ERROR;
}
-
+
/*
- * If a menu has cascades, then every instance of the menu has
- * to have its own parallel cascade structure. So adding an
- * entry to a menu with clones means that the menu that the
- * entry points to has to be cloned for every clone the
- * master menu has. This is special case #2 in the comment
- * at the top of this file.
+ * If a menu has cascades, then every instance of the menu has to have
+ * its own parallel cascade structure. So adding an entry to a menu
+ * with clones means that the menu that the entry points to has to be
+ * cloned for every clone the master menu has. This is special case #2
+ * in the comment at the top of this file.
*/
-
- if ((menuPtr != menuListPtr) && (type == CASCADE_ENTRY)) {
+
+ if ((menuPtr != menuListPtr) && (type == CASCADE_ENTRY)) {
if ((mePtr->namePtr != NULL)
&& (mePtr->childMenuRefPtr != NULL)
&& (mePtr->childMenuRefPtr->menuPtr != NULL)) {
- TkMenu *cascadeMenuPtr =
+ TkMenu *cascadeMenuPtr =
mePtr->childMenuRefPtr->menuPtr->masterMenuPtr;
- Tcl_Obj *newCascadePtr;
+ Tcl_Obj *newCascadePtr, *newObjv[2];
Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1);
- Tcl_Obj *windowNamePtr =
+ Tcl_Obj *windowNamePtr =
Tcl_NewStringObj(Tk_PathName(menuListPtr->tkwin), -1);
Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1);
- Tcl_Obj *newObjv[2];
TkMenuReferences *menuRefPtr;
-
+
Tcl_IncrRefCount(windowNamePtr);
newCascadePtr = TkNewMenuName(menuListPtr->interp,
windowNamePtr, cascadeMenuPtr);
Tcl_IncrRefCount(newCascadePtr);
Tcl_IncrRefCount(normalPtr);
CloneMenu(cascadeMenuPtr, newCascadePtr, normalPtr);
-
+
menuRefPtr = TkFindMenuReferencesObj(menuListPtr->interp,
newCascadePtr);
if (menuRefPtr == NULL) {
- panic("CloneMenu failed inside of MenuAddOrInsert.");
+ Tcl_Panic("CloneMenu failed inside of MenuAddOrInsert.");
}
newObjv[0] = menuNamePtr;
newObjv[1] = newCascadePtr;
Tcl_IncrRefCount(menuNamePtr);
Tcl_IncrRefCount(newCascadePtr);
- ConfigureMenuEntry(mePtr, 2, newObjv);
- Tcl_DecrRefCount(newCascadePtr);
+ ConfigureMenuEntry(mePtr, 2, newObjv);
+ Tcl_DecrRefCount(newCascadePtr);
Tcl_DecrRefCount(menuNamePtr);
Tcl_DecrRefCount(windowNamePtr);
Tcl_DecrRefCount(normalPtr);
@@ -2501,10 +2474,9 @@ MenuAddOrInsert(interp, menuPtr, indexPtr, objc, objv)
*
* MenuVarProc --
*
- * This procedure is invoked when someone changes the
- * state variable associated with a radiobutton or checkbutton
- * menu entry. The entry's selected state is set to match
- * the value of the variable.
+ * This function is invoked when someone changes the state variable
+ * associated with a radiobutton or checkbutton menu entry. The entry's
+ * selected state is set to match the value of the variable.
*
* Results:
* NULL is always returned.
@@ -2516,16 +2488,16 @@ MenuAddOrInsert(interp, menuPtr, indexPtr, objc, objv)
*/
static char *
-MenuVarProc(clientData, interp, name1, name2, flags)
- ClientData clientData; /* Information about menu entry. */
- Tcl_Interp *interp; /* Interpreter containing variable. */
- CONST char *name1; /* First part of variable's name. */
- CONST char *name2; /* Second part of variable's name. */
- int flags; /* Describes what just happened. */
+MenuVarProc(
+ ClientData clientData, /* Information about menu entry. */
+ Tcl_Interp *interp, /* Interpreter containing variable. */
+ const char *name1, /* First part of variable's name. */
+ const char *name2, /* Second part of variable's name. */
+ int flags) /* Describes what just happened. */
{
TkMenuEntry *mePtr = (TkMenuEntry *) clientData;
TkMenu *menuPtr;
- CONST char *value;
+ const char *value;
char *name;
char *onValue;
@@ -2534,11 +2506,11 @@ MenuVarProc(clientData, interp, name1, name2, flags)
* Do nothing if the interpreter is going away.
*/
- return (char *) NULL;
+ return NULL;
}
menuPtr = mePtr->menuPtr;
- name = Tcl_GetStringFromObj(mePtr->namePtr, NULL);
+ name = Tcl_GetString(mePtr->namePtr);
/*
* If the variable is being unset, then re-establish the trace.
@@ -2552,13 +2524,13 @@ MenuVarProc(clientData, interp, name1, name2, flags)
MenuVarProc, clientData);
}
TkpConfigureMenuEntry(mePtr);
- TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL);
- return (char *) NULL;
+ TkEventuallyRedrawMenu(menuPtr, NULL);
+ return NULL;
}
/*
- * Use the value of the variable to update the selected status of
- * the menu entry.
+ * Use the value of the variable to update the selected status of the menu
+ * entry.
*/
value = Tcl_GetVar(interp, name, TCL_GLOBAL_ONLY);
@@ -2566,23 +2538,23 @@ MenuVarProc(clientData, interp, name1, name2, flags)
value = "";
}
if (mePtr->onValuePtr != NULL) {
- onValue = Tcl_GetStringFromObj(mePtr->onValuePtr, NULL);
+ onValue = Tcl_GetString(mePtr->onValuePtr);
if (strcmp(value, onValue) == 0) {
if (mePtr->entryFlags & ENTRY_SELECTED) {
- return (char *) NULL;
+ return NULL;
}
mePtr->entryFlags |= ENTRY_SELECTED;
} else if (mePtr->entryFlags & ENTRY_SELECTED) {
mePtr->entryFlags &= ~ENTRY_SELECTED;
} else {
- return (char *) NULL;
+ return NULL;
}
} else {
- return (char *) NULL;
+ return NULL;
}
TkpConfigureMenuEntry(mePtr);
TkEventuallyRedrawMenu(menuPtr, mePtr);
- return (char *) NULL;
+ return NULL;
}
/*
@@ -2590,26 +2562,25 @@ MenuVarProc(clientData, interp, name1, name2, flags)
*
* TkActivateMenuEntry --
*
- * This procedure is invoked to make a particular menu entry
- * the active one, deactivating any other entry that might
- * currently be active.
+ * This function is invoked to make a particular menu entry the active
+ * one, deactivating any other entry that might currently be active.
*
* Results:
- * The return value is a standard Tcl result (errors can occur
- * while posting and unposting submenus).
+ * The return value is a standard Tcl result (errors can occur while
+ * posting and unposting submenus).
*
* Side effects:
- * Menu entries get redisplayed, and the active entry changes.
- * Submenus may get posted and unposted.
+ * Menu entries get redisplayed, and the active entry changes. Submenus
+ * may get posted and unposted.
*
*----------------------------------------------------------------------
*/
int
-TkActivateMenuEntry(menuPtr, index)
- register TkMenu *menuPtr; /* Menu in which to activate. */
- int index; /* Index of entry to activate, or
- * -1 to deactivate all entries. */
+TkActivateMenuEntry(
+ register TkMenu *menuPtr, /* Menu in which to activate. */
+ int index) /* Index of entry to activate, or -1 to
+ * deactivate all entries. */
{
register TkMenuEntry *mePtr;
int result = TCL_OK;
@@ -2618,8 +2589,8 @@ TkActivateMenuEntry(menuPtr, index)
mePtr = menuPtr->entries[menuPtr->active];
/*
- * Don't change the state unless it's currently active (state
- * might already have been changed to disabled).
+ * Don't change the state unless it's currently active (state might
+ * already have been changed to disabled).
*/
if (mePtr->state == ENTRY_ACTIVE) {
@@ -2644,8 +2615,8 @@ TkActivateMenuEntry(menuPtr, index)
* Execute the postcommand for the given menu.
*
* Results:
- * The return value is a standard Tcl result (errors can occur
- * while the postcommands are being processed).
+ * The return value is a standard Tcl result (errors can occur while the
+ * postcommands are being processed).
*
* Side effects:
* Since commands can get executed while this routine is being executed,
@@ -2653,17 +2624,17 @@ TkActivateMenuEntry(menuPtr, index)
*
*----------------------------------------------------------------------
*/
-
+
int
-TkPostCommand(menuPtr)
- TkMenu *menuPtr;
+TkPostCommand(
+ TkMenu *menuPtr)
{
int result;
/*
- * If there is a command for the menu, execute it. This
- * may change the size of the menu, so be sure to recompute
- * the menu's geometry if needed.
+ * If there is a command for the menu, execute it. This may change the
+ * size of the menu, so be sure to recompute the menu's geometry if
+ * needed.
*/
if (menuPtr->postCommandPtr != NULL) {
@@ -2686,37 +2657,36 @@ TkPostCommand(menuPtr)
*
* CloneMenu --
*
- * Creates a child copy of the menu. It will be inserted into
- * the menu's instance chain. All attributes and entry
- * attributes will be duplicated.
+ * Creates a child copy of the menu. It will be inserted into the menu's
+ * instance chain. All attributes and entry attributes will be
+ * duplicated.
*
* Results:
* A standard Tcl result.
*
* Side effects:
- * Allocates storage. After the menu is created, any
- * configuration done with this menu or any related one
- * will be reflected in all of them.
+ * Allocates storage. After the menu is created, any configuration done
+ * with this menu or any related one will be reflected in all of them.
*
*--------------------------------------------------------------
*/
static int
-CloneMenu(menuPtr, newMenuNamePtr, newMenuTypePtr)
- TkMenu *menuPtr; /* The menu we are going to clone */
- 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? */
+CloneMenu(
+ TkMenu *menuPtr, /* The menu we are going to clone. */
+ 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, i;
TkMenuReferences *menuRefPtr;
Tcl_Obj *menuDupCommandArray[4];
-
+
if (newMenuTypePtr == NULL) {
- menuType = MASTER_MENU;
+ menuType = MASTER_MENU;
} else {
- if (Tcl_GetIndexFromObj(menuPtr->interp, newMenuTypePtr,
+ if (Tcl_GetIndexFromObj(menuPtr->interp, newMenuTypePtr,
menuTypeStrings, "menu type", 0, &menuType) != TCL_OK) {
return TCL_ERROR;
}
@@ -2742,12 +2712,12 @@ CloneMenu(menuPtr, newMenuNamePtr, newMenuTypePtr)
/*
* Make sure the tcl command actually created the clone.
*/
-
+
if ((returnResult == TCL_OK) &&
- ((menuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,
- newMenuNamePtr)) != (TkMenuReferences *) NULL)
+ ((menuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,
+ newMenuNamePtr)) != NULL)
&& (menuPtr->numEntries == menuRefPtr->menuPtr->numEntries)) {
- TkMenu *newMenuPtr = menuRefPtr->menuPtr;
+ TkMenu *newMenuPtr = menuRefPtr->menuPtr;
Tcl_Obj *newObjv[3];
int i, numElements;
@@ -2761,83 +2731,85 @@ CloneMenu(menuPtr, newMenuNamePtr, newMenuTypePtr)
newMenuPtr->masterMenuPtr = menuPtr->masterMenuPtr;
} else {
TkMenu *masterMenuPtr;
-
+
masterMenuPtr = menuPtr->masterMenuPtr;
newMenuPtr->nextInstancePtr = masterMenuPtr->nextInstancePtr;
masterMenuPtr->nextInstancePtr = newMenuPtr;
newMenuPtr->masterMenuPtr = masterMenuPtr;
}
-
- /*
- * Add the master menu's window to the bind tags for this window
- * after this window's tag. This is so the user can bind to either
- * this clone (which may not be easy to do) or the entire menu
- * clone structure.
- */
-
+
+ /*
+ * Add the master menu's window to the bind tags for this window after
+ * this window's tag. This is so the user can bind to either this
+ * clone (which may not be easy to do) or the entire menu clone
+ * structure.
+ */
+
newObjv[0] = Tcl_NewStringObj("bindtags", -1);
- newObjv[1] = Tcl_NewStringObj(Tk_PathName(newMenuPtr->tkwin), -1);
+ newObjv[1] = Tcl_NewStringObj(Tk_PathName(newMenuPtr->tkwin), -1);
Tcl_IncrRefCount(newObjv[0]);
Tcl_IncrRefCount(newObjv[1]);
- if (Tk_BindtagsObjCmd((ClientData)newMenuPtr->tkwin,
- newMenuPtr->interp, 2, newObjv) == TCL_OK) {
- char *windowName;
- Tcl_Obj *bindingsPtr =
+ if (Tk_BindtagsObjCmd((ClientData)newMenuPtr->tkwin,
+ newMenuPtr->interp, 2, newObjv) == TCL_OK) {
+ char *windowName;
+ Tcl_Obj *bindingsPtr =
Tcl_DuplicateObj(Tcl_GetObjResult(newMenuPtr->interp));
- Tcl_Obj *elementPtr;
-
+ Tcl_Obj *elementPtr;
+
Tcl_IncrRefCount(bindingsPtr);
- Tcl_ListObjLength(newMenuPtr->interp, bindingsPtr, &numElements);
- for (i = 0; i < numElements; i++) {
- Tcl_ListObjIndex(newMenuPtr->interp, bindingsPtr, i,
+ Tcl_ListObjLength(newMenuPtr->interp, bindingsPtr, &numElements);
+ for (i = 0; i < numElements; i++) {
+ Tcl_ListObjIndex(newMenuPtr->interp, bindingsPtr, i,
&elementPtr);
- windowName = Tcl_GetStringFromObj(elementPtr, NULL);
- if (strcmp(windowName, Tk_PathName(newMenuPtr->tkwin))
- == 0) {
- Tcl_Obj *newElementPtr = Tcl_NewStringObj(
- Tk_PathName(newMenuPtr->masterMenuPtr->tkwin), -1);
- /*
+ windowName = Tcl_GetString(elementPtr);
+ if (strcmp(windowName, Tk_PathName(newMenuPtr->tkwin))
+ == 0) {
+ Tcl_Obj *newElementPtr = Tcl_NewStringObj(
+ Tk_PathName(newMenuPtr->masterMenuPtr->tkwin), -1);
+
+ /*
* The newElementPtr will have its refCount incremented
* here, so we don't need to worry about it any more.
*/
- Tcl_ListObjReplace(menuPtr->interp, bindingsPtr,
- i + 1, 0, 1, &newElementPtr);
+
+ Tcl_ListObjReplace(menuPtr->interp, bindingsPtr,
+ i + 1, 0, 1, &newElementPtr);
newObjv[2] = bindingsPtr;
Tk_BindtagsObjCmd((ClientData)newMenuPtr->tkwin,
menuPtr->interp, 3, newObjv);
- break;
- }
- }
- Tcl_DecrRefCount(bindingsPtr);
- }
+ break;
+ }
+ }
+ Tcl_DecrRefCount(bindingsPtr);
+ }
Tcl_DecrRefCount(newObjv[0]);
Tcl_DecrRefCount(newObjv[1]);
- Tcl_ResetResult(menuPtr->interp);
-
- /*
- * Clone all of the cascade menus that this menu points to.
- */
-
- for (i = 0; i < menuPtr->numEntries; i++) {
- TkMenuReferences *cascadeRefPtr;
- TkMenu *oldCascadePtr;
-
- if ((menuPtr->entries[i]->type == CASCADE_ENTRY)
+ Tcl_ResetResult(menuPtr->interp);
+
+ /*
+ * Clone all of the cascade menus that this menu points to.
+ */
+
+ for (i = 0; i < menuPtr->numEntries; i++) {
+ TkMenuReferences *cascadeRefPtr;
+ TkMenu *oldCascadePtr;
+
+ if ((menuPtr->entries[i]->type == CASCADE_ENTRY)
&& (menuPtr->entries[i]->namePtr != NULL)) {
- cascadeRefPtr =
+ cascadeRefPtr =
TkFindMenuReferencesObj(menuPtr->interp,
menuPtr->entries[i]->namePtr);
- if ((cascadeRefPtr != NULL) && (cascadeRefPtr->menuPtr)) {
- Tcl_Obj *windowNamePtr =
+ if ((cascadeRefPtr != NULL) && (cascadeRefPtr->menuPtr)) {
+ Tcl_Obj *windowNamePtr =
Tcl_NewStringObj(Tk_PathName(newMenuPtr->tkwin),
-1);
Tcl_Obj *newCascadePtr;
-
- oldCascadePtr = cascadeRefPtr->menuPtr;
+
+ oldCascadePtr = cascadeRefPtr->menuPtr;
Tcl_IncrRefCount(windowNamePtr);
- newCascadePtr = TkNewMenuName(menuPtr->interp,
- windowNamePtr, oldCascadePtr);
+ newCascadePtr = TkNewMenuName(menuPtr->interp,
+ windowNamePtr, oldCascadePtr);
Tcl_IncrRefCount(newCascadePtr);
CloneMenu(oldCascadePtr, newCascadePtr, NULL);
@@ -2848,13 +2820,13 @@ CloneMenu(menuPtr, newMenuNamePtr, newMenuTypePtr)
Tcl_DecrRefCount(newObjv[0]);
Tcl_DecrRefCount(newCascadePtr);
Tcl_DecrRefCount(windowNamePtr);
- }
- }
- }
-
- returnResult = TCL_OK;
+ }
+ }
+ }
+
+ returnResult = TCL_OK;
} else {
- returnResult = TCL_ERROR;
+ returnResult = TCL_ERROR;
}
Tcl_Release((ClientData) menuPtr);
return returnResult;
@@ -2863,6 +2835,43 @@ CloneMenu(menuPtr, newMenuNamePtr, newMenuTypePtr)
/*
*----------------------------------------------------------------------
*
+ * MenuDoXPosition --
+ *
+ * Given arguments from an option command line, returns the X position.
+ *
+ * Results:
+ * Returns TCL_OK or TCL_Error
+ *
+ * Side effects:
+ * xPosition is set to the X-position of the menu entry.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+MenuDoXPosition(
+ Tcl_Interp *interp,
+ TkMenu *menuPtr,
+ Tcl_Obj *objPtr)
+{
+ int index;
+
+ TkRecomputeMenu(menuPtr);
+ if (TkGetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ Tcl_ResetResult(interp);
+ if (index < 0) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(menuPtr->entries[index]->x));
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* MenuDoYPosition --
*
* Given arguments from an option command line, returns the Y position.
@@ -2875,18 +2884,18 @@ CloneMenu(menuPtr, newMenuNamePtr, newMenuTypePtr)
*
*----------------------------------------------------------------------
*/
-
+
static int
-MenuDoYPosition(interp, menuPtr, objPtr)
- Tcl_Interp *interp;
- TkMenu *menuPtr;
- Tcl_Obj *objPtr;
+MenuDoYPosition(
+ Tcl_Interp *interp,
+ TkMenu *menuPtr,
+ Tcl_Obj *objPtr)
{
int index;
-
+
TkRecomputeMenu(menuPtr);
if (TkGetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
- goto error;
+ goto error;
}
Tcl_ResetResult(interp);
if (index < 0) {
@@ -2896,8 +2905,8 @@ MenuDoYPosition(interp, menuPtr, objPtr)
}
return TCL_OK;
-
-error:
+
+ error:
return TCL_ERROR;
}
@@ -2906,36 +2915,39 @@ error:
*
* GetIndexFromCoords --
*
- * Given a string of the form "@int", return the menu item corresponding
- * to int.
+ * Given a string of the form "@integer", return the menu item
+ * corresponding to the provided y-coordinate in the menu window.
*
* Results:
- * If int is a valid number, *indexPtr will be the number of the menuentry
- * that is the correct height. If int is invaled, *indexPtr will be
- * unchanged. Returns appropriate Tcl error number.
+ * If int is a valid number, *indexPtr will be the number of the
+ * menuentry that is the correct height. If int is invalid, *indexPtr
+ * will be unchanged. Returns appropriate Tcl error number.
*
* Side effects:
- * If int is invalid, interp's result will set to NULL.
+ * If int is invalid, interp's result will be set to NULL.
*
*----------------------------------------------------------------------
*/
static int
-GetIndexFromCoords(interp, menuPtr, string, indexPtr)
- Tcl_Interp *interp; /* interp of menu */
- TkMenu *menuPtr; /* the menu we are searching */
- char *string; /* The @string we are parsing */
- int *indexPtr; /* The index of the item that matches */
+GetIndexFromCoords(
+ Tcl_Interp *interp, /* Interpreter of menu. */
+ TkMenu *menuPtr, /* The menu we are searching. */
+ char *string, /* The @string we are parsing. */
+ int *indexPtr) /* The index of the item that matches. */
{
int x, y, i;
char *p, *end;
-
+ int x2, borderwidth, max;
+
TkRecomputeMenu(menuPtr);
p = string + 1;
y = strtol(p, &end, 0);
if (end == p) {
goto error;
}
+ Tk_GetPixelsFromObj(interp, menuPtr->tkwin,
+ menuPtr->borderWidthPtr, &borderwidth);
if (*end == ',') {
x = y;
p = end + 1;
@@ -2944,27 +2956,36 @@ GetIndexFromCoords(interp, menuPtr, string, indexPtr)
goto error;
}
} else {
- Tk_GetPixelsFromObj(interp, menuPtr->tkwin,
- menuPtr->borderWidthPtr, &x);
+ x = borderwidth;
}
-
+
+ *indexPtr = -1;
+
+ /* set the width of the final column to the remainder of the window
+ * being aware of windows that may not be mapped yet.
+ */
+ max = Tk_IsMapped(menuPtr->tkwin)
+ ? Tk_Width(menuPtr->tkwin) : Tk_ReqWidth(menuPtr->tkwin);
+ max -= borderwidth;
+
for (i = 0; i < menuPtr->numEntries; i++) {
+ if (menuPtr->entries[i]->entryFlags & ENTRY_LAST_COLUMN) {
+ x2 = max;
+ } else {
+ x2 = menuPtr->entries[i]->x + menuPtr->entries[i]->width;
+ }
if ((x >= menuPtr->entries[i]->x) && (y >= menuPtr->entries[i]->y)
- && (x < (menuPtr->entries[i]->x + menuPtr->entries[i]->width))
+ && (x < x2)
&& (y < (menuPtr->entries[i]->y
+ menuPtr->entries[i]->height))) {
+ *indexPtr = i;
break;
}
}
- if (i >= menuPtr->numEntries) {
- /* i = menuPtr->numEntries - 1; */
- i = -1;
- }
- *indexPtr = i;
return TCL_OK;
- error:
- Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);
+ error:
+ Tcl_SetResult(interp, NULL, TCL_STATIC);
return TCL_ERROR;
}
@@ -2974,8 +2995,8 @@ GetIndexFromCoords(interp, menuPtr, string, indexPtr)
* RecursivelyDeleteMenu --
*
* Deletes a menu and any cascades underneath it. Used for deleting
- * instances when a menu is no longer being used as a menubar,
- * for instance.
+ * instances when a menu is no longer being used as a menubar, for
+ * instance.
*
* Results:
* None.
@@ -2987,19 +3008,19 @@ GetIndexFromCoords(interp, menuPtr, string, indexPtr)
*/
static void
-RecursivelyDeleteMenu(menuPtr)
- TkMenu *menuPtr; /* The menubar instance we are deleting */
+RecursivelyDeleteMenu(
+ TkMenu *menuPtr) /* The menubar instance we are deleting. */
{
int i;
TkMenuEntry *mePtr;
-
- /*
- * It is not 100% clear that this preserve/release pair is
- * required, but we have added them for safety in this
- * very complex code.
+
+ /*
+ * It is not 100% clear that this preserve/release pair is required, but
+ * we have added them for safety in this very complex code.
*/
+
Tcl_Preserve(menuPtr);
-
+
for (i = 0; i < menuPtr->numEntries; i++) {
mePtr = menuPtr->entries[i];
if ((mePtr->type == CASCADE_ENTRY)
@@ -3011,7 +3032,7 @@ RecursivelyDeleteMenu(menuPtr)
if (menuPtr->tkwin != NULL) {
Tk_DestroyWindow(menuPtr->tkwin);
}
-
+
Tcl_Release(menuPtr);
}
@@ -3020,8 +3041,7 @@ RecursivelyDeleteMenu(menuPtr)
*
* TkNewMenuName --
*
- * Makes a new unique name for a cloned menu. Will be a child
- * of oldName.
+ * Makes a new unique name for a cloned menu. Will be a child of oldName.
*
* Results:
* Returns a char * which has been allocated; caller must free.
@@ -3033,10 +3053,10 @@ RecursivelyDeleteMenu(menuPtr)
*/
Tcl_Obj *
-TkNewMenuName(interp, parentPtr, menuPtr)
- Tcl_Interp *interp; /* The interp the new name has to live in.*/
- Tcl_Obj *parentPtr; /* The prefix path of the new name. */
- TkMenu *menuPtr; /* The menu we are cloning. */
+TkNewMenuName(
+ Tcl_Interp *interp, /* The interp the new name has to live in.*/
+ Tcl_Obj *parentPtr, /* The prefix path of the new name. */
+ TkMenu *menuPtr) /* The menu we are cloning. */
{
Tcl_Obj *resultPtr = NULL; /* Initialization needed only to prevent
* compiler warning. */
@@ -3047,7 +3067,7 @@ TkNewMenuName(interp, parentPtr, menuPtr)
Tcl_CmdInfo cmdInfo;
Tcl_HashTable *nameTablePtr = NULL;
TkWindow *winPtr = (TkWindow *) menuPtr->tkwin;
- char *parentName = Tcl_GetStringFromObj(parentPtr, NULL);
+ char *parentName = Tcl_GetString(parentPtr);
if (winPtr->mainPtr != NULL) {
nameTablePtr = &(winPtr->mainPtr->nameTable);
@@ -3056,13 +3076,13 @@ TkNewMenuName(interp, parentPtr, menuPtr)
doDot = parentName[strlen(parentName) - 1] != '.';
childPtr = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin), -1);
- for (destString = Tcl_GetStringFromObj(childPtr, NULL);
+ for (destString = Tcl_GetString(childPtr);
*destString != '\0'; destString++) {
if (*destString == '.') {
*destString = '#';
}
}
-
+
for (i = 0; ; i++) {
if (i == 0) {
resultPtr = Tcl_DuplicateObj(parentPtr);
@@ -3083,7 +3103,7 @@ TkNewMenuName(interp, parentPtr, menuPtr)
Tcl_AppendObjToObj(resultPtr, intPtr);
Tcl_DecrRefCount(intPtr);
}
- destString = Tcl_GetStringFromObj(resultPtr, NULL);
+ destString = Tcl_GetString(resultPtr);
if ((Tcl_GetCommandInfo(interp, destString, &cmdInfo) == 0)
&& ((nameTablePtr == NULL)
|| (Tcl_FindHashEntry(nameTablePtr, destString) == NULL))) {
@@ -3099,76 +3119,73 @@ TkNewMenuName(interp, parentPtr, menuPtr)
*
* TkSetWindowMenuBar --
*
- * Associates a menu with a window. Called by ConfigureFrame in
- * in response to a "-menu .foo" configuration option for a top
- * level.
+ * Associates a menu with a window. Called by ConfigureFrame in in
+ * response to a "-menu .foo" configuration option for a top level.
*
* Results:
* None.
*
* Side effects:
- * The old menu clones for the menubar are thrown away, and a
- * handler is set up to allocate the new ones.
+ * The old menu clones for the menubar are thrown away, and a handler is
+ * set up to allocate the new ones.
*
*----------------------------------------------------------------------
*/
+
void
-TkSetWindowMenuBar(interp, tkwin, oldMenuName, menuName)
- Tcl_Interp *interp; /* The interpreter the toplevel lives in. */
- Tk_Window tkwin; /* The toplevel window */
- char *oldMenuName; /* The name of the menubar previously set in
- * this toplevel. NULL means no menu was
- * set previously. */
- char *menuName; /* The name of the new menubar that the
+TkSetWindowMenuBar(
+ Tcl_Interp *interp, /* The interpreter the toplevel lives in. */
+ Tk_Window tkwin, /* The toplevel window. */
+ char *oldMenuName, /* The name of the menubar previously set in
+ * this toplevel. NULL means no menu was set
+ * previously. */
+ char *menuName) /* The name of the new menubar that the
* toplevel needs to be set to. NULL means
* that their is no menu now. */
{
TkMenuTopLevelList *topLevelListPtr, *prevTopLevelPtr;
TkMenu *menuPtr;
TkMenuReferences *menuRefPtr;
-
- TkMenuInit();
/*
- * Destroy the menubar instances of the old menu. Take this window
- * out of the old menu's top level reference list.
+ * Destroy the menubar instances of the old menu. Take this window out of
+ * the old menu's top level reference list.
*/
-
- if (oldMenuName != NULL) {
- menuRefPtr = TkFindMenuReferences(interp, oldMenuName);
- if (menuRefPtr != NULL) {
+ if (oldMenuName != NULL) {
+ menuRefPtr = TkFindMenuReferences(interp, oldMenuName);
+ if (menuRefPtr != NULL) {
/*
- * Find the menubar instance that is to be removed. Destroy
- * it and all of the cascades underneath it.
+ * Find the menubar instance that is to be removed. Destroy it and
+ * all of the cascades underneath it.
*/
- if (menuRefPtr->menuPtr != NULL) {
- TkMenu *instancePtr;
-
- menuPtr = menuRefPtr->menuPtr;
-
- for (instancePtr = menuPtr->masterMenuPtr;
- instancePtr != NULL;
- instancePtr = instancePtr->nextInstancePtr) {
- if (instancePtr->menuType == MENUBAR
- && instancePtr->parentTopLevelPtr == tkwin) {
- RecursivelyDeleteMenu(instancePtr);
- break;
- }
- }
- }
-
- /*
- * Now we need to remove this toplevel from the list of toplevels
+ if (menuRefPtr->menuPtr != NULL) {
+ TkMenu *instancePtr;
+
+ menuPtr = menuRefPtr->menuPtr;
+
+ for (instancePtr = menuPtr->masterMenuPtr;
+ instancePtr != NULL;
+ instancePtr = instancePtr->nextInstancePtr) {
+ if (instancePtr->menuType == MENUBAR
+ && instancePtr->parentTopLevelPtr == tkwin) {
+ RecursivelyDeleteMenu(instancePtr);
+ break;
+ }
+ }
+ }
+
+ /*
+ * Now we need to remove this toplevel from the list of toplevels
* that reference this menu.
- */
-
+ */
+
topLevelListPtr = menuRefPtr->topLevelListPtr;
prevTopLevelPtr = NULL;
-
- while ((topLevelListPtr != NULL)
- && (topLevelListPtr->tkwin != tkwin)) {
+
+ while ((topLevelListPtr != NULL)
+ && (topLevelListPtr->tkwin != tkwin)) {
prevTopLevelPtr = topLevelListPtr;
topLevelListPtr = topLevelListPtr->nextPtr;
}
@@ -3179,54 +3196,54 @@ TkSetWindowMenuBar(interp, tkwin, oldMenuName, menuName)
*/
if (topLevelListPtr != NULL) {
- if (prevTopLevelPtr == NULL) {
+ if (prevTopLevelPtr == NULL) {
menuRefPtr->topLevelListPtr =
menuRefPtr->topLevelListPtr->nextPtr;
} else {
- prevTopLevelPtr->nextPtr = topLevelListPtr->nextPtr;
- }
- ckfree((char *) topLevelListPtr);
- TkFreeMenuReferences(menuRefPtr);
- }
- }
+ prevTopLevelPtr->nextPtr = topLevelListPtr->nextPtr;
+ }
+ ckfree((char *) topLevelListPtr);
+ TkFreeMenuReferences(menuRefPtr);
+ }
+ }
}
/*
* Now, add the clone references for the new menu.
*/
-
+
if (menuName != NULL && menuName[0] != 0) {
- TkMenu *menuBarPtr = NULL;
-
- menuRefPtr = TkCreateMenuReferences(interp, menuName);
-
- menuPtr = menuRefPtr->menuPtr;
- if (menuPtr != NULL) {
- Tcl_Obj *cloneMenuPtr;
- TkMenuReferences *cloneMenuRefPtr;
+ TkMenu *menuBarPtr = NULL;
+
+ menuRefPtr = TkCreateMenuReferences(interp, menuName);
+
+ menuPtr = menuRefPtr->menuPtr;
+ if (menuPtr != NULL) {
+ Tcl_Obj *cloneMenuPtr;
+ TkMenuReferences *cloneMenuRefPtr;
Tcl_Obj *newObjv[4];
- Tcl_Obj *windowNamePtr = Tcl_NewStringObj(Tk_PathName(tkwin),
+ 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.
- */
+
+ /*
+ * Clone the menu and all of the cascades underneath it.
+ */
Tcl_IncrRefCount(windowNamePtr);
- cloneMenuPtr = TkNewMenuName(interp, windowNamePtr,
- menuPtr);
+ cloneMenuPtr = TkNewMenuName(interp, windowNamePtr,
+ menuPtr);
Tcl_IncrRefCount(cloneMenuPtr);
Tcl_IncrRefCount(menubarPtr);
- CloneMenu(menuPtr, cloneMenuPtr, menubarPtr);
-
- cloneMenuRefPtr = TkFindMenuReferencesObj(interp, cloneMenuPtr);
- if ((cloneMenuRefPtr != NULL)
+ CloneMenu(menuPtr, cloneMenuPtr, menubarPtr);
+
+ 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;
+ cloneMenuRefPtr->menuPtr->parentTopLevelPtr = tkwin;
+ menuBarPtr = cloneMenuRefPtr->menuPtr;
newObjv[0] = cursorPtr;
newObjv[1] = nullPtr;
Tcl_IncrRefCount(cursorPtr);
@@ -3235,27 +3252,26 @@ TkSetWindowMenuBar(interp, tkwin, oldMenuName, menuName)
2, newObjv);
Tcl_DecrRefCount(cursorPtr);
Tcl_DecrRefCount(nullPtr);
- }
+ }
TkpSetWindowMenuBar(tkwin, menuBarPtr);
Tcl_DecrRefCount(cloneMenuPtr);
Tcl_DecrRefCount(menubarPtr);
Tcl_DecrRefCount(windowNamePtr);
- } else {
- TkpSetWindowMenuBar(tkwin, NULL);
+ } else {
+ TkpSetWindowMenuBar(tkwin, NULL);
}
-
- /*
- * Add this window to the menu's list of windows that refer
- * to this menu.
- */
+ /*
+ * Add this window to the menu's list of windows that refer to this
+ * menu.
+ */
- topLevelListPtr = (TkMenuTopLevelList *)
+ topLevelListPtr = (TkMenuTopLevelList *)
ckalloc(sizeof(TkMenuTopLevelList));
- topLevelListPtr->tkwin = tkwin;
- topLevelListPtr->nextPtr = menuRefPtr->topLevelListPtr;
- menuRefPtr->topLevelListPtr = topLevelListPtr;
+ topLevelListPtr->tkwin = tkwin;
+ topLevelListPtr->nextPtr = menuRefPtr->topLevelListPtr;
+ menuRefPtr->topLevelListPtr = topLevelListPtr;
} else {
TkpSetWindowMenuBar(tkwin, NULL);
}
@@ -3267,8 +3283,8 @@ TkSetWindowMenuBar(interp, tkwin, oldMenuName, menuName)
*
* DestroyMenuHashTable --
*
- * Called when an interp is deleted and a menu hash table has
- * been set in it.
+ * Called when an interp is deleted and a menu hash table has been set in
+ * it.
*
* Results:
* None.
@@ -3280,9 +3296,9 @@ TkSetWindowMenuBar(interp, tkwin, oldMenuName, menuName)
*/
static void
-DestroyMenuHashTable(clientData, interp)
- ClientData clientData; /* The menu hash table we are destroying */
- Tcl_Interp *interp; /* The interpreter we are destroying */
+DestroyMenuHashTable(
+ ClientData clientData, /* The menu hash table we are destroying. */
+ Tcl_Interp *interp) /* The interpreter we are destroying. */
{
Tcl_DeleteHashTable((Tcl_HashTable *) clientData);
ckfree((char *) clientData);
@@ -3293,8 +3309,8 @@ DestroyMenuHashTable(clientData, interp)
*
* TkGetMenuHashTable --
*
- * For a given interp, give back the menu hash table that goes with
- * it. If the hash table does not exist, it is created.
+ * For a given interp, give back the menu hash table that goes with it.
+ * If the hash table does not exist, it is created.
*
* Results:
* Returns a hash table pointer.
@@ -3307,13 +3323,13 @@ DestroyMenuHashTable(clientData, interp)
*/
Tcl_HashTable *
-TkGetMenuHashTable(interp)
- Tcl_Interp *interp; /* The interp we need the hash table in.*/
+TkGetMenuHashTable(
+ Tcl_Interp *interp) /* The interp we need the hash table in.*/
{
Tcl_HashTable *menuTablePtr;
- menuTablePtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, MENU_HASH_KEY,
- NULL);
+ menuTablePtr = (Tcl_HashTable *)
+ Tcl_GetAssocData(interp, MENU_HASH_KEY, NULL);
if (menuTablePtr == NULL) {
menuTablePtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
Tcl_InitHashTable(menuTablePtr, TCL_STRING_KEYS);
@@ -3328,25 +3344,26 @@ TkGetMenuHashTable(interp)
*
* TkCreateMenuReferences --
*
- * Given a pathname, gives back a pointer to a TkMenuReferences structure.
- * If a reference is not already in the hash table, one is created.
+ * Given a pathname, gives back a pointer to a TkMenuReferences
+ * structure. If a reference is not already in the hash table, one is
+ * created.
*
* Results:
- * Returns a pointer to a menu reference structure. Should not
- * be freed by calller; when a field of the reference is cleared,
+ * 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.
*
* Side effects:
- * A new hash table entry is created if there were no references
- * to the menu originally.
+ * A new hash table entry is created if there were no references to the
+ * menu originally.
*
*----------------------------------------------------------------------
*/
TkMenuReferences *
-TkCreateMenuReferences(interp, pathName)
- Tcl_Interp *interp;
- char *pathName; /* The path of the menu widget */
+TkCreateMenuReferences(
+ Tcl_Interp *interp,
+ char *pathName) /* The path of the menu widget. */
{
Tcl_HashEntry *hashEntryPtr;
TkMenuReferences *menuRefPtr;
@@ -3376,8 +3393,8 @@ TkCreateMenuReferences(interp, pathName)
* structure.
*
* Results:
- * Returns a pointer to a menu reference structure. Should not
- * be freed by calller; when a field of the reference is cleared,
+ * 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.
*
@@ -3388,9 +3405,9 @@ TkCreateMenuReferences(interp, pathName)
*/
TkMenuReferences *
-TkFindMenuReferences(interp, pathName)
- Tcl_Interp *interp; /* The interp the menu is living in. */
- char *pathName; /* The path of the menu widget */
+TkFindMenuReferences(
+ Tcl_Interp *interp, /* The interp the menu is living in. */
+ char *pathName) /* The path of the menu widget. */
{
Tcl_HashEntry *hashEntryPtr;
TkMenuReferences *menuRefPtr = NULL;
@@ -3413,8 +3430,8 @@ TkFindMenuReferences(interp, pathName)
* structure.
*
* Results:
- * Returns a pointer to a menu reference structure. Should not
- * be freed by calller; when a field of the reference is cleared,
+ * 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.
*
@@ -3425,11 +3442,11 @@ TkFindMenuReferences(interp, pathName)
*/
TkMenuReferences *
-TkFindMenuReferencesObj(interp, objPtr)
- Tcl_Interp *interp; /* The interp the menu is living in. */
- Tcl_Obj *objPtr; /* The path of the menu widget */
+TkFindMenuReferencesObj(
+ 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);
+ char *pathName = Tcl_GetString(objPtr);
return TkFindMenuReferences(interp, pathName);
}
@@ -3438,26 +3455,25 @@ TkFindMenuReferencesObj(interp, objPtr)
*
* TkFreeMenuReferences --
*
- * This is called after one of the fields in a menu reference
- * is cleared. It cleans up the ref if it is now empty.
+ * This is called after one of the fields in a menu reference is cleared.
+ * It cleans up the ref if it is now empty.
*
* Results:
- * Returns 1 if the references structure was freed, and 0
- * otherwise.
+ * Returns 1 if the references structure was freed, and 0 otherwise.
*
* Side effects:
- * If this is the last field to be cleared, the menu ref is
- * taken out of the hash table.
+ * If this is the last field to be cleared, the menu ref is taken out of
+ * the hash table.
*
*----------------------------------------------------------------------
*/
int
-TkFreeMenuReferences(menuRefPtr)
- TkMenuReferences *menuRefPtr; /* The menu reference to
- * free */
+TkFreeMenuReferences(
+ TkMenuReferences *menuRefPtr)
+ /* The menu reference to free. */
{
- if ((menuRefPtr->menuPtr == NULL)
+ if ((menuRefPtr->menuPtr == NULL)
&& (menuRefPtr->parentEntryPtr == NULL)
&& (menuRefPtr->topLevelListPtr == NULL)) {
Tcl_DeleteHashEntry(menuRefPtr->hashEntryPtr);
@@ -3472,8 +3488,8 @@ TkFreeMenuReferences(menuRefPtr)
*
* DeleteMenuCloneEntries --
*
- * For every clone in this clone chain, delete the menu entries
- * given by the parameters.
+ * For every clone in this clone chain, delete the menu entries given by
+ * the parameters.
*
* Results:
* None.
@@ -3485,13 +3501,12 @@ TkFreeMenuReferences(menuRefPtr)
*/
static void
-DeleteMenuCloneEntries(menuPtr, first, last)
- TkMenu *menuPtr; /* the menu the command was issued with */
- int first; /* the zero-based first entry in the set
- * of entries to delete. */
- int last; /* the zero-based last entry */
+DeleteMenuCloneEntries(
+ TkMenu *menuPtr, /* The menu the command was issued with. */
+ int first, /* The zero-based first entry in the set of
+ * entries to delete. */
+ int last) /* The zero-based last entry. */
{
-
TkMenu *menuListPtr;
int numDeleted, i, j;
@@ -3506,13 +3521,13 @@ DeleteMenuCloneEntries(menuPtr, first, last)
j = i - numDeleted;
menuListPtr->entries[j] = menuListPtr->entries[i];
menuListPtr->entries[j]->index = j;
- }
+ }
menuListPtr->numEntries -= numDeleted;
if (menuListPtr->numEntries == 0) {
ckfree((char *) menuListPtr->entries);
menuListPtr->entries = NULL;
}
- if ((menuListPtr->active >= first)
+ if ((menuListPtr->active >= first)
&& (menuListPtr->active <= last)) {
menuListPtr->active = -1;
} else if (menuListPtr->active > last) {
@@ -3522,28 +3537,29 @@ DeleteMenuCloneEntries(menuPtr, first, last)
}
}
-/*
- *----------------------------------------------------------------------
- *
- * TkMenuCleanup --
- *
- * Resets menusInitialized to allow Tk to be finalized and reused
- * without the DLL being unloaded.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-TkMenuCleanup(ClientData unused)
-{
- menusInitialized = 0;
-}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMenuCleanup --
+ *
+ * Resets menusInitialized to allow Tk to be finalized and reused without
+ * the DLL being unloaded.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TkMenuCleanup(
+ ClientData unused)
+{
+ menusInitialized = 0;
+}
/*
*----------------------------------------------------------------------
@@ -3563,21 +3579,23 @@ TkMenuCleanup(ClientData unused)
*/
void
-TkMenuInit()
+TkMenuInit(void)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
+
if (!menusInitialized) {
Tcl_MutexLock(&menuMutex);
if (!menusInitialized) {
TkpMenuInit();
menusInitialized = 1;
}
- /*
- * Make sure we cleanup on finalize.
- */
- TkCreateExitHandler(TkMenuCleanup, NULL);
+
+ /*
+ * Make sure we cleanup on finalize.
+ */
+
+ TkCreateExitHandler((Tcl_ExitProc *) TkMenuCleanup, NULL);
Tcl_MutexUnlock(&menuMutex);
}
if (!tsdPtr->menusInitialized) {
@@ -3585,3 +3603,11 @@ TkMenuInit()
tsdPtr->menusInitialized = 1;
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkMenu.h b/generic/tkMenu.h
index a428d4c..e8470ca 100644
--- a/generic/tkMenu.h
+++ b/generic/tkMenu.h
@@ -1,12 +1,13 @@
/*
* tkMenu.h --
*
- * Declarations shared among all of the files that implement menu widgets.
+ * Declarations shared among all of the files that implement menu
+ * widgets.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKMENU
@@ -37,26 +38,41 @@ typedef struct TkMenuPlatformData_ *TkMenuPlatformData;
typedef struct TkMenuPlatformEntryData_ *TkMenuPlatformEntryData;
/*
- * Legal values for the "compound" field of TkMenuEntry and TkMenuButton records.
+ * Legal values for the "compound" field of TkMenuEntry and TkMenuButton
+ * records.
*/
enum compound {
COMPOUND_BOTTOM, COMPOUND_CENTER, COMPOUND_LEFT, COMPOUND_NONE,
- COMPOUND_RIGHT, COMPOUND_TOP
+ COMPOUND_RIGHT, COMPOUND_TOP
};
/*
- * One of the following data structures is kept for each entry of each
- * menu managed by this file:
+ * Additional menu entry drawing parameters for Windows platform.
+ * DRAW_MENU_ENTRY_ARROW makes TkpDrawMenuEntry draw the arrow
+ * itself when cascade entry is disabled.
+ * DRAW_MENU_ENTRY_NOUNDERLINE forbids underline when ODS_NOACCEL
+ * is set, thus obeying the system-wide Windows UI setting.
+ */
+
+enum drawingParameters {
+ DRAW_MENU_ENTRY_ARROW = (1<<0),
+ DRAW_MENU_ENTRY_NOUNDERLINE = (1<<1)
+};
+
+/*
+ * One of the following data structures is kept for each entry of each menu
+ * managed by this file:
*/
typedef struct TkMenuEntry {
- int type; /* Type of menu entry; see below for
- * valid types. */
- struct TkMenu *menuPtr; /* Menu with which this entry is associated. */
+ int type; /* Type of menu entry; see below for valid
+ * types. */
+ struct TkMenu *menuPtr; /* Menu with which this entry is
+ * associated. */
Tk_OptionTable optionTable; /* Option table for this menu entry. */
- Tcl_Obj *labelPtr; /* Main text label displayed in entry (NULL
- * if no label). */
+ Tcl_Obj *labelPtr; /* Main text label displayed in entry (NULL if
+ * no label). */
int labelLength; /* Number of non-NULL characters in label. */
int state; /* State of button for display purposes:
* normal, active, or disabled. */
@@ -66,19 +82,18 @@ typedef struct TkMenuEntry {
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. */
- Tcl_Obj *imagePtr; /* Name of image to display, or
- * NULL. If non-NULL, bitmap, text, and
- * textVarName are ignored. */
+ Tcl_Obj *imagePtr; /* Name of image to display, or NULL. If not
+ * NULL, bitmap, text, and textVarName are
+ * ignored. */
Tk_Image image; /* Image to display in menu entry, or NULL if
* none. */
- Tcl_Obj *selectImagePtr; /* Name of image to display when selected, or
+ 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. */
- Tcl_Obj *accelPtr; /* Accelerator string displayed at right
- * of menu entry. NULL means no such
- * accelerator. Malloc'ed. */
+ Tk_Image selectImage; /* Image to display in entry when selected, or
+ * NULL if none. Ignored if image is NULL. */
+ 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
@@ -89,42 +104,43 @@ typedef struct TkMenuEntry {
*/
Tcl_Obj *borderPtr; /* Structure used to draw background for
- * entry. NULL means use overall border
- * for menu. */
- Tcl_Obj *fgPtr; /* Foreground color to use for entry. NULL
+ * entry. NULL means use overall border for
+ * menu. */
+ Tcl_Obj *fgPtr; /* Foreground color to use for entry. NULL
* means use foreground color from menu. */
Tcl_Obj *activeBorderPtr; /* Used to draw background and border when
- * element is active. NULL means use
+ * element is active. NULL means use
* activeBorder from menu. */
Tcl_Obj *activeFgPtr; /* Foreground color to use when entry is
- * active. NULL means use active foreground
+ * active. NULL means use active foreground
* from menu. */
Tcl_Obj *indicatorFgPtr; /* Color for indicators in radio and check
- * button entries. NULL means use indicatorFg
+ * button entries. NULL means use indicatorFg
* GC from menu. */
- 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. This
- * field is always 0 for tearoff and separator
+ 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. 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
+ * 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. */
+ * 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. */
int labelWidth; /* Number of pixels to allow for displaying
* labels in menu entries. */
- int compound; /* Value of -compound option; specifies whether
- * the entry should show both an image and
- * text, and, if so, how. */
+ int compound; /* Value of -compound option; specifies
+ * whether the entry should show both an image
+ * and text, and, if so, how. */
/*
* Information used to implement this entry's action:
@@ -134,78 +150,76 @@ typedef struct TkMenuEntry {
* Malloc'ed. */
Tcl_Obj *namePtr; /* Name of variable (for check buttons and
* radio buttons) or menu (for cascade
- * entries). Malloc'ed.*/
+ * entries). Malloc'ed. */
Tcl_Obj *onValuePtr; /* Value to store in variable when selected
* (only for radio and check buttons).
* Malloc'ed. */
Tcl_Obj *offValuePtr; /* Value to store in variable when not
* selected (only for check buttons).
* Malloc'ed. */
-
+
/*
* Information used for drawing this menu entry.
*/
-
+
int width; /* Number of pixels occupied by entry in
- * horizontal dimension. Not used except
- * in menubars. The width of norma menus
- * is dependent on the rest of the menu. */
- int x; /* X-coordinate of leftmost pixel in entry */
+ * horizontal dimension. Not used except in
+ * menubars. The width of norma menus is
+ * dependent on the rest of the menu. */
+ int x; /* X-coordinate of leftmost pixel in entry. */
int height; /* Number of pixels occupied by entry in
- * vertical dimension, including raised
- * border drawn around entry when active. */
+ * vertical dimension, including raised border
+ * drawn around entry when active. */
int y; /* Y-coordinate of topmost pixel in entry. */
- GC textGC; /* GC for drawing text in entry. NULL means
+ GC textGC; /* GC for drawing text in entry. NULL means
* use overall textGC for menu. */
GC activeGC; /* GC for drawing text in entry when active.
* NULL means use overall activeGC for
* menu. */
GC disabledGC; /* Used to produce disabled effect for entry.
- * NULL means use overall disabledGC from
- * menu structure. See comments for
- * disabledFg in menu structure for more
- * information. */
- GC indicatorGC; /* For drawing indicators. None means use
- * GC from menu. */
+ * NULL means use overall disabledGC from menu
+ * structure. See comments for disabledFg in
+ * menu structure for more information. */
+ GC indicatorGC; /* For drawing indicators. None means use GC
+ * from menu. */
/*
* Miscellaneous fields.
*/
-
- int entryFlags; /* Various flags. See below for
- definitions. */
- int index; /* Need to know which index we are. This
- * is zero-based. This is the top-left entry
- * of the menu. */
-
+
+ int entryFlags; /* Various flags. See below for
+ * definitions. */
+ int index; /* Need to know which index we are. This is
+ * zero-based. This is the top-left entry of
+ * the menu. */
+
/*
* Bookeeping for master menus and cascade menus.
*/
-
+
struct TkMenuReferences *childMenuRefPtr;
- /* A pointer to the hash table entry for
- * the child menu. Stored here when the menu
- * entry is configured so that a hash lookup
- * is not necessary later.*/
+ /* A pointer to the hash table entry for the
+ * child menu. Stored here when the menu entry
+ * is configured so that a hash lookup is not
+ * necessary later.*/
struct TkMenuEntry *nextCascadePtr;
/* The next cascade entry that is a parent of
- * this entry's child cascade menu. NULL
- * end of list, this is not a cascade entry,
- * or the menu that this entry point to
- * does not yet exist. */
+ * this entry's child cascade menu. NULL end
+ * of list, this is not a cascade entry, or
+ * the menu that this entry point to does not
+ * yet exist. */
TkMenuPlatformEntryData platformEntryData;
/* The data for the specific type of menu.
- * Depends on platform and menu type what
- * kind of options are in this structure.
- */
+ * Depends on platform and menu type what kind
+ * of options are in this structure. */
} TkMenuEntry;
/*
* Flag values defined for menu entries:
*
- * ENTRY_SELECTED: Non-zero means this is a radio or check
- * button and that it should be drawn in
- * the "selected" state.
+ * ENTRY_SELECTED: Non-zero means this is a radio or check 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
@@ -238,44 +252,43 @@ typedef struct TkMenuEntry {
* Menu states
*/
-EXTERN CONST char *tkMenuStateStrings[];
+MODULE_SCOPE const 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
- * menu widget:
+ * A data structure of the following type is kept for each menu widget:
*/
typedef struct TkMenu {
- Tk_Window tkwin; /* Window that embodies the pane. NULL
- * means that the window has been destroyed
- * but the data structures haven't yet been
- * cleaned up.*/
- Display *display; /* Display containing widget. Needed, among
+ Tk_Window tkwin; /* Window that embodies the pane. NULL means
+ * that the window has been destroyed but the
+ * data structures haven't yet been cleaned
+ * up. */
+ Display *display; /* Display containing widget. Needed, among
* other things, so that resources can be
* freed up even after tkwin has gone away. */
Tcl_Interp *interp; /* Interpreter associated with menu. */
Tcl_Command widgetCmd; /* Token for menu's widget command. */
- TkMenuEntry **entries; /* Array of pointers to all the entries
- * in the menu. NULL means no entries. */
+ TkMenuEntry **entries; /* Array of pointers to all the entries in the
+ * menu. NULL means no entries. */
int numEntries; /* Number of elements in entries. */
- int active; /* Index of active entry. -1 means
- * nothing active. */
- int menuType; /* MASTER_MENU, TEAROFF_MENU, or MENUBAR.
- * See below for definitions. */
- Tcl_Obj *menuTypePtr; /* Used to control whether created tkwin
- * is a toplevel or not. "normal", "menubar",
- * or "toplevel" */
+ int active; /* Index of active entry. -1 means nothing
+ * active. */
+ int menuType; /* MASTER_MENU, TEAROFF_MENU, or MENUBAR. See
+ * below for definitions. */
+ Tcl_Obj *menuTypePtr; /* Used to control whether created tkwin is a
+ * toplevel or not. "normal", "menubar", or
+ * "toplevel" */
/*
* Information used when displaying widget:
*/
- Tcl_Obj *borderPtr; /* Structure used to draw 3-D
- * border and background for menu. */
+ Tcl_Obj *borderPtr; /* Structure used to draw 3-D border and
+ * background for menu. */
Tcl_Obj *borderWidthPtr; /* Width of border around whole menu. */
Tcl_Obj *activeBorderPtr; /* Used to draw background and border for
* active element (if any). */
@@ -284,18 +297,17 @@ typedef struct TkMenu {
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. */
+ Tcl_Obj *disabledFgPtr; /* Foreground color when disabled. NULL means
+ * use normalFg with a 50% stipple instead. */
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
- * allocated yet. */
- GC textGC; /* GC for drawing text and other features
- * of menu entries. */
- GC disabledGC; /* Used to produce disabled effect. If
+ Pixmap gray; /* Bitmap for drawing disabled entries in a
+ * stippled fashion. None means not allocated
+ * yet. */
+ GC textGC; /* GC for drawing text and other features of
+ * menu entries. */
+ GC disabledGC; /* Used to produce disabled effect. If
* disabledFg isn't NULL, this GC is used to
* draw text and icons for disabled entries.
* Otherwise text and icons are drawn with
@@ -303,52 +315,51 @@ typedef struct TkMenu {
* background across them. */
GC activeGC; /* GC for drawing active entry. */
GC indicatorGC; /* For drawing indicators. */
- GC disabledImageGC; /* Used for drawing disabled images. They
- * have to be stippled. This is created
- * when the image is about to be drawn the
- * first time. */
+ GC disabledImageGC; /* Used for drawing disabled images. They have
+ * to be stippled. This is created when the
+ * image is about to be drawn the first
+ * time. */
/*
* Information about geometry of menu.
*/
-
- int totalWidth; /* Width of entire menu */
- int totalHeight; /* Height of entire menu */
-
+
+ int totalWidth; /* Width of entire menu. */
+ int totalHeight; /* Height of entire menu. */
+
/*
* Miscellaneous information:
*/
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
- * the mouse is released. On others, an
- * indicator (such as a dashed stripe) is
- * drawn, and when the menu is selected, the
- * tearoff is created. */
+ * platforms, the user can drag an outline of
+ * the menu by just dragging outside of the
+ * menu, and the tearoff is created where the
+ * mouse is released. On others, an indicator
+ * (such as a dashed stripe) is drawn, and
+ * when the menu is selected, the tearoff is
+ * created. */
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. */
- Tcl_Obj *tearoffCommandPtr; /* If non-NULL, points to a command to
- * run whenever the menu is torn-off. */
- 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. */
+ * off. If this is NULL, a default scheme will
+ * be used to generate a title for tearoff. */
+ Tcl_Obj *tearoffCommandPtr; /* If non-NULL, points to a command to run
+ * whenever the menu is torn-off. */
+ 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. */
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. */
+ * trees when preprocessing postcommands on
+ * some platforms. See PostMenu for more
+ * details. */
int postCommandGeneration; /* Need to do pre-invocation post command
- * traversal */
+ * traversal. */
int menuFlags; /* Flags for use by X; see below for
- definition */
+ * definition. */
TkMenuEntry *postedCascade; /* Points to menu entry for cascaded submenu
* that is currently posted or NULL if no
* submenu posted. */
- struct TkMenu *nextInstancePtr;
+ struct TkMenu *nextInstancePtr;
/* The next instance of this menu in the
* chain. */
struct TkMenu *masterMenuPtr;
@@ -356,29 +367,26 @@ typedef struct TkMenu {
* 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. */
+ /* 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.
- */
- struct TkMenuReferences *menuRefPtr;
+ * toplevel that owns the menu. Only
+ * applicable for menubar clones. */
+ struct TkMenuReferences *menuRefPtr;
/* Each menu is hashed into a table with the
- * name of the menu's window as the key.
- * The information in this hash table includes
- * a pointer to the menu (so that cascades
- * can find this menu), a pointer to the
- * list of toplevel widgets that have this
- * menu as its menubar, and a list of menu
- * entries that have this menu specified
- * as a cascade. */
+ * name of the menu's window as the key. The
+ * information in this hash table includes a
+ * pointer to the menu (so that cascades can
+ * find this menu), a pointer to the list of
+ * toplevel widgets that have this menu as its
+ * menubar, and a list of menu entries that
+ * have this menu specified as a cascade. */
TkMenuPlatformData platformData;
/* The data for the specific type of menu.
- * Depends on platform and menu type what
- * kind of options are in this structure.
- */
- Tk_OptionSpec *extensionPtr;
- /* Needed by the configuration package for
+ * 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
@@ -388,95 +396,94 @@ typedef struct TkMenu {
/*
* When the toplevel configure -menu command is executed, the menu may not
- * exist yet. We need to keep a linked list of windows that reference
- * a particular menu.
+ * exist yet. We need to keep a linked list of windows that reference a
+ * particular menu.
*/
typedef struct TkMenuTopLevelList {
struct TkMenuTopLevelList *nextPtr;
- /* The next window in the list */
+ /* The next window in the list. */
Tk_Window tkwin; /* The window that has this menu as its
* menubar. */
} TkMenuTopLevelList;
/*
- * The following structure is used to keep track of things which
- * reference a menu. It is created when:
+ * The following structure is used to keep track of things which reference a
+ * menu. It is created when:
* - a menu is created.
* - a cascade entry is added to a menu with a non-null name
- * - the "-menu" configuration option is used on a toplevel widget
- * with a non-null parameter.
+ * - the "-menu" configuration option is used on a toplevel widget with a
+ * non-null parameter.
*
- * One of these three fields must be non-NULL, but any of the fields may
- * be NULL. This structure makes it easy to determine whether or not
- * anything like recalculating platform data or geometry is necessary
- * when one of the three actions above is performed.
+ * One of these three fields must be non-NULL, but any of the fields may be
+ * NULL. This structure makes it easy to determine whether or not anything
+ * like recalculating platform data or geometry is necessary when one of the
+ * three actions above is performed.
*/
typedef struct TkMenuReferences {
- struct TkMenu *menuPtr; /* The menu data structure. This is NULL
- * if the menu does not exist. */
+ struct TkMenu *menuPtr; /* The menu data structure. This is NULL if
+ * the menu does not exist. */
TkMenuTopLevelList *topLevelListPtr;
- /* First in the list of all toplevels that
- * have this menu as its menubar. NULL if no
+ /* First in the list of all toplevels that
+ * have this menu as its menubar. NULL if no
* toplevel widgets have this menu as its
* menubar. */
- TkMenuEntry *parentEntryPtr;/* First in the list of all cascade menu
+ TkMenuEntry *parentEntryPtr;/* First in the list of all cascade menu
* entries that have this menu as their child.
* NULL means no cascade entries. */
Tcl_HashEntry *hashEntryPtr;/* This is needed because the pathname of the
* window (which is what we hash on) may not
- * be around when we are deleting.
- */
+ * be around when we are deleting. */
} TkMenuReferences;
/*
- * This structure contains all of the option tables that are needed
- * by menus.
+ * 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. */
+ Tk_OptionTable menuOptionTable;
+ /* The option table for menus. */
+ Tk_OptionTable entryOptionTables[6];
+ /* The tables for menu entries. */
} TkMenuOptionTables;
/*
* Flag bits for menus:
*
- * REDRAW_PENDING: Non-zero means a DoWhenIdle handler
- * has already been queued to redraw
- * this window.
+ * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has
+ * already been queued to redraw this window.
* RESIZE_PENDING: Non-zero means a call to ComputeMenuGeometry
* has already been scheduled.
- * MENU_DELETION_PENDING Non-zero means that we are currently destroying
- * this menu's internal structures. This is useful
- * when we are in the middle of cleaning
- * this master menu's chain of menus up when
- * TkDestroyMenu was called again on this
+ * MENU_DELETION_PENDING Non-zero means that we are currently
+ * destroying this menu's internal structures.
+ * This is useful when we are in the middle of
+ * cleaning this master menu's chain of menus up
+ * when TkDestroyMenu was called again on this
* menu (via a destroy binding or somesuch).
- * MENU_WIN_DESTRUCTION_PENDING Non-zero means we are in the middle of
- * destroying this menu's Tk_Window.
+ * MENU_WIN_DESTRUCTION_PENDING Non-zero means we are in the middle of
+ * destroying this menu's Tk_Window.
* MENU_PLATFORM_FLAG1... Reserved for use by the platform-specific menu
* code.
*/
-#define REDRAW_PENDING 1
-#define RESIZE_PENDING 2
-#define MENU_DELETION_PENDING 4
+#define REDRAW_PENDING 1
+#define RESIZE_PENDING 2
+#define MENU_DELETION_PENDING 4
#define MENU_WIN_DESTRUCTION_PENDING 8
#define MENU_PLATFORM_FLAG1 (1 << 30)
#define MENU_PLATFORM_FLAG2 (1 << 29)
#define MENU_PLATFORM_FLAG3 (1 << 28)
/*
- * Each menu created by the user is a MASTER_MENU. When a menu is torn off,
- * a TEAROFF_MENU instance is created. When a menu is assigned to a toplevel
- * as a menu bar, a MENUBAR instance is created. All instances have the same
+ * Each menu created by the user is a MASTER_MENU. When a menu is torn off, a
+ * TEAROFF_MENU instance is created. When a menu is assigned to a toplevel as
+ * a menu bar, a MENUBAR instance is created. All instances have the same
* configuration information. If the master instance is deleted, all instances
* are deleted. If one of the other instances is deleted, only that instance
* is deleted.
*/
-
+
#define UNKNOWN_TYPE -1
#define MASTER_MENU 0
#define TEAROFF_MENU 1
@@ -486,101 +493,81 @@ typedef struct TkMenuOptionTables {
* Various geometry definitions:
*/
-#define CASCADE_ARROW_HEIGHT 10
-#define CASCADE_ARROW_WIDTH 8
-#define DECORATION_BORDER_WIDTH 2
+#define CASCADE_ARROW_HEIGHT 10
+#define CASCADE_ARROW_WIDTH 8
+#define DECORATION_BORDER_WIDTH 2
/*
- * Menu-related procedures that are shared among Tk modules but not exported
- * to the outside world:
+ * Menu-related functions that are shared among Tk modules but not exported to
+ * the outside world:
*/
-EXTERN int TkActivateMenuEntry _ANSI_ARGS_((TkMenu *menuPtr,
- int index));
-EXTERN void TkBindMenu _ANSI_ARGS_((
- Tk_Window tkwin, TkMenu *menuPtr));
-EXTERN TkMenuReferences *
- TkCreateMenuReferences _ANSI_ARGS_((Tcl_Interp *interp,
- char *name));
-EXTERN void TkDestroyMenu _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 *name));
-EXTERN TkMenuReferences *
- TkFindMenuReferencesObj _ANSI_ARGS_((
- Tcl_Interp *interp, Tcl_Obj *namePtr));
-EXTERN int TkFreeMenuReferences _ANSI_ARGS_((
- TkMenuReferences *menuRefPtr));
-EXTERN Tcl_HashTable * TkGetMenuHashTable _ANSI_ARGS_((Tcl_Interp *interp));
-EXTERN int TkGetMenuIndex _ANSI_ARGS_((Tcl_Interp *interp,
- TkMenu *menuPtr, Tcl_Obj *objPtr, int lastOK,
- int *indexPtr));
-EXTERN void TkMenuInitializeDrawingFields _ANSI_ARGS_((
- TkMenu *menuPtr));
-EXTERN void TkMenuInitializeEntryDrawingFields _ANSI_ARGS_((
- TkMenuEntry *mePtr));
-EXTERN int TkInvokeMenu _ANSI_ARGS_((Tcl_Interp *interp,
- TkMenu *menuPtr, int index));
-EXTERN void TkMenuConfigureDrawOptions _ANSI_ARGS_((
- TkMenu *menuPtr));
-EXTERN int TkMenuConfigureEntryDrawOptions _ANSI_ARGS_((
- TkMenuEntry *mePtr, int index));
-EXTERN void TkMenuFreeDrawOptions _ANSI_ARGS_((TkMenu *menuPtr));
-EXTERN void TkMenuEntryFreeDrawOptions _ANSI_ARGS_((
- TkMenuEntry *mePtr));
-EXTERN void TkMenuEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-EXTERN void TkMenuImageProc _ANSI_ARGS_((
- ClientData clientData, int x, int y, int width,
- int height, int imgWidth, int imgHeight));
-EXTERN void TkMenuInit _ANSI_ARGS_((void));
-EXTERN void TkMenuSelectImageProc _ANSI_ARGS_
- ((ClientData clientData, int x, int y,
+MODULE_SCOPE int TkActivateMenuEntry(TkMenu *menuPtr, int index);
+MODULE_SCOPE void TkBindMenu(Tk_Window tkwin, TkMenu *menuPtr);
+MODULE_SCOPE TkMenuReferences*TkCreateMenuReferences(Tcl_Interp *interp,
+ char *name);
+MODULE_SCOPE void TkDestroyMenu(TkMenu *menuPtr);
+MODULE_SCOPE void TkEventuallyRecomputeMenu(TkMenu *menuPtr);
+MODULE_SCOPE void TkEventuallyRedrawMenu(TkMenu *menuPtr,
+ TkMenuEntry *mePtr);
+MODULE_SCOPE TkMenuReferences*TkFindMenuReferences(Tcl_Interp *interp, char *name);
+MODULE_SCOPE TkMenuReferences*TkFindMenuReferencesObj(Tcl_Interp *interp,
+ Tcl_Obj *namePtr);
+MODULE_SCOPE int TkFreeMenuReferences(TkMenuReferences *menuRefPtr);
+MODULE_SCOPE Tcl_HashTable *TkGetMenuHashTable(Tcl_Interp *interp);
+MODULE_SCOPE int TkGetMenuIndex(Tcl_Interp *interp, TkMenu *menuPtr,
+ Tcl_Obj *objPtr, int lastOK, int *indexPtr);
+MODULE_SCOPE void TkMenuInitializeDrawingFields(TkMenu *menuPtr);
+MODULE_SCOPE void TkMenuInitializeEntryDrawingFields(TkMenuEntry *mePtr);
+MODULE_SCOPE int TkInvokeMenu(Tcl_Interp *interp, TkMenu *menuPtr,
+ int index);
+MODULE_SCOPE void TkMenuConfigureDrawOptions(TkMenu *menuPtr);
+MODULE_SCOPE int TkMenuConfigureEntryDrawOptions(
+ TkMenuEntry *mePtr, int index);
+MODULE_SCOPE void TkMenuFreeDrawOptions(TkMenu *menuPtr);
+MODULE_SCOPE void TkMenuEntryFreeDrawOptions(TkMenuEntry *mePtr);
+MODULE_SCOPE void TkMenuEventProc(ClientData clientData,
+ XEvent *eventPtr);
+MODULE_SCOPE void TkMenuImageProc(ClientData clientData, int x, int y,
int width, int height, int imgWidth,
- int imgHeight));
-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));
-EXTERN int TkPostTearoffMenu _ANSI_ARGS_((Tcl_Interp *interp,
- TkMenu *menuPtr, int x, int y));
-EXTERN int TkPreprocessMenu _ANSI_ARGS_((TkMenu *menuPtr));
-EXTERN void TkRecomputeMenu _ANSI_ARGS_((TkMenu *menuPtr));
+ int imgHeight);
+MODULE_SCOPE void TkMenuInit(void);
+MODULE_SCOPE void TkMenuSelectImageProc(ClientData clientData, int x,
+ int y, int width, int height, int imgWidth,
+ int imgHeight);
+MODULE_SCOPE Tcl_Obj * TkNewMenuName(Tcl_Interp *interp,
+ Tcl_Obj *parentNamePtr, TkMenu *menuPtr);
+MODULE_SCOPE int TkPostCommand(TkMenu *menuPtr);
+MODULE_SCOPE int TkPostSubmenu(Tcl_Interp *interp, TkMenu *menuPtr,
+ TkMenuEntry *mePtr);
+MODULE_SCOPE int TkPostTearoffMenu(Tcl_Interp *interp, TkMenu *menuPtr,
+ int x, int y);
+MODULE_SCOPE int TkPreprocessMenu(TkMenu *menuPtr);
+MODULE_SCOPE void TkRecomputeMenu(TkMenu *menuPtr);
/*
- * These routines are the platform-dependent routines called by the
- * common code.
+ * These routines are the platform-dependent routines called by the common
+ * code.
*/
-EXTERN void TkpComputeMenubarGeometry _ANSI_ARGS_((
- TkMenu *menuPtr));
-EXTERN void TkpComputeStandardMenuGeometry _ANSI_ARGS_
- ((TkMenu *menuPtr));
-EXTERN int TkpConfigureMenuEntry
- _ANSI_ARGS_((TkMenuEntry *mePtr));
-EXTERN void TkpDestroyMenu _ANSI_ARGS_((TkMenu *menuPtr));
-EXTERN void TkpDestroyMenuEntry
- _ANSI_ARGS_((TkMenuEntry *mEntryPtr));
-EXTERN void TkpDrawMenuEntry _ANSI_ARGS_((TkMenuEntry *mePtr,
- Drawable d, Tk_Font tkfont,
- CONST Tk_FontMetrics *menuMetricsPtr, int x,
+MODULE_SCOPE void TkpComputeMenubarGeometry(TkMenu *menuPtr);
+MODULE_SCOPE void TkpComputeStandardMenuGeometry(TkMenu *menuPtr);
+MODULE_SCOPE int TkpConfigureMenuEntry(TkMenuEntry *mePtr);
+MODULE_SCOPE void TkpDestroyMenu(TkMenu *menuPtr);
+MODULE_SCOPE void TkpDestroyMenuEntry(TkMenuEntry *mEntryPtr);
+MODULE_SCOPE void TkpDrawMenuEntry(TkMenuEntry *mePtr,
+ Drawable d, Tk_Font tkfont,
+ const Tk_FontMetrics *menuMetricsPtr, int x,
int y, int width, int height, int strictMotif,
- int drawArrow));
-EXTERN void TkpMenuInit _ANSI_ARGS_((void));
-EXTERN int TkpMenuNewEntry _ANSI_ARGS_((TkMenuEntry *mePtr));
-EXTERN int TkpNewMenu _ANSI_ARGS_((TkMenu *menuPtr));
-EXTERN int TkpPostMenu _ANSI_ARGS_((Tcl_Interp *interp,
- TkMenu *menuPtr, int x, int y));
-EXTERN void TkpSetWindowMenuBar _ANSI_ARGS_((Tk_Window tkwin,
- TkMenu *menuPtr));
+ int drawingParameters);
+MODULE_SCOPE void TkpMenuInit(void);
+MODULE_SCOPE int TkpMenuNewEntry(TkMenuEntry *mePtr);
+MODULE_SCOPE int TkpNewMenu(TkMenu *menuPtr);
+MODULE_SCOPE int TkpPostMenu(Tcl_Interp *interp, TkMenu *menuPtr,
+ int x, int y);
+MODULE_SCOPE void TkpSetWindowMenuBar(Tk_Window tkwin, TkMenu *menuPtr);
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLIMPORT
#endif /* _TKMENU */
-
diff --git a/generic/tkMenuDraw.c b/generic/tkMenuDraw.c
index d4634cd..c49f513 100644
--- a/generic/tkMenuDraw.c
+++ b/generic/tkMenuDraw.c
@@ -1,35 +1,34 @@
-/*
+/*
* tkMenuDraw.c --
*
- * This module implements the platform-independent drawing and
- * geometry calculations of menu widgets.
+ * This module implements the platform-independent drawing and geometry
+ * calculations of menu widgets.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
+#include "tkInt.h"
#include "tkMenu.h"
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static void AdjustMenuCoords _ANSI_ARGS_ ((TkMenu *menuPtr,
- TkMenuEntry *mePtr, int *xPtr, int *yPtr,
- char *string));
-static void ComputeMenuGeometry _ANSI_ARGS_((
- ClientData clientData));
-static void DisplayMenu _ANSI_ARGS_((ClientData clientData));
+static void AdjustMenuCoords(TkMenu *menuPtr, TkMenuEntry *mePtr,
+ int *xPtr, int *yPtr);
+static void ComputeMenuGeometry(ClientData clientData);
+static void DisplayMenu(ClientData clientData);
/*
*----------------------------------------------------------------------
*
* TkMenuInitializeDrawingFields --
*
- * Fills in drawing fields of a new menu. Called when new menu is
- * created by MenuCmd.
+ * Fills in drawing fields of a new menu. Called when new menu is created
+ * by MenuCmd.
*
* Results:
* None.
@@ -41,8 +40,8 @@ static void DisplayMenu _ANSI_ARGS_((ClientData clientData));
*/
void
-TkMenuInitializeDrawingFields(menuPtr)
- TkMenu *menuPtr; /* The menu we are initializing. */
+TkMenuInitializeDrawingFields(
+ TkMenu *menuPtr) /* The menu we are initializing. */
{
menuPtr->textGC = None;
menuPtr->gray = None;
@@ -58,8 +57,8 @@ TkMenuInitializeDrawingFields(menuPtr)
*
* TkMenuInitializeEntryDrawingFields --
*
- * Fills in drawing fields of a new menu entry. Called when an
- * entry is created.
+ * Fills in drawing fields of a new menu entry. Called when an entry is
+ * created.
*
* Results:
* None.
@@ -71,8 +70,8 @@ TkMenuInitializeDrawingFields(menuPtr)
*/
void
-TkMenuInitializeEntryDrawingFields(mePtr)
- TkMenuEntry *mePtr; /* The menu we are initializing. */
+TkMenuInitializeEntryDrawingFields(
+ TkMenuEntry *mePtr) /* The menu we are initializing. */
{
mePtr->width = 0;
mePtr->height = 0;
@@ -91,8 +90,8 @@ TkMenuInitializeEntryDrawingFields(mePtr)
*
* TkMenuFreeDrawOptions --
*
- * Frees up any structures allocated for the drawing of a menu.
- * Called when menu is deleted.
+ * Frees up any structures allocated for the drawing of a menu. Called
+ * when menu is deleted.
*
* Results:
* None.
@@ -104,8 +103,8 @@ TkMenuInitializeEntryDrawingFields(mePtr)
*/
void
-TkMenuFreeDrawOptions(menuPtr)
- TkMenu *menuPtr;
+TkMenuFreeDrawOptions(
+ TkMenu *menuPtr)
{
if (menuPtr->textGC != None) {
Tk_FreeGC(menuPtr->display, menuPtr->textGC);
@@ -132,8 +131,8 @@ TkMenuFreeDrawOptions(menuPtr)
*
* TkMenuEntryFreeDrawOptions --
*
- * Frees up drawing structures for a menu entry. Called when
- * menu entry is freed.
+ * Frees up drawing structures for a menu entry. Called when menu entry
+ * is freed.
*
* RESULTS:
* None.
@@ -145,8 +144,8 @@ TkMenuFreeDrawOptions(menuPtr)
*/
void
-TkMenuEntryFreeDrawOptions(mePtr)
- TkMenuEntry *mePtr;
+TkMenuEntryFreeDrawOptions(
+ TkMenuEntry *mePtr)
{
if (mePtr->textGC != None) {
Tk_FreeGC(mePtr->menuPtr->display, mePtr->textGC);
@@ -167,8 +166,8 @@ TkMenuEntryFreeDrawOptions(mePtr)
*
* TkMenuConfigureDrawOptions --
*
- * Sets the menu's drawing attributes in preparation for drawing
- * the menu.
+ * Sets the menu's drawing attributes in preparation for drawing the
+ * menu.
*
* RESULTS:
* None.
@@ -180,8 +179,8 @@ TkMenuEntryFreeDrawOptions(mePtr)
*/
void
-TkMenuConfigureDrawOptions(menuPtr)
- TkMenu *menuPtr; /* The menu we are configuring. */
+TkMenuConfigureDrawOptions(
+ TkMenu *menuPtr) /* The menu we are configuring. */
{
XGCValues gcValues;
GC newGC;
@@ -189,11 +188,11 @@ TkMenuConfigureDrawOptions(menuPtr)
Tk_3DBorder border, activeBorder;
Tk_Font tkfont;
XColor *fg, *activeFg, *indicatorFg;
-
+
/*
- * 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.
+ * 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.
*/
border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
@@ -216,7 +215,7 @@ TkMenuConfigureDrawOptions(menuPtr)
if (menuPtr->disabledFgPtr != NULL) {
XColor *disabledFg;
- disabledFg = Tk_GetColorFromObj(menuPtr->tkwin,
+ disabledFg = Tk_GetColorFromObj(menuPtr->tkwin,
menuPtr->disabledFgPtr);
gcValues.foreground = disabledFg->pixel;
mask = GCForeground|GCBackground|GCFont;
@@ -247,7 +246,7 @@ TkMenuConfigureDrawOptions(menuPtr)
if (menuPtr->gray != None) {
gcValues.fill_style = FillStippled;
gcValues.stipple = menuPtr->gray;
- newGC = Tk_GetGC(menuPtr->tkwin,
+ newGC = Tk_GetGC(menuPtr->tkwin,
GCForeground|GCFillStyle|GCStipple, &gcValues);
}
if (menuPtr->disabledImageGC != None) {
@@ -258,7 +257,7 @@ TkMenuConfigureDrawOptions(menuPtr)
gcValues.font = Tk_FontId(tkfont);
activeFg = Tk_GetColorFromObj(menuPtr->tkwin, menuPtr->activeFgPtr);
gcValues.foreground = activeFg->pixel;
- activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin,
+ activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin,
menuPtr->activeBorderPtr);
gcValues.background = Tk_3DBorderColor(activeBorder)->pixel;
newGC = Tk_GetGC(menuPtr->tkwin, GCForeground|GCBackground|GCFont,
@@ -268,7 +267,7 @@ TkMenuConfigureDrawOptions(menuPtr)
}
menuPtr->activeGC = newGC;
- indicatorFg = Tk_GetColorFromObj(menuPtr->tkwin,
+ indicatorFg = Tk_GetColorFromObj(menuPtr->tkwin,
menuPtr->indicatorFgPtr);
gcValues.foreground = indicatorFg->pixel;
gcValues.background = Tk_3DBorderColor(border)->pixel;
@@ -285,8 +284,7 @@ TkMenuConfigureDrawOptions(menuPtr)
*
* TkMenuConfigureEntryDrawOptions --
*
- * Calculates any entry-specific draw options for the given menu
- * entry.
+ * Calculates any entry-specific draw options for the given menu entry.
*
* Results:
* Returns a standard Tcl error.
@@ -298,11 +296,10 @@ TkMenuConfigureDrawOptions(menuPtr)
*/
int
-TkMenuConfigureEntryDrawOptions(mePtr, index)
- TkMenuEntry *mePtr;
- int index;
+TkMenuConfigureEntryDrawOptions(
+ TkMenuEntry *mePtr,
+ int index)
{
-
XGCValues gcValues;
GC newGC, newActiveGC, newDisabledGC, newIndicatorGC;
unsigned long mask;
@@ -311,7 +308,7 @@ TkMenuConfigureEntryDrawOptions(mePtr, index)
tkfont = Tk_GetFontFromObj(menuPtr->tkwin,
(mePtr->fontPtr != NULL) ? mePtr->fontPtr : menuPtr->fontPtr);
-
+
if (mePtr->state == ENTRY_ACTIVE) {
if (index != menuPtr->active) {
TkActivateMenuEntry(menuPtr, index);
@@ -330,21 +327,21 @@ TkMenuConfigureEntryDrawOptions(mePtr, index)
|| (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
+ border = Tk_Get3DBorderFromObj(menuPtr->tkwin,
+ (mePtr->borderPtr != NULL) ? mePtr->borderPtr
: menuPtr->borderPtr);
gcValues.background = Tk_3DBorderColor(border)->pixel;
gcValues.font = Tk_FontId(tkfont);
/*
- * Note: disable GraphicsExpose events; we know there won't be
- * obscured areas when copying from an off-screen pixmap to the
- * screen and this gets rid of unnecessary events.
+ * Note: disable GraphicsExpose events; we know there won't be
+ * obscured areas when copying from an off-screen pixmap to the screen
+ * and this gets rid of unnecessary events.
*/
gcValues.graphics_exposures = False;
@@ -352,7 +349,7 @@ TkMenuConfigureEntryDrawOptions(mePtr, index)
GCForeground|GCBackground|GCFont|GCGraphicsExposures,
&gcValues);
- indicatorFg = Tk_GetColorFromObj(menuPtr->tkwin,
+ indicatorFg = Tk_GetColorFromObj(menuPtr->tkwin,
(mePtr->indicatorFgPtr != NULL) ? mePtr->indicatorFgPtr
: menuPtr->indicatorFgPtr);
gcValues.foreground = indicatorFg->pixel;
@@ -363,7 +360,7 @@ TkMenuConfigureEntryDrawOptions(mePtr, index)
if ((menuPtr->disabledFgPtr != NULL) || (mePtr->image != NULL)) {
XColor *disabledFg;
- disabledFg = Tk_GetColorFromObj(menuPtr->tkwin,
+ disabledFg = Tk_GetColorFromObj(menuPtr->tkwin,
menuPtr->disabledFgPtr);
gcValues.foreground = disabledFg->pixel;
mask = GCForeground|GCBackground|GCFont|GCGraphicsExposures;
@@ -375,13 +372,13 @@ TkMenuConfigureEntryDrawOptions(mePtr, index)
}
newDisabledGC = Tk_GetGC(menuPtr->tkwin, mask, &gcValues);
- activeFg = Tk_GetColorFromObj(menuPtr->tkwin,
+ activeFg = Tk_GetColorFromObj(menuPtr->tkwin,
(mePtr->activeFgPtr != NULL) ? mePtr->activeFgPtr
: menuPtr->activeFgPtr);
- activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin,
- (mePtr->activeBorderPtr != NULL) ? mePtr->activeBorderPtr
+ 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,
@@ -394,15 +391,15 @@ TkMenuConfigureEntryDrawOptions(mePtr, index)
newIndicatorGC = None;
}
if (mePtr->textGC != None) {
- Tk_FreeGC(menuPtr->display, mePtr->textGC);
+ Tk_FreeGC(menuPtr->display, mePtr->textGC);
}
mePtr->textGC = newGC;
if (mePtr->activeGC != None) {
- Tk_FreeGC(menuPtr->display, mePtr->activeGC);
+ Tk_FreeGC(menuPtr->display, mePtr->activeGC);
}
mePtr->activeGC = newActiveGC;
if (mePtr->disabledGC != None) {
- Tk_FreeGC(menuPtr->display, mePtr->disabledGC);
+ Tk_FreeGC(menuPtr->display, mePtr->disabledGC);
}
mePtr->disabledGC = newDisabledGC;
if (mePtr->indicatorGC != None) {
@@ -430,8 +427,8 @@ TkMenuConfigureEntryDrawOptions(mePtr, index)
*/
void
-TkEventuallyRecomputeMenu(menuPtr)
- TkMenu *menuPtr;
+TkEventuallyRecomputeMenu(
+ TkMenu *menuPtr)
{
if (!(menuPtr->menuFlags & RESIZE_PENDING)) {
menuPtr->menuFlags |= RESIZE_PENDING;
@@ -444,8 +441,8 @@ TkEventuallyRecomputeMenu(menuPtr)
*
* TkRecomputeMenu --
*
- * Tells Tcl to redo the geometry because this menu has changed.
- * Does it now; removes any ComputeMenuGeometries from the idler.
+ * Tells Tcl to redo the geometry because this menu has changed. Does it
+ * now; removes any ComputeMenuGeometries from the idler.
*
* Results:
* None.
@@ -457,9 +454,9 @@ TkEventuallyRecomputeMenu(menuPtr)
*/
void
-TkRecomputeMenu(menuPtr)
- TkMenu *menuPtr;
-{
+TkRecomputeMenu(
+ TkMenu *menuPtr)
+{
if (menuPtr->menuFlags & RESIZE_PENDING) {
Tcl_CancelIdleCall(ComputeMenuGeometry, (ClientData) menuPtr);
ComputeMenuGeometry((ClientData) menuPtr);
@@ -471,27 +468,27 @@ TkRecomputeMenu(menuPtr)
*
* TkEventuallyRedrawMenu --
*
- * Arrange for an entry of a menu, or the whole menu, to be
- * redisplayed at some point in the future.
+ * Arrange for an entry of a menu, or the whole menu, to be redisplayed
+ * at some point in the future.
*
* Results:
* None.
*
* Side effects:
- * A when-idle hander is scheduled to do the redisplay, if there
- * isn't one already scheduled.
+ * A when-idle hander is scheduled to do the redisplay, if there isn't
+ * one already scheduled.
*
*----------------------------------------------------------------------
*/
void
-TkEventuallyRedrawMenu(menuPtr, mePtr)
- register TkMenu *menuPtr; /* Information about menu to redraw. */
- register TkMenuEntry *mePtr;/* Entry to redraw. NULL means redraw
- * all the entries in the menu. */
+TkEventuallyRedrawMenu(
+ register TkMenu *menuPtr, /* Information about menu to redraw. */
+ register TkMenuEntry *mePtr)/* Entry to redraw. NULL means redraw all the
+ * entries in the menu. */
{
int i;
-
+
if (menuPtr->tkwin == NULL) {
return;
}
@@ -515,25 +512,23 @@ TkEventuallyRedrawMenu(menuPtr, mePtr)
*
* ComputeMenuGeometry --
*
- * This procedure is invoked to recompute the size and
- * layout of a menu. It is called as a when-idle handler so
- * that it only gets done once, even if a group of changes is
- * made to the menu.
+ * This function is invoked to recompute the size and layout of a menu.
+ * It is called as a when-idle handler so that it only gets done once,
+ * even if a group of changes is made to the menu.
*
* Results:
* None.
*
* Side effects:
- * Fields of menu entries are changed to reflect their
- * current positions, and the size of the menu window
- * itself may be changed.
+ * Fields of menu entries are changed to reflect their current positions,
+ * and the size of the menu window itself may be changed.
*
*--------------------------------------------------------------
*/
static void
-ComputeMenuGeometry(clientData)
- ClientData clientData; /* Structure describing menu. */
+ComputeMenuGeometry(
+ ClientData clientData) /* Structure describing menu. */
{
TkMenu *menuPtr = (TkMenu *) clientData;
@@ -552,16 +547,15 @@ ComputeMenuGeometry(clientData)
Tk_GeometryRequest(menuPtr->tkwin, menuPtr->totalWidth,
menuPtr->totalHeight);
}
-
+
/*
- * Must always force a redisplay here if the window is mapped
- * (even if the size didn't change, something else might have
- * changed in the menu, such as a label or accelerator). The
- * resize will force a redisplay above.
+ * Must always force a redisplay here if the window is mapped (even if the
+ * size didn't change, something else might have changed in the menu, such
+ * as a label or accelerator). The resize will force a redisplay above.
*/
-
- TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL);
-
+
+ TkEventuallyRedrawMenu(menuPtr, NULL);
+
menuPtr->menuFlags &= ~RESIZE_PENDING;
}
@@ -570,9 +564,9 @@ ComputeMenuGeometry(clientData)
*
* TkMenuSelectImageProc --
*
- * This procedure is invoked by the image code whenever the manager
- * for an image does something that affects the size of contents
- * of an image displayed in a menu entry when it is selected.
+ * This function is invoked by the image code whenever the manager for an
+ * image does something that affects the size of contents of an image
+ * displayed in a menu entry when it is selected.
*
* Results:
* None.
@@ -584,20 +578,18 @@ ComputeMenuGeometry(clientData)
*/
void
-TkMenuSelectImageProc(clientData, x, y, width, height, imgWidth,
- imgHeight)
- ClientData clientData; /* Pointer to widget record. */
- int x, y; /* Upper left pixel (within image)
- * that must be redisplayed. */
- int width, height; /* Dimensions of area to redisplay
- * (may be <= 0). */
- int imgWidth, imgHeight; /* New dimensions of image. */
+TkMenuSelectImageProc(
+ ClientData clientData, /* Pointer to widget record. */
+ int x, int y, /* Upper left pixel (within image) that must
+ * be redisplayed. */
+ int width, int height, /* Dimensions of area to redisplay (may be
+ * <=0). */
+ int imgWidth, int imgHeight)/* New dimensions of image. */
{
register TkMenuEntry *mePtr = (TkMenuEntry *) clientData;
if ((mePtr->entryFlags & ENTRY_SELECTED)
- && !(mePtr->menuPtr->menuFlags &
- REDRAW_PENDING)) {
+ && !(mePtr->menuPtr->menuFlags & REDRAW_PENDING)) {
mePtr->menuPtr->menuFlags |= REDRAW_PENDING;
Tcl_DoWhenIdle(DisplayMenu, (ClientData) mePtr->menuPtr);
}
@@ -608,21 +600,20 @@ TkMenuSelectImageProc(clientData, x, y, width, height, imgWidth,
*
* DisplayMenu --
*
- * This procedure is invoked to display a menu widget.
+ * This function is invoked to display a menu widget.
*
* Results:
* None.
*
* Side effects:
- * Commands are output to X to display the menu in its
- * current mode.
+ * Commands are output to X to display the menu in its current mode.
*
*----------------------------------------------------------------------
*/
static void
-DisplayMenu(clientData)
- ClientData clientData; /* Information about widget. */
+DisplayMenu(
+ ClientData clientData) /* Information about widget. */
{
register TkMenu *menuPtr = (TkMenu *) clientData;
register TkMenuEntry *mePtr;
@@ -649,8 +640,8 @@ DisplayMenu(clientData)
menuPtr->activeBorderWidthPtr, &activeBorderWidth);
if (menuPtr->menuType == MENUBAR) {
- Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth,
- borderWidth, Tk_Width(tkwin) - 2 * borderWidth,
+ Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth,
+ borderWidth, Tk_Width(tkwin) - 2 * borderWidth,
Tk_Height(tkwin) - 2 * borderWidth, 0, TK_RELIEF_FLAT);
}
@@ -688,15 +679,15 @@ DisplayMenu(clientData)
}
}
TkpDrawMenuEntry(mePtr, Tk_WindowId(menuPtr->tkwin), tkfont,
- &menuMetrics, mePtr->x, mePtr->y, width,
+ &menuMetrics, mePtr->x, mePtr->y, width,
mePtr->height, strictMotif, 1);
if ((index > 0) && (menuPtr->menuType != MENUBAR)
&& mePtr->columnBreak) {
mePtr = menuPtr->entries[index - 1];
Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border,
- mePtr->x, mePtr->y + mePtr->height,
+ mePtr->x, mePtr->y + mePtr->height,
mePtr->width,
- Tk_Height(tkwin) - mePtr->y - mePtr->height -
+ Tk_Height(tkwin) - mePtr->y - mePtr->height -
activeBorderWidth, 0,
TK_RELIEF_FLAT);
}
@@ -712,7 +703,7 @@ DisplayMenu(clientData)
} else {
mePtr = menuPtr->entries[menuPtr->numEntries - 1];
Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin),
- border, mePtr->x, mePtr->y + mePtr->height, mePtr->width,
+ border, mePtr->x, mePtr->y + mePtr->height, mePtr->width,
Tk_Height(tkwin) - mePtr->y - mePtr->height
- activeBorderWidth, 0,
TK_RELIEF_FLAT);
@@ -721,13 +712,13 @@ DisplayMenu(clientData)
width = Tk_Width(tkwin) - x - activeBorderWidth;
height = Tk_Height(tkwin) - y - activeBorderWidth;
}
- Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), 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),
- border, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), borderWidth,
+ border, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), borderWidth,
relief);
}
@@ -736,31 +727,31 @@ DisplayMenu(clientData)
*
* TkMenuEventProc --
*
- * This procedure is invoked by the Tk dispatcher for various
- * events on menus.
+ * This function is invoked by the Tk dispatcher for various events on
+ * menus.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up. When
+ * it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
void
-TkMenuEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- XEvent *eventPtr; /* Information about event. */
+TkMenuEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
TkMenu *menuPtr = (TkMenu *) clientData;
-
+
if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
- TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL);
+ TkEventuallyRedrawMenu(menuPtr, NULL);
} else if (eventPtr->type == ConfigureNotify) {
TkEventuallyRecomputeMenu(menuPtr);
- TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL);
+ TkEventuallyRedrawMenu(menuPtr, NULL);
} else if (eventPtr->type == ActivateNotify) {
if (menuPtr->menuType == TEAROFF_MENU) {
TkpSetMainMenubar(menuPtr->interp, menuPtr->tkwin, NULL);
@@ -797,9 +788,9 @@ TkMenuEventProc(clientData, eventPtr)
*
* TkMenuImageProc --
*
- * This procedure is invoked by the image code whenever the manager
- * for an image does something that affects the size of contents
- * of an image displayed in a menu entry.
+ * This function is invoked by the image code whenever the manager for an
+ * image does something that affects the size of contents of an image
+ * displayed in a menu entry.
*
* Results:
* None.
@@ -811,19 +802,17 @@ TkMenuEventProc(clientData, eventPtr)
*/
void
-TkMenuImageProc(clientData, x, y, width, height, imgWidth,
- imgHeight)
- ClientData clientData; /* Pointer to widget record. */
- int x, y; /* Upper left pixel (within image)
- * that must be redisplayed. */
- int width, height; /* Dimensions of area to redisplay
- * (may be <= 0). */
- int imgWidth, imgHeight; /* New dimensions of image. */
+TkMenuImageProc(
+ ClientData clientData, /* Pointer to widget record. */
+ int x, int y, /* Upper left pixel (within image) that must
+ * be redisplayed. */
+ int width, int height, /* Dimensions of area to redisplay (may be
+ * <=0). */
+ int imgWidth, int imgHeight)/* New dimensions of image. */
{
register TkMenu *menuPtr = ((TkMenuEntry *)clientData)->menuPtr;
- if ((menuPtr->tkwin != NULL) && !(menuPtr->menuFlags
- & RESIZE_PENDING)) {
+ if ((menuPtr->tkwin != NULL) && !(menuPtr->menuFlags & RESIZE_PENDING)) {
menuPtr->menuFlags |= RESIZE_PENDING;
Tcl_DoWhenIdle(ComputeMenuGeometry, (ClientData) menuPtr);
}
@@ -834,9 +823,9 @@ TkMenuImageProc(clientData, x, y, width, height, imgWidth,
*
* TkPostTearoffMenu --
*
- * Posts a menu on the screen. Used to post tearoff menus. On Unix,
- * all menus are posted this way. Adjusts the menu's position
- * so that it fits on the screen, and maps and raises the menu.
+ * Posts a menu on the screen. Used to post tearoff menus. On Unix, all
+ * menus are posted this way. Adjusts the menu's position so that it fits
+ * on the screen, and maps and raises the menu.
*
* Results:
* Returns a standard Tcl Error.
@@ -848,13 +837,11 @@ TkMenuImageProc(clientData, x, y, width, height, imgWidth,
*/
int
-TkPostTearoffMenu(interp, menuPtr, x, y)
- Tcl_Interp *interp; /* The interpreter of the menu */
- TkMenu *menuPtr; /* The menu we are posting */
- int x; /* The root X coordinate where we
- * are posting */
- int y; /* The root Y coordinate where we
- * are posting */
+TkPostTearoffMenu(
+ Tcl_Interp *interp, /* The interpreter of the menu */
+ TkMenu *menuPtr, /* The menu we are posting */
+ int x, int y) /* The root X,Y coordinates where we are
+ * posting */
{
int vRootX, vRootY, vRootWidth, vRootHeight;
int result;
@@ -867,8 +854,8 @@ TkPostTearoffMenu(interp, menuPtr, x, y)
}
/*
- * The post commands could have deleted the menu, which means
- * we are dead and should go away.
+ * The post commands could have deleted the menu, which means we are dead
+ * and should go away.
*/
if (menuPtr->tkwin == NULL) {
@@ -876,22 +863,20 @@ TkPostTearoffMenu(interp, menuPtr, x, y)
}
/*
- * Adjust the position of the menu if necessary to keep it
- * visible on the screen. There are two special tricks to
- * make this work right:
+ * Adjust the position of the menu if necessary to keep it visible on the
+ * screen. There are two special tricks to make this work right:
*
- * 1. If a virtual root window manager is being used then
- * the coordinates are in the virtual root window of
- * menuPtr's parent; since the menu uses override-redirect
- * mode it will be in the *real* root window for the screen,
- * so we have to map the coordinates from the virtual root
- * (if any) to the real root. Can't get the virtual root
- * from the menu itself (it will never be seen by the wm)
- * so use its parent instead (it would be better to have an
- * an option that names a window to use for this...).
- * 2. The menu may not have been mapped yet, so its current size
- * might be the default 1x1. To compute how much space it
- * needs, use its requested size, not its actual size.
+ * 1. If a virtual root window manager is being used then the coordinates
+ * are in the virtual root window of menuPtr's parent; since the menu
+ * uses override-redirect mode it will be in the *real* root window for
+ * the screen, so we have to map the coordinates from the virtual root
+ * (if any) to the real root. Can't get the virtual root from the menu
+ * itself (it will never be seen by the wm) so use its parent instead
+ * (it would be better to have an an option that names a window to use
+ * for this...).
+ * 2. The menu may not have been mapped yet, so its current size might be
+ * the default 1x1. To compute how much space it needs, use its
+ * requested size, not its actual size.
*/
Tk_GetVRootGeometry(Tk_Parent(menuPtr->tkwin), &vRootX, &vRootY,
@@ -923,59 +908,58 @@ TkPostTearoffMenu(interp, menuPtr, x, y)
*
* TkPostSubmenu --
*
- * This procedure arranges for a particular submenu (i.e. the
- * menu corresponding to a given cascade entry) to be
- * posted.
+ * This function arranges for a particular submenu (i.e. the menu
+ * corresponding to a given cascade entry) to be posted.
*
* Results:
- * A standard Tcl return result. Errors may occur in the
- * Tcl commands generated to post and unpost submenus.
+ * A standard Tcl return result. Errors may occur in the Tcl commands
+ * generated to post and unpost submenus.
*
* Side effects:
- * If there is already a submenu posted, it is unposted.
- * The new submenu is then posted.
+ * If there is already a submenu posted, it is unposted. The new submenu
+ * is then posted.
*
*--------------------------------------------------------------
*/
int
-TkPostSubmenu(interp, menuPtr, mePtr)
- Tcl_Interp *interp; /* Used for invoking sub-commands and
+TkPostSubmenu(
+ Tcl_Interp *interp, /* Used for invoking sub-commands and
* reporting errors. */
- register TkMenu *menuPtr; /* Information about menu as a whole. */
- register TkMenuEntry *mePtr; /* Info about submenu that is to be
- * posted. NULL means make sure that
- * no submenu is posted. */
+ register TkMenu *menuPtr, /* Information about menu as a whole. */
+ register TkMenuEntry *mePtr)/* Info about submenu that is to be posted.
+ * NULL means make sure that no submenu is
+ * posted. */
{
int result, x, y;
+ Tcl_Obj *subary[4];
if (mePtr == menuPtr->postedCascade) {
return TCL_OK;
}
if (menuPtr->postedCascade != NULL) {
- char *name = Tcl_GetStringFromObj(menuPtr->postedCascade->namePtr,
- NULL);
-
/*
- * Note: when unposting a submenu, we have to redraw the entire
- * parent menu. This is because of a combination of the following
- * things:
+ * Note: when unposting a submenu, we have to redraw the entire parent
+ * menu. This is because of a combination of the following things:
* (a) the submenu partially overlaps the parent.
- * (b) the submenu specifies "save under", which causes the X
- * server to make a copy of the information under it when it
- * is posted. When the submenu is unposted, the X server
- * copies this data back and doesn't generate any Expose
- * events for the parent.
- * (c) the parent may have redisplayed itself after the submenu
- * was posted, in which case the saved information is no
- * longer correct.
- * The simplest solution is just force a complete redisplay of
- * the parent.
+ * (b) the submenu specifies "save under", which causes the X server
+ * to make a copy of the information under it when it is posted.
+ * When the submenu is unposted, the X server copies this data
+ * back and doesn't generate any Expose events for the parent.
+ * (c) the parent may have redisplayed itself after the submenu was
+ * posted, in which case the saved information is no longer
+ * correct.
+ * The simplest solution is just force a complete redisplay of the
+ * parent.
*/
- TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL);
- result = Tcl_VarEval(interp, "{", name, "} unpost", (char *) NULL);
+ subary[0] = menuPtr->postedCascade->namePtr;
+ subary[1] = Tcl_NewStringObj("unpost", -1);
+ Tcl_IncrRefCount(subary[1]);
+ TkEventuallyRedrawMenu(menuPtr, NULL);
+ result = Tcl_EvalObjv(interp, 2, subary, 0);
+ Tcl_DecrRefCount(subary[1]);
menuPtr->postedCascade = NULL;
if (result != TCL_OK) {
return result;
@@ -985,21 +969,31 @@ TkPostSubmenu(interp, menuPtr, mePtr)
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
- * menu entry (this is an attempt to match Motif behavior).
+ * Position the cascade with its upper left corner slightly below and
+ * to the left of the upper right corner of the menu entry (this is an
+ * attempt to match Motif behavior).
*
* The menu has to redrawn so that the entry can change relief.
+ *
+ * Set postedCascade early to ensure tear-off submenus work on
+ * Windows. [Bug 873613]
*/
- 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);
+ AdjustMenuCoords(menuPtr, mePtr, &x, &y);
+
menuPtr->postedCascade = mePtr;
- result = Tcl_VarEval(interp, "{", name, "} post ", string, (char *) NULL);
+ subary[0] = mePtr->namePtr;
+ subary[1] = Tcl_NewStringObj("post", -1);
+ subary[2] = Tcl_NewIntObj(x);
+ subary[3] = Tcl_NewIntObj(y);
+ Tcl_IncrRefCount(subary[1]);
+ Tcl_IncrRefCount(subary[2]);
+ Tcl_IncrRefCount(subary[3]);
+ result = Tcl_EvalObjv(interp, 4, subary, 0);
+ Tcl_DecrRefCount(subary[1]);
+ Tcl_DecrRefCount(subary[2]);
+ Tcl_DecrRefCount(subary[3]);
if (result != TCL_OK) {
menuPtr->postedCascade = NULL;
return result;
@@ -1014,8 +1008,7 @@ TkPostSubmenu(interp, menuPtr, mePtr)
*
* AdjustMenuCoords --
*
- * Adjusts the given coordinates down and the left to give a Motif
- * look.
+ * Adjusts the given coordinates down and the left to give a Motif look.
*
* Results:
* None.
@@ -1027,12 +1020,11 @@ TkPostSubmenu(interp, menuPtr, mePtr)
*/
static void
-AdjustMenuCoords(menuPtr, mePtr, xPtr, yPtr, string)
- TkMenu *menuPtr;
- TkMenuEntry *mePtr;
- int *xPtr;
- int *yPtr;
- char *string;
+AdjustMenuCoords(
+ TkMenu *menuPtr,
+ TkMenuEntry *mePtr,
+ int *xPtr,
+ int *yPtr)
{
if (menuPtr->menuType == MENUBAR) {
*xPtr += mePtr->x;
@@ -1042,11 +1034,18 @@ AdjustMenuCoords(menuPtr, mePtr, xPtr, yPtr, string)
Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
&borderWidth);
- Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
+ Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
menuPtr->activeBorderWidthPtr, &activeBorderWidth);
- *xPtr += Tk_Width(menuPtr->tkwin) - borderWidth - activeBorderWidth
+ *xPtr += Tk_Width(menuPtr->tkwin) - borderWidth - activeBorderWidth
- 2;
*yPtr += mePtr->y + activeBorderWidth + 2;
}
- sprintf(string, "%d %d", *xPtr, *yPtr);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkMenubutton.c b/generic/tkMenubutton.c
index 0e85308..94ac8b2 100644
--- a/generic/tkMenubutton.c
+++ b/generic/tkMenubutton.c
@@ -1,115 +1,114 @@
-/*
+/*
* tkMenubutton.c --
*
- * This module implements button-like widgets that are used
- * to invoke pull-down menus.
+ * This module implements button-like widgets that are used to invoke
+ * pull-down menus.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
+#include "tkInt.h"
#include "tkMenubutton.h"
-#include "tkPort.h"
#include "default.h"
/*
- * The following table defines the legal values for the -direction
- * option. It is used together with the "enum direction" declaration
- * in tkMenubutton.h.
+ * The following table defines the legal values for the -direction option. It
+ * is used together with the "enum direction" declaration in tkMenubutton.h.
*/
-static CONST char *CONST directionStrings[] = {
- "above", "below", "flush", "left", "right", (char *) NULL
+static const char *const directionStrings[] = {
+ "above", "below", "flush", "left", "right", NULL
};
/*
- * The following table defines the legal values for the -state option.
- * It is used together with the "enum state" declaration in tkMenubutton.h.
+ * The following table defines the legal values for the -state option. It is
+ * used together with the "enum state" declaration in tkMenubutton.h.
*/
-static CONST char *CONST stateStrings[] = {
- "active", "disabled", "normal", (char *) NULL
+static const char *const stateStrings[] = {
+ "active", "disabled", "normal", NULL
};
/*
- * The following table defines the legal values for the -compound option.
- * It is used with the "enum compound" declaration in tkMenuButton.h
+ * The following table defines the legal values for the -compound option. It
+ * is used with the "enum compound" declaration in tkMenuButton.h
*/
-static CONST char *CONST compoundStrings[] = {
- "bottom", "center", "left", "none", "right", "top", (char *) NULL
+static const char *const compoundStrings[] = {
+ "bottom", "center", "left", "none", "right", "top", NULL
};
/*
* Information used for parsing configuration specs:
*/
-static CONST Tk_OptionSpec optionSpecs[] = {
+static const 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},
+ 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},
+ 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},
+ 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},
+ 0, (ClientData) DEF_MENUBUTTON_BG_MONO, 0},
+ {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, 0, -1, 0,
+ (ClientData) "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL, 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},
+ 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),
+ DEF_MENUBUTTON_DIRECTION, -1, Tk_Offset(TkMenuButton, direction),
0, (ClientData) directionStrings, 0},
{TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
"DisabledForeground", DEF_MENUBUTTON_DISABLED_FG_COLOR,
-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_SYNONYM, "-fg", "foreground", NULL, 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},
+ 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},
+ DEF_MENUBUTTON_HIGHLIGHT, -1,
+ Tk_Offset(TkMenuButton, highlightColorPtr), 0, 0, 0},
{TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
"HighlightThickness", DEF_MENUBUTTON_HIGHLIGHT_WIDTH,
-1, Tk_Offset(TkMenuButton, highlightWidth), 0, 0, 0},
{TK_OPTION_STRING, "-image", "image", "Image",
- DEF_MENUBUTTON_IMAGE, -1, Tk_Offset(TkMenuButton, imageString),
+ 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},
+ 0, 0, 0},
{TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
- DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkMenuButton, justify), 0, 0, 0},
+ DEF_MENUBUTTON_JUSTIFY, -1, Tk_Offset(TkMenuButton, justify), 0, 0, 0},
{TK_OPTION_STRING, "-menu", "menu", "Menu",
- DEF_MENUBUTTON_MENU, -1, Tk_Offset(TkMenuButton, menuName),
+ 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),
@@ -118,43 +117,42 @@ static CONST Tk_OptionSpec optionSpecs[] = {
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},
+ DEF_MENUBUTTON_RELIEF, -1, Tk_Offset(TkMenuButton, relief),
+ 0, 0, 0},
{TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
- DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkMenuButton, compound), 0,
- (ClientData) compoundStrings, 0},
+ DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkMenuButton, compound), 0,
+ (ClientData) compoundStrings, 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},
+ 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},
+ 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},
+ 0, 0, 0},
{TK_OPTION_STRING, "-width", "width", "Width",
- DEF_MENUBUTTON_WIDTH, -1, Tk_Offset(TkMenuButton, widthString),
- 0, 0, 0},
+ 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}
+ 0, 0, 0},
+ {TK_OPTION_END, NULL, NULL, NULL, 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.
+ * 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 CONST char *commandNames[] = {
- "cget", "configure", (char *) NULL
+static const char *commandNames[] = {
+ "cget", "configure", NULL
};
enum command {
@@ -162,35 +160,34 @@ enum command {
};
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static void MenuButtonCmdDeletedProc _ANSI_ARGS_((
- ClientData clientData));
-static void MenuButtonEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void MenuButtonImageProc _ANSI_ARGS_((ClientData clientData,
+static void MenuButtonCmdDeletedProc(ClientData clientData);
+static void MenuButtonEventProc(ClientData clientData,
+ XEvent *eventPtr);
+static void MenuButtonImageProc(ClientData clientData,
int x, int y, int width, int height, int imgWidth,
- int imgHeight));
-static char * MenuButtonTextVarProc _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp,
- CONST char *name1, CONST char *name2, int flags));
-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 objc,
- Tcl_Obj *CONST objv[]));
-static void DestroyMenuButton _ANSI_ARGS_((char *memPtr));
+ int imgHeight);
+static char * MenuButtonTextVarProc(ClientData clientData,
+ Tcl_Interp *interp, const char *name1,
+ const char *name2, int flags);
+static int MenuButtonWidgetObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+static int ConfigureMenuButton(Tcl_Interp *interp,
+ TkMenuButton *mbPtr, int objc,
+ Tcl_Obj *const objv[]);
+static void DestroyMenuButton(char *memPtr);
/*
*--------------------------------------------------------------
*
* Tk_MenubuttonObjCmd --
*
- * This procedure is invoked to process the "button", "label",
- * "radiobutton", and "checkbutton" Tcl commands. See the
- * user documentation for details on what it does.
+ * This function is invoked to process the "button", "label",
+ * "radiobutton", and "checkbutton" Tcl commands. See the user
+ * documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -202,11 +199,11 @@ static void DestroyMenuButton _ANSI_ARGS_((char *memPtr));
*/
int
-Tk_MenubuttonObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* NULL. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_MenubuttonObjCmd(
+ ClientData clientData, /* NULL. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
register TkMenuButton *mbPtr;
Tk_OptionTable optionTable;
@@ -222,14 +219,14 @@ Tk_MenubuttonObjCmd(clientData, interp, objc, objv)
*/
tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
- Tcl_GetString(objv[1]), (char *) NULL);
+ Tcl_GetString(objv[1]), NULL);
if (tkwin == NULL) {
return TCL_ERROR;
}
/*
- * Create the option table for this widget class. If it has already
- * been created, the cached pointer will be returned.
+ * Create the option table for this widget class. If it has already been
+ * created, the cached pointer will be returned.
*/
optionTable = Tk_CreateOptionTable(interp, optionSpecs);
@@ -246,9 +243,9 @@ Tk_MenubuttonObjCmd(clientData, interp, objc, objv)
mbPtr->tkwin = tkwin;
mbPtr->display = Tk_Display (tkwin);
mbPtr->interp = interp;
- mbPtr->widgetCmd = Tcl_CreateObjCommand(interp,
- Tk_PathName(mbPtr->tkwin), MenuButtonWidgetObjCmd,
- (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;
@@ -318,9 +315,9 @@ Tk_MenubuttonObjCmd(clientData, interp, objc, objv)
*
* MenuButtonWidgetObjCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to a widget managed by this module.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the Tcl command that corresponds
+ * to a widget managed by this module. See the user documentation for
+ * details on what it does.
*
* Results:
* A standard Tcl result.
@@ -332,66 +329,62 @@ Tk_MenubuttonObjCmd(clientData, interp, objc, objv)
*/
static int
-MenuButtonWidgetObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Information about button widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+MenuButtonWidgetObjCmd(
+ ClientData clientData, /* Information about button widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
register TkMenuButton *mbPtr = (TkMenuButton *) clientData;
int result, index;
Tcl_Obj *objPtr;
if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
+ Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
return TCL_ERROR;
}
- result = Tcl_GetIndexFromObj(interp, objv[1],
- commandNames, "option", 0, &index);
+ result = Tcl_GetIndexFromObj(interp, objv[1], commandNames, "option", 0,
+ &index);
if (result != TCL_OK) {
- return result;
+ return result;
}
Tcl_Preserve((ClientData) mbPtr);
switch (index) {
- case COMMAND_CGET: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "cget option");
+ 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;
+ objPtr = Tk_GetOptionValue(interp, (char *) mbPtr,
+ mbPtr->optionTable, objv[2], mbPtr->tkwin);
+ if (objPtr == NULL) {
+ goto error;
+ } else {
+ Tcl_SetObjResult(interp, objPtr);
}
+ break;
- 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);
- }
+ case COMMAND_CONFIGURE:
+ if (objc <= 3) {
+ objPtr = Tk_GetOptionInfo(interp, (char *) mbPtr,
+ mbPtr->optionTable, (objc == 3) ? objv[2] : NULL,
+ mbPtr->tkwin);
+ if (objPtr == NULL) {
+ goto error;
} else {
- result = ConfigureMenuButton(interp, mbPtr, objc-2,
- objv+2);
+ Tcl_SetObjResult(interp, objPtr);
}
- break;
+ } else {
+ result = ConfigureMenuButton(interp, mbPtr, objc-2, objv+2);
}
+ break;
}
Tcl_Release((ClientData) mbPtr);
return result;
- error:
+ error:
Tcl_Release((ClientData) mbPtr);
return TCL_ERROR;
}
@@ -401,10 +394,10 @@ MenuButtonWidgetObjCmd(clientData, interp, objc, objv)
*
* DestroyMenuButton --
*
- * This procedure is invoked to recycle all of the resources
- * 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 menubutton pending at the time of the deletion.
+ * This function is invoked to recycle all of the resources 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 menubutton
+ * pending at the time of the deletion.
*
* Results:
* None.
@@ -416,20 +409,19 @@ MenuButtonWidgetObjCmd(clientData, interp, objc, objv)
*/
static void
-DestroyMenuButton(memPtr)
- char *memPtr; /* Info about button widget. */
+DestroyMenuButton(
+ char *memPtr) /* Info about button widget. */
{
register TkMenuButton *mbPtr = (TkMenuButton *) memPtr;
TkpDestroyMenuButton(mbPtr);
if (mbPtr->flags & REDRAW_PENDING) {
- Tcl_CancelIdleCall(TkpDisplayMenuButton, (ClientData) mbPtr);
+ Tcl_CancelIdleCall(TkpDisplayMenuButton, (ClientData) mbPtr);
}
/*
- * Free up all the stuff that requires special handling, then
- * let Tk_FreeOptions handle all the standard option-related
- * stuff.
+ * Free up all the stuff that requires special handling, then let
+ * Tk_FreeOptions handle all the standard option-related stuff.
*/
Tcl_DeleteCommandFromToken(mbPtr->interp, mbPtr->widgetCmd);
@@ -457,7 +449,7 @@ DestroyMenuButton(memPtr)
Tk_FreeBitmap(mbPtr->display, mbPtr->gray);
}
if (mbPtr->textLayout != NULL) {
- Tk_FreeTextLayout(mbPtr->textLayout);
+ Tk_FreeTextLayout(mbPtr->textLayout);
}
Tk_FreeConfigOptions((char *) mbPtr, mbPtr->optionTable, mbPtr->tkwin);
mbPtr->tkwin = NULL;
@@ -469,31 +461,30 @@ DestroyMenuButton(memPtr)
*
* ConfigureMenuButton --
*
- * This procedure is called to process an argv/argc list, plus
- * the Tk option database, in order to configure (or
- * reconfigure) a menubutton widget.
+ * This function is called to process an argv/argc list, plus the Tk
+ * option database, in order to configure (or reconfigure) a menubutton
+ * widget.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message.
+ * 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 text string, colors, font,
- * etc. get set for mbPtr; old resources get freed, if there
- * were any. The menubutton is redisplayed.
+ * Configuration information, such as text string, colors, font, etc. get
+ * set for mbPtr; old resources get freed, if there were any. The
+ * menubutton is redisplayed.
*
*----------------------------------------------------------------------
*/
static int
-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 objc; /* Number of valid entries in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments. */
+ConfigureMenuButton(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ 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. */
{
Tk_SavedOptions savedOptions;
Tcl_Obj *errorResult = NULL;
@@ -501,21 +492,20 @@ ConfigureMenuButton(interp, mbPtr, objc, objv)
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);
}
/*
- * 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.
+ * 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.
*/
for (error = 0; error <= 1; error++) {
@@ -526,7 +516,7 @@ ConfigureMenuButton(interp, mbPtr, objc, objv)
if (Tk_SetOptions(interp, (char *) mbPtr,
mbPtr->optionTable, objc, objv,
- mbPtr->tkwin, &savedOptions, (int *) NULL) != TCL_OK) {
+ mbPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
continue;
}
} else {
@@ -541,8 +531,8 @@ ConfigureMenuButton(interp, mbPtr, objc, objv)
/*
* 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.
+ * background from a 3-D border, or filling in complicated defaults
+ * that couldn't be specified to Tk_SetOptions.
*/
if ((mbPtr->state == STATE_ACTIVE)
@@ -564,17 +554,17 @@ ConfigureMenuButton(interp, mbPtr, objc, objv)
}
/*
- * 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.
+ * 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->imageString != NULL) {
image = Tk_GetImage(mbPtr->interp, mbPtr->tkwin,
- mbPtr->imageString, MenuButtonImageProc,
+ mbPtr->imageString, MenuButtonImageProc,
(ClientData) mbPtr);
if (image == NULL) {
- return TCL_ERROR;
+ return TCL_ERROR;
}
} else {
image = NULL;
@@ -590,32 +580,32 @@ ConfigureMenuButton(interp, mbPtr, objc, objv)
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)");
+ &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)");
+ heightError:
+ Tcl_AddErrorInfo(interp, "\n (processing -height option)");
continue;
}
} else {
if (Tcl_GetInt(interp, mbPtr->widthString, &mbPtr->width)
!= TCL_OK) {
- goto widthError;
+ goto widthError;
}
if (Tcl_GetInt(interp, mbPtr->heightString, &mbPtr->height)
!= TCL_OK) {
- goto heightError;
+ goto heightError;
}
}
break;
}
if (!error) {
- Tk_FreeSavedOptions(&savedOptions);
+ Tk_FreeSavedOptions(&savedOptions);
}
if (mbPtr->textVarName != NULL) {
@@ -624,7 +614,7 @@ ConfigureMenuButton(interp, mbPtr, objc, objv)
* Set up a trace to watch for any changes in it, create the variable
* if it doesn't exist, and fetch its current value.
*/
- CONST char *value;
+ const char *value;
value = Tcl_GetVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY);
if (value == NULL) {
@@ -646,10 +636,9 @@ ConfigureMenuButton(interp, mbPtr, objc, objv)
if (error) {
Tcl_SetObjResult(interp, errorResult);
Tcl_DecrRefCount(errorResult);
- return TCL_ERROR;
- } else {
- return TCL_OK;
+ return TCL_ERROR;
}
+ return TCL_OK;
}
/*
@@ -657,22 +646,22 @@ ConfigureMenuButton(interp, mbPtr, objc, objv)
*
* TkMenuButtonWorldChanged --
*
- * This procedure is called when the world has changed in some
- * way and the widget needs to recompute all its graphics contexts
- * and determine its new geometry.
+ * This function is called when the world has changed in some way and the
+ * widget needs to recompute all its graphics contexts and determine its
+ * new geometry.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * TkMenuButton will be relayed out and redisplayed.
+ * TkMenuButton will be relayed out and redisplayed.
*
*---------------------------------------------------------------------------
*/
-
+
void
-TkMenuButtonWorldChanged(instanceData)
- ClientData instanceData; /* Information about widget. */
+TkMenuButtonWorldChanged(
+ ClientData instanceData) /* Information about widget. */
{
XGCValues gcValues;
GC gc;
@@ -686,9 +675,9 @@ TkMenuButtonWorldChanged(instanceData)
gcValues.background = Tk_3DBorderColor(mbPtr->normalBorder)->pixel;
/*
- * Note: GraphicsExpose events are disabled in GC's because they're
- * used to copy stuff from an off-screen pixmap onto the screen (we know
- * that there's no problem with obscured areas).
+ * Note: GraphicsExpose events are disabled in GC's because they're used
+ * to copy stuff from an off-screen pixmap onto the screen (we know that
+ * there's no problem with obscured areas).
*/
gcValues.graphics_exposures = False;
@@ -729,8 +718,8 @@ TkMenuButtonWorldChanged(instanceData)
}
/*
- * Allocate the disabled graphics context, for drawing text in
- * its disabled state.
+ * Allocate the disabled graphics context, for drawing text in its
+ * disabled state.
*/
mask = GCForeground | GCBackground | GCFont;
@@ -762,36 +751,36 @@ TkMenuButtonWorldChanged(instanceData)
*
* MenuButtonEventProc --
*
- * This procedure is invoked by the Tk dispatcher for various
- * events on buttons.
+ * This function is invoked by the Tk dispatcher for various events on
+ * buttons.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up.
+ * When it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-MenuButtonEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- XEvent *eventPtr; /* Information about event. */
+MenuButtonEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
TkMenuButton *mbPtr = (TkMenuButton *) clientData;
if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
goto redraw;
} else if (eventPtr->type == ConfigureNotify) {
/*
- * Must redraw after size changes, since layout could have changed
- * and borders will need to be redrawn.
+ * Must redraw after size changes, since layout could have changed and
+ * borders will need to be redrawn.
*/
goto redraw;
} else if (eventPtr->type == DestroyNotify) {
- DestroyMenuButton((char *) mbPtr);
+ DestroyMenuButton((char *) mbPtr);
} else if (eventPtr->type == FocusIn) {
if (eventPtr->xfocus.detail != NotifyInferior) {
mbPtr->flags |= GOT_FOCUS;
@@ -809,7 +798,7 @@ MenuButtonEventProc(clientData, eventPtr)
}
return;
- redraw:
+ redraw:
if ((mbPtr->tkwin != NULL) && !(mbPtr->flags & REDRAW_PENDING)) {
Tcl_DoWhenIdle(TkpDisplayMenuButton, (ClientData) mbPtr);
mbPtr->flags |= REDRAW_PENDING;
@@ -821,9 +810,9 @@ MenuButtonEventProc(clientData, eventPtr)
*
* MenuButtonCmdDeletedProc --
*
- * 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.
+ * This function 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.
@@ -835,17 +824,17 @@ MenuButtonEventProc(clientData, eventPtr)
*/
static void
-MenuButtonCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+MenuButtonCmdDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
TkMenuButton *mbPtr = (TkMenuButton *) clientData;
Tk_Window tkwin = mbPtr->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.
+ * This function 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 function destroys the
+ * widget.
*/
if (tkwin != NULL) {
@@ -858,8 +847,8 @@ MenuButtonCmdDeletedProc(clientData)
*
* MenuButtonTextVarProc --
*
- * This procedure is invoked when someone changes the variable
- * whose contents are to be displayed in a menu button.
+ * This function is invoked when someone changes the variable whose
+ * contents are to be displayed in a menu button.
*
* Results:
* NULL is always returned.
@@ -873,19 +862,20 @@ MenuButtonCmdDeletedProc(clientData)
/* ARGSUSED */
static char *
-MenuButtonTextVarProc(clientData, interp, name1, name2, flags)
- ClientData clientData; /* Information about button. */
- Tcl_Interp *interp; /* Interpreter containing variable. */
- CONST char *name1; /* Name of variable. */
- CONST char *name2; /* Second part of variable name. */
- int flags; /* Information about what happened. */
+MenuButtonTextVarProc(
+ ClientData clientData, /* Information about button. */
+ Tcl_Interp *interp, /* Interpreter containing variable. */
+ const char *name1, /* Name of variable. */
+ const char *name2, /* Second part of variable name. */
+ int flags) /* Information about what happened. */
{
register TkMenuButton *mbPtr = (TkMenuButton *) clientData;
- CONST char *value;
+ const char *value;
+ unsigned len;
/*
- * If the variable is unset, then immediately recreate it unless
- * the whole interpreter is going away.
+ * If the variable is unset, then immediately recreate it unless the whole
+ * interpreter is going away.
*/
if (flags & TCL_TRACE_UNSETS) {
@@ -896,7 +886,7 @@ MenuButtonTextVarProc(clientData, interp, name1, name2, flags)
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MenuButtonTextVarProc, clientData);
}
- return (char *) NULL;
+ return NULL;
}
value = Tcl_GetVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY);
@@ -906,8 +896,9 @@ MenuButtonTextVarProc(clientData, interp, name1, name2, flags)
if (mbPtr->text != NULL) {
ckfree(mbPtr->text);
}
- mbPtr->text = (char *) ckalloc((unsigned) (strlen(value) + 1));
- strcpy(mbPtr->text, value);
+ len = 1 + (unsigned) strlen(value);
+ mbPtr->text = (char *) ckalloc(len);
+ memcpy(mbPtr->text, value, len);
TkpComputeMenuButtonGeometry(mbPtr);
if ((mbPtr->tkwin != NULL) && Tk_IsMapped(mbPtr->tkwin)
@@ -915,7 +906,7 @@ MenuButtonTextVarProc(clientData, interp, name1, name2, flags)
Tcl_DoWhenIdle(TkpDisplayMenuButton, (ClientData) mbPtr);
mbPtr->flags |= REDRAW_PENDING;
}
- return (char *) NULL;
+ return NULL;
}
/*
@@ -923,9 +914,9 @@ MenuButtonTextVarProc(clientData, interp, name1, name2, flags)
*
* MenuButtonImageProc --
*
- * This procedure is invoked by the image code whenever the manager
- * for an image does something that affects the size of contents
- * of an image displayed in a button.
+ * This function is invoked by the image code whenever the manager for an
+ * image does something that affects the size of contents of an image
+ * displayed in a button.
*
* Results:
* None.
@@ -937,13 +928,13 @@ MenuButtonTextVarProc(clientData, interp, name1, name2, flags)
*/
static void
-MenuButtonImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
- ClientData clientData; /* Pointer to widget record. */
- int x, y; /* Upper left pixel (within image)
- * that must be redisplayed. */
- int width, height; /* Dimensions of area to redisplay
- * (may be <= 0). */
- int imgWidth, imgHeight; /* New dimensions of image. */
+MenuButtonImageProc(
+ ClientData clientData, /* Pointer to widget record. */
+ int x, int y, /* Upper left pixel (within image) that must
+ * be redisplayed. */
+ int width, int height, /* Dimensions of area to redisplay (may be <=
+ * 0). */
+ int imgWidth, int imgHeight)/* New dimensions of image. */
{
register TkMenuButton *mbPtr = (TkMenuButton *) clientData;
@@ -955,3 +946,11 @@ MenuButtonImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
}
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkMenubutton.h b/generic/tkMenubutton.h
index 7e36fe6..41af675 100644
--- a/generic/tkMenubutton.h
+++ b/generic/tkMenubutton.h
@@ -1,13 +1,13 @@
/*
* tkMenubutton.h --
*
- * Declarations of types and functions used to implement
- * the menubutton widget.
+ * Declarations of types and functions used to implement the menubutton
+ * widget.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKMENUBUTTON
@@ -31,7 +31,7 @@
*/
enum direction {
- DIRECTION_ABOVE, DIRECTION_BELOW, DIRECTION_FLUSH,
+ DIRECTION_ABOVE, DIRECTION_BELOW, DIRECTION_FLUSH,
DIRECTION_LEFT, DIRECTION_RIGHT
};
@@ -44,16 +44,16 @@ enum state {
};
/*
- * A data structure of the following type is kept for each
- * widget managed by this file:
+ * A data structure of the following type is kept for each widget managed by
+ * this file:
*/
typedef struct {
- Tk_Window tkwin; /* Window that embodies the widget. NULL
- * means that the window has been destroyed
- * but the data structures haven't yet been
- * cleaned up.*/
- Display *display; /* Display containing widget. Needed, among
+ Tk_Window tkwin; /* Window that embodies the widget. NULL means
+ * that the window has been destroyed but the
+ * data structures haven't yet been cleaned
+ * up. */
+ Display *display; /* Display containing widget. Needed, among
* other things, so that resources can bee
* freed up even after tkwin has gone away. */
Tcl_Interp *interp; /* Interpreter associated with menubutton. */
@@ -67,17 +67,17 @@ typedef struct {
* Information about what's displayed in the menu button:
*/
- char *text; /* Text to display in button (malloc'ed)
- * or NULL. */
+ char *text; /* Text to display in button (malloc'ed) or
+ * NULL. */
int underline; /* Index of character to underline. */
- 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 and underline
- * are ignored. */
+ 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 and underline are
+ * ignored. */
char *imageString; /* Name of image to display (malloc'ed), or
- * NULL. If non-NULL, bitmap, text, and
+ * NULL. If non-NULL, bitmap, text, and
* textVarName are ignored. */
Tk_Image image; /* Image to display in window, or NULL if
* none. */
@@ -86,115 +86,113 @@ typedef struct {
* Information used when displaying widget:
*/
- enum state 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
- * 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. */
+ 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.
- * <= 0 means don't draw a highlight. */
- XColor *highlightBgColorPtr;
- /* Color for drawing traversal highlight
- * area when highlight is off. */
+ 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. */
XColor *highlightColorPtr; /* 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. */
+ * 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
- * means use normalFg with a 50% stipple
- * instead. */
+ XColor *activeFg; /* Foreground color in active mode. NULL means
+ * use normalFg instead. */
+ XColor *disabledFg; /* Foreground color when disabled. NULL means
+ * use normalFg with a 50% stipple instead. */
GC normalTextGC; /* GC for drawing text in normal mode. */
GC activeTextGC; /* GC for drawing text in active mode (NULL
* means use normalTextGC). */
Pixmap gray; /* Pixmap for displaying disabled text/icon if
* disabledFg is NULL. */
- GC disabledGC; /* Used to produce disabled effect for text. */
- GC stippleGC; /* Used to produce disabled stipple effect
- * for images when disabled. */
+ GC disabledGC; /* Used to produce disabled effect for
+ * text. */
+ GC stippleGC; /* Used to produce disabled stipple effect for
+ * images when disabled. */
int leftBearing; /* Distance from text origin to leftmost drawn
* pixel (positive means to right). */
- int rightBearing; /* Amount text sticks right from its origin. */
- char *widthString; /* Value of -width option. Malloc'ed. */
- char *heightString; /* Value of -height option. Malloc'ed. */
+ int rightBearing; /* Amount text sticks right from its
+ * origin. */
+ 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
+ * pixels for bitmaps. In this case the actual
* size of the text string or bitmap is
- * ignored in computing desired window size. */
+ * ignored in computing desired window
+ * size. */
int wrapLength; /* Line length (in pixels) at which to wrap
- * onto next line. <= 0 means don't wrap
+ * onto next line. <= 0 means don't wrap
* except at newlines. */
int padX, padY; /* Extra space around text or bitmap (pixels
* on each side). */
Tk_Anchor anchor; /* Where text/bitmap should be displayed
* inside window region. */
- Tk_Justify justify; /* Justification to use for multi-line text. */
+ Tk_Justify justify; /* Justification to use for multi-line
+ * text. */
int textWidth; /* Width needed to display text as requested,
* in pixels. */
int textHeight; /* Height needed to display text as requested,
* in pixels. */
Tk_TextLayout textLayout; /* Saved text layout information. */
- int indicatorOn; /* Non-zero means display indicator; 0 means
+ int indicatorOn; /* Non-zero means display indicator; 0 means
* don't display. */
- int indicatorHeight; /* Height of indicator in pixels. This same
+ int indicatorHeight; /* Height of indicator in pixels. This same
* amount of extra space is also left on each
- * side of the indicator. 0 if no indicator. */
+ * side of the indicator. 0 if no
+ * indicator. */
int indicatorWidth; /* Width of indicator in pixels, including
- * indicatorHeight in padding on each side.
- * 0 if no indicator. */
+ * indicatorHeight in padding on each side. 0
+ * if no indicator. */
/*
* Miscellaneous information:
*/
- int compound; /* Value of -compound option; specifies whether
- * the menubutton should show both an image and
- * text, and, if so, how. */
-
- 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
- * menubutton is where the menu pops up.
- * "above" and "below" will attempt to pop
- * the menu compleletly above or below
- * the menu respectively.
- * "left" and "right" will pop the menu
- * left or right, and the active item
- * will be next to the button. */
+ int compound; /* Value of -compound option; specifies
+ * whether the menubutton should show both an
+ * image and text, and, if so, how. */
+ 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 menubutton is
+ * where the menu pops up. "above" and "below"
+ * will attempt to pop the menu compleletly
+ * above or below the menu respectively.
+ * "left" and "right" will pop the menu left
+ * or right, and the active item will be next
+ * to the button. */
Tk_Cursor cursor; /* Current cursor for window, or None. */
- char *takeFocus; /* Value of -takefocus option; not used in
- * the C code, but used by keyboard traversal
- * scripts. Malloc'ed, but may be NULL. */
- int flags; /* Various flags; see below for
+ char *takeFocus; /* Value of -takefocus option; not used in the
+ * C code, but used by keyboard traversal
+ * scripts. Malloc'ed, but may be NULL. */
+ int flags; /* Various flags; see below for
* definitions. */
} TkMenuButton;
/*
* Flag bits for buttons:
*
- * REDRAW_PENDING: Non-zero means a DoWhenIdle handler
- * has already been queued to redraw
- * this window.
- * POSTED: Non-zero means that the menu associated
- * with this button has been posted (typically
- * because of an active button press).
- * GOT_FOCUS: Non-zero means this button currently
- * has the input focus.
+ * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has
+ * already been queued to redraw this window.
+ * POSTED: Non-zero means that the menu associated with
+ * this button has been posted (typically because
+ * of an active button press).
+ * GOT_FOCUS: Non-zero means this button currently has the
+ * input focus.
*/
#define REDRAW_PENDING 1
@@ -203,7 +201,7 @@ typedef struct {
/*
* The following constants define the dimensions of the cascade indicator,
- * which is displayed if the "-indicatoron" option is true. The units for
+ * which is displayed if the "-indicatoron" option is true. The units for
* these options are 1/10 millimeters.
*/
@@ -214,22 +212,17 @@ typedef struct {
* Declaration of variables shared between the files in the button module.
*/
-extern Tk_ClassProcs tkpMenubuttonClass;
+MODULE_SCOPE Tk_ClassProcs tkpMenubuttonClass;
/*
- * Declaration of procedures used in the implementation of the button
- * widget.
+ * Declaration of procedures used in the implementation of the button widget.
*/
-EXTERN void TkpComputeMenuButtonGeometry _ANSI_ARGS_((
- TkMenuButton *mbPtr));
-EXTERN TkMenuButton * TkpCreateMenuButton _ANSI_ARGS_((Tk_Window tkwin));
-EXTERN void TkpDisplayMenuButton _ANSI_ARGS_((
- ClientData clientData));
-EXTERN void TkpDestroyMenuButton _ANSI_ARGS_((
- TkMenuButton *mbPtr));
-EXTERN void TkMenuButtonWorldChanged _ANSI_ARGS_((
- ClientData instanceData));
+MODULE_SCOPE void TkpComputeMenuButtonGeometry(TkMenuButton *mbPtr);
+MODULE_SCOPE TkMenuButton *TkpCreateMenuButton(Tk_Window tkwin);
+MODULE_SCOPE void TkpDisplayMenuButton(ClientData clientData);
+MODULE_SCOPE void TkpDestroyMenuButton(TkMenuButton *mbPtr);
+MODULE_SCOPE void TkMenuButtonWorldChanged(ClientData instanceData);
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLIMPORT
diff --git a/generic/tkMessage.c b/generic/tkMessage.c
index 0b3f36d..0fd57a9 100644
--- a/generic/tkMessage.c
+++ b/generic/tkMessage.c
@@ -1,35 +1,34 @@
-/*
+/*
* tkMessage.c --
*
- * This module implements a message widgets for the Tk
- * toolkit. A message widget displays a multi-line string
- * in a window according to a particular aspect ratio.
+ * This module implements a message widgets for the Tk toolkit. A message
+ * widget displays a multi-line string in a window according to a
+ * particular aspect ratio.
*
* Copyright (c) 1990-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
* Copyright (c) 1998-2000 by Ajuba Solutions.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "default.h"
#include "tkInt.h"
/*
- * A data structure of the following type is kept for each message
- * widget managed by this file:
+ * A data structure of the following type is kept for each message widget
+ * managed by this file:
*/
typedef struct {
- Tk_Window tkwin; /* Window that embodies the message. NULL
+ Tk_Window tkwin; /* Window that embodies the message. NULL
* means that the window has been destroyed
* but the data structures haven't yet been
* cleaned up.*/
Tk_OptionTable optionTable; /* Table that defines options available for
* this widget. */
- Display *display; /* Display containing widget. Used, among
+ Display *display; /* Display containing widget. Used, among
* other things, so that resources can be
* freed even after tkwin has gone away. */
Tcl_Interp *interp; /* Interpreter associated with message. */
@@ -46,8 +45,8 @@ typedef struct {
* If non-NULL, message displays the contents
* of this variable. */
Tk_3DBorder border; /* Structure used to draw 3-D border and
- * background. NULL means a border hasn't
- * been created yet. */
+ * background. NULL means a border hasn't been
+ * created yet. */
int borderWidth; /* Width of border. */
int relief; /* 3-D effect: TK_RELIEF_RAISED, etc. */
int highlightWidth; /* Width in pixels of highlight to draw
@@ -61,7 +60,7 @@ typedef struct {
XColor *fgColorPtr; /* Foreground color in normal mode. */
Tcl_Obj *padXPtr, *padYPtr; /* Tcl_Obj rep's of padX, padY values. */
int padX, padY; /* User-requested extra space around text. */
- int width; /* User-requested width, in pixels. 0 means
+ int width; /* User-requested width, in pixels. 0 means
* compute width using aspect ratio below. */
int aspect; /* Desired aspect ratio for window
* (100*width/height). */
@@ -82,10 +81,10 @@ typedef struct {
*/
Tk_Cursor cursor; /* Current cursor for window, or None. */
- char *takeFocus; /* Value of -takefocus option; not used in
- * the C code, but used by keyboard traversal
- * scripts. Malloc'ed, but may be NULL. */
- int flags; /* Various flags; see below for
+ char *takeFocus; /* Value of -takefocus option; not used in the
+ * C code, but used by keyboard traversal
+ * scripts. Malloc'ed, but may be NULL. */
+ int flags; /* Various flags; see below for
* definitions. */
} Message;
@@ -108,7 +107,7 @@ typedef struct {
* Information used for argv parsing.
*/
-static CONST Tk_OptionSpec optionSpecs[] = {
+static const Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", DEF_MESSAGE_ANCHOR,
-1, Tk_Offset(Message, anchor), 0, 0, 0},
{TK_OPTION_INT, "-aspect", "aspect", "Aspect", DEF_MESSAGE_ASPECT,
@@ -116,9 +115,9 @@ static CONST Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_BORDER, "-background", "background", "Background",
DEF_MESSAGE_BG_COLOR, -1, Tk_Offset(Message, border), 0,
(ClientData) DEF_MESSAGE_BG_MONO, 0},
- {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL, (char *) NULL,
+ {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL,
0, -1, 0, (ClientData) "-borderwidth", 0},
- {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, (char *) NULL,
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL,
0, -1, 0, (ClientData) "-background", 0},
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
DEF_MESSAGE_BORDER_WIDTH, -1,
@@ -126,7 +125,7 @@ static CONST Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
DEF_MESSAGE_CURSOR, -1, Tk_Offset(Message, cursor),
TK_OPTION_NULL_OK, 0, 0},
- {TK_OPTION_SYNONYM, "-fg", (char *) NULL, (char *) NULL, (char *) NULL,
+ {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL,
0, -1, 0, (ClientData) "-foreground", 0},
{TK_OPTION_FONT, "-font", "font", "Font",
DEF_MESSAGE_FONT, -1, Tk_Offset(Message, tkfont), 0, 0, 0},
@@ -161,35 +160,31 @@ static CONST Tk_OptionSpec optionSpecs[] = {
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-width", "width", "Width",
DEF_MESSAGE_WIDTH, -1, Tk_Offset(Message, width), 0, 0 ,0},
- {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0, 0, 0}
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0}
};
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static void MessageCmdDeletedProc _ANSI_ARGS_((
- ClientData clientData));
-static void MessageEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static char * MessageTextVarProc _ANSI_ARGS_((ClientData clientData,
+static void MessageCmdDeletedProc(ClientData clientData);
+static void MessageEventProc(ClientData clientData,
+ XEvent *eventPtr);
+static char * MessageTextVarProc(ClientData clientData,
Tcl_Interp *interp, CONST char *name1,
- CONST char *name2, int flags));
-static int MessageWidgetObjCmd _ANSI_ARGS_((ClientData clientData,
+ CONST char *name2, int flags);
+static int MessageWidgetObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static void MessageWorldChanged _ANSI_ARGS_((
- ClientData instanceData));
-static void ComputeMessageGeometry _ANSI_ARGS_((Message *msgPtr));
-static int ConfigureMessage _ANSI_ARGS_((Tcl_Interp *interp,
- Message *msgPtr, int objc, Tcl_Obj *CONST objv[],
- int flags));
-static void DestroyMessage _ANSI_ARGS_((char *memPtr));
-static void DisplayMessage _ANSI_ARGS_((ClientData clientData));
+ Tcl_Obj *CONST objv[]);
+static void MessageWorldChanged(ClientData instanceData);
+static void ComputeMessageGeometry(Message *msgPtr);
+static int ConfigureMessage(Tcl_Interp *interp, Message *msgPtr,
+ int objc, Tcl_Obj *CONST objv[], int flags);
+static void DestroyMessage(char *memPtr);
+static void DisplayMessage(ClientData clientData);
/*
- * The structure below defines message class behavior by means of procedures
+ * The structure below defines message class behavior by means of functions
* that can be invoked from generic window code.
*/
@@ -197,16 +192,14 @@ static Tk_ClassProcs messageClass = {
sizeof(Tk_ClassProcs), /* size */
MessageWorldChanged, /* worldChangedProc */
};
-
/*
*--------------------------------------------------------------
*
* Tk_MessageObjCmd --
*
- * This procedure is invoked to process the "message" Tcl
- * command. See the user documentation for details on what
- * it does.
+ * This function is invoked to process the "message" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -218,11 +211,11 @@ static Tk_ClassProcs messageClass = {
*/
int
-Tk_MessageObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* NULL. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument strings. */
+Tk_MessageObjCmd(
+ ClientData clientData, /* NULL. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument strings. */
{
register Message *msgPtr;
Tk_OptionTable optionTable;
@@ -234,14 +227,14 @@ Tk_MessageObjCmd(clientData, interp, objc, objv)
}
tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
- Tcl_GetString(objv[1]), (char *) NULL);
+ Tcl_GetString(objv[1]), NULL);
if (tkwin == NULL) {
return TCL_ERROR;
}
/*
- * Create the option table for this widget class. If it has already
- * been created, the cached pointer will be returned.
+ * Create the option table for this widget class. If it has already been
+ * created, the cached pointer will be returned.
*/
optionTable = Tk_CreateOptionTable(interp, optionSpecs);
@@ -252,19 +245,20 @@ Tk_MessageObjCmd(clientData, interp, objc, objv)
/*
* Set values for those fields that don't take a 0 or NULL value.
*/
- msgPtr->tkwin = tkwin;
- msgPtr->display = Tk_Display(tkwin);
- msgPtr->interp = interp;
- msgPtr->widgetCmd = Tcl_CreateObjCommand(interp,
+
+ msgPtr->tkwin = tkwin;
+ msgPtr->display = Tk_Display(tkwin);
+ msgPtr->interp = interp;
+ msgPtr->widgetCmd = Tcl_CreateObjCommand(interp,
Tk_PathName(msgPtr->tkwin), MessageWidgetObjCmd,
(ClientData) msgPtr, MessageCmdDeletedProc);
- msgPtr->optionTable = optionTable;
- msgPtr->relief = TK_RELIEF_FLAT;
- msgPtr->textGC = None;
- msgPtr->anchor = TK_ANCHOR_CENTER;
- msgPtr->aspect = 150;
- msgPtr->justify = TK_JUSTIFY_LEFT;
- msgPtr->cursor = None;
+ msgPtr->optionTable = optionTable;
+ msgPtr->relief = TK_RELIEF_FLAT;
+ msgPtr->textGC = None;
+ msgPtr->anchor = TK_ANCHOR_CENTER;
+ msgPtr->aspect = 150;
+ msgPtr->justify = TK_JUSTIFY_LEFT;
+ msgPtr->cursor = None;
Tk_SetClass(msgPtr->tkwin, "Message");
Tk_SetClassProcs(msgPtr->tkwin, &messageClass, (ClientData) msgPtr);
@@ -290,9 +284,9 @@ Tk_MessageObjCmd(clientData, interp, objc, objv)
*
* MessageWidgetObjCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to a widget managed by this module.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the Tcl command that corresponds
+ * to a widget managed by this module. See the user documentation for
+ * details on what it does.
*
* Results:
* A standard Tcl result.
@@ -304,19 +298,19 @@ Tk_MessageObjCmd(clientData, interp, objc, objv)
*/
static int
-MessageWidgetObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Information about message widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument strings. */
+MessageWidgetObjCmd(
+ ClientData clientData, /* Information about message widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument strings. */
{
register Message *msgPtr = (Message *) clientData;
- static CONST char *optionStrings[] = { "cget", "configure", (char *) NULL };
+ static CONST char *optionStrings[] = { "cget", "configure", NULL };
enum options { MESSAGE_CGET, MESSAGE_CONFIGURE };
int index;
int result = TCL_OK;
Tcl_Obj *objPtr;
-
+
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
return TCL_ERROR;
@@ -328,43 +322,40 @@ MessageWidgetObjCmd(clientData, interp, objc, objv)
}
Tcl_Preserve((ClientData) msgPtr);
-
+
switch ((enum options) index) {
- case MESSAGE_CGET: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "option");
+ case MESSAGE_CGET:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option");
+ result = TCL_ERROR;
+ } else {
+ objPtr = Tk_GetOptionValue(interp, (char *) msgPtr,
+ msgPtr->optionTable, objv[2], msgPtr->tkwin);
+ if (objPtr == NULL) {
result = TCL_ERROR;
} else {
- objPtr = Tk_GetOptionValue(interp, (char *) msgPtr,
- msgPtr->optionTable, objv[2], msgPtr->tkwin);
- if (objPtr == NULL) {
- result = TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, objPtr);
- result = TCL_OK;
- }
+ Tcl_SetObjResult(interp, objPtr);
+ result = TCL_OK;
}
- break;
}
- case MESSAGE_CONFIGURE: {
- if (objc <= 3) {
- objPtr = Tk_GetOptionInfo(interp, (char *) msgPtr,
- msgPtr->optionTable,
- (objc == 3) ? objv[2] : (Tcl_Obj *) NULL,
- msgPtr->tkwin);
- if (objPtr == NULL) {
- result = TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, objPtr);
- result = TCL_OK;
- }
+ break;
+ case MESSAGE_CONFIGURE:
+ if (objc <= 3) {
+ objPtr = Tk_GetOptionInfo(interp, (char *) msgPtr,
+ msgPtr->optionTable, (objc == 3) ? objv[2] : NULL,
+ msgPtr->tkwin);
+ if (objPtr == NULL) {
+ result = TCL_ERROR;
} else {
- result = ConfigureMessage(interp, msgPtr, objc-2, objv+2, 0);
+ Tcl_SetObjResult(interp, objPtr);
+ result = TCL_OK;
}
- break;
+ } else {
+ result = ConfigureMessage(interp, msgPtr, objc-2, objv+2, 0);
}
+ break;
}
-
+
Tcl_Release((ClientData) msgPtr);
return result;
}
@@ -374,9 +365,9 @@ MessageWidgetObjCmd(clientData, interp, objc, objv)
*
* DestroyMessage --
*
- * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release
- * to clean up the internal structure of a message at a safe time
- * (when no-one is using it anymore).
+ * This function is invoked by Tcl_EventuallyFree or Tcl_Release to clean
+ * up the internal structure of a message at a safe time (when no-one is
+ * using it anymore).
*
* Results:
* None.
@@ -388,8 +379,8 @@ MessageWidgetObjCmd(clientData, interp, objc, objv)
*/
static void
-DestroyMessage(memPtr)
- char *memPtr; /* Info about message widget. */
+DestroyMessage(
+ char *memPtr) /* Info about message widget. */
{
register Message *msgPtr = (Message *) memPtr;
@@ -399,11 +390,10 @@ DestroyMessage(memPtr)
if (msgPtr->flags & REDRAW_PENDING) {
Tcl_CancelIdleCall(DisplayMessage, (ClientData) msgPtr);
}
-
+
/*
- * Free up all the stuff that requires special handling, then
- * let Tk_FreeConfigOptions handle all the standard option-related
- * stuff.
+ * Free up all the stuff that requires special handling, then let
+ * Tk_FreeConfigOptions handle all the standard option-related stuff.
*/
if (msgPtr->textGC != None) {
@@ -427,30 +417,29 @@ DestroyMessage(memPtr)
*
* ConfigureMessage --
*
- * This procedure is called to process an argv/argc list, plus
- * the Tk option database, in order to configure (or
- * reconfigure) a message widget.
+ * This function is called to process an argv/argc list, plus the Tk
+ * option database, in order to configure (or reconfigure) a message
+ * widget.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message.
+ * 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 text string, colors, font,
- * etc. get set for msgPtr; old resources get freed, if there
- * were any.
+ * Configuration information, such as text string, colors, font, etc. get
+ * set for msgPtr; old resources get freed, if there were any.
*
*----------------------------------------------------------------------
*/
static int
-ConfigureMessage(interp, msgPtr, objc, objv, flags)
- Tcl_Interp *interp; /* Used for error reporting. */
- register Message *msgPtr; /* Information about widget; may or may
- * not already have values for some fields. */
- int objc; /* Number of valid entries in argv. */
- Tcl_Obj *CONST objv[]; /* Arguments. */
- int flags; /* Flags to pass to Tk_ConfigureWidget. */
+ConfigureMessage(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ register Message *msgPtr, /* Information about widget; may or may not
+ * already have values for some fields. */
+ int objc, /* Number of valid entries in argv. */
+ Tcl_Obj *CONST objv[], /* Arguments. */
+ int flags) /* Flags to pass to Tk_ConfigureWidget. */
{
Tk_SavedOptions savedOptions;
@@ -459,22 +448,21 @@ ConfigureMessage(interp, msgPtr, objc, objv, flags)
*/
if (msgPtr->textVarName != NULL) {
- Tcl_UntraceVar(interp, msgPtr->textVarName,
+ Tcl_UntraceVar(interp, msgPtr->textVarName,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MessageTextVarProc, (ClientData) msgPtr);
}
if (Tk_SetOptions(interp, (char *) msgPtr, msgPtr->optionTable, objc, objv,
- msgPtr->tkwin, &savedOptions, (int *)NULL) != TCL_OK) {
+ msgPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
Tk_RestoreSavedOptions(&savedOptions);
return TCL_ERROR;
}
-
-
+
/*
- * If the message is to display the value of a variable, then set up
- * a trace on the variable's value, create the variable if it doesn't
- * exist, and fetch its current value.
+ * If the message is to display the value of a variable, then set up a
+ * trace on the variable's value, create the variable if it doesn't exist,
+ * and fetch its current value.
*/
if (msgPtr->textVarName != NULL) {
@@ -496,9 +484,9 @@ ConfigureMessage(interp, msgPtr, objc, objv, flags)
}
/*
- * A few other options need special processing, such as setting
- * the background from a 3-D border or handling special defaults
- * that couldn't be specified to Tk_ConfigureWidget.
+ * A few other options need special processing, such as setting the
+ * background from a 3-D border or handling special defaults that couldn't
+ * be specified to Tk_ConfigureWidget.
*/
msgPtr->numChars = Tcl_NumUtfChars(msgPtr->string, -1);
@@ -517,22 +505,22 @@ ConfigureMessage(interp, msgPtr, objc, objv, flags)
*
* MessageWorldChanged --
*
- * This procedure is called when the world has changed in some
- * way and the widget needs to recompute all its graphics contexts
- * and determine its new geometry.
+ * This function is called when the world has changed in some way and the
+ * widget needs to recompute all its graphics contexts and determine its
+ * new geometry.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Message will be relayed out and redisplayed.
+ * Message will be relayed out and redisplayed.
*
*---------------------------------------------------------------------------
*/
-
+
static void
-MessageWorldChanged(instanceData)
- ClientData instanceData; /* Information about widget. */
+MessageWorldChanged(
+ ClientData instanceData) /* Information about widget. */
{
XGCValues gcValues;
GC gc = None;
@@ -562,8 +550,8 @@ MessageWorldChanged(instanceData)
}
/*
- * Recompute the desired geometry for the window, and arrange for
- * the window to be redisplayed.
+ * Recompute the desired geometry for the window, and arrange for the
+ * window to be redisplayed.
*/
ComputeMessageGeometry(msgPtr);
@@ -579,23 +567,22 @@ MessageWorldChanged(instanceData)
*
* ComputeMessageGeometry --
*
- * Compute the desired geometry for a message window,
- * taking into account the desired aspect ratio for the
- * window.
+ * Compute the desired geometry for a message window, taking into account
+ * the desired aspect ratio for the window.
*
* Results:
* None.
*
* Side effects:
- * Tk_GeometryRequest is called to inform the geometry
- * manager of the desired geometry for this window.
+ * Tk_GeometryRequest is called to inform the geometry manager of the
+ * desired geometry for this window.
*
*--------------------------------------------------------------
*/
static void
-ComputeMessageGeometry(msgPtr)
- register Message *msgPtr; /* Information about window. */
+ComputeMessageGeometry(
+ register Message *msgPtr) /* Information about window. */
{
int width, inc, height;
int thisWidth, thisHeight, maxWidth;
@@ -617,12 +604,11 @@ ComputeMessageGeometry(msgPtr)
upperBound = msgPtr->aspect + aspect;
/*
- * Do the computation in multiple passes: start off with
- * a very wide window, and compute its height. Then change
- * the width and try again. Reduce the size of the change
- * and iterate until dimensions are found that approximate
- * the desired aspect ratio. Or, if the user gave an explicit
- * width then just use that.
+ * Do the computation in multiple passes: start off with a very wide
+ * window, and compute its height. Then change the width and try again.
+ * Reduce the size of the change and iterate until dimensions are found
+ * that approximate the desired aspect ratio. Or, if the user gave an
+ * explicit width then just use that.
*/
if (msgPtr->width > 0) {
@@ -665,7 +651,7 @@ ComputeMessageGeometry(msgPtr)
*
* DisplayMessage --
*
- * This procedure redraws the contents of a message window.
+ * This function redraws the contents of a message window.
*
* Results:
* None.
@@ -677,8 +663,8 @@ ComputeMessageGeometry(msgPtr)
*/
static void
-DisplayMessage(clientData)
- ClientData clientData; /* Information about window. */
+DisplayMessage(
+ ClientData clientData) /* Information about window. */
{
register Message *msgPtr = (Message *) clientData;
register Tk_Window tkwin = msgPtr->tkwin;
@@ -702,8 +688,8 @@ DisplayMessage(clientData)
0, TK_RELIEF_FLAT);
/*
- * Compute starting y-location for message based on message size
- * and anchor option.
+ * Compute starting y-location for message based on message size and
+ * anchor option.
*/
TkComputeAnchor(msgPtr->anchor, tkwin, msgPtr->padX, msgPtr->padY,
@@ -723,7 +709,7 @@ DisplayMessage(clientData)
bgGC = Tk_GCForColor(msgPtr->highlightBgColorPtr, Tk_WindowId(tkwin));
if (msgPtr->flags & GOT_FOCUS) {
- fgGC = Tk_GCForColor(msgPtr->highlightColorPtr, Tk_WindowId(tkwin));
+ fgGC = Tk_GCForColor(msgPtr->highlightColorPtr,Tk_WindowId(tkwin));
TkpDrawHighlightBorder(tkwin, fgGC, bgGC, msgPtr->highlightWidth,
Tk_WindowId(tkwin));
} else {
@@ -738,23 +724,23 @@ DisplayMessage(clientData)
*
* MessageEventProc --
*
- * This procedure is invoked by the Tk dispatcher for various
- * events on messages.
+ * This function is invoked by the Tk dispatcher for various events on
+ * messages.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up.
+ * When it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-MessageEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- XEvent *eventPtr; /* Information about event. */
+MessageEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
Message *msgPtr = (Message *) clientData;
@@ -780,7 +766,7 @@ MessageEventProc(clientData, eventPtr)
}
return;
- redraw:
+ redraw:
if ((msgPtr->tkwin != NULL) && !(msgPtr->flags & REDRAW_PENDING)) {
Tcl_DoWhenIdle(DisplayMessage, (ClientData) msgPtr);
msgPtr->flags |= REDRAW_PENDING;
@@ -792,9 +778,9 @@ MessageEventProc(clientData, eventPtr)
*
* MessageCmdDeletedProc --
*
- * 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.
+ * This function 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.
@@ -806,16 +792,16 @@ MessageEventProc(clientData, eventPtr)
*/
static void
-MessageCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+MessageCmdDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
Message *msgPtr = (Message *) clientData;
/*
- * 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.
+ * This function 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 function destroys the
+ * widget.
*/
if (!(msgPtr->flags & MESSAGE_DELETED)) {
@@ -828,34 +814,33 @@ MessageCmdDeletedProc(clientData)
*
* MessageTextVarProc --
*
- * This procedure is invoked when someone changes the variable
- * whose contents are to be displayed in a message.
+ * This function is invoked when someone changes the variable whose
+ * contents are to be displayed in a message.
*
* Results:
* NULL is always returned.
*
* Side effects:
- * The text displayed in the message will change to match the
- * variable.
+ * The text displayed in the message will change to match the variable.
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static char *
-MessageTextVarProc(clientData, interp, name1, name2, flags)
- ClientData clientData; /* Information about message. */
- Tcl_Interp *interp; /* Interpreter containing variable. */
- CONST char *name1; /* Name of variable. */
- CONST char *name2; /* Second part of variable name. */
- int flags; /* Information about what happened. */
+MessageTextVarProc(
+ ClientData clientData, /* Information about message. */
+ Tcl_Interp *interp, /* Interpreter containing variable. */
+ CONST char *name1, /* Name of variable. */
+ CONST char *name2, /* Second part of variable name. */
+ int flags) /* Information about what happened. */
{
register Message *msgPtr = (Message *) clientData;
CONST char *value;
/*
- * If the variable is unset, then immediately recreate it unless
- * the whole interpreter is going away.
+ * If the variable is unset, then immediately recreate it unless the whole
+ * interpreter is going away.
*/
if (flags & TCL_TRACE_UNSETS) {
@@ -866,7 +851,7 @@ MessageTextVarProc(clientData, interp, name1, name2, flags)
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MessageTextVarProc, clientData);
}
- return (char *) NULL;
+ return NULL;
}
value = Tcl_GetVar(interp, msgPtr->textVarName, TCL_GLOBAL_ONLY);
@@ -886,5 +871,13 @@ MessageTextVarProc(clientData, interp, name1, name2, flags)
Tcl_DoWhenIdle(DisplayMessage, (ClientData) msgPtr);
msgPtr->flags |= REDRAW_PENDING;
}
- return (char *) NULL;
+ return NULL;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkObj.c b/generic/tkObj.c
index 291c70d..7672240 100644
--- a/generic/tkObj.c
+++ b/generic/tkObj.c
@@ -1,13 +1,12 @@
-/*
+/*
* tkObj.c --
*
- * This file contains procedures that implement the common Tk object
- * types
+ * This file contains functions 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
@@ -15,7 +14,7 @@
/*
* The following structure is the internal representation for pixel objects.
*/
-
+
typedef struct PixelRep {
double value;
int units;
@@ -27,11 +26,11 @@ typedef struct PixelRep {
((objPtr)->internalRep.twoPtrValue.ptr2 == 0)
#define SET_SIMPLEPIXEL(objPtr, intval) \
- (objPtr)->internalRep.twoPtrValue.ptr1 = (VOID *) (intval); \
+ (objPtr)->internalRep.twoPtrValue.ptr1 = INT2PTR(intval); \
(objPtr)->internalRep.twoPtrValue.ptr2 = 0
#define GET_SIMPLEPIXEL(objPtr) \
- ((int) (objPtr)->internalRep.twoPtrValue.ptr1)
+ (PTR2INT((objPtr)->internalRep.twoPtrValue.ptr1))
#define SET_COMPLEXPIXEL(objPtr, repPtr) \
(objPtr)->internalRep.twoPtrValue.ptr1 = 0; \
@@ -40,11 +39,24 @@ typedef struct PixelRep {
#define GET_COMPLEXPIXEL(objPtr) \
((PixelRep *) (objPtr)->internalRep.twoPtrValue.ptr2)
+/*
+ * One of these structures is created per thread to store thread-specific
+ * data. In this case, it is used to contain references to selected
+ * Tcl_ObjTypes that we can use as screen distances without conversion. The
+ * "dataKey" below is used to locate the ThreadSpecificData for the current
+ * thread.
+ */
+
+typedef struct ThreadSpecificData {
+ const Tcl_ObjType *doubleTypePtr;
+ const Tcl_ObjType *intTypePtr;
+} ThreadSpecificData;
+static Tcl_ThreadDataKey dataKey;
/*
* The following structure is the internal representation for mm objects.
*/
-
+
typedef struct MMRep {
double value;
int units;
@@ -54,41 +66,37 @@ typedef struct MMRep {
/*
* The following structure is the internal representation for window objects.
- * A WindowRep caches name-to-window lookups. The cache is invalid
- * if tkwin is NULL or if mainPtr->deletionEpoch does not match epoch.
+ * A WindowRep caches name-to-window lookups. The cache is invalid if tkwin is
+ * NULL or if mainPtr->deletionEpoch does not match epoch.
*/
+
typedef struct WindowRep {
- Tk_Window tkwin; /* Cached window; NULL if not found */
- TkMainInfo *mainPtr; /* MainWindow associated with tkwin */
+ Tk_Window tkwin; /* Cached window; NULL if not found. */
+ TkMainInfo *mainPtr; /* MainWindow associated with tkwin. */
long epoch; /* Value of mainPtr->deletionEpoch at last
- * successful lookup. */
+ * successful lookup. */
} WindowRep;
/*
- * Prototypes for procedures defined later in this file:
+ * Prototypes for functions 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 DupWindowInternalRep _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 void FreeWindowInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr));
-static void UpdateStringOfMM _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));
+static void DupMMInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
+static void DupPixelInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
+static void DupWindowInternalRep(Tcl_Obj *srcPtr,Tcl_Obj *copyPtr);
+static void FreeMMInternalRep(Tcl_Obj *objPtr);
+static void FreePixelInternalRep(Tcl_Obj *objPtr);
+static void FreeWindowInternalRep(Tcl_Obj *objPtr);
+static ThreadSpecificData *GetTypeCache(void);
+static void UpdateStringOfMM(Tcl_Obj *objPtr);
+static int SetMMFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static int SetPixelFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static int SetWindowFromAny(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.
+ * 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 = {
@@ -100,9 +108,9 @@ static Tcl_ObjType pixelObjType = {
};
/*
- * The following structure defines the implementation of the "pixel"
- * Tcl object, used for measuring distances. The pixel object remembers
- * its initial display-independant settings.
+ * 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 = {
@@ -119,23 +127,46 @@ static Tcl_ObjType mmObjType = {
*/
static Tcl_ObjType windowObjType = {
- "window", /* name */
- FreeWindowInternalRep, /* freeIntRepProc */
- DupWindowInternalRep, /* dupIntRepProc */
- NULL, /* updateStringProc */
- SetWindowFromAny /* setFromAnyProc */
+ "window", /* name */
+ FreeWindowInternalRep, /* freeIntRepProc */
+ DupWindowInternalRep, /* dupIntRepProc */
+ NULL, /* updateStringProc */
+ SetWindowFromAny /* setFromAnyProc */
};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetTypeCache --
+ *
+ * Get (and build if necessary) the cache of useful Tcl object types for
+ * comparisons in the conversion functions. This allows optimized checks
+ * for standard cases.
+ *
+ *----------------------------------------------------------------------
+ */
+static ThreadSpecificData *
+GetTypeCache()
+{
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ if (tsdPtr->doubleTypePtr == NULL) {
+ tsdPtr->doubleTypePtr = Tcl_GetObjType("double");
+ tsdPtr->intTypePtr = Tcl_GetObjType("int");
+ }
+ return tsdPtr;
+}
/*
*----------------------------------------------------------------------
*
- * Tk_GetPixelsFromObj --
+ * GetPixelsFromObjEx --
*
* 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.
+ * 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
@@ -143,51 +174,94 @@ static Tcl_ObjType windowObjType = {
* result unless "interp" is NULL.
*
* Side effects:
- * If the object is not already a pixel, the conversion will free
- * any old internal representation.
+ * If the object is not already a pixel, the conversion will free any old
+ * internal representation.
*
*----------------------------------------------------------------------
*/
+static
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. */
+GetPixelsFromObjEx(
+ 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,
+ double *dblPtr) /* Places to store resulting pixels. */
{
- int result;
+ int result,fresh;
double d;
PixelRep *pixelPtr;
static double bias[] = {
- 1.0, 10.0, 25.4, 25.4 / 72.0
+ 1.0, 10.0, 25.4, 0.35278 /*25.4 / 72.0*/
};
+ /*
+ * Special hacks where the type of the object is known to be something
+ * that is just numeric and cannot require distance conversion. This pokes
+ * holes in Tcl's abstractions, but they are just for optimization, not
+ * semantics.
+ */
+
+ if (objPtr->typePtr != &pixelObjType) {
+ ThreadSpecificData *tsdPtr = GetTypeCache();
+
+ if (objPtr->typePtr == tsdPtr->doubleTypePtr) {
+ (void) Tcl_GetDoubleFromObj(interp, objPtr, &d);
+ if (dblPtr != NULL) {
+ *dblPtr = d;
+ }
+ *intPtr = (int) (d<0 ? d-0.5 : d+0.5);
+ return TCL_OK;
+ } else if (objPtr->typePtr == tsdPtr->intTypePtr) {
+ (void) Tcl_GetIntFromObj(interp, objPtr, intPtr);
+ if (dblPtr) {
+ *dblPtr = (double) (*intPtr);
+ }
+ return TCL_OK;
+ }
+ }
+
+ retry:
if (objPtr->typePtr != &pixelObjType) {
result = SetPixelFromAny(interp, objPtr);
if (result != TCL_OK) {
return result;
}
+ fresh = 1;
+ } else {
+ fresh = 0;
}
if (SIMPLE_PIXELREP(objPtr)) {
*intPtr = GET_SIMPLEPIXEL(objPtr);
+ if (dblPtr) {
+ *dblPtr = (double) (*intPtr);
+ }
} else {
pixelPtr = GET_COMPLEXPIXEL(objPtr);
- if (pixelPtr->tkwin != tkwin) {
+ if ((!fresh) && (pixelPtr->tkwin != tkwin)) {
+ /*
+ * In case of exo-screen conversions of non-pixels we force a
+ * recomputation from the string.
+ */
+
+ FreePixelInternalRep(objPtr);
+ goto retry;
+ }
+ if ((pixelPtr->tkwin != tkwin)||dblPtr) {
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->returnValue = (int) (d<0 ? d-0.5 : d+0.5);
pixelPtr->tkwin = tkwin;
+ if (dblPtr) {
+ *dblPtr = d;
+ }
}
- *intPtr = pixelPtr->returnValue;
+ *intPtr = pixelPtr->returnValue;
}
return TCL_OK;
}
@@ -195,6 +269,88 @@ Tk_GetPixelsFromObj(interp, tkwin, objPtr, intPtr)
/*
*----------------------------------------------------------------------
*
+ * 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(
+ 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. */
+{
+ return GetPixelsFromObjEx(interp,tkwin,objPtr,intPtr,NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_GetDoublePixelsFromObj --
+ *
+ * Attempt to return a double 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, the internal unit being pixels.
+ *
+ * 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_GetDoublePixelsFromObj(
+ Tcl_Interp *interp, /* Used for error reporting if not NULL. */
+ Tk_Window tkwin,
+ Tcl_Obj *objPtr, /* The object from which to get pixels. */
+ double *doublePtr) /* Place to store resulting pixels. */
+{
+ double d;
+ int result,val;
+
+ result = GetPixelsFromObjEx(interp, tkwin, objPtr, &val, &d);
+ if (result != TCL_OK) {
+ return result;
+ }
+ if (objPtr->typePtr == &pixelObjType && !SIMPLE_PIXELREP(objPtr)) {
+ PixelRep *pixelPtr = GET_COMPLEXPIXEL(objPtr);
+
+ if (pixelPtr->units >= 0) {
+ /*
+ * Internally "shimmer" to pixel units.
+ */
+
+ pixelPtr->units = -1;
+ pixelPtr->value = d;
+ }
+ }
+ *doublePtr = d;
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* FreePixelInternalRep --
*
* Deallocate the storage associated with a pixel object's internal
@@ -204,20 +360,19 @@ Tk_GetPixelsFromObj(interp, tkwin, objPtr, intPtr)
* None.
*
* Side effects:
- * Frees objPtr's internal representation and sets objPtr's
- * internalRep to NULL.
+ * 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. */
+FreePixelInternalRep(
+ Tcl_Obj *objPtr) /* Pixel object with internal rep to free. */
{
- PixelRep *pixelPtr;
-
if (!SIMPLE_PIXELREP(objPtr)) {
- pixelPtr = GET_COMPLEXPIXEL(objPtr);
+ PixelRep *pixelPtr = GET_COMPLEXPIXEL(objPtr);
+
ckfree((char *) pixelPtr);
}
SET_SIMPLEPIXEL(objPtr, 0);
@@ -229,31 +384,31 @@ FreePixelInternalRep(objPtr)
*
* DupPixelInternalRep --
*
- * Initialize the internal representation of a pixel Tcl_Obj to a
- * copy of the internal representation of an existing pixel object.
+ * 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.
+ * 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. */
+DupPixelInternalRep(
+ 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 {
+ PixelRep *oldPtr, *newPtr;
+
oldPtr = GET_COMPLEXPIXEL(srcPtr);
newPtr = (PixelRep *) ckalloc(sizeof(PixelRep));
newPtr->value = oldPtr->value;
@@ -269,8 +424,7 @@ DupPixelInternalRep(srcPtr, copyPtr)
*
* SetPixelFromAny --
*
- * Attempt to generate a pixel internal form for the Tcl object
- * "objPtr".
+ * 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
@@ -278,70 +432,54 @@ DupPixelInternalRep(srcPtr, copyPtr)
* 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.
+ * 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. */
+SetPixelFromAny(
+ Tcl_Interp *interp, /* Used for error reporting if not NULL. */
+ Tcl_Obj *objPtr) /* The object to convert. */
{
- Tcl_ObjType *typePtr;
+ const 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;
+ goto 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;
+ 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.
+ * Free the old internalRep before setting the new one.
*/
typePtr = objPtr->typePtr;
@@ -355,7 +493,8 @@ SetPixelFromAny(interp, objPtr)
if ((units < 0) && (i == d)) {
SET_SIMPLEPIXEL(objPtr, i);
} else {
- pixelPtr = (PixelRep *) ckalloc(sizeof(PixelRep));
+ PixelRep *pixelPtr = (PixelRep *) ckalloc(sizeof(PixelRep));
+
pixelPtr->value = d;
pixelPtr->units = units;
pixelPtr->tkwin = NULL;
@@ -363,6 +502,21 @@ SetPixelFromAny(interp, objPtr)
SET_COMPLEXPIXEL(objPtr, pixelPtr);
}
return TCL_OK;
+
+ error:
+ if (interp != NULL) {
+ /*
+ * Must copy string before resetting the result in case a caller is
+ * trying to convert the interpreter's result to pixels.
+ */
+
+ char buf[100];
+
+ sprintf(buf, "bad screen distance \"%.50s\"", string);
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, buf, NULL);
+ }
+ return TCL_ERROR;
}
/*
@@ -380,24 +534,24 @@ SetPixelFromAny(interp, objPtr)
* result unless "interp" is NULL.
*
* Side effects:
- * If the object is not already a pixel, the conversion will free
- * any old internal representation.
+ * 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. */
+Tk_GetMMFromObj(
+ 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
+ 10.0, 25.4, 1.0, 0.35278 /*25.4 / 72.0*/
};
if (objPtr->typePtr != &mmObjType) {
@@ -436,15 +590,15 @@ Tk_GetMMFromObj(interp, tkwin, objPtr, doublePtr)
* None.
*
* Side effects:
- * Frees objPtr's internal representation and sets objPtr's
- * internalRep to NULL.
+ * 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. */
+FreeMMInternalRep(
+ Tcl_Obj *objPtr) /* MM object with internal rep to free. */
{
ckfree((char *) objPtr->internalRep.otherValuePtr);
objPtr->internalRep.otherValuePtr = NULL;
@@ -456,26 +610,26 @@ FreeMMInternalRep(objPtr)
*
* DupMMInternalRep --
*
- * Initialize the internal representation of a pixel Tcl_Obj to a
- * copy of the internal representation of an existing pixel object.
+ * 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.
+ * 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. */
+DupMMInternalRep(
+ 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));
@@ -491,24 +645,23 @@ DupMMInternalRep(srcPtr, copyPtr)
*
* UpdateStringOfMM --
*
- * Update the string representation for a pixel Tcl_Obj
- * this function is only called, if the pixel Tcl_Obj has no unit,
- * because with units the string representation is created by
- * SetMMFromAny
+ * Update the string representation for a pixel Tcl_Obj this function is
+ * only called, if the pixel Tcl_Obj has no unit, because with units the
+ * string representation is created by SetMMFromAny
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * The object's string is set to a valid string that results from
- * the double-to-string conversion.
+ * The object's string is set to a valid string that results from the
+ * double-to-string conversion.
*
*----------------------------------------------------------------------
*/
static void
-UpdateStringOfMM(objPtr)
- register Tcl_Obj *objPtr; /* pixel obj with string rep to update. */
+UpdateStringOfMM(
+ register Tcl_Obj *objPtr) /* pixel obj with string rep to update. */
{
MMRep *mmPtr;
char buffer[TCL_DOUBLE_SPACE];
@@ -517,11 +670,11 @@ UpdateStringOfMM(objPtr)
mmPtr = (MMRep *) objPtr->internalRep.otherValuePtr;
/* assert( mmPtr->units == -1 && objPtr->bytes == NULL ); */
if ((mmPtr->units != -1) || (objPtr->bytes != NULL)) {
- panic("UpdateStringOfMM: false precondition");
+ Tcl_Panic("UpdateStringOfMM: false precondition");
}
- Tcl_PrintDouble((Tcl_Interp *) NULL, mmPtr->value, buffer);
- len = strlen(buffer);
+ Tcl_PrintDouble(NULL, mmPtr->value, buffer);
+ len = (int)strlen(buffer);
objPtr->bytes = (char *) ckalloc((unsigned) len + 1);
strcpy(objPtr->bytes, buffer);
@@ -533,8 +686,7 @@ UpdateStringOfMM(objPtr)
*
* SetMMFromAny --
*
- * Attempt to generate a mm internal form for the Tcl object
- * "objPtr".
+ * 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
@@ -542,49 +694,38 @@ UpdateStringOfMM(objPtr)
* 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.
+ * 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. */
+SetMMFromAny(
+ Tcl_Interp *interp, /* Used for error reporting if not NULL. */
+ Tcl_Obj *objPtr) /* The object to convert. */
{
- Tcl_ObjType *typePtr;
+ ThreadSpecificData *tsdPtr = GetTypeCache();
+ const Tcl_ObjType *typePtr;
char *string, *rest;
double d;
int units;
MMRep *mmPtr;
- static Tcl_ObjType *tclDoubleObjType = NULL;
- static Tcl_ObjType *tclIntObjType = NULL;
-
- if (tclDoubleObjType == NULL) {
- /*
- * Cache the object types for comaprison below.
- * This allows optimized checks for standard cases.
- */
-
- tclDoubleObjType = Tcl_GetObjType("double");
- tclIntObjType = Tcl_GetObjType("int");
- }
-
- if (objPtr->typePtr == tclDoubleObjType) {
+ if (objPtr->typePtr == tsdPtr->doubleTypePtr) {
Tcl_GetDoubleFromObj(interp, objPtr, &d);
units = -1;
- } else if (objPtr->typePtr == tclIntObjType) {
+ } else if (objPtr->typePtr == tsdPtr->intTypePtr) {
Tcl_GetIntFromObj(interp, objPtr, &units);
d = (double) units;
units = -1;
/*
- * In the case of ints, we need to ensure that a valid
- * string exists in order for int-but-not-string objects
- * to be converted back to ints again from mm obj types.
+ * In the case of ints, we need to ensure that a valid string exists
+ * in order for int-but-not-string objects to be converted back to
+ * ints again from mm obj types.
*/
+
(void) Tcl_GetStringFromObj(objPtr, NULL);
} else {
/*
@@ -600,42 +741,38 @@ SetMMFromAny(interp, objPtr)
* 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;
+ error:
+ Tcl_AppendResult(interp, "bad screen distance \"", string,
+ "\"", 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.
+ * Free the old internalRep before setting the new one.
*/
typePtr = objPtr->typePtr;
@@ -671,18 +808,18 @@ SetMMFromAny(interp, objPtr)
* result unless "interp" is NULL.
*
* Side effects:
- * If the object is not already a Tk_Window, the conversion will free
- * any old internal representation.
+ * 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. */
- Tcl_Obj *objPtr; /* The object from which to get window. */
- Tk_Window *windowPtr; /* Place to store resulting window. */
+TkGetWindowFromObj(
+ Tcl_Interp *interp, /* Used for error reporting if not NULL. */
+ Tk_Window tkwin, /* A token to get the main window from. */
+ Tcl_Obj *objPtr, /* The object from which to get window. */
+ Tk_Window *windowPtr) /* Place to store resulting window. */
{
TkMainInfo *mainPtr = ((TkWindow *)tkwin)->mainPtr;
register WindowRep *winPtr;
@@ -696,11 +833,13 @@ TkGetWindowFromObj(interp, tkwin, objPtr, windowPtr)
winPtr = (WindowRep *) objPtr->internalRep.otherValuePtr;
if ( winPtr->tkwin == NULL
|| winPtr->mainPtr == NULL
- || winPtr->mainPtr != mainPtr
- || winPtr->epoch != mainPtr->deletionEpoch)
+ || winPtr->mainPtr != mainPtr
+ || winPtr->epoch != mainPtr->deletionEpoch)
{
- /* Cache is invalid.
+ /*
+ * Cache is invalid.
*/
+
winPtr->tkwin = Tk_NameToWindow(interp,
Tcl_GetStringFromObj(objPtr, NULL), tkwin);
winPtr->mainPtr = mainPtr;
@@ -720,14 +859,15 @@ TkGetWindowFromObj(interp, tkwin, objPtr, windowPtr)
*----------------------------------------------------------------------
*
* SetWindowFromAny --
+ *
* Generate a windowObj internal form for the Tcl object "objPtr".
*
* Results:
- * Always returns TCL_OK.
+ * Always returns TCL_OK.
*
* Side effects:
- * Sets objPtr's internal representation to an uninitialized
- * windowObj. Frees the old internal representation, if any.
+ * Sets objPtr's internal representation to an uninitialized windowObj.
+ * Frees the old internal representation, if any.
*
* See also:
* TkGetWindowFromObj, which initializes the WindowRep cache.
@@ -736,15 +876,15 @@ TkGetWindowFromObj(interp, tkwin, objPtr, windowPtr)
*/
static int
-SetWindowFromAny(interp, objPtr)
- Tcl_Interp *interp; /* Used for error reporting if not NULL. */
- register Tcl_Obj *objPtr; /* The object to convert. */
+SetWindowFromAny(
+ Tcl_Interp *interp, /* Used for error reporting if not NULL. */
+ register Tcl_Obj *objPtr) /* The object to convert. */
{
- Tcl_ObjType *typePtr;
+ const Tcl_ObjType *typePtr;
WindowRep *winPtr;
/*
- * Free the old internalRep before setting the new one.
+ * Free the old internalRep before setting the new one.
*/
Tcl_GetStringFromObj(objPtr, NULL);
@@ -769,23 +909,23 @@ SetWindowFromAny(interp, objPtr)
*
* DupWindowInternalRep --
*
- * Initialize the internal representation of a window Tcl_Obj to a
- * copy of the internal representation of an existing window object.
+ * Initialize the internal representation of a window Tcl_Obj to a copy
+ * of the internal representation of an existing window object.
*
* Results:
* None.
*
* Side effects:
- * copyPtr's internal rep is set to refer to the same window as
- * srcPtr's internal rep.
+ * copyPtr's internal rep is set to refer to the same window as srcPtr's
+ * internal rep.
*
*----------------------------------------------------------------------
*/
static void
-DupWindowInternalRep(srcPtr, copyPtr)
- register Tcl_Obj *srcPtr;
- register Tcl_Obj *copyPtr;
+DupWindowInternalRep(
+ register Tcl_Obj *srcPtr,
+ register Tcl_Obj *copyPtr)
{
register WindowRep *oldPtr, *newPtr;
@@ -810,15 +950,15 @@ DupWindowInternalRep(srcPtr, copyPtr)
* None.
*
* Side effects:
- * Frees objPtr's internal representation and sets objPtr's
- * internalRep to NULL.
+ * Frees objPtr's internal representation and sets objPtr's internalRep
+ * to NULL.
*
*----------------------------------------------------------------------
*/
static void
-FreeWindowInternalRep(objPtr)
- Tcl_Obj *objPtr; /* Window object with internal rep to free. */
+FreeWindowInternalRep(
+ Tcl_Obj *objPtr) /* Window object with internal rep to free. */
{
ckfree((char *) objPtr->internalRep.otherValuePtr);
objPtr->internalRep.otherValuePtr = NULL;
@@ -830,39 +970,39 @@ FreeWindowInternalRep(objPtr)
*
* TkParsePadAmount --
*
- * This procedure parses a padding specification and returns
- * the appropriate padding values. A padding specification can
- * be either a single pixel width, or a list of two pixel widths.
- * If a single pixel width, the amount specified is used for
- * padding on both sides. If two amounts are specified, then
- * they specify the left/right or top/bottom padding.
+ * This function parses a padding specification and returns the
+ * appropriate padding values. A padding specification can be either a
+ * single pixel width, or a list of two pixel widths. If a single pixel
+ * width, the amount specified is used for padding on both sides. If two
+ * amounts are specified, then they specify the left/right or top/bottom
+ * padding.
*
* Results:
* A standard Tcl return value.
*
* Side effects:
- * An error message is written to the interpreter is something
- * is not right.
+ * An error message is written to the interpreter if something is not
+ * right.
*
*--------------------------------------------------------------
*/
int
-TkParsePadAmount(interp, tkwin, specObj, halfPtr, allPtr)
- Tcl_Interp *interp; /* Interpreter for error reporting. */
- Tk_Window tkwin; /* A window. Needed by Tk_GetPixels() */
- Tcl_Obj *specObj; /* The argument to "-padx", "-pady", "-ipadx",
- * or "-ipady". The thing to be parsed. */
- int *halfPtr; /* Write the left/top part of padding here */
- int *allPtr; /* Write the total padding here */
+TkParsePadAmount(
+ Tcl_Interp *interp, /* Interpreter for error reporting. */
+ Tk_Window tkwin, /* A window. Needed by Tk_GetPixels() */
+ Tcl_Obj *specObj, /* The argument to "-padx", "-pady", "-ipadx",
+ * or "-ipady". The thing to be parsed. */
+ int *halfPtr, /* Write the left/top part of padding here */
+ int *allPtr) /* Write the total padding here */
{
int firstInt, secondInt; /* The two components of the padding */
int objc; /* The length of the list (should be 1 or 2) */
Tcl_Obj **objv; /* The objects in the list */
/*
- * Check for a common case where a single object would otherwise
- * be shimmered between a list and a pixel spec.
+ * Check for a common case where a single object would otherwise be
+ * shimmered between a list and a pixel spec.
*/
if (specObj->typePtr == &pixelObjType) {
@@ -870,7 +1010,7 @@ TkParsePadAmount(interp, tkwin, specObj, halfPtr, allPtr)
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "bad pad value \"",
Tcl_GetString(specObj),
- "\": must be positive screen distance", (char *) NULL);
+ "\": must be positive screen distance", NULL);
return TCL_ERROR;
}
secondInt = firstInt;
@@ -878,8 +1018,8 @@ TkParsePadAmount(interp, tkwin, specObj, halfPtr, allPtr)
}
/*
- * Pad specifications are a list of one or two elements, each of
- * which is a pixel specification.
+ * Pad specifications are a list of one or two elements, each of which is
+ * a pixel specification.
*/
if (Tcl_ListObjGetElements(interp, specObj, &objc, &objv) != TCL_OK) {
@@ -899,13 +1039,13 @@ TkParsePadAmount(interp, tkwin, specObj, halfPtr, allPtr)
(firstInt < 0)) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "bad pad value \"", Tcl_GetString(objv[0]),
- "\": must be positive screen distance", (char *) NULL);
+ "\": must be positive screen distance", NULL);
return TCL_ERROR;
}
/*
- * Parse the second part if it exists, otherwise it is as if it
- * was the same as the first part.
+ * Parse the second part if it exists, otherwise it is as if it was the
+ * same as the first part.
*/
if (objc == 1) {
@@ -915,7 +1055,7 @@ TkParsePadAmount(interp, tkwin, specObj, halfPtr, allPtr)
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "bad 2nd pad value \"",
Tcl_GetString(objv[1]),
- "\": must be positive screen distance", (char *) NULL);
+ "\": must be positive screen distance", NULL);
return TCL_ERROR;
}
@@ -942,14 +1082,14 @@ TkParsePadAmount(interp, tkwin, specObj, halfPtr, allPtr)
* None
*
* Side effects:
- * All instances of Tcl_ObjType structues used in Tk are registered
- * with Tcl.
+ * All instances of Tcl_ObjType structues used in Tk are registered with
+ * Tcl.
*
*----------------------------------------------------------------------
*/
void
-TkRegisterObjTypes()
+TkRegisterObjTypes(void)
{
Tcl_RegisterObjType(&tkBorderObjType);
Tcl_RegisterObjType(&tkBitmapObjType);
@@ -961,4 +1101,13 @@ TkRegisterObjTypes()
Tcl_RegisterObjType(&pixelObjType);
Tcl_RegisterObjType(&tkStateKeyObjType);
Tcl_RegisterObjType(&windowObjType);
+ Tcl_RegisterObjType(&tkTextIndexType);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkOldConfig.c b/generic/tkOldConfig.c
index 6c6303d..97ad5cb 100644
--- a/generic/tkOldConfig.c
+++ b/generic/tkOldConfig.c
@@ -1,106 +1,101 @@
-/*
+/*
* 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.
+ * This file contains the Tk_ConfigureWidget function. 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#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!
+ * 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.
+ * 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:
+ * Forward declarations for functions 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,
+static int DoConfig(Tcl_Interp *interp, Tk_Window tkwin,
+ Tk_ConfigSpec *specPtr, Tk_Uid value,
+ int valueIsUid, char *widgRec);
+static Tk_ConfigSpec * FindConfigSpec(Tcl_Interp *interp,
Tk_ConfigSpec *specs, CONST char *argvName,
- int needFlags, int hateFlags));
-static char * FormatConfigInfo _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, Tk_ConfigSpec *specPtr,
- char *widgRec));
-static CONST char * FormatConfigValue _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, Tk_ConfigSpec *specPtr,
- char *widgRec, char *buffer,
- Tcl_FreeProc **freeProcPtr));
-static Tk_ConfigSpec * GetCachedSpecs _ANSI_ARGS_((Tcl_Interp *interp,
- CONST Tk_ConfigSpec *staticSpecs));
-static void DeleteSpecCacheTable _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp));
+ int needFlags, int hateFlags);
+static char * FormatConfigInfo(Tcl_Interp *interp, Tk_Window tkwin,
+ Tk_ConfigSpec *specPtr, char *widgRec);
+static CONST char * FormatConfigValue(Tcl_Interp *interp, Tk_Window tkwin,
+ Tk_ConfigSpec *specPtr, char *widgRec,
+ char *buffer, Tcl_FreeProc **freeProcPtr);
+static Tk_ConfigSpec * GetCachedSpecs(Tcl_Interp *interp,
+ const Tk_ConfigSpec *staticSpecs);
+static void DeleteSpecCacheTable(ClientData clientData,
+ Tcl_Interp *interp);
/*
*--------------------------------------------------------------
*
* Tk_ConfigureWidget --
*
- * Process command-line options and database options to
- * fill in fields of a widget record with resources and
- * other parameters.
+ * 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.
+ * 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. A copy of the spec-table is
- * taken with (some of) the char* *fields converted into Tk_Uid
- * fields; this copy will be released when *the interpreter
- * terminates.
+ * The fields of widgRec get filled in with information from argc/argv
+ * and the option database. Old information in widgRec's fields gets
+ * recycled. A copy of the spec-table is taken with (some of) the char*
+ * fields converted into Tk_Uid fields; this copy will be released when
+ * the interpreter terminates.
*
*--------------------------------------------------------------
*/
int
-Tk_ConfigureWidget(interp, tkwin, origSpecs, 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 *origSpecs; /* Describes legal options. */
- int argc; /* Number of elements in argv. */
- CONST 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_ConfigureWidget(
+ 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. */
+ CONST 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 *specs, *specPtr, *origSpecPtr;
+ 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. */
+ 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. */
if (tkwin == NULL) {
/*
* Either we're not really in Tk, or the main window was destroyed and
* we're on our way out of the application
*/
- Tcl_AppendResult(interp, "NULL main window", (char *)NULL);
+
+ Tcl_AppendResult(interp, "NULL main window", NULL);
return TCL_ERROR;
}
@@ -112,19 +107,14 @@ Tk_ConfigureWidget(interp, tkwin, origSpecs, argc, argv, widgRec, flags)
}
/*
- * Get the build of the config for this interpreter and reset any
- * indication of changed options.
+ * Get the build of the config for this interpreter.
*/
- specs = GetCachedSpecs(interp, origSpecs);
-
- for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
- specPtr->specFlags &= ~TK_CONFIG_OPTION_SPECIFIED;
- }
+ specs = GetCachedSpecs(interp, specs);
/*
- * Pass one: scan through all of the arguments, processing those
- * that match entries in the specs.
+ * Pass one: scan through all of the arguments, processing those that
+ * match entries in the specs.
*/
for ( ; argc > 0; argc -= 2, argv += 2) {
@@ -145,8 +135,7 @@ Tk_ConfigureWidget(interp, tkwin, origSpecs, argc, argv, widgRec, flags)
*/
if (argc < 2) {
- Tcl_AppendResult(interp, "value for \"", arg,
- "\" missing", (char *) NULL);
+ Tcl_AppendResult(interp, "value for \"", arg, "\" missing", NULL);
return TCL_ERROR;
}
if (flags & TK_CONFIG_OBJS) {
@@ -162,25 +151,15 @@ Tk_ConfigureWidget(interp, tkwin, origSpecs, argc, argv, widgRec, flags)
Tcl_AddErrorInfo(interp, msg);
return TCL_ERROR;
}
- specPtr->specFlags |= TK_CONFIG_OPTION_SPECIFIED;
- }
-
- /*
- * Thread Unsafe! For compatibility through 8.4.x, we set the original
- * specPtr flags to indicate changed options. This has been removed
- * from 8.5. Switch to Tcl_Obj-based options instead. [Bug 749908]
- */
-
- for (origSpecPtr = origSpecs, specPtr = specs;
- specPtr->type != TK_CONFIG_END; origSpecPtr++, specPtr++) {
- origSpecPtr->specFlags = specPtr->specFlags;
+ if (!(flags & TK_CONFIG_ARGV_ONLY)) {
+ specPtr->specFlags |= TK_CONFIG_OPTION_SPECIFIED;
+ }
}
/*
- * Pass two: 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.
+ * Pass two: 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)) {
@@ -188,6 +167,7 @@ Tk_ConfigureWidget(interp, tkwin, origSpecs, argc, argv, widgRec, flags)
if ((specPtr->specFlags & TK_CONFIG_OPTION_SPECIFIED)
|| (specPtr->argvName == NULL)
|| (specPtr->type == TK_CONFIG_SYNONYM)) {
+ specPtr->specFlags &= ~TK_CONFIG_OPTION_SPECIFIED;
continue;
}
if (((specPtr->specFlags & needFlags) != needFlags)
@@ -241,13 +221,13 @@ Tk_ConfigureWidget(interp, tkwin, origSpecs, argc, argv, widgRec, flags)
*
* FindConfigSpec --
*
- * Search through a table of configuration specs, looking for
- * one that matches a given argvName.
+ * 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.
+ * 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.
@@ -256,16 +236,16 @@ Tk_ConfigureWidget(interp, tkwin, origSpecs, argc, argv, widgRec, flags)
*/
static Tk_ConfigSpec *
-FindConfigSpec(interp, specs, argvName, needFlags, hateFlags)
- Tcl_Interp *interp; /* Used for reporting errors. */
- Tk_ConfigSpec *specs; /* Pointer to table of configuration
+FindConfigSpec(
+ Tcl_Interp *interp, /* Used for reporting errors. */
+ Tk_ConfigSpec *specs, /* Pointer to table of configuration
* specifications for a widget. */
- CONST char *argvName; /* Name (suitable for use in a "config"
+ CONST char *argvName, /* Name (suitable for use in a "config"
* command) identifying particular option. */
- int needFlags; /* Flags that must be present in matching
+ int needFlags, /* Flags that must be present in matching
+ * entry. */
+ int hateFlags) /* Flags that must NOT 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. */
@@ -293,34 +273,32 @@ FindConfigSpec(interp, specs, argvName, needFlags, hateFlags)
}
if (matchPtr != NULL) {
Tcl_AppendResult(interp, "ambiguous option \"", argvName,
- "\"", (char *) NULL);
- return (Tk_ConfigSpec *) NULL;
+ "\"", NULL);
+ return NULL;
}
matchPtr = specPtr;
}
if (matchPtr == NULL) {
- Tcl_AppendResult(interp, "unknown option \"", argvName,
- "\"", (char *) NULL);
- return (Tk_ConfigSpec *) NULL;
+ Tcl_AppendResult(interp, "unknown option \"", argvName, "\"", NULL);
+ return NULL;
}
/*
- * Found a matching entry. If it's a synonym, then find the
- * entry that it's a synonym for.
+ * Found a matching entry. If it's a synonym, then find the entry that
+ * it's a synonym for.
*/
- gotMatch:
+ 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;
+ Tcl_AppendResult(interp, "couldn't find synonym for option \"",
+ argvName, "\"", NULL);
+ return NULL;
}
- if ((specPtr->dbName == matchPtr->dbName)
+ if ((specPtr->dbName == matchPtr->dbName)
&& (specPtr->type != TK_CONFIG_SYNONYM)
&& ((specPtr->specFlags & needFlags) == needFlags)
&& !(specPtr->specFlags & hateFlags)) {
@@ -336,32 +314,30 @@ FindConfigSpec(interp, specs, argvName, needFlags, hateFlags)
*
* DoConfig --
*
- * This procedure applies a single configuration option
- * to a widget record.
+ * This function 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.
+ * 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. */
- Tk_Uid 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. */
+DoConfig(
+ 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. */
+ Tk_Uid 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;
@@ -375,211 +351,209 @@ DoConfig(interp, tkwin, specPtr, value, valueIsUid, widgRec)
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_BOOLEAN:
+ if (Tcl_GetBoolean(interp, value, (int *) ptr) != TCL_OK) {
+ return TCL_ERROR;
}
- 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;
+ 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;
}
- case TK_CONFIG_FONT: {
- Tk_Font new;
+ break;
+ case TK_CONFIG_STRING: {
+ char *oldStr, *newStr;
- 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;
+ if (nullValue) {
+ newStr = NULL;
+ } else {
+ newStr = (char *) ckalloc((unsigned) (strlen(value) + 1));
+ strcpy(newStr, value);
}
- 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;
+ oldStr = *((char **) ptr);
+ if (oldStr != NULL) {
+ ckfree(oldStr);
}
- 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;
+ *((char **) ptr) = newStr;
+ break;
+ }
+ case TK_CONFIG_UID:
+ if (nullValue) {
+ *((Tk_Uid *) ptr) = NULL;
+ } else {
+ uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
+ *((Tk_Uid *) ptr) = uid;
}
- case TK_CONFIG_RELIEF:
+ break;
+ case TK_CONFIG_COLOR: {
+ XColor *newPtr, *oldPtr;
+
+ if (nullValue) {
+ newPtr = NULL;
+ } else {
uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
- if (Tk_GetRelief(interp, uid, (int *) ptr) != TCL_OK) {
+ newPtr = Tk_GetColor(interp, tkwin, uid);
+ if (newPtr == NULL) {
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) {
+ oldPtr = *((XColor **) ptr);
+ if (oldPtr != NULL) {
+ Tk_FreeColor(oldPtr);
+ }
+ *((XColor **) ptr) = newPtr;
+ break;
+ }
+ case TK_CONFIG_FONT: {
+ Tk_Font newFont;
+
+ if (nullValue) {
+ newFont = NULL;
+ } else {
+ newFont = Tk_GetFont(interp, tkwin, value);
+ if (newFont == NULL) {
return TCL_ERROR;
}
- break;
- case TK_CONFIG_ANCHOR:
+ }
+ Tk_FreeFont(*((Tk_Font *) ptr));
+ *((Tk_Font *) ptr) = newFont;
+ break;
+ }
+ case TK_CONFIG_BITMAP: {
+ Pixmap newBmp, oldBmp;
+
+ if (nullValue) {
+ newBmp = None;
+ } else {
uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
- if (Tk_GetAnchor(interp, uid, (Tk_Anchor *) ptr) != TCL_OK) {
+ newBmp = Tk_GetBitmap(interp, tkwin, uid);
+ if (newBmp == None) {
return TCL_ERROR;
}
- break;
- case TK_CONFIG_CAP_STYLE:
+ }
+ oldBmp = *((Pixmap *) ptr);
+ if (oldBmp != None) {
+ Tk_FreeBitmap(Tk_Display(tkwin), oldBmp);
+ }
+ *((Pixmap *) ptr) = newBmp;
+ break;
+ }
+ case TK_CONFIG_BORDER: {
+ Tk_3DBorder newBorder, oldBorder;
+
+ if (nullValue) {
+ newBorder = NULL;
+ } else {
uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
- if (Tk_GetCapStyle(interp, uid, (int *) ptr) != TCL_OK) {
+ newBorder = Tk_Get3DBorder(interp, tkwin, uid);
+ if (newBorder == NULL) {
return TCL_ERROR;
}
- break;
- case TK_CONFIG_JOIN_STYLE:
+ }
+ oldBorder = *((Tk_3DBorder *) ptr);
+ if (oldBorder != NULL) {
+ Tk_Free3DBorder(oldBorder);
+ }
+ *((Tk_3DBorder *) ptr) = newBorder;
+ 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 newCursor, oldCursor;
+
+ if (nullValue) {
+ newCursor = None;
+ } else {
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) {
+ newCursor = Tk_GetCursor(interp, tkwin, uid);
+ if (newCursor == None) {
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) {
+ oldCursor = *((Tk_Cursor *) ptr);
+ if (oldCursor != None) {
+ Tk_FreeCursor(Tk_Display(tkwin), oldCursor);
+ }
+ *((Tk_Cursor *) ptr) = newCursor;
+ if (specPtr->type == TK_CONFIG_ACTIVE_CURSOR) {
+ Tk_DefineCursor(tkwin, newCursor);
+ }
+ 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;
}
- break;
- default: {
- char buf[64 + TCL_INTEGER_SPACE];
-
- sprintf(buf, "bad config table: unknown type %d",
- specPtr->type);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ *((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));
@@ -591,24 +565,22 @@ DoConfig(interp, tkwin, specPtr, value, valueIsUid, widgRec)
*
* Tk_ConfigureInfo --
*
- * Return information about the configuration options
- * for a window, and their current values.
+ * 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).
+ * 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.
@@ -617,18 +589,18 @@ 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
- * values for options. */
- CONST char *argvName; /* If non-NULL, indicates a single option
- * whose info is to be returned. Otherwise
+Tk_ConfigureInfo(
+ 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. */
+ CONST 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. */
+ 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;
@@ -649,11 +621,11 @@ Tk_ConfigureInfo(interp, tkwin, specs, widgRec, argvName, flags)
specs = GetCachedSpecs(interp, specs);
/*
- * If information is only wanted for a single configuration
- * spec, then handle that one spec specially.
+ * If information is only wanted for a single configuration spec, then
+ * handle that one spec specially.
*/
- Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);
+ Tcl_SetResult(interp, NULL, TCL_STATIC);
if (argvName != NULL) {
specPtr = FindConfigSpec(interp, specs, argvName, needFlags,hateFlags);
if (specPtr == NULL) {
@@ -666,8 +638,8 @@ Tk_ConfigureInfo(interp, tkwin, specs, widgRec, argvName, flags)
}
/*
- * Loop through all the specs, creating a big list with all
- * their information.
+ * Loop through all the specs, creating a big list with all their
+ * information.
*/
for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
@@ -682,7 +654,7 @@ Tk_ConfigureInfo(interp, tkwin, specs, widgRec, argvName, flags)
continue;
}
list = FormatConfigInfo(interp, tkwin, specPtr, widgRec);
- Tcl_AppendResult(interp, leader, list, "}", (char *) NULL);
+ Tcl_AppendResult(interp, leader, list, "}", NULL);
ckfree(list);
leader = " {";
}
@@ -694,12 +666,12 @@ Tk_ConfigureInfo(interp, tkwin, specs, widgRec, argvName, flags)
*
* FormatConfigInfo --
*
- * Create a valid Tcl list holding the configuration information
- * for a single configuration option.
+ * 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.
+ * A Tcl list, dynamically allocated. The caller is expected to arrange
+ * for this list to be freed eventually.
*
* Side effects:
* Memory is allocated.
@@ -708,19 +680,20 @@ 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. */
+FormatConfigInfo(
+ 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. */
{
CONST char *argv[6];
char *result;
char buffer[200];
- Tcl_FreeProc *freeProc = (Tcl_FreeProc *) NULL;
+ Tcl_FreeProc *freeProc = NULL;
argv[0] = specPtr->argvName;
argv[1] = specPtr->dbName;
@@ -759,16 +732,14 @@ FormatConfigInfo(interp, tkwin, specPtr, widgRec)
*
* FormatConfigValue --
*
- * This procedure formats the current value of a configuration
- * option.
+ * This function 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.
+ * 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 function to free the result, and the caller must
+ * invoke this function when it is finished with the result.
*
* Side effects:
* None.
@@ -777,18 +748,18 @@ FormatConfigInfo(interp, tkwin, specPtr, widgRec)
*/
static CONST 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.
+FormatConfigValue(
+ 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.
+ 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. */
+ Tcl_FreeProc **freeProcPtr) /* Pointer to word to fill in with address of
+ * function to free the result, or NULL if
+ * result is static. */
{
CONST char *ptr, *result;
@@ -796,109 +767,115 @@ FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer, freeProcPtr)
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_BOOLEAN:
+ if (*((int *) ptr) == 0) {
+ result = "0";
+ } else {
+ result = "1";
}
- case TK_CONFIG_COLOR: {
- XColor *colorPtr = *((XColor **) ptr);
- if (colorPtr != NULL) {
- result = Tk_NameOfColor(colorPtr);
- }
- break;
+ 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 = "";
}
- case TK_CONFIG_FONT: {
- Tk_Font tkfont = *((Tk_Font *) ptr);
- if (tkfont != NULL) {
- result = Tk_NameOfFont(tkfont);
- }
- break;
+ break;
+ case TK_CONFIG_UID: {
+ Tk_Uid uid = *((Tk_Uid *) ptr);
+
+ if (uid != NULL) {
+ result = uid;
}
- case TK_CONFIG_BITMAP: {
- Pixmap pixmap = *((Pixmap *) ptr);
- if (pixmap != None) {
- result = Tk_NameOfBitmap(Tk_Display(tkwin), pixmap);
- }
- break;
+ break;
+ }
+ case TK_CONFIG_COLOR: {
+ XColor *colorPtr = *((XColor **) ptr);
+
+ if (colorPtr != NULL) {
+ result = Tk_NameOfColor(colorPtr);
}
- case TK_CONFIG_BORDER: {
- Tk_3DBorder border = *((Tk_3DBorder *) ptr);
- if (border != NULL) {
- result = Tk_NameOf3DBorder(border);
- }
- break;
+ break;
+ }
+ case TK_CONFIG_FONT: {
+ Tk_Font tkfont = *((Tk_Font *) ptr);
+
+ if (tkfont != NULL) {
+ result = Tk_NameOfFont(tkfont);
}
- 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;
+ break;
+ }
+ case TK_CONFIG_BITMAP: {
+ Pixmap pixmap = *((Pixmap *) ptr);
+
+ if (pixmap != None) {
+ result = Tk_NameOfBitmap(Tk_Display(tkwin), pixmap);
}
- 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;
+ break;
+ }
+ case TK_CONFIG_BORDER: {
+ Tk_3DBorder border = *((Tk_3DBorder *) ptr);
- tkwin = *((Tk_Window *) ptr);
- if (tkwin != NULL) {
- result = Tk_PathName(tkwin);
- }
- break;
+ if (border != NULL) {
+ result = Tk_NameOf3DBorder(border);
}
- case TK_CONFIG_CUSTOM:
- result = (*specPtr->customPtr->printProc)(
- specPtr->customPtr->clientData, tkwin, widgRec,
- specPtr->offset, freeProcPtr);
- break;
- default:
- result = "?? unknown type ??";
+ 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;
}
@@ -908,14 +885,14 @@ FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer, freeProcPtr)
*
* Tk_ConfigureValue --
*
- * This procedure returns the current value of a configuration
- * option for a widget.
+ * This function 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).
+ * 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.
@@ -924,17 +901,17 @@ 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
- * values for options. */
- CONST 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_ConfigureValue(
+ 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. */
+ CONST 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;
@@ -959,7 +936,8 @@ Tk_ConfigureValue(interp, tkwin, specs, widgRec, argvName, flags)
if (specPtr == NULL) {
return TCL_ERROR;
}
- result = FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer, &freeProc);
+ result = FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer,
+ &freeProc);
Tcl_SetResult(interp, (char *) result, TCL_VOLATILE);
if (freeProc != NULL) {
if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) {
@@ -982,24 +960,27 @@ Tk_ConfigureValue(interp, tkwin, specs, widgRec, argvName, flags)
* 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.
+ * Any resource in widgRec that is controlled by a configuration option
+ * (e.g. a Tk_3DBorder or XColor) is freed in the appropriate fashion.
+ *
+ * Notes:
+ * Since this is not looking anything up, this uses the static version of
+ * the config specs.
*
*----------------------------------------------------------------------
*/
/* 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
+Tk_FreeOptions(
+ 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. */
+ 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;
@@ -1010,40 +991,40 @@ Tk_FreeOptions(specs, widgRec, display, needFlags)
}
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;
- }
+ 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;
+ }
}
}
}
@@ -1053,28 +1034,28 @@ Tk_FreeOptions(specs, widgRec, display, needFlags)
*
* GetCachedSpecs --
*
- *Returns a writable per-interpreter (and hence thread-local) copy of
- *the given spec-table with (some of) the char* fields converted into
- *Tk_Uid fields; this copy will be released when the interpreter
- *terminates (during AssocData cleanup).
+ * Returns a writable per-interpreter (and hence thread-local) copy of
+ * the given spec-table with (some of) the char* fields converted into
+ * Tk_Uid fields; this copy will be released when the interpreter
+ * terminates (during AssocData cleanup).
*
* Results:
- *A pointer to the copied table.
+ * A pointer to the copied table.
*
* Notes:
- *The conversion to Tk_Uid is only done the first time, when the table
- *copy is taken. After that, the table is assumed to have Tk_Uids where
- *they are needed. The time of deletion of the caches isn't very
- *important unless you've got a lot of code that uses Tk_ConfigureWidget
- *(or *Info or *Value} when the interpreter is being deleted.
+ * The conversion to Tk_Uid is only done the first time, when the table
+ * copy is taken. After that, the table is assumed to have Tk_Uids where
+ * they are needed. The time of deletion of the caches isn't very
+ * important unless you've got a lot of code that uses Tk_ConfigureWidget
+ * (or *Info or *Value} when the interpreter is being deleted.
*
*--------------------------------------------------------------
*/
static Tk_ConfigSpec *
-GetCachedSpecs(interp, staticSpecs)
- Tcl_Interp *interp; /* Interpreter in which to store the cache. */
- CONST Tk_ConfigSpec *staticSpecs;
+GetCachedSpecs(
+ Tcl_Interp *interp, /* Interpreter in which to store the cache. */
+ const Tk_ConfigSpec *staticSpecs)
/* Value to cache a copy of; it is also used
* as a key into the cache. */
{
@@ -1107,7 +1088,7 @@ GetCachedSpecs(interp, staticSpecs)
&isNew);
if (isNew) {
unsigned int entrySpace = sizeof(Tk_ConfigSpec);
- CONST Tk_ConfigSpec *staticSpecPtr;
+ const Tk_ConfigSpec *staticSpecPtr;
Tk_ConfigSpec *specPtr;
/*
@@ -1126,7 +1107,7 @@ GetCachedSpecs(interp, staticSpecs)
*/
cachedSpecs = (Tk_ConfigSpec *) ckalloc(entrySpace);
- memcpy((void *) cachedSpecs, (void *) staticSpecs, entrySpace);
+ memcpy(cachedSpecs, staticSpecs, entrySpace);
Tcl_SetHashValue(entryPtr, (ClientData) cachedSpecs);
/*
@@ -1147,6 +1128,7 @@ GetCachedSpecs(interp, staticSpecs)
specPtr->defValue = Tk_GetUid(specPtr->defValue);
}
}
+ specPtr->specFlags &= ~TK_CONFIG_OPTION_SPECIFIED;
}
} else {
cachedSpecs = (Tk_ConfigSpec *) Tcl_GetHashValue(entryPtr);
@@ -1167,15 +1149,15 @@ GetCachedSpecs(interp, staticSpecs)
* None
*
* Side effects:
- * None
+ * None (does *not* use any Tk API).
*
*--------------------------------------------------------------
*/
static void
-DeleteSpecCacheTable(clientData, interp)
- ClientData clientData;
- Tcl_Interp *interp;
+DeleteSpecCacheTable(
+ ClientData clientData,
+ Tcl_Interp *interp)
{
Tcl_HashTable *tablePtr = (Tcl_HashTable *) clientData;
Tcl_HashEntry *entryPtr;
@@ -1192,3 +1174,11 @@ DeleteSpecCacheTable(clientData, interp)
Tcl_DeleteHashTable(tablePtr);
ckfree((char *) tablePtr);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkOldTest.c b/generic/tkOldTest.c
new file mode 100644
index 0000000..cfbce23
--- /dev/null
+++ b/generic/tkOldTest.c
@@ -0,0 +1,404 @@
+/*
+ * tkOldTest.c --
+ *
+ * This file contains C command functions for additional Tcl
+ * commands that are used to test Tk's support for legacy
+ * interfaces. These commands are not normally included in Tcl/Tk
+ * applications; they're only used for testing.
+ *
+ * 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.
+ * Contributions by Don Porter, NIST, 2007. (not subject to US copyright)
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#define USE_OLD_IMAGE
+#include "tkInt.h"
+
+/*
+ * The following data structure represents the master for a test image:
+ */
+
+typedef struct TImageMaster {
+ Tk_ImageMaster master; /* Tk's token for image master. */
+ Tcl_Interp *interp; /* Interpreter for application. */
+ int width, height; /* Dimensions of image. */
+ char *imageName; /* Name of image (malloc-ed). */
+ char *varName; /* Name of variable in which to log events for
+ * image (malloc-ed). */
+} TImageMaster;
+
+/*
+ * The following data structure represents a particular use of a particular
+ * test image.
+ */
+
+typedef struct TImageInstance {
+ TImageMaster *masterPtr; /* Pointer to master for image. */
+ XColor *fg; /* Foreground color for drawing in image. */
+ GC gc; /* Graphics context for drawing in image. */
+} TImageInstance;
+
+/*
+ * The type record for test images:
+ */
+
+static int ImageCreate(Tcl_Interp *interp,
+ char *name, int argc, char **argv,
+ Tk_ImageType *typePtr, Tk_ImageMaster master,
+ ClientData *clientDataPtr);
+static ClientData ImageGet(Tk_Window tkwin, ClientData clientData);
+static void ImageDisplay(ClientData clientData,
+ Display *display, Drawable drawable,
+ int imageX, int imageY, int width,
+ int height, int drawableX,
+ int drawableY);
+static void ImageFree(ClientData clientData, Display *display);
+static void ImageDelete(ClientData clientData);
+
+static Tk_ImageType imageType = {
+ "oldtest", /* name */
+ (Tk_ImageCreateProc *) ImageCreate, /* createProc */
+ ImageGet, /* getProc */
+ ImageDisplay, /* displayProc */
+ ImageFree, /* freeProc */
+ ImageDelete, /* deleteProc */
+ NULL, /* postscriptPtr */
+ NULL /* nextPtr */
+};
+
+/*
+ * Forward declarations for functions defined later in this file:
+ */
+
+static int ImageCmd(ClientData dummy,
+ Tcl_Interp *interp, int argc, CONST char **argv);
+MODULE_SCOPE int TkOldTestInit(Tcl_Interp *interp);
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkOldTestInit --
+ *
+ * This function performs intialization for the Tk test suite
+ * extensions for testing support for legacy interfaces.
+ *
+ * Results:
+ * Returns a standard Tcl completion code, and leaves an error message in
+ * the interp's result if an error occurs.
+ *
+ * Side effects:
+ * Creates several test commands.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkOldTestInit(
+ Tcl_Interp *interp)
+{
+ static int initialized = 0;
+
+ if (!initialized) {
+ initialized = 1;
+ Tk_CreateImageType(&imageType);
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ImageCreate --
+ *
+ * This function is called by the Tk image code to create "oldtest" images.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * The data structure for a new image is allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ /* ARGSUSED */
+static int
+ImageCreate(
+ Tcl_Interp *interp, /* Interpreter for application containing
+ * image. */
+ char *name, /* Name to use for image. */
+ int argc, /* Number of arguments. */
+ char **argv, /* Argument strings for options (doesn't
+ * include image name or type). */
+ Tk_ImageType *typePtr, /* Pointer to our type record (not used). */
+ Tk_ImageMaster master, /* Token for image, to be used by us in later
+ * callbacks. */
+ ClientData *clientDataPtr) /* Store manager's token for image here; it
+ * will be returned in later callbacks. */
+{
+ TImageMaster *timPtr;
+ char *varName;
+ int i;
+
+ varName = "log";
+ for (i = 0; i < argc; i += 2) {
+ if (strcmp(argv[i], "-variable") != 0) {
+ Tcl_AppendResult(interp, "bad option name \"",
+ argv[i], "\"", NULL);
+ return TCL_ERROR;
+ }
+ if ((i+1) == argc) {
+ Tcl_AppendResult(interp, "no value given for \"",
+ argv[i], "\" option", NULL);
+ return TCL_ERROR;
+ }
+ varName = argv[i+1];
+ }
+
+ timPtr = (TImageMaster *) ckalloc(sizeof(TImageMaster));
+ timPtr->master = master;
+ timPtr->interp = interp;
+ timPtr->width = 30;
+ timPtr->height = 15;
+ timPtr->imageName = (char *) ckalloc((unsigned) (strlen(name) + 1));
+ strcpy(timPtr->imageName, name);
+ timPtr->varName = (char *) ckalloc((unsigned) (strlen(varName) + 1));
+ strcpy(timPtr->varName, varName);
+ Tcl_CreateCommand(interp, name, ImageCmd, (ClientData) timPtr, NULL);
+ *clientDataPtr = (ClientData) timPtr;
+ Tk_ImageChanged(master, 0, 0, 30, 15, 30, 15);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ImageCmd --
+ *
+ * This function implements the commands corresponding to individual
+ * images.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * Forces windows to be created.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ /* ARGSUSED */
+static int
+ImageCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ CONST char **argv) /* Argument strings. */
+{
+ TImageMaster *timPtr = (TImageMaster *) clientData;
+ int x, y, width, height;
+
+ if (argc < 2) {
+ Tcl_AppendResult(interp, "wrong # args: should be \"",
+ argv[0], "option ?arg arg ...?", NULL);
+ return TCL_ERROR;
+ }
+ if (strcmp(argv[1], "changed") == 0) {
+ if (argc != 8) {
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+ " changed x y width height imageWidth imageHeight", NULL);
+ return TCL_ERROR;
+ }
+ if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK)
+ || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)
+ || (Tcl_GetInt(interp, argv[4], &width) != TCL_OK)
+ || (Tcl_GetInt(interp, argv[5], &height) != TCL_OK)
+ || (Tcl_GetInt(interp, argv[6], &timPtr->width) != TCL_OK)
+ || (Tcl_GetInt(interp, argv[7], &timPtr->height) != TCL_OK)) {
+ return TCL_ERROR;
+ }
+ Tk_ImageChanged(timPtr->master, x, y, width, height, timPtr->width,
+ timPtr->height);
+ } else {
+ Tcl_AppendResult(interp, "bad option \"", argv[1],
+ "\": must be changed", NULL);
+ return TCL_ERROR;
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ImageGet --
+ *
+ * This function is called by Tk to set things up for using a test image
+ * in a particular widget.
+ *
+ * Results:
+ * The return value is a token for the image instance, which is used in
+ * future callbacks to ImageDisplay and ImageFree.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ClientData
+ImageGet(
+ Tk_Window tkwin, /* Token for window in which image will be
+ * used. */
+ ClientData clientData) /* Pointer to TImageMaster for image. */
+{
+ TImageMaster *timPtr = (TImageMaster *) clientData;
+ TImageInstance *instPtr;
+ char buffer[100];
+ XGCValues gcValues;
+
+ sprintf(buffer, "%s get", timPtr->imageName);
+ Tcl_SetVar(timPtr->interp, timPtr->varName, buffer,
+ TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+
+ instPtr = (TImageInstance *) ckalloc(sizeof(TImageInstance));
+ instPtr->masterPtr = timPtr;
+ instPtr->fg = Tk_GetColor(timPtr->interp, tkwin, "#ff0000");
+ gcValues.foreground = instPtr->fg->pixel;
+ instPtr->gc = Tk_GetGC(tkwin, GCForeground, &gcValues);
+ return (ClientData) instPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ImageDisplay --
+ *
+ * This function is invoked to redisplay part or all of an image in a
+ * given drawable.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The image gets partially redrawn, as an "X" that shows the exact
+ * redraw area.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ImageDisplay(
+ ClientData clientData, /* Pointer to TImageInstance for image. */
+ Display *display, /* Display to use for drawing. */
+ Drawable drawable, /* Where to redraw image. */
+ int imageX, int imageY, /* Origin of area to redraw, relative to
+ * origin of image. */
+ int width, int height, /* Dimensions of area to redraw. */
+ int drawableX, int drawableY)
+ /* Coordinates in drawable corresponding to
+ * imageX and imageY. */
+{
+ TImageInstance *instPtr = (TImageInstance *) clientData;
+ char buffer[200 + TCL_INTEGER_SPACE * 6];
+
+ sprintf(buffer, "%s display %d %d %d %d %d %d",
+ instPtr->masterPtr->imageName, imageX, imageY, width, height,
+ drawableX, drawableY);
+ Tcl_SetVar(instPtr->masterPtr->interp, instPtr->masterPtr->varName, buffer,
+ TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+ if (width > (instPtr->masterPtr->width - imageX)) {
+ width = instPtr->masterPtr->width - imageX;
+ }
+ if (height > (instPtr->masterPtr->height - imageY)) {
+ height = instPtr->masterPtr->height - imageY;
+ }
+ XDrawRectangle(display, drawable, instPtr->gc, drawableX, drawableY,
+ (unsigned) (width-1), (unsigned) (height-1));
+ XDrawLine(display, drawable, instPtr->gc, drawableX, drawableY,
+ (int) (drawableX + width - 1), (int) (drawableY + height - 1));
+ XDrawLine(display, drawable, instPtr->gc, drawableX,
+ (int) (drawableY + height - 1),
+ (int) (drawableX + width - 1), drawableY);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ImageFree --
+ *
+ * This function is called when an instance of an image is no longer
+ * used.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Information related to the instance is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ImageFree(
+ ClientData clientData, /* Pointer to TImageInstance for instance. */
+ Display *display) /* Display where image was to be drawn. */
+{
+ TImageInstance *instPtr = (TImageInstance *) clientData;
+ char buffer[200];
+
+ sprintf(buffer, "%s free", instPtr->masterPtr->imageName);
+ Tcl_SetVar(instPtr->masterPtr->interp, instPtr->masterPtr->varName, buffer,
+ TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+ Tk_FreeColor(instPtr->fg);
+ Tk_FreeGC(display, instPtr->gc);
+ ckfree((char *) instPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ImageDelete --
+ *
+ * This function is called to clean up a test image when an application
+ * goes away.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Information about the image is deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ImageDelete(
+ ClientData clientData) /* Pointer to TImageMaster for image. When
+ * this function is called, no more instances
+ * exist. */
+{
+ TImageMaster *timPtr = (TImageMaster *) clientData;
+ char buffer[100];
+
+ sprintf(buffer, "%s delete", timPtr->imageName);
+ Tcl_SetVar(timPtr->interp, timPtr->varName, buffer,
+ TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+
+ Tcl_DeleteCommand(timPtr->interp, timPtr->imageName);
+ ckfree(timPtr->imageName);
+ ckfree(timPtr->varName);
+ ckfree((char *) timPtr);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkOption.c b/generic/tkOption.c
index 0df3f8d..de92627 100644
--- a/generic/tkOption.c
+++ b/generic/tkOption.c
@@ -1,93 +1,90 @@
-/*
+/*
* tkOption.c --
*
- * This module contains procedures to manage the option
- * database, which allows various strings to be associated
- * with windows either by name or by class or both.
+ * This module contains functions to manage the option database, which
+ * allows various strings to be associated with windows either by name or
+ * by class or both.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
/*
- * The option database is stored as one tree for each main window.
- * Each name or class field in an option is associated with a node or
- * leaf of the tree. For example, the options "x.y.z" and "x.y*a"
- * each correspond to three nodes in the tree; they share the nodes
- * "x" and "x.y", but have different leaf nodes. One of the following
- * structures exists for each node or leaf in the option tree. It is
- * actually stored as part of the parent node, and describes a particular
- * child of the parent.
- *
- * The structure of the option db tree is a little confusing. There are
- * four different kinds of nodes in the tree:
+ * The option database is stored as one tree for each main window. Each name
+ * or class field in an option is associated with a node or leaf of the tree.
+ * For example, the options "x.y.z" and "x.y*a" each correspond to three nodes
+ * in the tree; they share the nodes "x" and "x.y", but have different leaf
+ * nodes. One of the following structures exists for each node or leaf in the
+ * option tree. It is actually stored as part of the parent node, and
+ * describes a particular child of the parent.
+ *
+ * The structure of the option db tree is a little confusing. There are four
+ * different kinds of nodes in the tree:
* interior class nodes
* interior name nodes
* leaf class nodes
* leaf name nodes
*
* All interior nodes refer to _window_ classes and names; all leaf nodes
- * refer to _option_ classes and names. When looking for a particular option,
+ * refer to _option_ classes and names. When looking for a particular option,
* therefore, you must compare interior node values to corresponding window
* values, and compare leaf node values to corresponding option values.
*
* The tree is actually stored in a collection of arrays; there is one each
- * combination of WILDCARD/EXACT and CLASS/NAME and NODE/LEAF. The NODE arrays
+ * combination of WILDCARD/EXACT and CLASS/NAME and NODE/LEAF. The NODE arrays
* contain the interior nodes of the tree; each element has a pointer to an
- * array of elements which are the leaves of the tree. The LEAF arrays, rather
+ * array of elements which are the leaves of the tree. The LEAF arrays, rather
* than holding the leaves of the tree, hold a cached subset of the option
* database, consisting of the values of all defined options for a single
* window, and some additional information about each ancestor of the window
- * (since some options may be inherited from a parent), all the way back to the
- * root window.
+ * (since some options may be inherited from a parent), all the way back to
+ * the root window.
*
* Each time a call is made to Tk_GetOption, Tk will attempt to use the cached
- * information to satisfy the lookup. If the call is for a window other than
+ * information to satisfy the lookup. If the call is for a window other than
* that for which options are currently cached, the portion of the cache that
- * contains information for common ancestors of the two windows is retained and
- * the remainder is discarded and rebuilt with new information for the new
+ * contains information for common ancestors of the two windows is retained
+ * and the remainder is discarded and rebuilt with new information for the new
* window.
*/
typedef struct Element {
- Tk_Uid nameUid; /* Name or class from one element of
- * an option spec. */
+ Tk_Uid nameUid; /* Name or class from one element of an option
+ * spec. */
union {
- struct ElArray *arrayPtr; /* If this is an intermediate node,
- * a pointer to a structure describing
- * the remaining elements of all
- * options whose prefixes are the
- * same up through this element. */
- Tk_Uid valueUid; /* For leaf nodes, this is the string
- * value of the option. */
+ struct ElArray *arrayPtr;
+ /* If this is an intermediate node, a pointer
+ * to a structure describing the remaining
+ * elements of all options whose prefixes are
+ * the same up through this element. */
+ Tk_Uid valueUid; /* For leaf nodes, this is the string value of
+ * the option. */
} child;
- int priority; /* Used to select among matching
- * options. Includes both the
- * priority level and a serial #.
- * Greater value means higher
- * priority. Irrelevant except in
- * leaf nodes. */
- int flags; /* OR-ed combination of bits. See
- * below for values. */
+ int priority; /* Used to select among matching options.
+ * Includes both the priority level and a
+ * serial #. Greater value means higher
+ * priority. Irrelevant except in leaf
+ * nodes. */
+ int flags; /* OR-ed combination of bits. See below for
+ * values. */
} Element;
/*
* Flags in Element structures:
*
- * CLASS - Non-zero means this element refers to a class,
- * Zero means this element refers to a name.
- * NODE - Zero means this is a leaf element (the child
- * field is a value, not a pointer to another node).
- * One means this is a node element.
- * WILDCARD - Non-zero means this there was a star in the
- * original specification just before this element.
- * Zero means there was a dot.
+ * CLASS - Non-zero means this element refers to a class, zero
+ * means this element refers to a name.
+ * NODE - Zero means this is a leaf element (the child field is
+ * a value, not a pointer to another node). One means
+ * this is a node element.
+ * WILDCARD - Non-zero means this there was a star in the original
+ * specification just before this element. Zero means
+ * there was a dot.
*/
#define TYPE_MASK 0x7
@@ -106,25 +103,22 @@ typedef struct Element {
#define WILDCARD_NODE_CLASS 0x7
/*
- * The following structure is used to manage a dynamic array of
- * Elements. These structures are used for two purposes: to store
- * the contents of a node in the option tree, and for the option
- * stacks described below.
+ * The following structure is used to manage a dynamic array of Elements.
+ * These structures are used for two purposes: to store the contents of a node
+ * in the option tree, and for the option stacks described below.
*/
typedef struct ElArray {
- int arraySize; /* Number of elements actually
- * allocated in the "els" array. */
- int numUsed; /* Number of elements currently in
- * use out of els. */
+ int arraySize; /* Number of elements actually allocated in
+ * the "els" array. */
+ int numUsed; /* Number of elements currently in use out of
+ * els. */
Element *nextToUse; /* Pointer to &els[numUsed]. */
- Element els[1]; /* Array of structures describing
- * children of this node. The
- * array will actually contain enough
- * elements for all of the children
- * (and even a few extras, perhaps).
- * This must be the last field in
- * the structure. */
+ Element els[1]; /* Array of structures describing children of
+ * this node. The array will actually contain
+ * enough elements for all of the children
+ * (and even a few extras, perhaps). This must
+ * be the last field in the structure. */
} ElArray;
#define EL_ARRAY_SIZE(numEls) ((unsigned) (sizeof(ElArray) \
@@ -133,114 +127,104 @@ typedef struct ElArray {
/*
* In addition to the option tree, which is a relatively static structure,
- * there are eight additional structures called "stacks", which are used
- * to speed up queries into the option database. The stack structures
- * are designed for the situation where an individual widget makes repeated
- * requests for its particular options. The requests differ only in
- * their last name/class, so during the first request we extract all
- * the options pertaining to the particular widget and save them in a
- * stack-like cache; subsequent requests for the same widget can search
- * the cache relatively quickly. In fact, the cache is a hierarchical
- * one, storing a list of relevant options for this widget and all of
- * its ancestors up to the application root; hence the name "stack".
- *
- * Each of the eight stacks consists of an array of Elements, ordered in
- * terms of levels in the window hierarchy. All the elements relevant
- * for the top-level widget appear first in the array, followed by all
- * those from the next-level widget on the path to the current widget,
- * etc. down to those for the current widget.
- *
- * Cached information is divided into eight stacks according to the
- * CLASS, NODE, and WILDCARD flags. Leaf and non-leaf information is
- * kept separate to speed up individual probes (non-leaf information is
- * only relevant when building the stacks, but isn't relevant when
- * making probes; similarly, only non-leaf information is relevant
- * when the stacks are being extended to the next widget down in the
- * widget hierarchy). Wildcard elements are handled separately from
- * "exact" elements because once they appear at a particular level in
- * the stack they remain active for all deeper levels; exact elements
- * are only relevant at a particular level. For example, when searching
- * for options relevant in a particular window, the entire wildcard
- * stacks get checked, but only the portions of the exact stacks that
- * pertain to the window's parent. Lastly, name and class stacks are
- * kept separate because different search keys are used when searching
- * them; keeping them separate speeds up the searches.
+ * there are eight additional structures called "stacks", which are used to
+ * speed up queries into the option database. The stack structures are
+ * designed for the situation where an individual widget makes repeated
+ * requests for its particular options. The requests differ only in their last
+ * name/class, so during the first request we extract all the options
+ * pertaining to the particular widget and save them in a stack-like cache;
+ * subsequent requests for the same widget can search the cache relatively
+ * quickly. In fact, the cache is a hierarchical one, storing a list of
+ * relevant options for this widget and all of its ancestors up to the
+ * application root; hence the name "stack".
+ *
+ * Each of the eight stacks consists of an array of Elements, ordered in terms
+ * of levels in the window hierarchy. All the elements relevant for the
+ * top-level widget appear first in the array, followed by all those from the
+ * next-level widget on the path to the current widget, etc. down to those for
+ * the current widget.
+ *
+ * Cached information is divided into eight stacks according to the CLASS,
+ * NODE, and WILDCARD flags. Leaf and non-leaf information is kept separate to
+ * speed up individual probes (non-leaf information is only relevant when
+ * building the stacks, but isn't relevant when making probes; similarly, only
+ * non-leaf information is relevant when the stacks are being extended to the
+ * next widget down in the widget hierarchy). Wildcard elements are handled
+ * separately from "exact" elements because once they appear at a particular
+ * level in the stack they remain active for all deeper levels; exact elements
+ * are only relevant at a particular level. For example, when searching for
+ * options relevant in a particular window, the entire wildcard stacks get
+ * checked, but only the portions of the exact stacks that pertain to the
+ * window's parent. Lastly, name and class stacks are kept separate because
+ * different search keys are used when searching them; keeping them separate
+ * speeds up the searches.
*/
#define NUM_STACKS 8
/*
- * One of the following structures is used to keep track of each
- * level in the stacks.
+ * One of the following structures is used to keep track of each level in the
+ * stacks.
*/
typedef struct StackLevel {
TkWindow *winPtr; /* Window corresponding to this stack
* level. */
- int bases[NUM_STACKS]; /* For each stack, index of first
- * element on stack corresponding to
- * this level (used to restore "numUsed"
- * fields when popping out of a level. */
+ int bases[NUM_STACKS]; /* For each stack, index of first element on
+ * stack corresponding to this level (used to
+ * restore "numUsed" fields when popping out
+ * of a level. */
} StackLevel;
typedef struct ThreadSpecificData {
- int initialized; /* 0 means the ThreadSpecific Data structure
+ 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. */
+ 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.
+ * Information about all of the stack levels that are currently active.
+ * This array grows dynamically to become as large as needed.
*/
- 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.
- */
-
- int serial;
- Element defaultMatch; /* Special "no match" Element to use as
+ 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...) */
+ int serial; /* 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. */
+ 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:
+ * Forward declarations for functions defined in this file:
*/
-static int AddFromString _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, char *string, int priority));
-static void ClearOptionTree _ANSI_ARGS_((ElArray *arrayPtr));
-static ElArray * ExtendArray _ANSI_ARGS_((ElArray *arrayPtr,
- Element *elPtr));
-static void ExtendStacks _ANSI_ARGS_((ElArray *arrayPtr,
- int leaf));
-static int GetDefaultOptions _ANSI_ARGS_((Tcl_Interp *interp,
- TkWindow *winPtr));
-static ElArray * NewArray _ANSI_ARGS_((int numEls));
-static void OptionThreadExitProc _ANSI_ARGS_((
- ClientData clientData));
-static void OptionInit _ANSI_ARGS_((TkMainInfo *mainPtr));
-static int ParsePriority _ANSI_ARGS_((Tcl_Interp *interp,
- char *string));
-static int ReadOptionFile _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, char *fileName, int priority));
-static void SetupStacks _ANSI_ARGS_((TkWindow *winPtr, int leaf));
+static int AddFromString(Tcl_Interp *interp, Tk_Window tkwin,
+ char *string, int priority);
+static void ClearOptionTree(ElArray *arrayPtr);
+static ElArray * ExtendArray(ElArray *arrayPtr, Element *elPtr);
+static void ExtendStacks(ElArray *arrayPtr, int leaf);
+static int GetDefaultOptions(Tcl_Interp *interp,
+ TkWindow *winPtr);
+static ElArray * NewArray(int numEls);
+static void OptionThreadExitProc(ClientData clientData);
+static void OptionInit(TkMainInfo *mainPtr);
+static int ParsePriority(Tcl_Interp *interp, char *string);
+static int ReadOptionFile(Tcl_Interp *interp, Tk_Window tkwin,
+ char *fileName, int priority);
+static void SetupStacks(TkWindow *winPtr, int leaf);
/*
*--------------------------------------------------------------
@@ -259,15 +243,15 @@ static void SetupStacks _ANSI_ARGS_((TkWindow *winPtr, int leaf));
*/
void
-Tk_AddOption(tkwin, name, value, priority)
- Tk_Window tkwin; /* Window token; option will be associated
+Tk_AddOption(
+ Tk_Window tkwin, /* Window token; option will be associated
* with main window for this window. */
- CONST char *name; /* Multi-element name of option. */
- CONST char *value; /* String value for option. */
- int priority; /* Overall priority level to use for
- * this option, such as TK_USER_DEFAULT_PRIO
- * or TK_INTERACTIVE_PRIO. Must be between
- * 0 and TK_MAX_PRIO. */
+ CONST char *name, /* Multi-element name of option. */
+ CONST char *value, /* String value for option. */
+ int priority) /* Overall priority level to use for this
+ * option, such as TK_USER_DEFAULT_PRIO or
+ * TK_INTERACTIVE_PRIO. Must be between 0 and
+ * TK_MAX_PRIO. */
{
TkWindow *winPtr = ((TkWindow *) tkwin)->mainPtr->winPtr;
register ElArray **arrayPtrPtr;
@@ -275,21 +259,21 @@ Tk_AddOption(tkwin, name, value, priority)
Element newEl;
register CONST char *p;
CONST char *field;
- int count, firstField, length;
+ int count, firstField;
+ ptrdiff_t length;
#define TMP_SIZE 100
char tmp[TMP_SIZE+1];
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (winPtr->mainPtr->optionRootPtr == NULL) {
OptionInit(winPtr->mainPtr);
}
- tsdPtr->cachedWindow = NULL; /* Invalidate the cache. */
+ tsdPtr->cachedWindow = NULL;/* Invalidate the cache. */
/*
- * Compute the priority for the new element, including both the
- * overall level and the serial number (to disambiguate with the
- * level).
+ * Compute the priority for the new element, including both the overall
+ * level and the serial number (to disambiguate with the level).
*/
if (priority < 0) {
@@ -307,11 +291,10 @@ Tk_AddOption(tkwin, name, value, priority)
arrayPtrPtr = &(((TkWindow *) tkwin)->mainPtr->optionRootPtr);
p = name;
for (firstField = 1; ; firstField = 0) {
-
/*
- * Scan the next field from the name and convert it to a Tk_Uid.
- * Must copy the field before calling Tk_Uid, so that a terminating
- * NULL may be added without modifying the source string.
+ * Scan the next field from the name and convert it to a Tk_Uid. Must
+ * copy the field before calling Tk_Uid, so that a terminating NULL
+ * may be added without modifying the source string.
*/
if (*p == '*') {
@@ -336,12 +319,10 @@ Tk_AddOption(tkwin, name, value, priority)
}
if (*p != 0) {
-
/*
- * New element will be a node. If this option can't possibly
- * apply to this main window, then just skip it. Otherwise,
- * add it to the parent, if it isn't already there, and descend
- * into it.
+ * New element will be a node. If this option can't possibly apply
+ * to this main window, then just skip it. Otherwise, add it to
+ * the parent, if it isn't already there, and descend into it.
*/
newEl.flags |= NODE;
@@ -355,7 +336,8 @@ Tk_AddOption(tkwin, name, value, priority)
if (count == 0) {
newEl.child.arrayPtr = NewArray(5);
*arrayPtrPtr = ExtendArray(*arrayPtrPtr, &newEl);
- arrayPtrPtr = &((*arrayPtrPtr)->nextToUse[-1].child.arrayPtr);
+ arrayPtrPtr = &((*arrayPtrPtr)
+ ->nextToUse[-1].child.arrayPtr);
break;
}
if ((elPtr->nameUid == newEl.nameUid)
@@ -368,11 +350,10 @@ Tk_AddOption(tkwin, name, value, priority)
p++;
}
} else {
-
/*
- * New element is a leaf. Add it to the parent, if it isn't
- * already there. If it exists already, keep whichever value
- * has highest priority.
+ * New element is a leaf. Add it to the parent, if it isn't
+ * already there. If it exists already, keep whichever value has
+ * highest priority.
*/
newEl.child.valueUid = Tk_GetUid(value);
@@ -403,27 +384,26 @@ Tk_AddOption(tkwin, name, value, priority)
* Retrieve an option from the option database.
*
* Results:
- * The return value is the value specified in the option
- * database for the given name and class on the given
- * window. If there is nothing specified in the database
- * for that option, then NULL is returned.
+ * The return value is the value specified in the option database for the
+ * given name and class on the given window. If there is nothing
+ * specified in the database for that option, then NULL is returned.
*
* Side effects:
- * The internal caches used to speed up option mapping
- * may be modified, if this tkwin is different from the
- * last tkwin used for option retrieval.
+ * The internal caches used to speed up option mapping may be modified,
+ * if this tkwin is different from the last tkwin used for option
+ * retrieval.
*
*--------------------------------------------------------------
*/
Tk_Uid
-Tk_GetOption(tkwin, name, className)
- Tk_Window tkwin; /* Token for window that option is
- * associated with. */
- CONST char *name; /* Name of option. */
- CONST char *className; /* Class of option. NULL means there
- * is no class for this option: just
- * check for name. */
+Tk_GetOption(
+ Tk_Window tkwin, /* Token for window that option is associated
+ * with. */
+ CONST char *name, /* Name of option. */
+ CONST char *className) /* Class of option. NULL means there is no
+ * class for this option: just check for
+ * name. */
{
Tk_Uid nameId, classId = NULL;
char *masqName;
@@ -431,12 +411,12 @@ Tk_GetOption(tkwin, name, className)
register int count;
StackLevel *levelPtr;
int stackDepth[NUM_STACKS];
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ 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).
+ * Note: no need to call OptionInit here: it will be done by the
+ * SetupStacks call below (squeeze out those nanoseconds).
*/
if (tkwin != (Tk_Window) tsdPtr->cachedWindow) {
@@ -446,32 +426,33 @@ Tk_GetOption(tkwin, name, className)
/*
* Get a default "best" match.
*/
-
+
bestPtr = &tsdPtr->defaultMatch;
/*
* For megawidget support, we want to have some widget options masquerade
- * as options for other widgets. For example, a combobox has a button in
+ * as options for other widgets. For example, a combobox has a button in
* it; this button ought to pick up the *Button.background, etc., options.
* But because the class of the widget is Combobox, our normal search
* won't get that option.
*
* To work around this, the option name field syntax was extended to allow
* for a "." in the name; if this character occurs in the name, then it
- * indicates that this name contains a new window class and an option name,
- * ie, "Button.foreground". If we see this form in the name field, we
- * query the option database directly (since the option stacks will not
+ * indicates that this name contains a new window class and an option
+ * name, ie, "Button.foreground". If we see this form in the name field,
+ * we query the option database directly (since the option stacks will not
* have the information we need).
*/
masqName = strchr(name, (int)'.');
if (masqName != NULL) {
/*
- * This option is masquerading with a different window class.
- * Search the stack to the depth it was before the current window's
+ * This option is masquerading with a different window class. Search
+ * the stack to the depth it was before the current window's
* information was pushed (the value for which is stored in the bases
* field).
*/
+
levelPtr = &tsdPtr->levels[tsdPtr->curLevel];
nameId = Tk_GetUid(masqName+1);
for (count = 0; count < NUM_STACKS; count++) {
@@ -479,9 +460,10 @@ Tk_GetOption(tkwin, name, className)
}
} else {
/*
- * No option masquerading here. Just use the current level to get the
+ * No option masquerading here. Just use the current level to get the
* stack depths.
*/
+
nameId = Tk_GetUid(name);
for (count = 0; count < NUM_STACKS; count++) {
stackDepth[count] = tsdPtr->stacks[count]->numUsed;
@@ -528,11 +510,11 @@ Tk_GetOption(tkwin, name, className)
}
}
}
-
+
/*
- * If this option was masquerading with a different window class,
- * probe the option database now. Note that this will be inefficient
- * if the option database is densely populated, or if the widget has many
+ * If this option was masquerading with a different window class, probe
+ * the option database now. Note that this will be inefficient if the
+ * option database is densely populated, or if the widget has many
* masquerading options.
*/
@@ -541,43 +523,42 @@ Tk_GetOption(tkwin, name, className)
Tk_Uid nodeId, winClassId, winNameId;
unsigned int classNameLength;
register Element *nodePtr, *leafPtr;
- static int searchOrder[] = { EXACT_NODE_NAME,
- WILDCARD_NODE_NAME,
- EXACT_NODE_CLASS,
- WILDCARD_NODE_CLASS,
- -1 };
+ static int searchOrder[] = {
+ EXACT_NODE_NAME, WILDCARD_NODE_NAME, EXACT_NODE_CLASS,
+ WILDCARD_NODE_CLASS, -1
+ };
int *currentPtr, currentStack, leafCount;
-
+
/*
* Extract the masquerade class name from the name field.
*/
-
+
classNameLength = (unsigned int)(masqName - name);
- masqClass = (char *)ckalloc(classNameLength + 1);
+ masqClass = (char *) ckalloc(classNameLength + 1);
strncpy(masqClass, name, classNameLength);
masqClass[classNameLength] = '\0';
-
- winClassId = Tk_GetUid(masqClass);
+
+ winClassId = Tk_GetUid(masqClass);
ckfree(masqClass);
- winNameId = ((TkWindow *)tkwin)->nameUid;
+ winNameId = ((TkWindow *)tkwin)->nameUid;
levelPtr = &tsdPtr->levels[tsdPtr->curLevel];
for (currentPtr = searchOrder; *currentPtr != -1; currentPtr++) {
currentStack = *currentPtr;
- nodePtr = tsdPtr->stacks[currentStack]->els;
- count = levelPtr->bases[currentStack];
+ nodePtr = tsdPtr->stacks[currentStack]->els;
+ count = levelPtr->bases[currentStack];
/*
- * For wildcard stacks, check all entries; for non-wildcard
+ * For wildcard stacks, check all entries; for non-wildcard
* stacks, only check things that matched in the parent.
*/
-
+
if (!(currentStack & WILDCARD)) {
nodePtr += levelPtr[-1].bases[currentStack];
count -= levelPtr[-1].bases[currentStack];
}
-
+
if (currentStack && CLASS) {
nodeId = winClassId;
} else {
@@ -586,8 +567,8 @@ Tk_GetOption(tkwin, name, className)
for ( ; count > 0; nodePtr++, count--) {
if (nodePtr->nameUid == nodeId) {
- leafPtr = nodePtr->child.arrayPtr->els;
- leafCount = nodePtr->child.arrayPtr->numUsed;
+ leafPtr = nodePtr->child.arrayPtr->els;
+ leafCount = nodePtr->child.arrayPtr->numUsed;
for ( ; leafCount > 0; leafPtr++, leafCount--) {
if (leafPtr->flags & CLASS && className != NULL) {
if (leafPtr->nameUid == classId &&
@@ -605,7 +586,7 @@ Tk_GetOption(tkwin, name, className)
}
}
}
-
+
return bestPtr->child.valueUid;
}
@@ -614,8 +595,8 @@ Tk_GetOption(tkwin, name, className)
*
* Tk_OptionObjCmd --
*
- * This procedure is invoked to process the "option" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "option" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -627,17 +608,16 @@ Tk_GetOption(tkwin, name, className)
*/
int
-Tk_OptionObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of Tcl_Obj arguments. */
- Tcl_Obj *CONST objv[]; /* Tcl_Obj arguments. */
+Tk_OptionObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of Tcl_Obj arguments. */
+ Tcl_Obj *CONST objv[]) /* Tcl_Obj arguments. */
{
Tk_Window tkwin = (Tk_Window) clientData;
int index, result;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
static CONST char *optionCmds[] = {
"add", "clear", "get", "readfile", NULL
@@ -657,85 +637,85 @@ Tk_OptionObjCmd(clientData, interp, objc, objv)
if (result != TCL_OK) {
return result;
}
-
+
result = TCL_OK;
switch ((enum optionVals) index) {
- case OPTION_ADD: {
- int priority;
- if ((objc != 4) && (objc != 5)) {
- Tcl_WrongNumArgs(interp, 2, objv, "pattern value ?priority?");
+ case OPTION_ADD: {
+ int priority;
+ if ((objc != 4) && (objc != 5)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pattern value ?priority?");
+ return TCL_ERROR;
+ }
+
+ if (objc == 4) {
+ priority = TK_INTERACTIVE_PRIO;
+ } else {
+ priority = ParsePriority(interp, Tcl_GetString(objv[4]));
+ if (priority < 0) {
return TCL_ERROR;
}
+ }
+ Tk_AddOption(tkwin, Tcl_GetString(objv[2]), Tcl_GetString(objv[3]),
+ priority);
+ break;
+ }
- if (objc == 4) {
- priority = TK_INTERACTIVE_PRIO;
- } else {
- priority = ParsePriority(interp, Tcl_GetString(objv[4]));
- if (priority < 0) {
- return TCL_ERROR;
- }
- }
- Tk_AddOption(tkwin, Tcl_GetString(objv[2]),
- Tcl_GetString(objv[3]), priority);
- break;
+ case OPTION_CLEAR: {
+ TkMainInfo *mainPtr;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "");
+ return TCL_ERROR;
+ }
+ mainPtr = ((TkWindow *) tkwin)->mainPtr;
+ if (mainPtr->optionRootPtr != NULL) {
+ ClearOptionTree(mainPtr->optionRootPtr);
+ mainPtr->optionRootPtr = NULL;
}
+ tsdPtr->cachedWindow = NULL;
+ break;
+ }
- case OPTION_CLEAR: {
- TkMainInfo *mainPtr;
+ case OPTION_GET: {
+ Tk_Window window;
+ Tk_Uid value;
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "");
- return TCL_ERROR;
- }
- mainPtr = ((TkWindow *) tkwin)->mainPtr;
- if (mainPtr->optionRootPtr != NULL) {
- ClearOptionTree(mainPtr->optionRootPtr);
- mainPtr->optionRootPtr = NULL;
- }
- tsdPtr->cachedWindow = NULL;
- break;
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window name class");
+ return TCL_ERROR;
+ }
+ window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
+ if (window == NULL) {
+ return TCL_ERROR;
}
+ value = Tk_GetOption(window, Tcl_GetString(objv[3]),
+ Tcl_GetString(objv[4]));
+ if (value != NULL) {
+ Tcl_SetResult(interp, (char *)value, TCL_STATIC);
+ }
+ break;
+ }
- case OPTION_GET: {
- Tk_Window window;
- Tk_Uid value;
-
- if (objc != 5) {
- Tcl_WrongNumArgs(interp, 2, objv, "window name class");
- return TCL_ERROR;
- }
- window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
- if (window == NULL) {
- return TCL_ERROR;
- }
- value = Tk_GetOption(window, Tcl_GetString(objv[3]),
- Tcl_GetString(objv[4]));
- if (value != NULL) {
- Tcl_SetResult(interp, (char *)value, TCL_STATIC);
- }
- break;
+ case OPTION_READFILE: {
+ int priority;
+
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "fileName ?priority?");
+ return TCL_ERROR;
}
- case OPTION_READFILE: {
- int priority;
-
- if ((objc != 3) && (objc != 4)) {
- Tcl_WrongNumArgs(interp, 2, objv, "fileName ?priority?");
+ if (objc == 4) {
+ priority = ParsePriority(interp, Tcl_GetString(objv[3]));
+ if (priority < 0) {
return TCL_ERROR;
}
-
- if (objc == 4) {
- priority = ParsePriority(interp, Tcl_GetString(objv[3]));
- if (priority < 0) {
- return TCL_ERROR;
- }
- } else {
- priority = TK_INTERACTIVE_PRIO;
- }
- result = ReadOptionFile(interp, tkwin, Tcl_GetString(objv[2]),
- priority);
- break;
+ } else {
+ priority = TK_INTERACTIVE_PRIO;
}
+ result = ReadOptionFile(interp, tkwin, Tcl_GetString(objv[2]),
+ priority);
+ break;
+ }
}
return result;
}
@@ -745,33 +725,31 @@ Tk_OptionObjCmd(clientData, interp, objc, objv)
*
* TkOptionDeadWindow --
*
- * This procedure is called whenever a window is deleted.
- * It cleans up any option-related stuff associated with
- * the window.
+ * This function is called whenever a window is deleted. It cleans up any
+ * option-related stuff associated with the window.
*
* Results:
* None.
*
* Side effects:
- * Option-related resources are freed. See code below
- * for details.
+ * Option-related resources are freed. See code below for details.
*
*--------------------------------------------------------------
*/
void
-TkOptionDeadWindow(winPtr)
- register TkWindow *winPtr; /* Window to be cleaned up. */
+TkOptionDeadWindow(
+ register TkWindow *winPtr) /* Window to be cleaned up. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
* If this window is in the option stacks, then clear the stacks.
*
* XXX: OptionThreadExitProc will be invoked before DeleteWindowsExitProc
* XXX: if it is thread-specific (which it should be), invalidating the
- * XXX: tsd. Tk shutdown needs to be verified to handle this correctly.
+ * XXX: tsd. Tk shutdown needs to be verified to handle this correctly.
*/
if (tsdPtr->initialized && (winPtr->optionLevel != -1)) {
@@ -785,8 +763,7 @@ TkOptionDeadWindow(winPtr)
}
/*
- * If this window was a main window, then delete its option
- * database.
+ * If this window was a main window, then delete its option database.
*/
if ((winPtr->mainPtr != NULL) && (winPtr->mainPtr->winPtr == winPtr)
@@ -801,10 +778,9 @@ TkOptionDeadWindow(winPtr)
*
* TkOptionClassChanged --
*
- * This procedure is invoked when a window's class changes. If
- * the window is on the option cache, this procedure flushes
- * any information for the window, since the new class could change
- * what is relevant.
+ * This function is invoked when a window's class changes. If the window
+ * is on the option cache, this function flushes any information for the
+ * window, since the new class could change what is relevant.
*
* Results:
* None.
@@ -816,21 +792,21 @@ TkOptionDeadWindow(winPtr)
*/
void
-TkOptionClassChanged(winPtr)
- TkWindow *winPtr; /* Window whose class changed. */
+TkOptionClassChanged(
+ TkWindow *winPtr) /* Window whose class changed. */
{
int i, j, *basePtr;
ElArray *arrayPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (winPtr->optionLevel == -1) {
return;
}
/*
- * Find the lowest stack level that refers to this window, then
- * flush all of the levels above the matching one.
+ * Find the lowest stack level that refers to this window, then flush all
+ * of the levels above the matching one.
*/
for (i = 1; i <= tsdPtr->curLevel; i++) {
@@ -863,9 +839,9 @@ TkOptionClassChanged(winPtr)
* Parse a string priority value.
*
* 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 the interp's result.
+ * 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 the interp's result.
*
* Side effects:
* None.
@@ -874,9 +850,9 @@ TkOptionClassChanged(winPtr)
*/
static int
-ParsePriority(interp, string)
- Tcl_Interp *interp; /* Interpreter to use for error reporting. */
- char *string; /* Describes a priority level, either
+ParsePriority(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ char *string) /* Describes a priority level, either
* symbolically or numerically. */
{
int priority, c;
@@ -902,10 +878,9 @@ ParsePriority(interp, string)
priority = strtoul(string, &end, 0);
if ((end == string) || (*end != 0) || (priority < 0)
|| (priority > 100)) {
- Tcl_AppendResult(interp, "bad priority level \"", string,
+ Tcl_AppendResult(interp, "bad priority level \"", string,
"\": must be widgetDefault, startupFile, userDefault, ",
- "interactive, or a number between 0 and 100",
- (char *) NULL);
+ "interactive, or a number between 0 and 100", NULL);
return -1;
}
}
@@ -917,17 +892,17 @@ ParsePriority(interp, string)
*
* AddFromString --
*
- * Given a string containing lines in the standard format for
- * X resources (see other documentation for details on what this
- * is), parse the resource specifications and enter them as options
- * for tkwin's main window.
+ * Given a string containing lines in the standard format for X resources
+ * (see other documentation for details on what this is), parse the
+ * resource specifications and enter them as options for tkwin's main
+ * window.
*
* 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 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.
+ * 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 the interp's result. The memory at string is
+ * totally trashed by this function. If you care about its contents, make
+ * a copy before calling here.
*
* Side effects:
* None.
@@ -936,15 +911,15 @@ ParsePriority(interp, string)
*/
static int
-AddFromString(interp, tkwin, string, priority)
- Tcl_Interp *interp; /* Interpreter to use for reporting results. */
- Tk_Window tkwin; /* Token for window: options are entered
- * for this window's main window. */
- char *string; /* String containing option specifiers. */
- int priority; /* Priority level to use for options in
- * this string, such as TK_USER_DEFAULT_PRIO
- * or TK_INTERACTIVE_PRIO. Must be between
- * 0 and TK_MAX_PRIO. */
+AddFromString(
+ Tcl_Interp *interp, /* Interpreter to use for reporting results. */
+ Tk_Window tkwin, /* Token for window: options are entered for
+ * this window's main window. */
+ char *string, /* String containing option specifiers. */
+ int priority) /* Priority level to use for options in this
+ * string, such as TK_USER_DEFAULT_PRIO or
+ * TK_INTERACTIVE_PRIO. Must be between 0 and
+ * TK_MAX_PRIO. */
{
register char *src, *dst;
char *name, *value;
@@ -975,7 +950,7 @@ AddFromString(interp, tkwin, string, priority)
src++;
lineNum++;
continue;
- }
+ }
if (*src == '\0') {
break;
}
@@ -989,7 +964,7 @@ AddFromString(interp, tkwin, string, priority)
while (*src != ':') {
if ((*src == '\0') || (*src == '\n')) {
char buf[32 + TCL_INTEGER_SPACE];
-
+
sprintf(buf, "missing colon on line %d", lineNum);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_ERROR;
@@ -1024,7 +999,7 @@ AddFromString(interp, tkwin, string, priority)
}
if (*src == '\0') {
char buf[32 + TCL_INTEGER_SPACE];
-
+
sprintf(buf, "missing value on line %d", lineNum);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_ERROR;
@@ -1039,7 +1014,7 @@ AddFromString(interp, tkwin, string, priority)
while (*src != '\n') {
if (*src == '\0') {
char buf[32 + TCL_INTEGER_SPACE];
-
+
sprintf(buf, "missing newline on line %d", lineNum);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_ERROR;
@@ -1071,13 +1046,13 @@ AddFromString(interp, tkwin, string, priority)
*
* ReadOptionFile --
*
- * Read a file of options ("resources" in the old X terminology)
- * and load them into the option database.
+ * Read a file of options ("resources" in the old X terminology) and load
+ * them into the option database.
*
* 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 the interp's result.
+ * 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 the interp's result.
*
* Side effects:
* None.
@@ -1086,15 +1061,15 @@ AddFromString(interp, tkwin, string, priority)
*/
static int
-ReadOptionFile(interp, tkwin, fileName, priority)
- Tcl_Interp *interp; /* Interpreter to use for reporting results. */
- Tk_Window tkwin; /* Token for window: options are entered
- * for this window's main window. */
- char *fileName; /* Name of file containing options. */
- int priority; /* Priority level to use for options in
- * this file, such as TK_USER_DEFAULT_PRIO
- * or TK_INTERACTIVE_PRIO. Must be between
- * 0 and TK_MAX_PRIO. */
+ReadOptionFile(
+ Tcl_Interp *interp, /* Interpreter to use for reporting results. */
+ Tk_Window tkwin, /* Token for window: options are entered for
+ * this window's main window. */
+ char *fileName, /* Name of file containing options. */
+ int priority) /* Priority level to use for options in this
+ * file, such as TK_USER_DEFAULT_PRIO or
+ * TK_INTERACTIVE_PRIO. Must be between 0 and
+ * TK_MAX_PRIO. */
{
CONST char *realName;
char *buffer;
@@ -1105,13 +1080,13 @@ ReadOptionFile(interp, tkwin, fileName, priority)
/*
* Prevent file system access in a safe interpreter.
*/
-
+
if (Tcl_IsSafe(interp)) {
- Tcl_AppendResult(interp, "can't read options from a file in a",
- " safe interpreter", (char *) NULL);
- return TCL_ERROR;
+ Tcl_AppendResult(interp, "can't read options from a file in a",
+ " safe interpreter", NULL);
+ return TCL_ERROR;
}
-
+
realName = Tcl_TranslateFileName(interp, fileName, &newName);
if (realName == NULL) {
return TCL_ERROR;
@@ -1119,23 +1094,23 @@ ReadOptionFile(interp, tkwin, fileName, priority)
chan = Tcl_OpenFileChannel(interp, realName, "r", 0);
Tcl_DStringFree(&newName);
if (chan == NULL) {
- Tcl_ResetResult(interp);
+ Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "couldn't open \"", fileName,
- "\": ", Tcl_PosixError(interp), (char *) NULL);
+ "\": ", Tcl_PosixError(interp), NULL);
return TCL_ERROR;
}
/*
- * Compute size of file by seeking to the end of the file. This will
+ * Compute size of file by seeking to the end of the file. This will
* overallocate if we are performing CRLF translation.
*/
-
+
bufferSize = (int) Tcl_Seek(chan, (Tcl_WideInt) 0, SEEK_END);
(void) Tcl_Seek(chan, (Tcl_WideInt) 0, SEEK_SET);
if (bufferSize < 0) {
Tcl_AppendResult(interp, "error seeking to end of file \"",
- fileName, "\":", Tcl_PosixError(interp), (char *) NULL);
+ fileName, "\":", Tcl_PosixError(interp), NULL);
Tcl_Close(NULL, chan);
return TCL_ERROR;
@@ -1144,7 +1119,7 @@ ReadOptionFile(interp, tkwin, fileName, priority)
bufferSize = Tcl_Read(chan, buffer, bufferSize);
if (bufferSize < 0) {
Tcl_AppendResult(interp, "error reading file \"", fileName, "\":",
- Tcl_PosixError(interp), (char *) NULL);
+ Tcl_PosixError(interp), NULL);
Tcl_Close(NULL, chan);
return TCL_ERROR;
}
@@ -1163,9 +1138,8 @@ ReadOptionFile(interp, tkwin, fileName, priority)
* Create a new ElArray structure of a given size.
*
* Results:
- * The return value is a pointer to a properly initialized
- * element array with "numEls" space. The array is marked
- * as having no active elements.
+ * The return value is a pointer to a properly initialized element array
+ * with "numEls" space. The array is marked as having no active elements.
*
* Side effects:
* Memory is allocated.
@@ -1174,8 +1148,8 @@ ReadOptionFile(interp, tkwin, fileName, priority)
*/
static ElArray *
-NewArray(numEls)
- int numEls; /* How many elements of space to allocate. */
+NewArray(
+ int numEls) /* How many elements of space to allocate. */
{
register ElArray *arrayPtr;
@@ -1191,12 +1165,11 @@ NewArray(numEls)
*
* ExtendArray --
*
- * Add a new element to an array, extending the array if
- * necessary.
+ * Add a new element to an array, extending the array if necessary.
*
* Results:
- * The return value is a pointer to the new array, which
- * will be different from arrayPtr if the array got expanded.
+ * The return value is a pointer to the new array, which will be
+ * different from arrayPtr if the array got expanded.
*
* Side effects:
* Memory may be allocated or freed.
@@ -1205,9 +1178,9 @@ NewArray(numEls)
*/
static ElArray *
-ExtendArray(arrayPtr, elPtr)
- register ElArray *arrayPtr; /* Array to be extended. */
- register Element *elPtr; /* Element to be copied into array. */
+ExtendArray(
+ register ElArray *arrayPtr, /* Array to be extended. */
+ register Element *elPtr) /* Element to be copied into array. */
{
/*
* If the current array has filled up, make it bigger.
@@ -1220,8 +1193,8 @@ ExtendArray(arrayPtr, elPtr)
newPtr->arraySize = 2*arrayPtr->arraySize;
newPtr->numUsed = arrayPtr->numUsed;
newPtr->nextToUse = &newPtr->els[newPtr->numUsed];
- memcpy((VOID *) newPtr->els, (VOID *) arrayPtr->els,
- (arrayPtr->arraySize*sizeof(Element)));
+ memcpy(newPtr->els, arrayPtr->els,
+ arrayPtr->arraySize * sizeof(Element));
ckfree((char *) arrayPtr);
arrayPtr = newPtr;
}
@@ -1237,40 +1210,40 @@ ExtendArray(arrayPtr, elPtr)
*
* SetupStacks --
*
- * Arrange the stacks so that they cache all the option
- * information for a particular window.
+ * Arrange the stacks so that they cache all the option information for a
+ * particular window.
*
* Results:
* None.
*
* Side effects:
- * The stacks are modified to hold information for tkwin
- * and all its ancestors in the window hierarchy.
+ * The stacks are modified to hold information for tkwin and all its
+ * ancestors in the window hierarchy.
*
*--------------------------------------------------------------
*/
static void
-SetupStacks(winPtr, leaf)
- TkWindow *winPtr; /* Window for which information is to
- * be cached. */
- int leaf; /* Non-zero means this is the leaf
- * window being probed. Zero means this
- * is an ancestor of the desired leaf. */
+SetupStacks(
+ TkWindow *winPtr, /* Window for which information is to be
+ * cached. */
+ int leaf) /* Non-zero means this is the leaf window
+ * being probed. Zero means this is an
+ * ancestor of the desired leaf. */
{
int level, i, *iPtr;
register StackLevel *levelPtr;
register ElArray *arrayPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
- * The following array defines the order in which the current
- * stacks are searched to find matching entries to add to the
- * stacks. Given the current priority-based scheme, the order
- * below is no longer relevant; all that matters is that an
- * element is on the list *somewhere*. The ordering is a relic
- * of the old days when priorities were determined differently.
+ * The following array defines the order in which the current stacks are
+ * searched to find matching entries to add to the stacks. Given the
+ * current priority-based scheme, the order below is no longer relevant;
+ * all that matters is that an element is on the list *somewhere*. The
+ * ordering is a relic of the old days when priorities were determined
+ * differently.
*/
static int searchOrder[] = {WILDCARD_NODE_CLASS, WILDCARD_NODE_NAME,
@@ -1281,8 +1254,7 @@ SetupStacks(winPtr, leaf)
}
/*
- * Step 1: make sure that options are cached for this window's
- * parent.
+ * Step 1: make sure that options are cached for this window's parent.
*/
if (winPtr->parentPtr != NULL) {
@@ -1297,8 +1269,8 @@ SetupStacks(winPtr, leaf)
}
/*
- * Step 2: pop extra unneeded information off the stacks and
- * mark those windows as no longer having cached information.
+ * Step 2: pop extra unneeded information off the stacks and mark those
+ * windows as no longer having cached information.
*/
if (tsdPtr->curLevel >= level) {
@@ -1316,9 +1288,9 @@ SetupStacks(winPtr, leaf)
tsdPtr->curLevel = winPtr->optionLevel = level;
/*
- * Step 3: if the root database information isn't loaded or
- * isn't valid, initialize level 0 of the stack from the
- * database root (this only happens if winPtr is a main window).
+ * Step 3: if the root database information isn't loaded or isn't valid,
+ * initialize level 0 of the stack from the database root (this only
+ * happens if winPtr is a main window).
*/
if ((tsdPtr->curLevel == 1)
@@ -1333,19 +1305,18 @@ SetupStacks(winPtr, leaf)
}
/*
- * Step 4: create a new stack level; grow the level array if
- * we've run out of levels. Clear the stacks for EXACT_LEAF_NAME
- * and EXACT_LEAF_CLASS (anything that was there is of no use
- * any more).
+ * Step 4: create a new stack level; grow the level array if we've run out
+ * of levels. Clear the stacks for EXACT_LEAF_NAME and EXACT_LEAF_CLASS
+ * (anything that was there is of no use any more).
*/
if (tsdPtr->curLevel >= tsdPtr->numLevels) {
StackLevel *newLevels;
newLevels = (StackLevel *) ckalloc((unsigned)
- (tsdPtr->numLevels*2*sizeof(StackLevel)));
- memcpy((VOID *) newLevels, (VOID *) tsdPtr->levels,
- (tsdPtr->numLevels*sizeof(StackLevel)));
+ (tsdPtr->numLevels * 2 * sizeof(StackLevel)));
+ memcpy(newLevels, tsdPtr->levels,
+ tsdPtr->numLevels * sizeof(StackLevel));
ckfree((char *) tsdPtr->levels);
tsdPtr->numLevels *= 2;
tsdPtr->levels = newLevels;
@@ -1361,10 +1332,10 @@ SetupStacks(winPtr, leaf)
for (i = 0; i < NUM_STACKS; i++) {
levelPtr->bases[i] = tsdPtr->stacks[i]->numUsed;
}
+
/*
* Step 5: scan the current stack level looking for matches to this
- * window's name or class; where found, add new information to the
- * stacks.
+ * window's name or class; where found, add new information to the stacks.
*/
for (iPtr = searchOrder; *iPtr != -1; iPtr++) {
@@ -1382,8 +1353,8 @@ SetupStacks(winPtr, leaf)
count = levelPtr->bases[i];
/*
- * For wildcard stacks, check all entries; for non-wildcard
- * stacks, only check things that matched in the parent.
+ * For wildcard stacks, check all entries; for non-wildcard stacks,
+ * only check things that matched in the parent.
*/
if (!(i & WILDCARD)) {
@@ -1405,9 +1376,8 @@ SetupStacks(winPtr, leaf)
*
* ExtendStacks --
*
- * Given an element array, copy all the elements from the
- * array onto the system stacks (except for irrelevant leaf
- * elements).
+ * Given an element array, copy all the elements from the array onto the
+ * system stacks (except for irrelevant leaf elements).
*
* Results:
* None.
@@ -1419,23 +1389,23 @@ SetupStacks(winPtr, leaf)
*/
static void
-ExtendStacks(arrayPtr, leaf)
- ElArray *arrayPtr; /* Array of elements to copy onto stacks. */
- int leaf; /* If zero, then don't copy exact leaf
+ExtendStacks(
+ ElArray *arrayPtr, /* Array of elements to copy onto stacks. */
+ int leaf) /* If zero, then don't copy exact leaf
* elements. */
{
register int count;
register Element *elPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ 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;
}
- tsdPtr->stacks[elPtr->flags] = ExtendArray(
- tsdPtr->stacks[elPtr->flags], elPtr);
+ tsdPtr->stacks[elPtr->flags] =
+ ExtendArray(tsdPtr->stacks[elPtr->flags], elPtr);
}
}
@@ -1456,14 +1426,15 @@ ExtendStacks(arrayPtr, leaf)
*/
static void
-OptionThreadExitProc(clientData)
- ClientData clientData; /* not used */
+OptionThreadExitProc(
+ ClientData clientData) /* not used */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (tsdPtr->initialized) {
int i;
+
for (i = 0; i < NUM_STACKS; i++) {
ckfree((char *) tsdPtr->stacks[i]);
}
@@ -1489,35 +1460,35 @@ OptionThreadExitProc(clientData)
*/
static void
-OptionInit(mainPtr)
- register TkMainInfo *mainPtr; /* Top-level information about
- * window that isn't initialized
- * yet. */
+OptionInit(
+ register TkMainInfo *mainPtr)
+ /* Top-level information about window that
+ * isn't initialized yet. */
{
int i;
Tcl_Interp *interp;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Element *defaultMatchPtr = &tsdPtr->defaultMatch;
/*
* First, once-only initialization.
*/
-
+
if (tsdPtr->initialized == 0) {
- tsdPtr->initialized = 1;
- tsdPtr->cachedWindow = NULL;
+ tsdPtr->initialized = 1;
+ tsdPtr->cachedWindow = NULL;
tsdPtr->numLevels = 5;
tsdPtr->curLevel = -1;
tsdPtr->serial = 0;
- tsdPtr->levels = (StackLevel *) ckalloc((unsigned)
- (5*sizeof(StackLevel)));
+ tsdPtr->levels = (StackLevel *)
+ ckalloc((unsigned) (5*sizeof(StackLevel)));
for (i = 0; i < NUM_STACKS; i++) {
tsdPtr->stacks[i] = NewArray(10);
tsdPtr->levels[0].bases[i] = 0;
}
-
+
defaultMatchPtr->nameUid = NULL;
defaultMatchPtr->child.valueUid = NULL;
defaultMatchPtr->priority = -1;
@@ -1526,7 +1497,7 @@ OptionInit(mainPtr)
}
/*
- * Then, per-main-window initialization. Create and delete dummy
+ * Then, per-main-window initialization. Create and delete dummy
* interpreter for message logging.
*/
@@ -1541,23 +1512,22 @@ OptionInit(mainPtr)
*
* ClearOptionTree --
*
- * This procedure is called to erase everything in a
- * hierarchical option database.
+ * This function is called to erase everything in a hierarchical option
+ * database.
*
* Results:
* None.
*
* Side effects:
- * All the options associated with arrayPtr are deleted,
- * along with all option subtrees. The space pointed to
- * by arrayPtr is freed.
+ * All the options associated with arrayPtr are deleted, along with all
+ * option subtrees. The space pointed to by arrayPtr is freed.
*
*--------------------------------------------------------------
*/
static void
-ClearOptionTree(arrayPtr)
- ElArray *arrayPtr; /* Array of options; delete everything
+ClearOptionTree(
+ ElArray *arrayPtr) /* Array of options; delete everything
* referred to recursively by this. */
{
register Element *elPtr;
@@ -1577,28 +1547,27 @@ ClearOptionTree(arrayPtr)
*
* GetDefaultOptions --
*
- * This procedure is invoked to load the default set of options
- * for a window.
+ * This function is invoked to load the default set of options for a
+ * window.
*
* Results:
* None.
*
* Side effects:
- * Options are added to those for winPtr's main window. If
- * there exists a RESOURCE_MANAGER proprety for winPtr's
- * display, that is used. Otherwise, the .Xdefaults file in
- * the user's home directory is used.
+ * Options are added to those for winPtr's main window. If there exists a
+ * RESOURCE_MANAGER proprety for winPtr's display, that is used.
+ * Otherwise, the .Xdefaults file in the user's home directory is used.
*
*--------------------------------------------------------------
*/
static int
-GetDefaultOptions(interp, winPtr)
- Tcl_Interp *interp; /* Interpreter to use for error reporting. */
- TkWindow *winPtr; /* Fetch option defaults for main window
+GetDefaultOptions(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ TkWindow *winPtr) /* Fetch option defaults for main window
* associated with this. */
{
- char *regProp;
+ char *regProp, **regPropPtr = &regProp;
int result, actualFormat;
unsigned long numItems, bytesAfter;
Atom actualType;
@@ -1609,10 +1578,9 @@ GetDefaultOptions(interp, winPtr)
regProp = NULL;
result = XGetWindowProperty(winPtr->display,
- RootWindow(winPtr->display, 0),
- XA_RESOURCE_MANAGER, 0, 100000,
- False, XA_STRING, &actualType, &actualFormat,
- &numItems, &bytesAfter, (unsigned char **) &regProp);
+ RootWindow(winPtr->display, 0), XA_RESOURCE_MANAGER, 0, 100000,
+ False, XA_STRING, &actualType, &actualFormat, &numItems,
+ &bytesAfter, (unsigned char **) regPropPtr);
if ((result == Success) && (actualType == XA_STRING)
&& (actualFormat == 8)) {
@@ -1623,8 +1591,7 @@ GetDefaultOptions(interp, winPtr)
}
/*
- * No luck there. Try a .Xdefaults file in the user's home
- * directory.
+ * No luck there. Try a .Xdefaults file in the user's home directory.
*/
if (regProp != NULL) {
@@ -1634,3 +1601,11 @@ GetDefaultOptions(interp, winPtr)
TK_USER_DEFAULT_PRIO);
return result;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkPack.c b/generic/tkPack.c
index 8498df6..47eddd6 100644
--- a/generic/tkPack.c
+++ b/generic/tkPack.c
@@ -1,22 +1,21 @@
-/*
+/*
* tkPack.c --
*
- * This file contains code to implement the "packer"
- * geometry manager for Tk.
+ * This file contains code to implement the "packer" geometry manager for
+ * Tk.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
typedef enum {TOP, BOTTOM, LEFT, RIGHT} Side;
static CONST char *sideNames[] = {
- "top", "bottom", "left", "right", (char *) NULL
+ "top", "bottom", "left", "right", NULL
};
/* For each window that the packer cares about (either because
@@ -26,70 +25,68 @@ static CONST char *sideNames[] = {
*/
typedef struct Packer {
- Tk_Window tkwin; /* Tk token for window. NULL means that
- * the window has been deleted, but the
- * packet hasn't had a chance to clean up
- * yet because the structure is still in
- * use. */
- struct Packer *masterPtr; /* Master window within which this window
- * is packed (NULL means this window
- * isn't managed by the packer). */
- struct Packer *nextPtr; /* Next window packed within same
- * parent. List is priority-ordered:
- * first on list gets packed first. */
- struct Packer *slavePtr; /* First in list of slaves packed
- * inside this window (NULL means
- * no packed slaves). */
- Side side; /* Side of parent against which
- * this window is packed. */
+ Tk_Window tkwin; /* Tk token for window. NULL means that the
+ * window has been deleted, but the packet
+ * hasn't had a chance to clean up yet because
+ * the structure is still in use. */
+ struct Packer *masterPtr; /* Master window within which this window is
+ * packed (NULL means this window isn't
+ * managed by the packer). */
+ struct Packer *nextPtr; /* Next window packed within same master.
+ * List is priority-ordered: first on list
+ * gets packed first. */
+ struct Packer *slavePtr; /* First in list of slaves packed inside this
+ * window (NULL means no packed slaves). */
+ Side side; /* Side of master against which this window is
+ * packed. */
Tk_Anchor anchor; /* If frame allocated for window is larger
- * than window needs, this indicates how
- * where to position window in frame. */
+ * than window needs, this indicates how where
+ * to position window in frame. */
int padX, padY; /* Total additional pixels to leave around the
- * window. Some is of this space is on each
- * side. This is space *outside* the window:
+ * window. Some is of this space is on each
+ * side. This is space *outside* the window:
* we'll allocate extra space in frame but
* won't enlarge window). */
- int padLeft, padTop; /* The part of padX or padY to use on the
- * left or top of the widget, respectively.
- * By default, this is half of padX or padY. */
+ int padLeft, padTop; /* The part of padX or padY to use on the left
+ * or top of the widget, respectively. By
+ * default, this is half of padX or padY. */
int iPadX, iPadY; /* Total extra pixels to allocate inside the
* window (half of this amount will appear on
* each side). */
- int doubleBw; /* Twice the window's last known border
- * width. If this changes, the window
- * must be repacked within its parent. */
- int *abortPtr; /* If non-NULL, it means that there is a nested
- * call to ArrangePacking already working on
- * this window. *abortPtr may be set to 1 to
- * abort that nested call. This happens, for
- * example, if tkwin or any of its slaves
- * is deleted. */
- int flags; /* Miscellaneous flags; see below
- * for definitions. */
+ int doubleBw; /* Twice the window's last known border width.
+ * If this changes, the window must be
+ * repacked within its master. */
+ int *abortPtr; /* If non-NULL, it means that there is a
+ * nested call to ArrangePacking already
+ * working on this window. *abortPtr may be
+ * set to 1 to abort that nested call. This
+ * happens, for example, if tkwin or any of
+ * its slaves is deleted. */
+ int flags; /* Miscellaneous flags; see below for
+ * definitions. */
} Packer;
/*
* Flag values for Packer structures:
*
- * REQUESTED_REPACK: 1 means a Tcl_DoWhenIdle request
- * has already been made to repack
- * all the slaves of this window.
- * FILLX: 1 means if frame allocated for window
- * is wider than window needs, expand window
- * to fill frame. 0 means don't make window
- * any larger than needed.
+ * REQUESTED_REPACK: 1 means a Tcl_DoWhenIdle request has already
+ * been made to repack all the slaves of this
+ * window.
+ * FILLX: 1 means if frame allocated for window is wider
+ * than window needs, expand window to fill
+ * frame. 0 means don't make window any larger
+ * than needed.
* FILLY: Same as FILLX, except for height.
* EXPAND: 1 means this window's frame will absorb any
- * extra space in the parent window.
- * OLD_STYLE: 1 means this window is being managed with
- * the old-style packer algorithms (before
- * Tk version 3.3). The main difference is
- * that padding and filling are done differently.
+ * extra space in the master window.
+ * OLD_STYLE: 1 means this window is being managed with the
+ * old-style packer algorithms (before Tk version
+ * 3.3). The main difference is that padding and
+ * filling are done differently.
* DONT_PROPAGATE: 1 means don't set this window's requested
- * size. 0 means if this window is a master
- * then Tk will set its requested size to fit
- * the needs of its slaves.
+ * size. 0 means if this window is a master then
+ * Tk will set its requested size to fit the
+ * needs of its slaves.
*/
#define REQUESTED_REPACK 1
@@ -100,52 +97,44 @@ typedef struct Packer {
#define DONT_PROPAGATE 32
/*
- * The following structure is the official type record for the
- * packer:
+ * The following structure is the official type record for the packer:
*/
-static void PackReqProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin));
-static void PackLostSlaveProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin));
+static void PackReqProc(ClientData clientData, Tk_Window tkwin);
+static void PackLostSlaveProc(ClientData clientData,
+ Tk_Window tkwin);
-static Tk_GeomMgr packerType = {
+static const Tk_GeomMgr packerType = {
"pack", /* name */
PackReqProc, /* requestProc */
PackLostSlaveProc, /* lostSlaveProc */
};
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static void ArrangePacking _ANSI_ARGS_((ClientData clientData));
-static int ConfigureSlaves _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, int objc, Tcl_Obj *CONST objv[]));
-static void DestroyPacker _ANSI_ARGS_((char *memPtr));
-static Packer * GetPacker _ANSI_ARGS_((Tk_Window tkwin));
-static int PackAfter _ANSI_ARGS_((Tcl_Interp *interp,
- Packer *prevPtr, Packer *masterPtr, int objc,
- Tcl_Obj *CONST objv[]));
-static void PackReqProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin));
-static void PackStructureProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void Unlink _ANSI_ARGS_((Packer *packPtr));
-static int XExpansion _ANSI_ARGS_((Packer *slavePtr,
- int cavityWidth));
-static int YExpansion _ANSI_ARGS_((Packer *slavePtr,
- int cavityHeight));
+static void ArrangePacking(ClientData clientData);
+static int ConfigureSlaves(Tcl_Interp *interp, Tk_Window tkwin,
+ int objc, Tcl_Obj *CONST objv[]);
+static void DestroyPacker(char *memPtr);
+static Packer * GetPacker(Tk_Window tkwin);
+static int PackAfter(Tcl_Interp *interp, Packer *prevPtr,
+ Packer *masterPtr, int objc,Tcl_Obj *CONST objv[]);
+static void PackStructureProc(ClientData clientData,
+ XEvent *eventPtr);
+static void Unlink(Packer *packPtr);
+static int XExpansion(Packer *slavePtr, int cavityWidth);
+static int YExpansion(Packer *slavePtr, int cavityHeight);
/*
*--------------------------------------------------------------
*
* TkPrintPadAmount --
*
- * This procedure generates a text value that describes one
- * of the -padx, -pady, -ipadx, or -ipady configuration options.
- * The text value generated is appended to the interpreter
- * result.
+ * This function generates a text value that describes one of the -padx,
+ * -pady, -ipadx, or -ipady configuration options. The text value
+ * generated is appended to the interpreter result.
*
* Results:
* None.
@@ -155,13 +144,14 @@ static int YExpansion _ANSI_ARGS_((Packer *slavePtr,
*
*--------------------------------------------------------------
*/
-void
-TkPrintPadAmount(interp, switchName, halfSpace, allSpace)
- Tcl_Interp *interp; /* The interpreter into which the result
- * is written. */
- char *switchName; /* One of "padx", "pady", "ipadx" or "ipady" */
- int halfSpace; /* The left or top padding amount */
- int allSpace; /* The total amount of padding */
+
+void
+TkPrintPadAmount(
+ Tcl_Interp *interp, /* The interpreter into which the result is
+ * written. */
+ char *switchName, /* One of "padx", "pady", "ipadx" or "ipady" */
+ int halfSpace, /* The left or top padding amount */
+ int allSpace) /* The total amount of padding */
{
char buffer[60 + 2*TCL_INTEGER_SPACE];
if (halfSpace*2 == allSpace) {
@@ -170,17 +160,16 @@ TkPrintPadAmount(interp, switchName, halfSpace, allSpace)
sprintf(buffer, " -%.10s {%d %d}", switchName, halfSpace,
allSpace - halfSpace);
}
- Tcl_AppendResult(interp, buffer, (char *)NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
}
-
/*
*--------------------------------------------------------------
*
* Tk_PackCmd --
*
- * This procedure is invoked to process the "pack" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "pack" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -192,19 +181,18 @@ TkPrintPadAmount(interp, switchName, halfSpace, allSpace)
*/
int
-Tk_PackObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_PackObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tk_Window tkwin = (Tk_Window) clientData;
char *argv2;
static CONST char *optionStrings[] = {
/* after, append, before and unpack are deprecated */
"after", "append", "before", "unpack",
- "configure", "forget", "info", "propagate", "slaves", (char *) NULL };
+ "configure", "forget", "info", "propagate", "slaves", NULL };
enum options {
PACK_AFTER, PACK_APPEND, PACK_BEFORE, PACK_UNPACK,
PACK_CONFIGURE, PACK_FORGET, PACK_INFO, PACK_PROPAGATE, PACK_SLAVES };
@@ -224,9 +212,8 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
&index) != TCL_OK) {
/*
- * Call it again without the deprecated ones to get a proper
- * error message.
- * This works well since there can't be any ambiguity between
+ * Call it again without the deprecated ones to get a proper error
+ * message. This works well since there can't be any ambiguity between
* deprecated and new options.
*/
@@ -237,7 +224,8 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
}
argv2 = Tcl_GetString(objv[2]);
- if (index == PACK_AFTER) {
+ switch ((enum options) index) {
+ case PACK_AFTER: {
Packer *prevPtr;
Tk_Window tkwin2;
@@ -247,11 +235,12 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
prevPtr = GetPacker(tkwin2);
if (prevPtr->masterPtr == NULL) {
Tcl_AppendResult(interp, "window \"", argv2,
- "\" isn't packed", (char *) NULL);
+ "\" isn't packed", NULL);
return TCL_ERROR;
}
return PackAfter(interp, prevPtr, prevPtr->masterPtr, objc-3, objv+3);
- } else if (index == PACK_APPEND) {
+ }
+ case PACK_APPEND: {
Packer *masterPtr;
register Packer *prevPtr;
Tk_Window tkwin2;
@@ -267,7 +256,8 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
}
}
return PackAfter(interp, prevPtr, masterPtr, objc-3, objv+3);
- } else if (index == PACK_BEFORE) {
+ }
+ case PACK_BEFORE: {
Packer *packPtr, *masterPtr;
register Packer *prevPtr;
Tk_Window tkwin2;
@@ -278,7 +268,7 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
packPtr = GetPacker(tkwin2);
if (packPtr->masterPtr == NULL) {
Tcl_AppendResult(interp, "window \"", argv2,
- "\" isn't packed", (char *) NULL);
+ "\" isn't packed", NULL);
return TCL_ERROR;
}
masterPtr = packPtr->masterPtr;
@@ -288,7 +278,7 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
} else {
for ( ; ; prevPtr = prevPtr->nextPtr) {
if (prevPtr == NULL) {
- panic("\"pack before\" couldn't find predecessor");
+ Tcl_Panic("\"pack before\" couldn't find predecessor");
}
if (prevPtr->nextPtr == packPtr) {
break;
@@ -296,14 +286,15 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
}
}
return PackAfter(interp, prevPtr, masterPtr, objc-3, objv+3);
- } else if (index == PACK_CONFIGURE) {
+ }
+ case PACK_CONFIGURE:
if (argv2[0] != '.') {
Tcl_AppendResult(interp, "bad argument \"", argv2,
- "\": must be name of window", (char *) NULL);
+ "\": must be name of window", NULL);
return TCL_ERROR;
}
return ConfigureSlaves(interp, tkwin, objc-2, objv+2);
- } else if (index == PACK_FORGET) {
+ case PACK_FORGET: {
Tk_Window slave;
Packer *slavePtr;
int i;
@@ -314,7 +305,7 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
}
slavePtr = GetPacker(slave);
if ((slavePtr != NULL) && (slavePtr->masterPtr != NULL)) {
- Tk_ManageGeometry(slave, (Tk_GeomMgr *) NULL,
+ Tk_ManageGeometry(slave, NULL,
(ClientData) NULL);
if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
Tk_UnmaintainGeometry(slavePtr->tkwin,
@@ -324,7 +315,9 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
Tk_UnmapWindow(slavePtr->tkwin);
}
}
- } else if (index == PACK_INFO) {
+ break;
+ }
+ case PACK_INFO: {
register Packer *slavePtr;
Tk_Window slave;
@@ -338,7 +331,7 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
slavePtr = GetPacker(slave);
if (slavePtr->masterPtr == NULL) {
Tcl_AppendResult(interp, "window \"", argv2,
- "\" isn't packed", (char *) NULL);
+ "\" isn't packed", NULL);
return TCL_ERROR;
}
Tcl_AppendElement(interp, "-in");
@@ -346,29 +339,29 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
Tcl_AppendElement(interp, "-anchor");
Tcl_AppendElement(interp, Tk_NameOfAnchor(slavePtr->anchor));
Tcl_AppendResult(interp, " -expand ",
- (slavePtr->flags & EXPAND) ? "1" : "0", " -fill ",
- (char *) NULL);
+ (slavePtr->flags & EXPAND) ? "1" : "0", " -fill ", NULL);
switch (slavePtr->flags & (FILLX|FILLY)) {
- case 0:
- Tcl_AppendResult(interp, "none", (char *) NULL);
- break;
- case FILLX:
- Tcl_AppendResult(interp, "x", (char *) NULL);
- break;
- case FILLY:
- Tcl_AppendResult(interp, "y", (char *) NULL);
- break;
- case FILLX|FILLY:
- Tcl_AppendResult(interp, "both", (char *) NULL);
- break;
+ case 0:
+ Tcl_AppendResult(interp, "none", NULL);
+ break;
+ case FILLX:
+ Tcl_AppendResult(interp, "x", NULL);
+ break;
+ case FILLY:
+ Tcl_AppendResult(interp, "y", NULL);
+ break;
+ case FILLX|FILLY:
+ Tcl_AppendResult(interp, "both", NULL);
+ break;
}
- TkPrintPadAmount(interp, "ipadx", slavePtr->iPadX/2, slavePtr->iPadX);
- TkPrintPadAmount(interp, "ipady", slavePtr->iPadY/2, slavePtr->iPadY);
- TkPrintPadAmount(interp, "padx", slavePtr->padLeft, slavePtr->padX);
- TkPrintPadAmount(interp, "pady", slavePtr->padTop, slavePtr->padY);
- Tcl_AppendResult(interp, " -side ", sideNames[slavePtr->side],
- (char *) NULL);
- } else if (index == PACK_PROPAGATE) {
+ TkPrintPadAmount(interp, "ipadx", slavePtr->iPadX/2, slavePtr->iPadX);
+ TkPrintPadAmount(interp, "ipady", slavePtr->iPadY/2, slavePtr->iPadY);
+ TkPrintPadAmount(interp, "padx", slavePtr->padLeft, slavePtr->padX);
+ TkPrintPadAmount(interp, "pady", slavePtr->padTop, slavePtr->padY);
+ Tcl_AppendResult(interp, " -side ", sideNames[slavePtr->side], NULL);
+ break;
+ }
+ case PACK_PROPAGATE: {
Tk_Window master;
Packer *masterPtr;
int propagate;
@@ -407,7 +400,9 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
} else {
masterPtr->flags |= DONT_PROPAGATE;
}
- } else if (index == PACK_SLAVES) {
+ break;
+ }
+ case PACK_SLAVES: {
Tk_Window master;
Packer *masterPtr, *slavePtr;
@@ -423,7 +418,9 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
slavePtr = slavePtr->nextPtr) {
Tcl_AppendElement(interp, Tk_PathName(slavePtr->tkwin));
}
- } else if (index == PACK_UNPACK) {
+ break;
+ }
+ case PACK_UNPACK: {
Tk_Window tkwin2;
Packer *packPtr;
@@ -436,7 +433,7 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
}
packPtr = GetPacker(tkwin2);
if ((packPtr != NULL) && (packPtr->masterPtr != NULL)) {
- Tk_ManageGeometry(tkwin2, (Tk_GeomMgr *) NULL,
+ Tk_ManageGeometry(tkwin2, NULL,
(ClientData) NULL);
if (packPtr->masterPtr->tkwin != Tk_Parent(packPtr->tkwin)) {
Tk_UnmaintainGeometry(packPtr->tkwin,
@@ -445,6 +442,8 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
Unlink(packPtr);
Tk_UnmapWindow(packPtr->tkwin);
}
+ break;
+ }
}
return TCL_OK;
@@ -455,27 +454,26 @@ Tk_PackObjCmd(clientData, interp, objc, objv)
*
* PackReqProc --
*
- * This procedure is invoked by Tk_GeometryRequest for
- * windows managed by the packer.
+ * This function is invoked by Tk_GeometryRequest for windows managed by
+ * the packer.
*
* Results:
* None.
*
* Side effects:
- * Arranges for tkwin, and all its managed siblings, to
- * be re-packed at the next idle point.
+ * Arranges for tkwin, and all its managed siblings, to be re-packed at
+ * the next idle point.
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static void
-PackReqProc(clientData, tkwin)
- ClientData clientData; /* Packer's information about
- * window that got new preferred
- * geometry. */
- Tk_Window tkwin; /* Other Tk-related information
- * about the window. */
+PackReqProc(
+ ClientData clientData, /* Packer's information about window that got
+ * new preferred geometry. */
+ Tk_Window tkwin) /* Other Tk-related information about the
+ * window. */
{
register Packer *packPtr = (Packer *) clientData;
@@ -491,8 +489,8 @@ PackReqProc(clientData, tkwin)
*
* PackLostSlaveProc --
*
- * This procedure is invoked by Tk whenever some other geometry
- * claims control over a slave that used to be managed by us.
+ * This function is invoked by Tk whenever some other geometry claims
+ * control over a slave that used to be managed by us.
*
* Results:
* None.
@@ -505,10 +503,10 @@ PackReqProc(clientData, tkwin)
/* ARGSUSED */
static void
-PackLostSlaveProc(clientData, tkwin)
- ClientData clientData; /* Packer structure for slave window that
- * was stolen away. */
- Tk_Window tkwin; /* Tk's handle for the slave window. */
+PackLostSlaveProc(
+ ClientData clientData, /* Packer structure for slave window that was
+ * stolen away. */
+ Tk_Window tkwin) /* Tk's handle for the slave window. */
{
register Packer *slavePtr = (Packer *) clientData;
@@ -524,38 +522,36 @@ PackLostSlaveProc(clientData, tkwin)
*
* ArrangePacking --
*
- * This procedure is invoked (using the Tcl_DoWhenIdle
- * mechanism) to re-layout a set of windows managed by
- * the packer. It is invoked at idle time so that a
- * series of packer requests can be merged into a single
- * layout operation.
+ * This function is invoked (using the Tcl_DoWhenIdle mechanism) to
+ * re-layout a set of windows managed by the packer. It is invoked at
+ * idle time so that a series of packer requests can be merged into a
+ * single layout operation.
*
* Results:
* None.
*
* Side effects:
- * The packed slaves of masterPtr may get resized or
- * moved.
+ * The packed slaves of masterPtr may get resized or moved.
*
*--------------------------------------------------------------
*/
static void
-ArrangePacking(clientData)
- ClientData clientData; /* Structure describing parent whose slaves
+ArrangePacking(
+ ClientData clientData) /* Structure describing master whose slaves
* are to be re-layed out. */
{
register Packer *masterPtr = (Packer *) clientData;
- register Packer *slavePtr;
+ register Packer *slavePtr;
int cavityX, cavityY, cavityWidth, cavityHeight;
/* These variables keep track of the
- * as-yet-unallocated space remaining in
- * the middle of the parent window. */
+ * as-yet-unallocated space remaining in the
+ * middle of the master window. */
int frameX, frameY, frameWidth, frameHeight;
/* These variables keep track of the frame
* allocated to the current window. */
- int x, y, width, height; /* These variables are used to hold the
- * actual geometry of the current window. */
+ int x, y, width, height; /* These variables are used to hold the actual
+ * geometry of the current window. */
int abort; /* May get set to non-zero to abort this
* repacking operation. */
int borderX, borderY;
@@ -566,8 +562,8 @@ ArrangePacking(clientData)
masterPtr->flags &= ~REQUESTED_REPACK;
/*
- * If the parent has no slaves anymore, then don't do anything
- * at all: just leave the parent's size as-is.
+ * If the master has no slaves anymore, then don't do anything at all:
+ * just leave the master's size as-is.
*/
if (masterPtr->slavePtr == NULL) {
@@ -575,9 +571,9 @@ ArrangePacking(clientData)
}
/*
- * Abort any nested call to ArrangePacking for this window, since
- * we'll do everything necessary here, and set up so this call
- * can be aborted if necessary.
+ * Abort any nested call to ArrangePacking for this window, since we'll do
+ * everything necessary here, and set up so this call can be aborted if
+ * necessary.
*/
if (masterPtr->abortPtr != NULL) {
@@ -588,22 +584,19 @@ ArrangePacking(clientData)
Tcl_Preserve((ClientData) masterPtr);
/*
- * Pass #1: scan all the slaves to figure out the total amount
- * of space needed. Two separate width and height values are
- * computed:
+ * Pass #1: scan all the slaves to figure out the total amount of space
+ * needed. Two separate width and height values are computed:
*
- * width - Holds the sum of the widths (plus padding) of
- * all the slaves seen so far that were packed LEFT
- * or RIGHT.
- * height - Holds the sum of the heights (plus padding) of
- * all the slaves seen so far that were packed TOP
- * or BOTTOM.
+ * width - Holds the sum of the widths (plus padding) of all the
+ * slaves seen so far that were packed LEFT or RIGHT.
+ * height - Holds the sum of the heights (plus padding) of all the
+ * slaves seen so far that were packed TOP or BOTTOM.
*
- * maxWidth - Gradually builds up the width needed by the master
- * to just barely satisfy all the slave's needs. For
- * each slave, the code computes the width needed for
- * all the slaves so far and updates maxWidth if the
- * new value is greater.
+ * maxWidth - Gradually builds up the width needed by the master to
+ * just barely satisfy all the slave's needs. For each
+ * slave, the code computes the width needed for all the
+ * slaves so far and updates maxWidth if the new value is
+ * greater.
* maxHeight - Same as maxWidth, except keeps height info.
*/
@@ -646,11 +639,10 @@ ArrangePacking(clientData)
}
/*
- * If the total amount of space needed in the parent window has
- * changed, and if we're propagating geometry information, then
- * notify the next geometry manager up and requeue ourselves to
- * start again after the parent has had a chance to
- * resize us.
+ * If the total amount of space needed in the master window has changed,
+ * and if we're propagating geometry information, then notify the next
+ * geometry manager up and requeue ourselves to start again after the
+ * master has had a chance to resize us.
*/
if (((maxWidth != Tk_ReqWidth(masterPtr->tkwin))
@@ -663,14 +655,12 @@ ArrangePacking(clientData)
}
/*
- * Pass #2: scan the slaves a second time assigning
- * new sizes. The "cavity" variables keep track of the
- * unclaimed space in the cavity of the window; this
- * shrinks inward as we allocate windows around the
- * edges. The "frame" variables keep track of the space
- * allocated to the current window and its frame. The
- * current window is then placed somewhere inside the
- * frame, depending on anchor.
+ * Pass #2: scan the slaves a second time assigning new sizes. The
+ * "cavity" variables keep track of the unclaimed space in the cavity of
+ * the window; this shrinks inward as we allocate windows around the
+ * edges. The "frame" variables keep track of the space allocated to the
+ * current window and its frame. The current window is then placed
+ * somewhere inside the frame, depending on anchor.
*/
cavityX = x = Tk_InternalBorderLeft(masterPtr->tkwin);
@@ -724,13 +714,12 @@ ArrangePacking(clientData)
}
/*
- * Now that we've got the size of the frame for the window,
- * compute the window's actual size and location using the
- * fill, padding, and frame factors. The variables "borderX"
- * and "borderY" are used to handle the differences between
- * old-style packing and the new style (in old-style, iPadX
- * and iPadY are always zero and padding is completely ignored
- * except when computing frame size).
+ * Now that we've got the size of the frame for the window, compute
+ * the window's actual size and location using the fill, padding, and
+ * frame factors. The variables "borderX" and "borderY" are used to
+ * handle the differences between old-style packing and the new style
+ * (in old-style, iPadX and iPadY are always zero and padding is
+ * completely ignored except when computing frame size).
*/
if (slavePtr->flags & OLD_STYLE) {
@@ -758,52 +747,52 @@ ArrangePacking(clientData)
height = frameHeight - borderY;
}
switch (slavePtr->anchor) {
- case TK_ANCHOR_N:
- x = frameX + (borderLeft + frameWidth - width - borderRight)/2;
- y = frameY + borderTop;
- break;
- case TK_ANCHOR_NE:
- x = frameX + frameWidth - width - borderRight;
- y = frameY + borderTop;
- break;
- case TK_ANCHOR_E:
- x = frameX + frameWidth - width - borderRight;
- y = frameY + (borderTop + frameHeight - height - borderBtm)/2;
- break;
- case TK_ANCHOR_SE:
- x = frameX + frameWidth - width - borderRight;
- y = frameY + frameHeight - height - borderBtm;
- break;
- case TK_ANCHOR_S:
- x = frameX + (borderLeft + frameWidth - width - borderRight)/2;
- y = frameY + frameHeight - height - borderBtm;
- break;
- case TK_ANCHOR_SW:
- x = frameX + borderLeft;
- y = frameY + frameHeight - height - borderBtm;
- break;
- case TK_ANCHOR_W:
- x = frameX + borderLeft;
- y = frameY + (borderTop + frameHeight - height - borderBtm)/2;
- break;
- case TK_ANCHOR_NW:
- x = frameX + borderLeft;
- y = frameY + borderTop;
- break;
- case TK_ANCHOR_CENTER:
- x = frameX + (borderLeft + frameWidth - width - borderRight)/2;
- y = frameY + (borderTop + frameHeight - height - borderBtm)/2;
- break;
- default:
- panic("bad frame factor in ArrangePacking");
+ case TK_ANCHOR_N:
+ x = frameX + (borderLeft + frameWidth - width - borderRight)/2;
+ y = frameY + borderTop;
+ break;
+ case TK_ANCHOR_NE:
+ x = frameX + frameWidth - width - borderRight;
+ y = frameY + borderTop;
+ break;
+ case TK_ANCHOR_E:
+ x = frameX + frameWidth - width - borderRight;
+ y = frameY + (borderTop + frameHeight - height - borderBtm)/2;
+ break;
+ case TK_ANCHOR_SE:
+ x = frameX + frameWidth - width - borderRight;
+ y = frameY + frameHeight - height - borderBtm;
+ break;
+ case TK_ANCHOR_S:
+ x = frameX + (borderLeft + frameWidth - width - borderRight)/2;
+ y = frameY + frameHeight - height - borderBtm;
+ break;
+ case TK_ANCHOR_SW:
+ x = frameX + borderLeft;
+ y = frameY + frameHeight - height - borderBtm;
+ break;
+ case TK_ANCHOR_W:
+ x = frameX + borderLeft;
+ y = frameY + (borderTop + frameHeight - height - borderBtm)/2;
+ break;
+ case TK_ANCHOR_NW:
+ x = frameX + borderLeft;
+ y = frameY + borderTop;
+ break;
+ case TK_ANCHOR_CENTER:
+ x = frameX + (borderLeft + frameWidth - width - borderRight)/2;
+ y = frameY + (borderTop + frameHeight - height - borderBtm)/2;
+ break;
+ default:
+ Tcl_Panic("bad frame factor in ArrangePacking");
}
width -= slavePtr->doubleBw;
height -= slavePtr->doubleBw;
/*
* The final step is to set the position, size, and mapped/unmapped
- * state of the slave. If the slave is a child of the master, then
- * do this here. Otherwise let Tk_MaintainGeometry do the work.
+ * state of the slave. If the slave is a child of the master, then do
+ * this here. Otherwise let Tk_MaintainGeometry do the work.
*/
if (masterPtr->tkwin == Tk_Parent(slavePtr->tkwin)) {
@@ -821,8 +810,8 @@ ArrangePacking(clientData)
}
/*
- * Don't map the slave if the master isn't mapped: wait
- * until the master gets mapped later.
+ * Don't map the slave if the master isn't mapped: wait until
+ * the master gets mapped later.
*/
if (Tk_IsMapped(masterPtr->tkwin)) {
@@ -840,9 +829,9 @@ ArrangePacking(clientData)
}
/*
- * Changes to the window's structure could cause almost anything
- * to happen, including deleting the parent or child. If this
- * happens, we'll be told to abort.
+ * Changes to the window's structure could cause almost anything to
+ * happen, including deleting the parent or child. If this happens,
+ * we'll be told to abort.
*/
if (abort) {
@@ -850,7 +839,7 @@ ArrangePacking(clientData)
}
}
- done:
+ done:
masterPtr->abortPtr = NULL;
Tcl_Release((ClientData) masterPtr);
}
@@ -860,13 +849,12 @@ ArrangePacking(clientData)
*
* XExpansion --
*
- * Given a list of packed slaves, the first of which is packed
- * on the left or right and is expandable, compute how much to
- * expand the child.
+ * Given a list of packed slaves, the first of which is packed on the
+ * left or right and is expandable, compute how much to expand the child.
*
* Results:
- * The return value is the number of additional pixels to give to
- * the child.
+ * The return value is the number of additional pixels to give to the
+ * child.
*
* Side effects:
* None.
@@ -875,24 +863,23 @@ ArrangePacking(clientData)
*/
static int
-XExpansion(slavePtr, cavityWidth)
- register Packer *slavePtr; /* First in list of remaining
- * slaves. */
- int cavityWidth; /* Horizontal space left for all
- * remaining slaves. */
+XExpansion(
+ register Packer *slavePtr, /* First in list of remaining slaves. */
+ int cavityWidth) /* Horizontal space left for all remaining
+ * slaves. */
{
int numExpand, minExpand, curExpand;
int childWidth;
/*
- * This procedure is tricky because windows packed top or bottom can
- * be interspersed among expandable windows packed left or right.
- * Scan through the list, keeping a running sum of the widths of
- * all left and right windows (actually, count the cavity space not
- * allocated) and a running count of all expandable left and right
- * windows. At each top or bottom window, and at the end of the
- * list, compute the expansion factor that seems reasonable at that
- * point. Return the smallest factor seen at any of these points.
+ * This function is tricky because windows packed top or bottom can be
+ * interspersed among expandable windows packed left or right. Scan
+ * through the list, keeping a running sum of the widths of all left and
+ * right windows (actually, count the cavity space not allocated) and a
+ * running count of all expandable left and right windows. At each top or
+ * bottom window, and at the end of the list, compute the expansion factor
+ * that seems reasonable at that point. Return the smallest factor seen at
+ * any of these points.
*/
minExpand = cavityWidth;
@@ -924,13 +911,12 @@ XExpansion(slavePtr, cavityWidth)
*
* YExpansion --
*
- * Given a list of packed slaves, the first of which is packed
- * on the top or bottom and is expandable, compute how much to
- * expand the child.
+ * Given a list of packed slaves, the first of which is packed on the top
+ * or bottom and is expandable, compute how much to expand the child.
*
* Results:
- * The return value is the number of additional pixels to give to
- * the child.
+ * The return value is the number of additional pixels to give to the
+ * child.
*
* Side effects:
* None.
@@ -939,11 +925,10 @@ XExpansion(slavePtr, cavityWidth)
*/
static int
-YExpansion(slavePtr, cavityHeight)
- register Packer *slavePtr; /* First in list of remaining
- * slaves. */
- int cavityHeight; /* Vertical space left for all
- * remaining slaves. */
+YExpansion(
+ register Packer *slavePtr, /* First in list of remaining slaves. */
+ int cavityHeight) /* Vertical space left for all remaining
+ * slaves. */
{
int numExpand, minExpand, curExpand;
int childHeight;
@@ -981,30 +966,28 @@ YExpansion(slavePtr, cavityHeight)
*
* GetPacker --
*
- * This internal procedure is used to locate a Packer
- * structure for a given window, creating one if one
- * doesn't exist already.
+ * This internal function is used to locate a Packer structure for a
+ * given window, creating one if one doesn't exist already.
*
* Results:
- * The return value is a pointer to the Packer structure
- * corresponding to tkwin.
+ * The return value is a pointer to the Packer structure corresponding to
+ * tkwin.
*
* Side effects:
- * A new packer structure may be created. If so, then
- * a callback is set up to clean things up when the
- * window is deleted.
+ * A new packer structure may be created. If so, then a callback is set
+ * up to clean things up when the window is deleted.
*
*--------------------------------------------------------------
*/
static Packer *
-GetPacker(tkwin)
- Tk_Window tkwin; /* Token for window for which
- * packer structure is desired. */
+GetPacker(
+ Tk_Window tkwin) /* Token for window for which packer structure
+ * is desired. */
{
register Packer *packPtr;
Tcl_HashEntry *hPtr;
- int new;
+ int isNew;
TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
if (!dispPtr->packInit) {
@@ -1013,13 +996,13 @@ GetPacker(tkwin)
}
/*
- * See if there's already packer for this window. If not,
- * then create a new one.
+ * See if there's already packer for this window. If not, then create a
+ * new one.
*/
- hPtr = Tcl_CreateHashEntry(&dispPtr->packerHashTable, (char *) tkwin,
- &new);
- if (!new) {
+ hPtr = Tcl_CreateHashEntry(&dispPtr->packerHashTable, (char *) tkwin,
+ &isNew);
+ if (!isNew) {
return (Packer *) Tcl_GetHashValue(hPtr);
}
packPtr = (Packer *) ckalloc(sizeof(Packer));
@@ -1046,30 +1029,30 @@ GetPacker(tkwin)
*
* PackAfter --
*
- * This procedure does most of the real work of adding
- * one or more windows into the packing order for its parent.
+ * This function does most of the real work of adding one or more windows
+ * into the packing order for its master.
*
* Results:
* A standard Tcl return value.
*
* Side effects:
- * The geometry of the specified windows may change, both now and
- * again in the future.
+ * The geometry of the specified windows may change, both now and again
+ * in the future.
*
*--------------------------------------------------------------
*/
static int
-PackAfter(interp, prevPtr, masterPtr, objc, objv)
- Tcl_Interp *interp; /* Interpreter for error reporting. */
- Packer *prevPtr; /* Pack windows in argv just after this
- * window; NULL means pack as first
- * child of masterPtr. */
- Packer *masterPtr; /* Master in which to pack windows. */
- int objc; /* Number of elements in objv. */
- Tcl_Obj *CONST objv[]; /* Array of lists, each containing 2
- * elements: window name and side
- * against which to pack. */
+PackAfter(
+ Tcl_Interp *interp, /* Interpreter for error reporting. */
+ Packer *prevPtr, /* Pack windows in argv just after this
+ * window; NULL means pack as first child of
+ * masterPtr. */
+ Packer *masterPtr, /* Master in which to pack windows. */
+ int objc, /* Number of elements in objv. */
+ Tcl_Obj *CONST objv[]) /* Array of lists, each containing 2 elements:
+ * window name and side against which to
+ * pack. */
{
register Packer *packPtr;
Tk_Window tkwin, ancestor, parent;
@@ -1078,24 +1061,23 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv)
int index, optionCount, c;
/*
- * Iterate over all of the window specifiers, each consisting of
- * two arguments. The first argument contains the window name and
- * the additional arguments contain options such as "top" or
- * "padx 20".
+ * Iterate over all of the window specifiers, each consisting of two
+ * arguments. The first argument contains the window name and the
+ * additional arguments contain options such as "top" or "padx 20".
*/
for ( ; objc > 0; objc -= 2, objv += 2, prevPtr = packPtr) {
if (objc < 2) {
Tcl_AppendResult(interp, "wrong # args: window \"",
Tcl_GetString(objv[0]), "\" should be followed by options",
- (char *) NULL);
+ NULL);
return TCL_ERROR;
}
/*
- * Find the packer for the window to be packed, and make sure
- * that the window in which it will be packed is either its
- * or a descendant of its parent.
+ * Find the packer for the window to be packed, and make sure that the
+ * window in which it will be packed is either its or a descendant of
+ * its parent.
*/
if (TkGetWindowFromObj(interp, masterPtr->tkwin, objv[0], &tkwin)
@@ -1109,10 +1091,9 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv)
break;
}
if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_HIERARCHY) {
- badWindow:
+ badWindow:
Tcl_AppendResult(interp, "can't pack ", Tcl_GetString(objv[0]),
- " inside ", Tk_PathName(masterPtr->tkwin),
- (char *) NULL);
+ " inside ", Tk_PathName(masterPtr->tkwin), NULL);
return TCL_ERROR;
}
}
@@ -1146,19 +1127,19 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv)
c = curOpt[0];
if ((c == 't')
- && (strncmp(curOpt, "top", (unsigned) length)) == 0) {
+ && (strncmp(curOpt, "top", (size_t) length)) == 0) {
packPtr->side = TOP;
} else if ((c == 'b')
- && (strncmp(curOpt, "bottom", (unsigned) length)) == 0) {
+ && (strncmp(curOpt, "bottom", (size_t) length)) == 0) {
packPtr->side = BOTTOM;
} else if ((c == 'l')
- && (strncmp(curOpt, "left", (unsigned) length)) == 0) {
+ && (strncmp(curOpt, "left", (size_t) length)) == 0) {
packPtr->side = LEFT;
} else if ((c == 'r')
- && (strncmp(curOpt, "right", (unsigned) length)) == 0) {
+ && (strncmp(curOpt, "right", (size_t) length)) == 0) {
packPtr->side = RIGHT;
} else if ((c == 'e')
- && (strncmp(curOpt, "expand", (unsigned) length)) == 0) {
+ && (strncmp(curOpt, "expand", (size_t) length)) == 0) {
packPtr->flags |= EXPAND;
} else if ((c == 'f')
&& (strcmp(curOpt, "fill")) == 0) {
@@ -1169,10 +1150,10 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv)
packPtr->flags |= FILLY;
} else if ((c == 'p') && (strcmp(curOpt, "padx")) == 0) {
if (optionCount < (index+2)) {
- missingPad:
+ missingPad:
Tcl_AppendResult(interp, "wrong # args: \"", curOpt,
"\" option must be followed by screen distance",
- (char *) NULL);
+ NULL);
return TCL_ERROR;
}
if (TkParsePadAmount(interp, tkwin, options[index+1],
@@ -1196,11 +1177,10 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv)
packPtr->iPadY = 0;
index++;
} else if ((c == 'f') && (length > 1)
- && (strncmp(curOpt, "frame", (unsigned) length) == 0)) {
+ && (strncmp(curOpt, "frame", (size_t) length) == 0)) {
if (optionCount < (index+2)) {
Tcl_AppendResult(interp, "wrong # args: \"frame\" ",
- "option must be followed by anchor point",
- (char *) NULL);
+ "option must be followed by anchor point", NULL);
return TCL_ERROR;
}
if (Tk_GetAnchorFromObj(interp, options[index+1],
@@ -1210,9 +1190,8 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv)
index++;
} else {
Tcl_AppendResult(interp, "bad option \"", curOpt,
- "\": should be top, bottom, left, right, ",
- "expand, fill, fillx, filly, padx, pady, or frame",
- (char *) NULL);
+ "\": should be top, bottom, left, right, expand, ",
+ "fill, fillx, filly, padx, pady, or frame", NULL);
return TCL_ERROR;
}
}
@@ -1232,11 +1211,10 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv)
}
Unlink(packPtr);
}
-
+
/*
- * Add the window in the correct place in its parent's
- * packing order, then make sure that the window is
- * managed by us.
+ * Add the window in the correct place in its master's packing
+ * order, then make sure that the window is managed by us.
*/
packPtr->masterPtr = masterPtr;
@@ -1252,8 +1230,7 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv)
}
/*
- * Arrange for the parent to be re-packed at the first
- * idle moment.
+ * Arrange for the master to be re-packed at the first idle moment.
*/
if (masterPtr->abortPtr != NULL) {
@@ -1271,20 +1248,20 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv)
*
* Unlink --
*
- * Remove a packer from its parent's list of slaves.
+ * Remove a packer from its master's list of slaves.
*
* Results:
* None.
*
* Side effects:
- * The parent will be scheduled for repacking.
+ * The master will be scheduled for repacking.
*
*----------------------------------------------------------------------
*/
static void
-Unlink(packPtr)
- register Packer *packPtr; /* Window to unlink. */
+Unlink(
+ register Packer *packPtr) /* Window to unlink. */
{
register Packer *masterPtr, *packPtr2;
@@ -1297,7 +1274,7 @@ Unlink(packPtr)
} else {
for (packPtr2 = masterPtr->slavePtr; ; packPtr2 = packPtr2->nextPtr) {
if (packPtr2 == NULL) {
- panic("Unlink couldn't find previous window");
+ Tcl_Panic("Unlink couldn't find previous window");
}
if (packPtr2->nextPtr == packPtr) {
packPtr2->nextPtr = packPtr->nextPtr;
@@ -1321,9 +1298,9 @@ Unlink(packPtr)
*
* DestroyPacker --
*
- * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release
- * to clean up the internal structure of a packer at a safe time
- * (when no-one is using it anymore).
+ * This function is invoked by Tcl_EventuallyFree or Tcl_Release to clean
+ * up the internal structure of a packer at a safe time (when no-one is
+ * using it anymore).
*
* Results:
* None.
@@ -1335,9 +1312,9 @@ Unlink(packPtr)
*/
static void
-DestroyPacker(memPtr)
- char *memPtr; /* Info about packed window that
- * is now dead. */
+DestroyPacker(
+ char *memPtr) /* Info about packed window that is now
+ * dead. */
{
register Packer *packPtr = (Packer *) memPtr;
ckfree((char *) packPtr);
@@ -1348,25 +1325,24 @@ DestroyPacker(memPtr)
*
* PackStructureProc --
*
- * This procedure is invoked by the Tk event dispatcher in response
- * to StructureNotify events.
+ * This function is invoked by the Tk event dispatcher in response to
+ * StructureNotify events.
*
* Results:
* None.
*
* Side effects:
* If a window was just deleted, clean up all its packer-related
- * information. If it was just resized, repack its slaves, if
- * any.
+ * information. If it was just resized, repack its slaves, if any.
*
*----------------------------------------------------------------------
*/
static void
-PackStructureProc(clientData, eventPtr)
- ClientData clientData; /* Our information about window
- * referred to by eventPtr. */
- XEvent *eventPtr; /* Describes what just happened. */
+PackStructureProc(
+ ClientData clientData, /* Our information about window referred to by
+ * eventPtr. */
+ XEvent *eventPtr) /* Describes what just happened. */
{
register Packer *packPtr = (Packer *) clientData;
@@ -1376,9 +1352,9 @@ PackStructureProc(clientData, eventPtr)
packPtr->flags |= REQUESTED_REPACK;
Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr);
}
- if (packPtr->doubleBw != 2*Tk_Changes(packPtr->tkwin)->border_width) {
- if ((packPtr->masterPtr != NULL)
- && !(packPtr->masterPtr->flags & REQUESTED_REPACK)) {
+ if ((packPtr->masterPtr != NULL)
+ && (packPtr->doubleBw != 2*Tk_Changes(packPtr->tkwin)->border_width)) {
+ if (!(packPtr->masterPtr->flags & REQUESTED_REPACK)) {
packPtr->doubleBw = 2*Tk_Changes(packPtr->tkwin)->border_width;
packPtr->masterPtr->flags |= REQUESTED_REPACK;
Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr->masterPtr);
@@ -1390,20 +1366,23 @@ PackStructureProc(clientData, eventPtr)
if (packPtr->masterPtr != NULL) {
Unlink(packPtr);
}
+
for (slavePtr = packPtr->slavePtr; slavePtr != NULL;
slavePtr = nextPtr) {
- Tk_ManageGeometry(slavePtr->tkwin, (Tk_GeomMgr *) NULL,
+ Tk_ManageGeometry(slavePtr->tkwin, NULL,
(ClientData) NULL);
Tk_UnmapWindow(slavePtr->tkwin);
slavePtr->masterPtr = NULL;
nextPtr = slavePtr->nextPtr;
slavePtr->nextPtr = NULL;
}
+
if (packPtr->tkwin != NULL) {
TkDisplay *dispPtr = ((TkWindow *) packPtr->tkwin)->dispPtr;
Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->packerHashTable,
(char *) packPtr->tkwin));
}
+
if (packPtr->flags & REQUESTED_REPACK) {
Tcl_CancelIdleCall(ArrangePacking, (ClientData) packPtr);
}
@@ -1411,8 +1390,8 @@ PackStructureProc(clientData, eventPtr)
Tcl_EventuallyFree((ClientData) packPtr, DestroyPacker);
} else if (eventPtr->type == MapNotify) {
/*
- * When a master gets mapped, must redo the geometry computation
- * so that all of its slaves get remapped.
+ * When a master gets mapped, must redo the geometry computation so
+ * that all of its slaves get remapped.
*/
if ((packPtr->slavePtr != NULL)
@@ -1424,10 +1403,10 @@ PackStructureProc(clientData, eventPtr)
register Packer *packPtr2;
/*
- * Unmap all of the slaves when the master gets unmapped,
- * so that they don't bother to keep redisplaying
- * themselves.
+ * Unmap all of the slaves when the master gets unmapped, so that they
+ * don't bother to keep redisplaying themselves.
*/
+
for (packPtr2 = packPtr->slavePtr; packPtr2 != NULL;
packPtr2 = packPtr2->nextPtr) {
Tk_UnmapWindow(packPtr2->tkwin);
@@ -1440,13 +1419,13 @@ PackStructureProc(clientData, eventPtr)
*
* ConfigureSlaves --
*
- * This implements the guts of the "pack configure" command. Given
- * a list of slaves and configuration options, it arranges for the
- * packer to manage the slaves and sets the specified options.
+ * This implements the guts of the "pack configure" command. Given a list
+ * of slaves and configuration options, it arranges for the packer to
+ * manage the slaves and sets the specified options.
*
* Results:
- * TCL_OK is returned if all went well. Otherwise, TCL_ERROR is
- * returned and the interp's result is set to contain an error message.
+ * TCL_OK is returned if all went well. Otherwise, TCL_ERROR is returned
+ * and the interp's result is set to contain an error message.
*
* Side effects:
* Slave windows get taken over by the packer.
@@ -1455,16 +1434,15 @@ PackStructureProc(clientData, eventPtr)
*/
static int
-ConfigureSlaves(interp, tkwin, objc, objv)
- Tcl_Interp *interp; /* Interpreter for error reporting. */
- Tk_Window tkwin; /* Any window in application containing
- * slaves. Used to look up slave names. */
- int objc; /* Number of elements in argv. */
- Tcl_Obj *CONST objv[]; /* Argument objects: contains one or more
- * window names followed by any number
- * of "option value" pairs. Caller must
- * make sure that there is at least one
- * window name. */
+ConfigureSlaves(
+ Tcl_Interp *interp, /* Interpreter for error reporting. */
+ Tk_Window tkwin, /* Any window in application containing
+ * slaves. Used to look up slave names. */
+ int objc, /* Number of elements in argv. */
+ Tcl_Obj *CONST objv[]) /* Argument objects: contains one or more
+ * window names followed by any number of
+ * "option value" pairs. Caller must make sure
+ * that there is at least one window name. */
{
Packer *masterPtr, *slavePtr, *prevPtr, *otherPtr;
Tk_Window other, slave, parent, ancestor;
@@ -1472,7 +1450,7 @@ ConfigureSlaves(interp, tkwin, objc, objv)
char *string;
static CONST char *optionStrings[] = {
"-after", "-anchor", "-before", "-expand", "-fill",
- "-in", "-ipadx", "-ipady", "-padx", "-pady", "-side", (char *) NULL };
+ "-in", "-ipadx", "-ipady", "-padx", "-pady", "-side", NULL };
enum options {
CONF_AFTER, CONF_ANCHOR, CONF_BEFORE, CONF_EXPAND, CONF_FILL,
CONF_IN, CONF_IPADX, CONF_IPADY, CONF_PADX, CONF_PADY, CONF_SIDE };
@@ -1491,13 +1469,12 @@ ConfigureSlaves(interp, tkwin, objc, objv)
/*
* Iterate over all of the slave windows, parsing the configuration
- * options for each slave. It's a bit wasteful to re-parse the
- * options for each slave, but things get too messy if we try to
- * parse the arguments just once at the beginning. For example,
- * if a slave already is packed we want to just change a few
- * existing values without resetting everything. If there are
- * multiple windows, the -after, -before, and -in options only
- * get processed for the first window.
+ * options for each slave. It's a bit wasteful to re-parse the options for
+ * each slave, but things get too messy if we try to parse the arguments
+ * just once at the beginning. For example, if a slave already is packed
+ * we want to just change a few existing values without resetting
+ * everything. If there are multiple windows, the -after, -before, and -in
+ * options only get processed for the first window.
*/
masterPtr = NULL;
@@ -1509,16 +1486,16 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
if (Tk_TopWinHierarchy(slave)) {
Tcl_AppendResult(interp, "can't pack \"", Tcl_GetString(objv[j]),
- "\": it's a top-level window", (char *) NULL);
+ "\": it's a top-level window", NULL);
return TCL_ERROR;
}
slavePtr = GetPacker(slave);
slavePtr->flags &= ~OLD_STYLE;
/*
- * If the slave isn't currently packed, reset all of its
- * configuration information to default values (there could
- * be old values left from a previous packing).
+ * If the slave isn't currently packed, reset all of its configuration
+ * information to default values (there could be old values left from
+ * a previous packing).
*/
if (slavePtr->masterPtr == NULL) {
@@ -1534,14 +1511,16 @@ ConfigureSlaves(interp, tkwin, objc, objv)
if ((i+2) > objc) {
Tcl_AppendResult(interp, "extra option \"",
Tcl_GetString(objv[i]),
- "\" (option with no value?)", (char *) NULL);
+ "\" (option with no value?)", NULL);
return TCL_ERROR;
}
if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option",
0, &index) != TCL_OK) {
return TCL_ERROR;
}
- if (index == CONF_AFTER) {
+
+ switch ((enum options) index) {
+ case CONF_AFTER:
if (j == 0) {
if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
!= TCL_OK) {
@@ -1549,21 +1528,23 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
prevPtr = GetPacker(other);
if (prevPtr->masterPtr == NULL) {
- notPacked:
+ notPacked:
Tcl_AppendResult(interp, "window \"",
Tcl_GetString(objv[i+1]),
- "\" isn't packed", (char *) NULL);
+ "\" isn't packed", NULL);
return TCL_ERROR;
}
masterPtr = prevPtr->masterPtr;
positionGiven = 1;
}
- } else if (index == CONF_ANCHOR) {
+ break;
+ case CONF_ANCHOR:
if (Tk_GetAnchorFromObj(interp, objv[i+1], &slavePtr->anchor)
!= TCL_OK) {
return TCL_ERROR;
}
- } else if (index == CONF_BEFORE) {
+ break;
+ case CONF_BEFORE:
if (j == 0) {
if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
!= TCL_OK) {
@@ -1584,7 +1565,8 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
positionGiven = 1;
}
- } else if (index == CONF_EXPAND) {
+ break;
+ case CONF_EXPAND:
if (Tcl_GetBooleanFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
return TCL_ERROR;
}
@@ -1592,7 +1574,8 @@ ConfigureSlaves(interp, tkwin, objc, objv)
if (tmp) {
slavePtr->flags |= EXPAND;
}
- } else if (index == CONF_FILL) {
+ break;
+ case CONF_FILL:
string = Tcl_GetString(objv[i+1]);
if (strcmp(string, "none") == 0) {
slavePtr->flags &= ~(FILLX|FILLY);
@@ -1604,10 +1587,11 @@ ConfigureSlaves(interp, tkwin, objc, objv)
slavePtr->flags |= FILLX|FILLY;
} else {
Tcl_AppendResult(interp, "bad fill style \"", string,
- "\": must be none, x, y, or both", (char *) NULL);
+ "\": must be none, x, y, or both", NULL);
return TCL_ERROR;
}
- } else if (index == CONF_IN) {
+ break;
+ case CONF_IN:
if (j == 0) {
if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
!= TCL_OK) {
@@ -1622,53 +1606,57 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
positionGiven = 1;
}
- } else if (index == CONF_IPADX) {
+ break;
+ case CONF_IPADX:
if ((Tk_GetPixelsFromObj(interp, slave, objv[i+1], &tmp)
!= TCL_OK)
|| (tmp < 0)) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "bad ipadx value \"",
Tcl_GetString(objv[i+1]),
- "\": must be positive screen distance",
- (char *) NULL);
+ "\": must be positive screen distance", NULL);
return TCL_ERROR;
}
slavePtr->iPadX = tmp * 2;
- } else if (index == CONF_IPADY) {
+ break;
+ case CONF_IPADY:
if ((Tk_GetPixelsFromObj(interp, slave, objv[i+1], &tmp)
!= TCL_OK)
|| (tmp < 0)) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "bad ipady value \"",
Tcl_GetString(objv[i+1]),
- "\": must be positive screen distance",
- (char *) NULL);
+ "\": must be positive screen distance", NULL);
return TCL_ERROR;
}
slavePtr->iPadY = tmp * 2;
- } else if (index == CONF_PADX) {
+ break;
+ case CONF_PADX:
if (TkParsePadAmount(interp, slave, objv[i+1],
&slavePtr->padLeft, &slavePtr->padX) != TCL_OK) {
return TCL_ERROR;
}
- } else if (index == CONF_PADY) {
+ break;
+ case CONF_PADY:
if (TkParsePadAmount(interp, slave, objv[i+1],
&slavePtr->padTop, &slavePtr->padY) != TCL_OK) {
return TCL_ERROR;
}
- } else if (index == CONF_SIDE) {
+ break;
+ case CONF_SIDE:
if (Tcl_GetIndexFromObj(interp, objv[i+1], sideNames, "side",
TCL_EXACT, &side) != TCL_OK) {
return TCL_ERROR;
}
slavePtr->side = (Side) side;
+ break;
}
}
/*
- * If no position in a packing list was specified and the slave
- * is already packed, then leave it in its current location in
- * its current packing list.
+ * If no position in a packing list was specified and the slave is
+ * already packed, then leave it in its current location in its
+ * current packing list.
*/
if (!positionGiven && (slavePtr->masterPtr != NULL)) {
@@ -1677,21 +1665,22 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
/*
- * If the slave is going to be put back after itself then
- * skip the whole operation, since it won't work anyway.
+ * If the slave is going to be put back after itself or the same -in
+ * window is passed in again, then just skip the whole operation,
+ * since it won't work anyway.
*/
if (prevPtr == slavePtr) {
masterPtr = slavePtr->masterPtr;
goto scheduleLayout;
}
-
+
/*
- * If none of the "-in", "-before", or "-after" options has
- * been specified, arrange for the slave to go at the end of
- * the order for its parent.
+ * If none of the "-in", "-before", or "-after" options has been
+ * specified, arrange for the slave to go at the end of the order for
+ * its parent.
*/
-
+
if (!positionGiven) {
masterPtr = GetPacker(Tk_Parent(slave));
prevPtr = masterPtr->slavePtr;
@@ -1703,11 +1692,11 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
/*
- * Make sure that the slave's parent is either the master or
- * an ancestor of the master, and that the master and slave
- * aren't the same.
+ * Make sure that the slave's parent is either the master or an
+ * ancestor of the master, and that the master and slave aren't the
+ * same.
*/
-
+
parent = Tk_Parent(slave);
for (ancestor = masterPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
if (ancestor == parent) {
@@ -1715,20 +1704,19 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
if (Tk_TopWinHierarchy(ancestor)) {
Tcl_AppendResult(interp, "can't pack ", Tcl_GetString(objv[j]),
- " inside ", Tk_PathName(masterPtr->tkwin),
- (char *) NULL);
+ " inside ", Tk_PathName(masterPtr->tkwin), NULL);
return TCL_ERROR;
}
}
if (slave == masterPtr->tkwin) {
Tcl_AppendResult(interp, "can't pack ", Tcl_GetString(objv[j]),
- " inside itself", (char *) NULL);
+ " inside itself", NULL);
return TCL_ERROR;
}
/*
- * Unpack the slave if it's currently packed, then position it
- * after prevPtr.
+ * Unpack the slave if it's currently packed, then position it after
+ * prevPtr.
*/
if (slavePtr->masterPtr != NULL) {
@@ -1752,11 +1740,10 @@ ConfigureSlaves(interp, tkwin, objc, objv)
prevPtr = slavePtr;
/*
- * Arrange for the parent to be re-packed at the first
- * idle moment.
+ * Arrange for the master to be re-packed at the first idle moment.
*/
- scheduleLayout:
+ scheduleLayout:
if (masterPtr->abortPtr != NULL) {
*masterPtr->abortPtr = 1;
}
@@ -1767,3 +1754,11 @@ ConfigureSlaves(interp, tkwin, objc, objv)
}
return TCL_OK;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkPanedWindow.c b/generic/tkPanedWindow.c
index a876ae8..cf3611f 100644
--- a/generic/tkPanedWindow.c
+++ b/generic/tkPanedWindow.c
@@ -1,23 +1,23 @@
-/*
+/*
* tkPanedWindow.c --
*
- * This module implements "paned window" widgets that are object
- * based. A "paned window" is a widget that manages the geometry for
- * some number of other widgets, placing a movable "sash" between them,
- * which can be used to alter the relative sizes of adjacent widgets.
+ * This module implements "paned window" widgets that are object based. A
+ * "paned window" is a widget that manages the geometry for some number
+ * of other widgets, placing a movable "sash" between them, which can be
+ * used to alter the relative sizes of adjacent widgets.
*
* Copyright (c) 1997 Sun Microsystems, Inc.
* Copyright (c) 2000 Ajuba Solutions.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "default.h"
#include "tkInt.h"
-/* Flag values for "sticky"ness The 16 combinations subsume the packer's
+/*
+ * Flag values for "sticky"ness. The 16 combinations subsume the packer's
* notion of anchor and fill.
*
* STICK_NORTH This window sticks to the top of its cavity.
@@ -30,16 +30,44 @@
#define STICK_EAST 2
#define STICK_SOUTH 4
#define STICK_WEST 8
+
/*
* The following table defines the legal values for the -orient option.
*/
-static CONST char *CONST orientStrings[] = {
- "horizontal", "vertical", (char *) NULL
+static const char *const orientStrings[] = {
+ "horizontal", "vertical", NULL
};
enum orient { ORIENT_HORIZONTAL, ORIENT_VERTICAL };
+/*
+ * The following table defines the legal values for the -stretch option.
+ */
+
+static const char *const stretchStrings[] = {
+ "always", "first", "last", "middle", "never", NULL
+};
+
+enum stretch {
+ STRETCH_ALWAYS, /* Always give extra space to this pane. */
+ STRETCH_FIRST, /* Give extra space to pane if it is first. */
+ STRETCH_LAST, /* Give extra space to pane if it is last. */
+ STRETCH_MIDDLE, /* Give extra space to pane only if it is
+ * neither first nor last. */
+ STRETCH_NEVER /* Never give extra space to this pane. */
+};
+
+/*
+ * Codify the stretchiness rule in one place.
+ */
+
+#define IsStretchable(stretch,index,first,last) \
+ (((stretch) == STRETCH_ALWAYS) || \
+ ((stretch) == STRETCH_FIRST && (index) == (first)) || \
+ ((stretch) == STRETCH_LAST && (index) == (last)) || \
+ ((stretch) == STRETCH_MIDDLE && (index) != (first) && (index) != (last)))
+
typedef struct {
Tk_OptionTable pwOptions; /* Token for paned window option table. */
Tk_OptionTable slaveOpts; /* Token for slave cget option table. */
@@ -51,35 +79,38 @@ typedef struct {
*/
typedef struct Slave {
- Tk_Window tkwin; /* Window being managed. */
-
- int minSize; /* Minimum size of this pane, on the
- * relevant axis, in pixels. */
- int padx; /* Additional padding requested for
- * slave, in the x dimension. */
- int pady; /* Additional padding requested for
- * slave, in the y dimension. */
- Tcl_Obj *widthPtr, *heightPtr; /* Tcl_Obj rep's of slave width/height,
- * to allow for null values. */
- int width; /* Slave width. */
- int height; /* Slave height. */
- int sticky; /* Sticky string. */
- int x, y; /* Coordinates of the widget. */
- int paneWidth, paneHeight; /* Pane dimensions (may be different
- * from slave width/height). */
- int sashx, sashy; /* Coordinates of the sash of the
- * right or bottom of this pane. */
- int markx, marky; /* Coordinates of the last mark set
- * for the sash. */
- int handlex, handley; /* Coordinates of the sash handle. */
- struct PanedWindow *masterPtr; /* Paned window managing the window. */
- Tk_Window after; /* Placeholder for parsing options. */
- Tk_Window before; /* Placeholder for parsing options. */
+ Tk_Window tkwin; /* Window being managed. */
+ int minSize; /* Minimum size of this pane, on the relevant
+ * axis, in pixels. */
+ int padx; /* Additional padding requested for slave, in
+ * the x dimension. */
+ int pady; /* Additional padding requested for slave, in
+ * the y dimension. */
+ Tcl_Obj *widthPtr, *heightPtr;
+ /* Tcl_Obj rep's of slave width/height, to
+ * allow for null values. */
+ int width; /* Slave width. */
+ int height; /* Slave height. */
+ int sticky; /* Sticky string. */
+ int x, y; /* Coordinates of the widget. */
+ int paneWidth, paneHeight; /* Pane dimensions (may be different from
+ * slave width/height). */
+ int sashx, sashy; /* Coordinates of the sash of the right or
+ * bottom of this pane. */
+ int markx, marky; /* Coordinates of the last mark set for the
+ * sash. */
+ int handlex, handley; /* Coordinates of the sash handle. */
+ enum stretch stretch; /* Controls how slave grows/shrinks */
+ int hide; /* Controls visibility of pane */
+ struct PanedWindow *masterPtr;
+ /* Paned window managing the window. */
+ Tk_Window after; /* Placeholder for parsing options. */
+ Tk_Window before; /* Placeholder for parsing options. */
} Slave;
/*
- * A data structure of the following type is kept for each paned window
- * widget managed by this file:
+ * A data structure of the following type is kept for each paned window widget
+ * managed by this file:
*/
typedef struct PanedWindow {
@@ -101,7 +132,6 @@ typedef struct PanedWindow {
Tk_Cursor cursor; /* Current cursor for window, or None. */
int resizeOpaque; /* Boolean indicating whether resize should be
* opaque or rubberband style. */
-
int sashRelief; /* Relief used to draw sash. */
int sashWidth; /* Width of each sash, in pixels. */
Tcl_Obj *sashWidthPtr; /* Tcl_Obj rep for sash width. */
@@ -114,7 +144,6 @@ typedef struct PanedWindow {
int handlePad; /* Distance from border to draw handle. */
Tcl_Obj *handleSizePtr; /* Tcl_Obj rep for handle size. */
Tk_Cursor sashCursor; /* Cursor used when mouse is above a sash. */
-
GC gc; /* Graphics context for copying from
* off-screen pixmap onto screen. */
int proxyx, proxyy; /* Proxy x,y coordinates. */
@@ -127,11 +156,11 @@ typedef struct PanedWindow {
/*
* Flags used for paned windows:
*
- * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has
- * been queued to redraw this window.
+ * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has been
+ * queued to redraw this window.
*
- * WIDGET_DELETED: Non-zero means that the paned window has
- * been, or is in the process of being, deleted.
+ * WIDGET_DELETED: Non-zero means that the paned window has been,
+ * or is in the process of being, deleted.
*
* RESIZE_PENDING: Non-zero means that the window might need to
* change its size (or the size of its panes)
@@ -147,59 +176,63 @@ typedef struct PanedWindow {
#define RESIZE_PENDING 0x0020
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-int Tk_PanedWindowObjCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]));
-static void PanedWindowCmdDeletedProc _ANSI_ARGS_((ClientData clientData));
-static int ConfigurePanedWindow _ANSI_ARGS_((Tcl_Interp *interp,
- PanedWindow *pwPtr, int objc, Tcl_Obj *CONST objv[]));
-static void DestroyPanedWindow _ANSI_ARGS_((PanedWindow *pwPtr));
-static void DisplayPanedWindow _ANSI_ARGS_((ClientData clientData));
-static void PanedWindowEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void ProxyWindowEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void DisplayProxyWindow _ANSI_ARGS_((ClientData clientData));
-static void PanedWindowWorldChanged _ANSI_ARGS_((ClientData instanceData));
-static int PanedWindowWidgetObjCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *, int objc, Tcl_Obj * CONST objv[]));
-static void PanedWindowLostSlaveProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin));
-static void PanedWindowReqProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin));
-static void ArrangePanes _ANSI_ARGS_((ClientData clientData));
-static void Unlink _ANSI_ARGS_((Slave *slavePtr));
-static Slave * GetPane _ANSI_ARGS_((PanedWindow *pwPtr, Tk_Window tkwin));
-static void SlaveStructureProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static int PanedWindowSashCommand _ANSI_ARGS_((PanedWindow *pwPtr,
- Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]));
-static int PanedWindowProxyCommand _ANSI_ARGS_((PanedWindow *pwPtr,
- Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]));
-static void ComputeGeometry _ANSI_ARGS_((PanedWindow *pwPtr));
-static int ConfigureSlaves _ANSI_ARGS_((PanedWindow *pwPtr,
- Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]));
-static void DestroyOptionTables _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp));
-static int SetSticky _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, Tk_Window tkwin,
- Tcl_Obj **value, char *recordPtr, int internalOffset,
- char *oldInternalPtr, int flags));
-static Tcl_Obj *GetSticky _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin,
- char *recordPtr, int internalOffset));
-static void RestoreSticky _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin, char *internalPtr,
- char *oldInternalPtr));
-static void AdjustForSticky _ANSI_ARGS_((int sticky, int cavityWidth,
- int cavityHeight, int *xPtr, int *yPtr,
- int *slaveWidthPtr, int *slaveHeightPtr));
-static void MoveSash _ANSI_ARGS_((PanedWindow *pwPtr, int sash, int diff));
-static int ObjectIsEmpty _ANSI_ARGS_((Tcl_Obj *objPtr));
-static char * ComputeSlotAddress _ANSI_ARGS_((char *recordPtr, int offset));
-static int PanedWindowIdentifyCoords _ANSI_ARGS_((PanedWindow *pwPtr,
- Tcl_Interp *interp, int x, int y));
+int Tk_PanedWindowObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+static void PanedWindowCmdDeletedProc(ClientData clientData);
+static int ConfigurePanedWindow(Tcl_Interp *interp,
+ PanedWindow *pwPtr, int objc,
+ Tcl_Obj *const objv[]);
+static void DestroyPanedWindow(PanedWindow *pwPtr);
+static void DisplayPanedWindow(ClientData clientData);
+static void PanedWindowEventProc(ClientData clientData,
+ XEvent *eventPtr);
+static void ProxyWindowEventProc(ClientData clientData,
+ XEvent *eventPtr);
+static void DisplayProxyWindow(ClientData clientData);
+static void PanedWindowWorldChanged(ClientData instanceData);
+static int PanedWindowWidgetObjCmd(ClientData clientData,
+ Tcl_Interp *, int objc, Tcl_Obj * const objv[]);
+static void PanedWindowLostSlaveProc(ClientData clientData,
+ Tk_Window tkwin);
+static void PanedWindowReqProc(ClientData clientData,
+ Tk_Window tkwin);
+static void ArrangePanes(ClientData clientData);
+static void Unlink(Slave *slavePtr);
+static Slave * GetPane(PanedWindow *pwPtr, Tk_Window tkwin);
+static void SlaveStructureProc(ClientData clientData,
+ XEvent *eventPtr);
+static int PanedWindowSashCommand(PanedWindow *pwPtr,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj * const objv[]);
+static int PanedWindowProxyCommand(PanedWindow *pwPtr,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj * const objv[]);
+static void ComputeGeometry(PanedWindow *pwPtr);
+static int ConfigureSlaves(PanedWindow *pwPtr,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj * const objv[]);
+static void DestroyOptionTables(ClientData clientData,
+ Tcl_Interp *interp);
+static int SetSticky(ClientData clientData, Tcl_Interp *interp,
+ Tk_Window tkwin, Tcl_Obj **value, char *recordPtr,
+ int internalOffset, char *oldInternalPtr,
+ int flags);
+static Tcl_Obj * GetSticky(ClientData clientData, Tk_Window tkwin,
+ char *recordPtr, int internalOffset);
+static void RestoreSticky(ClientData clientData, Tk_Window tkwin,
+ char *internalPtr, char *oldInternalPtr);
+static void AdjustForSticky(int sticky, int cavityWidth,
+ int cavityHeight, int *xPtr, int *yPtr,
+ int *slaveWidthPtr, int *slaveHeightPtr);
+static void MoveSash(PanedWindow *pwPtr, int sash, int diff);
+static int ObjectIsEmpty(Tcl_Obj *objPtr);
+static char * ComputeSlotAddress(char *recordPtr, int offset);
+static int PanedWindowIdentifyCoords(PanedWindow *pwPtr,
+ Tcl_Interp *interp, int x, int y);
/*
* Sashes are between panes only, so there is one less sash than slaves
@@ -208,7 +241,7 @@ static int PanedWindowIdentifyCoords _ANSI_ARGS_((PanedWindow *pwPtr,
#define ValidSashIndex(pwPtr, sash) \
(((sash) >= 0) && ((sash) < ((pwPtr)->numSlaves-1)))
-static Tk_GeomMgr panedWindowMgrType = {
+static const Tk_GeomMgr panedWindowMgrType = {
"panedwindow", /* name */
PanedWindowReqProc, /* requestProc */
PanedWindowLostSlaveProc, /* lostSlaveProc */
@@ -225,32 +258,32 @@ static Tk_GeomMgr panedWindowMgrType = {
* the custom "-sticky" option for slave windows.
*/
-static Tk_ObjCustomOption stickyOption = {
- "sticky", /* name */
- SetSticky, /* setProc */
- GetSticky, /* getProc */
- RestoreSticky, /* restoreProc */
- (Tk_CustomOptionFreeProc *)NULL, /* freeProc */
+static const Tk_ObjCustomOption stickyOption = {
+ "sticky", /* name */
+ SetSticky, /* setProc */
+ GetSticky, /* getProc */
+ RestoreSticky, /* restoreProc */
+ NULL, /* freeProc */
0
};
-static CONST Tk_OptionSpec optionSpecs[] = {
+static const Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_BORDER, "-background", "background", "Background",
DEF_PANEDWINDOW_BG_COLOR, -1, Tk_Offset(PanedWindow, background), 0,
(ClientData) DEF_PANEDWINDOW_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_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth"},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-background"},
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
DEF_PANEDWINDOW_BORDERWIDTH, -1, Tk_Offset(PanedWindow, borderWidth),
- 0, 0, GEOMETRY},
+ 0, 0, GEOMETRY},
{TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
DEF_PANEDWINDOW_CURSOR, -1, Tk_Offset(PanedWindow, cursor),
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-handlepad", "handlePad", "HandlePad",
DEF_PANEDWINDOW_HANDLEPAD, -1, Tk_Offset(PanedWindow, handlePad),
- 0, 0, GEOMETRY},
+ 0, 0, GEOMETRY},
{TK_OPTION_PIXELS, "-handlesize", "handleSize", "HandleSize",
DEF_PANEDWINDOW_HANDLESIZE, Tk_Offset(PanedWindow, handleSizePtr),
Tk_Offset(PanedWindow, handleSize), 0, 0, GEOMETRY},
@@ -259,9 +292,9 @@ static CONST Tk_OptionSpec optionSpecs[] = {
Tk_Offset(PanedWindow, height), TK_OPTION_NULL_OK, 0, GEOMETRY},
{TK_OPTION_BOOLEAN, "-opaqueresize", "opaqueResize", "OpaqueResize",
DEF_PANEDWINDOW_OPAQUERESIZE, -1,
- Tk_Offset(PanedWindow, resizeOpaque), 0, 0, 0},
+ Tk_Offset(PanedWindow, resizeOpaque), 0, 0, 0},
{TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
- DEF_PANEDWINDOW_ORIENT, -1, Tk_Offset(PanedWindow, orient),
+ DEF_PANEDWINDOW_ORIENT, -1, Tk_Offset(PanedWindow, orient),
0, (ClientData) orientStrings, GEOMETRY},
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
DEF_PANEDWINDOW_RELIEF, -1, Tk_Offset(PanedWindow, relief), 0, 0, 0},
@@ -270,55 +303,59 @@ static CONST Tk_OptionSpec optionSpecs[] = {
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-sashpad", "sashPad", "SashPad",
DEF_PANEDWINDOW_SASHPAD, -1, Tk_Offset(PanedWindow, sashPad),
- 0, 0, GEOMETRY},
+ 0, 0, GEOMETRY},
{TK_OPTION_RELIEF, "-sashrelief", "sashRelief", "Relief",
DEF_PANEDWINDOW_SASHRELIEF, -1, Tk_Offset(PanedWindow, sashRelief),
- 0, 0, 0},
+ 0, 0, 0},
{TK_OPTION_PIXELS, "-sashwidth", "sashWidth", "Width",
DEF_PANEDWINDOW_SASHWIDTH, Tk_Offset(PanedWindow, sashWidthPtr),
Tk_Offset(PanedWindow, sashWidth), 0, 0, GEOMETRY},
{TK_OPTION_BOOLEAN, "-showhandle", "showHandle", "ShowHandle",
DEF_PANEDWINDOW_SHOWHANDLE, -1, Tk_Offset(PanedWindow, showHandle),
- 0, 0, GEOMETRY},
+ 0, 0, GEOMETRY},
{TK_OPTION_PIXELS, "-width", "width", "Width",
DEF_PANEDWINDOW_WIDTH, Tk_Offset(PanedWindow, widthPtr),
Tk_Offset(PanedWindow, width), TK_OPTION_NULL_OK, 0, GEOMETRY},
{TK_OPTION_END}
};
-static CONST Tk_OptionSpec slaveOptionSpecs[] = {
- {TK_OPTION_WINDOW, "-after", (char *) NULL, (char *) NULL,
+static const Tk_OptionSpec slaveOptionSpecs[] = {
+ {TK_OPTION_WINDOW, "-after", NULL, NULL,
DEF_PANEDWINDOW_PANE_AFTER, -1, Tk_Offset(Slave, after),
- TK_OPTION_NULL_OK, 0, 0},
- {TK_OPTION_WINDOW, "-before", (char *) NULL, (char *) NULL,
- DEF_PANEDWINDOW_PANE_BEFORE, -1, Tk_Offset(Slave, before),
- TK_OPTION_NULL_OK, 0, 0},
- {TK_OPTION_PIXELS, "-height", (char *) NULL, (char *) NULL,
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_WINDOW, "-before", NULL, NULL,
+ DEF_PANEDWINDOW_PANE_BEFORE, -1, Tk_Offset(Slave, before),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_PIXELS, "-height", NULL, NULL,
DEF_PANEDWINDOW_PANE_HEIGHT, Tk_Offset(Slave, heightPtr),
- Tk_Offset(Slave, height), TK_OPTION_NULL_OK, 0, 0},
- {TK_OPTION_PIXELS, "-minsize", (char *) NULL, (char *) NULL,
+ Tk_Offset(Slave, height), TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_BOOLEAN, "-hide", "hide", "Hide",
+ DEF_PANEDWINDOW_PANE_HIDE, -1, Tk_Offset(Slave, hide), 0,0,GEOMETRY},
+ {TK_OPTION_PIXELS, "-minsize", NULL, NULL,
DEF_PANEDWINDOW_PANE_MINSIZE, -1, Tk_Offset(Slave, minSize), 0, 0, 0},
- {TK_OPTION_PIXELS, "-padx", (char *) NULL, (char *) NULL,
+ {TK_OPTION_PIXELS, "-padx", NULL, NULL,
DEF_PANEDWINDOW_PANE_PADX, -1, Tk_Offset(Slave, padx), 0, 0, 0},
- {TK_OPTION_PIXELS, "-pady", (char *) NULL, (char *) NULL,
+ {TK_OPTION_PIXELS, "-pady", NULL, NULL,
DEF_PANEDWINDOW_PANE_PADY, -1, Tk_Offset(Slave, pady), 0, 0, 0},
- {TK_OPTION_CUSTOM, "-sticky", (char *) NULL, (char *) NULL,
+ {TK_OPTION_CUSTOM, "-sticky", NULL, NULL,
DEF_PANEDWINDOW_PANE_STICKY, -1, Tk_Offset(Slave, sticky), 0,
- (ClientData) &stickyOption, 0},
- {TK_OPTION_PIXELS, "-width", (char *) NULL, (char *) NULL,
+ (ClientData) &stickyOption, 0},
+ {TK_OPTION_STRING_TABLE, "-stretch", "stretch", "Stretch",
+ DEF_PANEDWINDOW_PANE_STRETCH, -1, Tk_Offset(Slave, stretch), 0,
+ (ClientData) stretchStrings, 0},
+ {TK_OPTION_PIXELS, "-width", NULL, NULL,
DEF_PANEDWINDOW_PANE_WIDTH, Tk_Offset(Slave, widthPtr),
- Tk_Offset(Slave, width), TK_OPTION_NULL_OK, 0, 0},
+ Tk_Offset(Slave, width), TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_END}
};
-
/*
*--------------------------------------------------------------
*
* Tk_PanedWindowObjCmd --
*
- * This procedure is invoked to process the "panedwindow" Tcl
- * command. It creates a new "panedwindow" widget.
+ * This function is invoked to process the "panedwindow" Tcl command. It
+ * creates a new "panedwindow" widget.
*
* Results:
* A standard Tcl result.
@@ -330,11 +367,11 @@ static CONST Tk_OptionSpec slaveOptionSpecs[] = {
*/
int
-Tk_PanedWindowObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* NULL. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj * CONST objv[]; /* Argument objects. */
+Tk_PanedWindowObjCmd(
+ ClientData clientData, /* NULL. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj * const objv[]) /* Argument objects. */
{
PanedWindow *pwPtr;
Tk_Window tkwin, parent;
@@ -346,27 +383,35 @@ Tk_PanedWindowObjCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
- tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
+ tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
Tcl_GetStringFromObj(objv[1], NULL), NULL);
if (tkwin == NULL) {
return TCL_ERROR;
}
pwOpts = (OptionTables *)
- Tcl_GetAssocData(interp, "PanedWindowOptionTables", NULL);
+ Tcl_GetAssocData(interp, "PanedWindowOptionTables", NULL);
if (pwOpts == NULL) {
/*
- * The first time this procedure is invoked, the option tables will
- * be NULL. We then create the option tables from the templates
- * and store a pointer to the tables as the command's clinical so
- * we'll have easy access to it in the future.
+ * The first time this function is invoked, the option tables will be
+ * NULL. We then create the option tables from the templates and store
+ * a pointer to the tables as the command's clinical so we'll have
+ * easy access to it in the future.
*/
+
pwOpts = (OptionTables *) ckalloc(sizeof(OptionTables));
- /* Set up an exit handler to free the optionTables struct */
+
+ /*
+ * Set up an exit handler to free the optionTables struct.
+ */
+
Tcl_SetAssocData(interp, "PanedWindowOptionTables",
DestroyOptionTables, (ClientData) pwOpts);
- /* Create the paned window option tables. */
+ /*
+ * Create the paned window option tables.
+ */
+
pwOpts->pwOptions = Tk_CreateOptionTable(interp, optionSpecs);
pwOpts->slaveOpts = Tk_CreateOptionTable(interp, slaveOptionSpecs);
}
@@ -379,18 +424,18 @@ Tk_PanedWindowObjCmd(clientData, interp, objc, objv)
pwPtr = (PanedWindow *) ckalloc(sizeof(PanedWindow));
memset((void *)pwPtr, 0, (sizeof(PanedWindow)));
- pwPtr->tkwin = tkwin;
- pwPtr->display = Tk_Display(tkwin);
- pwPtr->interp = interp;
- pwPtr->widgetCmd = Tcl_CreateObjCommand(interp,
+ pwPtr->tkwin = tkwin;
+ pwPtr->display = Tk_Display(tkwin);
+ pwPtr->interp = interp;
+ pwPtr->widgetCmd = Tcl_CreateObjCommand(interp,
Tk_PathName(pwPtr->tkwin), PanedWindowWidgetObjCmd,
(ClientData) pwPtr, PanedWindowCmdDeletedProc);
- pwPtr->optionTable = pwOpts->pwOptions;
- pwPtr->slaveOpts = pwOpts->slaveOpts;
- pwPtr->relief = TK_RELIEF_RAISED;
- pwPtr->gc = None;
- pwPtr->cursor = None;
- pwPtr->sashCursor = None;
+ pwPtr->optionTable = pwOpts->pwOptions;
+ pwPtr->slaveOpts = pwOpts->slaveOpts;
+ pwPtr->relief = TK_RELIEF_RAISED;
+ pwPtr->gc = None;
+ pwPtr->cursor = None;
+ pwPtr->sashCursor = None;
/*
* Keep a hold of the associated tkwin until we destroy the widget,
@@ -409,10 +454,11 @@ Tk_PanedWindowObjCmd(clientData, interp, objc, objv)
PanedWindowEventProc, (ClientData) pwPtr);
/*
- * Find the toplevel ancestor of the panedwindow, and make a proxy
- * win as a child of that window; this way the proxy can always float
- * above slaves in the panedwindow.
+ * Find the toplevel ancestor of the panedwindow, and make a proxy win as
+ * a child of that window; this way the proxy can always float above
+ * slaves in the panedwindow.
*/
+
parent = Tk_Parent(pwPtr->tkwin);
while (!(Tk_IsTopLevel(parent))) {
parent = Tk_Parent(parent);
@@ -422,15 +468,16 @@ Tk_PanedWindowObjCmd(clientData, interp, objc, objv)
}
}
- pwPtr->proxywin = Tk_CreateAnonymousWindow(interp, parent, (char *) NULL);
+ pwPtr->proxywin = Tk_CreateAnonymousWindow(interp, parent, NULL);
+
/*
- * The proxy window has to be able to share GCs with the main
- * panedwindow despite being children of windows with potentially
- * different characteristics, and it looks better that way too.
- * [Bug 702230]
- * Also Set the X window save under attribute to avoid expose events as
- * the proxy sash is dragged across the panes. [Bug 1036963]
+ * The proxy window has to be able to share GCs with the main panedwindow
+ * despite being children of windows with potentially different
+ * characteristics, and it looks better that way too. [Bug 702230] Also
+ * set the X window save under attribute to avoid expose events as the
+ * proxy sash is dragged across the panes. [Bug 1036963]
*/
+
Tk_SetWindowVisual(pwPtr->proxywin,
Tk_Visual(tkwin), Tk_Depth(tkwin), Tk_Colormap(tkwin));
Tk_CreateEventHandler(pwPtr->proxywin, ExposureMask, ProxyWindowEventProc,
@@ -453,9 +500,9 @@ Tk_PanedWindowObjCmd(clientData, interp, objc, objv)
*
* PanedWindowWidgetObjCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to a widget managed by this module.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the Tcl command that corresponds
+ * to a widget managed by this module. See the user documentation for
+ * details on what it does.
*
* Results:
* A standard Tcl result.
@@ -467,26 +514,27 @@ Tk_PanedWindowObjCmd(clientData, interp, objc, objv)
*/
static int
-PanedWindowWidgetObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Information about square widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj * CONST objv[]; /* Argument objects. */
+PanedWindowWidgetObjCmd(
+ ClientData clientData, /* Information about square widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj * const objv[]) /* Argument objects. */
{
PanedWindow *pwPtr = (PanedWindow *) clientData;
int result = TCL_OK;
- static CONST char *optionStrings[] = {"add", "cget", "configure", "forget",
- "identify", "panecget",
- "paneconfigure", "panes",
- "proxy", "sash", (char *) NULL};
- enum options { PW_ADD, PW_CGET, PW_CONFIGURE, PW_FORGET, PW_IDENTIFY,
- PW_PANECGET, PW_PANECONFIGURE, PW_PANES, PW_PROXY,
- PW_SASH };
+ static const char *optionStrings[] = {
+ "add", "cget", "configure", "forget", "identify", "panecget",
+ "paneconfigure", "panes", "proxy", "sash", NULL
+ };
+ enum options {
+ PW_ADD, PW_CGET, PW_CONFIGURE, PW_FORGET, PW_IDENTIFY, PW_PANECGET,
+ PW_PANECONFIGURE, PW_PANES, PW_PROXY, PW_SASH
+ };
Tcl_Obj *resultObj;
int index, count, i, x, y;
Tk_Window tkwin;
Slave *slavePtr;
-
+
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg...?");
return TCL_ERROR;
@@ -498,196 +546,177 @@ PanedWindowWidgetObjCmd(clientData, interp, objc, objv)
}
Tcl_Preserve((ClientData) pwPtr);
-
+
switch ((enum options) index) {
- case PW_ADD: {
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "widget ?widget ...?");
- result = TCL_ERROR;
- break;
- }
-
- result = ConfigureSlaves(pwPtr, interp, objc, objv);
+ case PW_ADD:
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "widget ?widget ...?");
+ result = TCL_ERROR;
break;
}
-
- case PW_CGET: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "option");
- result = TCL_ERROR;
- break;
- }
- resultObj = Tk_GetOptionValue(interp, (char *) pwPtr,
- pwPtr->optionTable, objv[2], pwPtr->tkwin);
+ result = ConfigureSlaves(pwPtr, interp, objc, objv);
+ break;
+
+ case PW_CGET:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option");
+ result = TCL_ERROR;
+ break;
+ }
+ resultObj = Tk_GetOptionValue(interp, (char *) pwPtr,
+ pwPtr->optionTable, objv[2], pwPtr->tkwin);
+ if (resultObj == NULL) {
+ result = TCL_ERROR;
+ } else {
+ Tcl_SetObjResult(interp, resultObj);
+ }
+ break;
+
+ case PW_CONFIGURE:
+ resultObj = NULL;
+ if (objc <= 3) {
+ resultObj = Tk_GetOptionInfo(interp, (char *) pwPtr,
+ pwPtr->optionTable,
+ (objc == 3) ? objv[2] : NULL, pwPtr->tkwin);
if (resultObj == NULL) {
result = TCL_ERROR;
} else {
Tcl_SetObjResult(interp, resultObj);
}
+ } else {
+ result = ConfigurePanedWindow(interp, pwPtr, objc - 2, objv + 2);
+ }
+ break;
+
+ case PW_FORGET: {
+ int i;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "widget ?widget ...?");
+ result = TCL_ERROR;
break;
}
-
- case PW_CONFIGURE: {
- resultObj = NULL;
- if (objc <= 3) {
- resultObj = Tk_GetOptionInfo(interp, (char *) pwPtr,
- pwPtr->optionTable,
- (objc == 3) ? objv[2] : (Tcl_Obj *) NULL,
- pwPtr->tkwin);
- if (resultObj == NULL) {
- result = TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, resultObj);
- }
- } else {
- result = ConfigurePanedWindow(interp, pwPtr, objc - 2,
- objv + 2);
+
+ /*
+ * Clean up each window named in the arg list.
+ */
+ for (count = 0, i = 2; i < objc; i++) {
+ Tk_Window slave = Tk_NameToWindow(interp, Tcl_GetString(objv[i]),
+ pwPtr->tkwin);
+ if (slave == NULL) {
+ continue;
+ }
+ slavePtr = GetPane(pwPtr, slave);
+ if ((slavePtr != NULL) && (slavePtr->masterPtr != NULL)) {
+ count++;
+ Tk_ManageGeometry(slave, NULL, (ClientData)NULL);
+ Tk_UnmaintainGeometry(slavePtr->tkwin, pwPtr->tkwin);
+ Tk_DeleteEventHandler(slavePtr->tkwin, StructureNotifyMask,
+ SlaveStructureProc, (ClientData) slavePtr);
+ Tk_UnmapWindow(slavePtr->tkwin);
+ Unlink(slavePtr);
+ }
+ if (count != 0) {
+ ComputeGeometry(pwPtr);
}
+ }
+ break;
+ }
+
+ case PW_IDENTIFY:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ result = TCL_ERROR;
break;
}
-
- case PW_FORGET: {
- Tk_Window slave;
- int i;
-
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "widget ?widget ...?");
- result = TCL_ERROR;
- break;
- }
- /*
- * Clean up each window named in the arg list.
- */
- for (count = 0, i = 2; i < objc; i++) {
- slave = Tk_NameToWindow(interp, Tcl_GetString(objv[i]),
- pwPtr->tkwin);
- if (slave == NULL) {
- continue;
- }
- slavePtr = GetPane(pwPtr, slave);
- if ((slavePtr != NULL) && (slavePtr->masterPtr != NULL)) {
- count++;
- Tk_ManageGeometry(slave, (Tk_GeomMgr *) NULL,
- (ClientData) NULL);
- Tk_UnmaintainGeometry(slavePtr->tkwin, pwPtr->tkwin);
- Tk_DeleteEventHandler(slavePtr->tkwin, StructureNotifyMask,
- SlaveStructureProc, (ClientData) slavePtr);
- Tk_UnmapWindow(slavePtr->tkwin);
- Unlink(slavePtr);
- }
- if (count != 0) {
- ComputeGeometry(pwPtr);
- }
- }
+ if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
+ result = TCL_ERROR;
break;
}
+ result = PanedWindowIdentifyCoords(pwPtr, interp, x, y);
+ break;
- case PW_IDENTIFY: {
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "x y");
- result = TCL_ERROR;
- break;
+ case PW_PANECGET:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pane option");
+ result = TCL_ERROR;
+ break;
+ }
+ tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), pwPtr->tkwin);
+ if (tkwin == NULL) {
+ result = TCL_ERROR;
+ break;
+ }
+ resultObj = NULL;
+ for (i = 0; i < pwPtr->numSlaves; i++) {
+ if (pwPtr->slaves[i]->tkwin == tkwin) {
+ resultObj = Tk_GetOptionValue(interp,
+ (char *) pwPtr->slaves[i], pwPtr->slaveOpts,
+ objv[3], tkwin);
}
+ }
+ if (i == pwPtr->numSlaves) {
+ Tcl_SetResult(interp, "not managed by this window", TCL_STATIC);
+ }
+ if (resultObj == NULL) {
+ result = TCL_ERROR;
+ } else {
+ Tcl_SetObjResult(interp, resultObj);
+ }
+ break;
- if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
- || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
- result = TCL_ERROR;
- break;
- }
-
- result = PanedWindowIdentifyCoords(pwPtr, interp, x, y);
+ case PW_PANECONFIGURE:
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "pane ?option? ?value option value ...?");
+ result = TCL_ERROR;
break;
}
-
- case PW_PANECGET: {
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "pane option");
- result = TCL_ERROR;
- break;
- }
+ resultObj = NULL;
+ if (objc <= 4) {
tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
pwPtr->tkwin);
- if (tkwin == NULL) {
- result = TCL_ERROR;
- break;
- }
- resultObj = NULL;
for (i = 0; i < pwPtr->numSlaves; i++) {
if (pwPtr->slaves[i]->tkwin == tkwin) {
- resultObj = Tk_GetOptionValue(interp,
+ resultObj = Tk_GetOptionInfo(interp,
(char *) pwPtr->slaves[i], pwPtr->slaveOpts,
- objv[3], tkwin);
- }
- }
- if (i == pwPtr->numSlaves) {
- Tcl_SetResult(interp, "not managed by this window",
- TCL_STATIC);
- }
- if (resultObj == NULL) {
- result = TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, resultObj);
- }
- break;
- }
-
- case PW_PANECONFIGURE: {
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "pane ?option? ?value option value ...?");
- result = TCL_ERROR;
- break;
- }
- resultObj = NULL;
- if (objc <= 4) {
- tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
- pwPtr->tkwin);
- for (i = 0; i < pwPtr->numSlaves; i++) {
- if (pwPtr->slaves[i]->tkwin == tkwin) {
- resultObj = Tk_GetOptionInfo(interp,
- (char *) pwPtr->slaves[i],
- pwPtr->slaveOpts,
- (objc == 4) ? objv[3] : (Tcl_Obj *) NULL,
- pwPtr->tkwin);
- if (resultObj == NULL) {
- result = TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, resultObj);
- }
- break;
+ (objc == 4) ? objv[3] : NULL,
+ pwPtr->tkwin);
+ if (resultObj == NULL) {
+ result = TCL_ERROR;
+ } else {
+ Tcl_SetObjResult(interp, resultObj);
}
+ break;
}
- } else {
- result = ConfigureSlaves(pwPtr, interp, objc, objv);
}
- break;
+ } else {
+ result = ConfigureSlaves(pwPtr, interp, objc, objv);
}
-
- case PW_PANES: {
- resultObj = Tcl_NewObj();
+ break;
- Tcl_IncrRefCount(resultObj);
+ case PW_PANES:
+ resultObj = Tcl_NewObj();
- for (i = 0; i < pwPtr->numSlaves; i++) {
- Tcl_ListObjAppendElement(interp, resultObj,
- Tcl_NewStringObj(Tk_PathName(pwPtr->slaves[i]->tkwin),
- -1));
- }
- Tcl_SetObjResult(interp, resultObj);
- Tcl_DecrRefCount(resultObj);
- break;
- }
+ Tcl_IncrRefCount(resultObj);
- case PW_PROXY: {
- result = PanedWindowProxyCommand(pwPtr, interp, objc, objv);
- break;
+ for (i = 0; i < pwPtr->numSlaves; i++) {
+ Tcl_ListObjAppendElement(interp, resultObj,
+ Tcl_NewStringObj(Tk_PathName(pwPtr->slaves[i]->tkwin),-1));
}
+ Tcl_SetObjResult(interp, resultObj);
+ Tcl_DecrRefCount(resultObj);
+ break;
- case PW_SASH: {
- result = PanedWindowSashCommand(pwPtr, interp, objc, objv);
- break;
- }
+ case PW_PROXY:
+ result = PanedWindowProxyCommand(pwPtr, interp, objc, objv);
+ break;
+
+ case PW_SASH:
+ result = PanedWindowSashCommand(pwPtr, interp, objc, objv);
+ break;
}
Tcl_Release((ClientData) pwPtr);
return result;
@@ -698,39 +727,38 @@ PanedWindowWidgetObjCmd(clientData, interp, objc, objv)
*
* ConfigureSlaves --
*
- * Add or alter the configuration options of a slave in a paned
- * window.
+ * Add or alter the configuration options of a slave in a paned window.
*
* Results:
* Standard Tcl result.
*
* Side effects:
- * Depends on options; may add a slave to the paned window, may
- * alter the geometry management options of a slave.
+ * Depends on options; may add a slave to the paned window, may alter the
+ * geometry management options of a slave.
*
*----------------------------------------------------------------------
*/
static int
-ConfigureSlaves(pwPtr, interp, objc, objv)
- PanedWindow *pwPtr; /* Information about paned window. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj * CONST objv[]; /* Argument objects. */
+ConfigureSlaves(
+ PanedWindow *pwPtr, /* Information about paned window. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
int i, firstOptionArg, j, found, doubleBw, index, numNewSlaves, haveLoc;
int insertIndex;
Tk_Window tkwin = NULL, ancestor, parent;
- Slave *slavePtr, **inserts, **new;
+ Slave *slavePtr, **inserts, **newSlaves;
Slave options;
char *arg;
-
+
/*
- * Find the non-window name arguments; these are the configure options
- * for the slaves. Also validate that the window names given are
- * legitimate (ie, they are real windows, they are not the panedwindow
- * itself, etc.).
+ * Find the non-window name arguments; these are the configure options for
+ * the slaves. Also validate that the window names given are legitimate
+ * (ie, they are real windows, they are not the panedwindow itself, etc.).
*/
+
for (i = 2; i < objc; i++) {
arg = Tcl_GetString(objv[i]);
if (arg[0] == '-') {
@@ -742,28 +770,32 @@ ConfigureSlaves(pwPtr, interp, objc, objv)
* Just a plain old bad window; Tk_NameToWindow filled in an
* error message for us.
*/
+
return TCL_ERROR;
} else if (tkwin == pwPtr->tkwin) {
/*
* A panedwindow cannot manage itself.
*/
+
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "can't add ", arg, " to itself",
- (char *) NULL);
+ NULL);
return TCL_ERROR;
} else if (Tk_IsTopLevel(tkwin)) {
/*
* A panedwindow cannot manage a toplevel.
*/
+
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "can't add toplevel ", arg, " to ",
- Tk_PathName(pwPtr->tkwin), (char *) NULL);
+ Tk_PathName(pwPtr->tkwin), NULL);
return TCL_ERROR;
} else {
/*
* Make sure the panedwindow is the parent of the slave,
* or a descendant of the slave's parent.
*/
+
parent = Tk_Parent(tkwin);
for (ancestor = pwPtr->tkwin;;ancestor = Tk_Parent(ancestor)) {
if (ancestor == parent) {
@@ -771,9 +803,8 @@ ConfigureSlaves(pwPtr, interp, objc, objv)
}
if (Tk_IsTopLevel(ancestor)) {
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "can't add ", arg,
- " to ", Tk_PathName(pwPtr->tkwin),
- (char *) NULL);
+ Tcl_AppendResult(interp, "can't add ", arg, " to ",
+ Tk_PathName(pwPtr->tkwin), NULL);
return TCL_ERROR;
}
}
@@ -784,10 +815,11 @@ ConfigureSlaves(pwPtr, interp, objc, objv)
/*
* Pre-parse the configuration options, to get the before/after specifiers
- * into an easy-to-find location (a local variable). Also, check the
+ * into an easy-to-find location (a local variable). Also, check the
* return from Tk_SetOptions once, here, so we can save a little bit of
* extra testing in the for loop below.
*/
+
memset((void *)&options, 0, sizeof(Slave));
if (Tk_SetOptions(interp, (char *) &options, pwPtr->slaveOpts,
objc - firstOptionArg, objv + firstOptionArg,
@@ -797,9 +829,10 @@ ConfigureSlaves(pwPtr, interp, objc, objv)
/*
* If either -after or -before was given, find the numerical index that
- * corresponds to the given window. If both -after and -before are
- * given, the option precedence is: -after, then -before.
+ * corresponds to the given window. If both -after and -before are given,
+ * the option precedence is: -after, then -before.
*/
+
index = -1;
haveLoc = 0;
if (options.after != None) {
@@ -823,14 +856,14 @@ ConfigureSlaves(pwPtr, interp, objc, objv)
}
/*
- * If a window was given for -after/-before, but it's not a window
- * managed by the panedwindow, throw an error
+ * If a window was given for -after/-before, but it's not a window managed
+ * by the panedwindow, throw an error
*/
+
if (haveLoc && index == -1) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "window \"", Tk_PathName(tkwin),
- "\" is not managed by ", Tk_PathName(pwPtr->tkwin),
- (char *) NULL);
+ "\" is not managed by ", Tk_PathName(pwPtr->tkwin), NULL);
Tk_FreeConfigOptions((char *) &options, pwPtr->slaveOpts,
pwPtr->tkwin);
return TCL_ERROR;
@@ -838,23 +871,26 @@ ConfigureSlaves(pwPtr, interp, objc, objv)
/*
* Allocate an array to hold, in order, the pointers to the slave
- * structures corresponding to the windows specified. Some of those
+ * structures corresponding to the windows specified. Some of those
* structures may already have existed, some may be new.
*/
+
inserts = (Slave **)ckalloc(sizeof(Slave *) * (firstOptionArg - 2));
insertIndex = 0;
-
+
/*
* Populate the inserts array, creating new slave structures as necessary,
* applying the options to each structure as we go, and, if necessary,
- * marking the spot in the original slaves array as empty (for pre-existing
- * slave structures).
+ * marking the spot in the original slaves array as empty (for
+ * pre-existing slave structures).
*/
+
for (i = 0, numNewSlaves = 0; i < firstOptionArg - 2; i++) {
/*
* We don't check that tkwin is NULL here, because the pre-pass above
* guarantees that the input at this stage is good.
*/
+
tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[i + 2]),
pwPtr->tkwin);
@@ -888,8 +924,8 @@ ConfigureSlaves(pwPtr, interp, objc, objv)
/*
* Make sure this slave wasn't already put into the inserts array,
- * ie, when the user specifies the same window multiple times in
- * a single add commaned.
+ * i.e., when the user specifies the same window multiple times in a
+ * single add commaned.
*/
for (j = 0; j < insertIndex; j++) {
if (inserts[j]->tkwin == tkwin) {
@@ -900,12 +936,12 @@ ConfigureSlaves(pwPtr, interp, objc, objv)
if (found) {
continue;
}
-
+
/*
- * Create a new slave structure and initialize it. All slaves
- * start out with their "natural" dimensions.
+ * Create a new slave structure and initialize it. All slaves start
+ * out with their "natural" dimensions.
*/
-
+
slavePtr = (Slave *) ckalloc(sizeof(Slave));
memset(slavePtr, 0, sizeof(Slave));
Tk_InitOptions(interp, (char *)slavePtr, pwPtr->slaveOpts,
@@ -913,8 +949,8 @@ ConfigureSlaves(pwPtr, interp, objc, objv)
Tk_SetOptions(interp, (char *)slavePtr, pwPtr->slaveOpts,
objc - firstOptionArg, objv + firstOptionArg,
pwPtr->tkwin, NULL, NULL);
- slavePtr->tkwin = tkwin;
- slavePtr->masterPtr = pwPtr;
+ slavePtr->tkwin = tkwin;
+ slavePtr->masterPtr = pwPtr;
doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width;
if (slavePtr->width > 0) {
slavePtr->paneWidth = slavePtr->width;
@@ -943,43 +979,44 @@ ConfigureSlaves(pwPtr, interp, objc, objv)
}
/*
- * Allocate the new slaves array, then copy the slaves into it, in
- * order.
+ * Allocate the new slaves array, then copy the slaves into it, in order.
*/
+
i = sizeof(Slave *) * (pwPtr->numSlaves+numNewSlaves);
- new = (Slave **)ckalloc((unsigned) i);
- memset(new, 0, (size_t) i);
+ newSlaves = (Slave **)ckalloc((unsigned) i);
+ memset(newSlaves, 0, (size_t) i);
if (index == -1) {
/*
* If none of the existing slaves have to be moved, just copy the old
* and append the new.
*/
- memcpy((void *)&(new[0]), pwPtr->slaves,
+ memcpy((void *)&(newSlaves[0]), pwPtr->slaves,
sizeof(Slave *) * pwPtr->numSlaves);
- memcpy((void *)&(new[pwPtr->numSlaves]), inserts,
+ memcpy((void *)&(newSlaves[pwPtr->numSlaves]), inserts,
sizeof(Slave *) * numNewSlaves);
} else {
/*
* If some of the existing slaves were moved, the old slaves array
* will be partially populated, with some valid and some invalid
- * entries. Walk through it, copying valid entries to the new slaves
+ * entries. Walk through it, copying valid entries to the new slaves
* array as we go; when we get to the insert location for the new
* slaves, copy the inserts array over, then finish off the old slaves
* array.
*/
+
for (i = 0, j = 0; i < index; i++) {
if (pwPtr->slaves[i] != NULL) {
- new[j] = pwPtr->slaves[i];
+ newSlaves[j] = pwPtr->slaves[i];
j++;
}
}
-
- memcpy((void *)&(new[j]), inserts, sizeof(Slave *) * (insertIndex));
+
+ memcpy((void *)&(newSlaves[j]), inserts, sizeof(Slave *)*insertIndex);
j += firstOptionArg - 2;
-
+
for (i = index; i < pwPtr->numSlaves; i++) {
if (pwPtr->slaves[i] != NULL) {
- new[j] = pwPtr->slaves[i];
+ newSlaves[j] = pwPtr->slaves[i];
j++;
}
}
@@ -988,17 +1025,19 @@ ConfigureSlaves(pwPtr, interp, objc, objv)
/*
* Make the new slaves array the paned window's slave array, and clean up.
*/
+
ckfree((void *)pwPtr->slaves);
ckfree((void *)inserts);
- pwPtr->slaves = new;
+ pwPtr->slaves = newSlaves;
/*
* Set the paned window's slave count to the new value.
*/
+
pwPtr->numSlaves += numNewSlaves;
Tk_FreeConfigOptions((char *) &options, pwPtr->slaveOpts, pwPtr->tkwin);
-
+
ComputeGeometry(pwPtr);
return TCL_OK;
}
@@ -1008,7 +1047,7 @@ ConfigureSlaves(pwPtr, interp, objc, objv)
*
* PanedWindowSashCommand --
*
- * Implementation of the panedwindow sash subcommand. See the user
+ * Implementation of the panedwindow sash subcommand. See the user
* documentation for details on what it does.
*
* Results:
@@ -1021,133 +1060,132 @@ ConfigureSlaves(pwPtr, interp, objc, objv)
*/
static int
-PanedWindowSashCommand(pwPtr, interp, objc, objv)
- PanedWindow *pwPtr; /* Pointer to paned window information. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj * CONST objv[]; /* Argument objects. */
+PanedWindowSashCommand(
+ PanedWindow *pwPtr, /* Pointer to paned window information. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- static CONST char *sashOptionStrings[] = { "coord", "dragto", "mark",
- "place", (char *) NULL };
- enum sashOptions { SASH_COORD, SASH_DRAGTO, SASH_MARK, SASH_PLACE };
+ static const char *sashOptionStrings[] = {
+ "coord", "dragto", "mark", "place", NULL
+ };
+ enum sashOptions {
+ SASH_COORD, SASH_DRAGTO, SASH_MARK, SASH_PLACE
+ };
int index, sash, x, y, diff;
Tcl_Obj *coords[2];
Slave *slavePtr;
-
+
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[2], sashOptionStrings,
- "option", 0, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObj(interp, objv[2], sashOptionStrings, "option", 0,
+ &index) != TCL_OK) {
return TCL_ERROR;
}
Tcl_ResetResult(interp);
switch ((enum sashOptions) index) {
- case SASH_COORD: {
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 3, objv, "index");
- return TCL_ERROR;
- }
+ case SASH_COORD:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index");
+ return TCL_ERROR;
+ }
- if (Tcl_GetIntFromObj(interp, objv[3], &sash) != TCL_OK) {
- return TCL_ERROR;
- }
+ if (Tcl_GetIntFromObj(interp, objv[3], &sash) != TCL_OK) {
+ return TCL_ERROR;
+ }
- if (!ValidSashIndex(pwPtr, sash)) {
- Tcl_ResetResult(interp);
- Tcl_SetResult(interp, "invalid sash index", TCL_STATIC);
- return TCL_ERROR;
- }
- slavePtr = pwPtr->slaves[sash];
-
- coords[0] = Tcl_NewIntObj(slavePtr->sashx);
- coords[1] = Tcl_NewIntObj(slavePtr->sashy);
- Tcl_SetListObj(Tcl_GetObjResult(interp), 2, coords);
- break;
+ if (!ValidSashIndex(pwPtr, sash)) {
+ Tcl_ResetResult(interp);
+ Tcl_SetResult(interp, "invalid sash index", TCL_STATIC);
+ return TCL_ERROR;
}
+ slavePtr = pwPtr->slaves[sash];
- case SASH_MARK: {
- if (objc != 6 && objc != 4) {
- Tcl_WrongNumArgs(interp, 3, objv, "index ?x y?");
- return TCL_ERROR;
- }
-
- if (Tcl_GetIntFromObj(interp, objv[3], &sash) != TCL_OK) {
+ coords[0] = Tcl_NewIntObj(slavePtr->sashx);
+ coords[1] = Tcl_NewIntObj(slavePtr->sashy);
+ Tcl_SetListObj(Tcl_GetObjResult(interp), 2, coords);
+ break;
+
+ case SASH_MARK:
+ if (objc != 6 && objc != 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index ?x y?");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetIntFromObj(interp, objv[3], &sash) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (!ValidSashIndex(pwPtr, sash)) {
+ Tcl_ResetResult(interp);
+ Tcl_SetResult(interp, "invalid sash index", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+ if (objc == 6) {
+ if (Tcl_GetIntFromObj(interp, objv[4], &x) != TCL_OK) {
return TCL_ERROR;
}
- if (!ValidSashIndex(pwPtr, sash)) {
- Tcl_ResetResult(interp);
- Tcl_SetResult(interp, "invalid sash index", TCL_STATIC);
+ if (Tcl_GetIntFromObj(interp, objv[5], &y) != TCL_OK) {
return TCL_ERROR;
}
- if (objc == 6) {
- if (Tcl_GetIntFromObj(interp, objv[4], &x) != TCL_OK) {
- return TCL_ERROR;
- }
-
- if (Tcl_GetIntFromObj(interp, objv[5], &y) != TCL_OK) {
- return TCL_ERROR;
- }
+ pwPtr->slaves[sash]->markx = x;
+ pwPtr->slaves[sash]->marky = y;
+ } else {
+ coords[0] = Tcl_NewIntObj(pwPtr->slaves[sash]->markx);
+ coords[1] = Tcl_NewIntObj(pwPtr->slaves[sash]->marky);
+ Tcl_SetListObj(Tcl_GetObjResult(interp), 2, coords);
+ }
+ break;
- pwPtr->slaves[sash]->markx = x;
- pwPtr->slaves[sash]->marky = y;
- } else {
- coords[0] = Tcl_NewIntObj(pwPtr->slaves[sash]->markx);
- coords[1] = Tcl_NewIntObj(pwPtr->slaves[sash]->marky);
- Tcl_SetListObj(Tcl_GetObjResult(interp), 2, coords);
- }
+ case SASH_DRAGTO:
+ case SASH_PLACE:
+ if (objc != 6) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index x y");
+ return TCL_ERROR;
+ }
- break;
+ if (Tcl_GetIntFromObj(interp, objv[3], &sash) != TCL_OK) {
+ return TCL_ERROR;
}
-
- case SASH_DRAGTO:
- case SASH_PLACE: {
- if (objc != 6) {
- Tcl_WrongNumArgs(interp, 3, objv, "index x y");
- return TCL_ERROR;
- }
-
- if (Tcl_GetIntFromObj(interp, objv[3], &sash) != TCL_OK) {
- return TCL_ERROR;
- }
- if (!ValidSashIndex(pwPtr, sash)) {
- Tcl_ResetResult(interp);
- Tcl_SetResult(interp, "invalid sash index", TCL_STATIC);
- return TCL_ERROR;
- }
+ if (!ValidSashIndex(pwPtr, sash)) {
+ Tcl_ResetResult(interp);
+ Tcl_SetResult(interp, "invalid sash index", TCL_STATIC);
+ return TCL_ERROR;
+ }
- if (Tcl_GetIntFromObj(interp, objv[4], &x) != TCL_OK) {
- return TCL_ERROR;
- }
+ if (Tcl_GetIntFromObj(interp, objv[4], &x) != TCL_OK) {
+ return TCL_ERROR;
+ }
- if (Tcl_GetIntFromObj(interp, objv[5], &y) != TCL_OK) {
- return TCL_ERROR;
+ if (Tcl_GetIntFromObj(interp, objv[5], &y) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ slavePtr = pwPtr->slaves[sash];
+ if (pwPtr->orient == ORIENT_HORIZONTAL) {
+ if (index == SASH_PLACE) {
+ diff = x - pwPtr->slaves[sash]->sashx;
+ } else {
+ diff = x - pwPtr->slaves[sash]->markx;
}
-
- slavePtr = pwPtr->slaves[sash];
- if (pwPtr->orient == ORIENT_HORIZONTAL) {
- if (index == SASH_PLACE) {
- diff = x - pwPtr->slaves[sash]->sashx;
- } else {
- diff = x - pwPtr->slaves[sash]->markx;
- }
+ } else {
+ if (index == SASH_PLACE) {
+ diff = y - pwPtr->slaves[sash]->sashy;
} else {
- if (index == SASH_PLACE) {
- diff = y - pwPtr->slaves[sash]->sashy;
- } else {
- diff = y - pwPtr->slaves[sash]->marky;
- }
+ diff = y - pwPtr->slaves[sash]->marky;
}
-
- MoveSash(pwPtr, sash, diff);
- ComputeGeometry(pwPtr);
}
+
+ MoveSash(pwPtr, sash, diff);
+ ComputeGeometry(pwPtr);
}
return TCL_OK;
}
@@ -1157,32 +1195,31 @@ PanedWindowSashCommand(pwPtr, interp, objc, objv)
*
* ConfigurePanedWindow --
*
- * This procedure is called to process an argv/argc list in
- * conjunction with the Tk option database to configure (or
- * reconfigure) a paned window widget.
+ * This function is called to process an argv/argc list in conjunction
+ * with the Tk option database to configure (or reconfigure) a paned
+ * window widget.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message.
+ * 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 colors, border width,
- * etc. get set for pwPtr; old resources get freed,
- * if there were any.
+ * Configuration information, such as colors, border width, etc. get set
+ * for pwPtr; old resources get freed, if there were any.
*
*----------------------------------------------------------------------
*/
static int
-ConfigurePanedWindow(interp, pwPtr, objc, objv)
- Tcl_Interp *interp; /* Used for error reporting. */
- PanedWindow *pwPtr; /* Information about widget. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+ConfigurePanedWindow(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ PanedWindow *pwPtr, /* Information about widget. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument values. */
{
Tk_SavedOptions savedOptions;
int typemask = 0;
-
+
if (Tk_SetOptions(interp, (char *) pwPtr, pwPtr->optionTable, objc, objv,
pwPtr->tkwin, &savedOptions, &typemask) != TCL_OK) {
Tk_RestoreSavedOptions(&savedOptions);
@@ -1194,14 +1231,14 @@ ConfigurePanedWindow(interp, pwPtr, objc, objv)
PanedWindowWorldChanged((ClientData) pwPtr);
/*
- * If an option that affects geometry has changed, make a relayout
+ * If an option that affects geometry has changed, make a re-layout
* request.
*/
if (typemask & GEOMETRY) {
ComputeGeometry(pwPtr);
}
-
+
return TCL_OK;
}
@@ -1210,9 +1247,9 @@ ConfigurePanedWindow(interp, pwPtr, objc, objv)
*
* PanedWindowWorldChanged --
*
- * This procedure is invoked anytime a paned window's world has
- * changed in some way that causes the widget to have to recompute
- * graphics contexts and geometry.
+ * This function is invoked anytime a paned window's world has changed in
+ * some way that causes the widget to have to recompute graphics contexts
+ * and geometry.
*
* Results:
* None.
@@ -1224,8 +1261,8 @@ ConfigurePanedWindow(interp, pwPtr, objc, objv)
*/
static void
-PanedWindowWorldChanged(instanceData)
- ClientData instanceData; /* Information about the paned window. */
+PanedWindowWorldChanged(
+ ClientData instanceData) /* Information about the paned window. */
{
XGCValues gcValues;
GC newGC;
@@ -1235,7 +1272,7 @@ PanedWindowWorldChanged(instanceData)
* Allocated a graphics context for drawing the paned window widget
* elements (background, sashes, etc.) and set the window background.
*/
-
+
gcValues.background = Tk_3DBorderColor(pwPtr->background)->pixel;
newGC = Tk_GetGC(pwPtr->tkwin, GCBackground, &gcValues);
if (pwPtr->gc != None) {
@@ -1268,23 +1305,23 @@ PanedWindowWorldChanged(instanceData)
*
* PanedWindowEventProc --
*
- * This procedure is invoked by the Tk dispatcher for various
- * events on paned windows.
+ * This function is invoked by the Tk dispatcher for various events on
+ * paned windows.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up. When
+ * it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-PanedWindowEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- XEvent *eventPtr; /* Information about event. */
+PanedWindowEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
PanedWindow *pwPtr = (PanedWindow *) clientData;
@@ -1309,9 +1346,9 @@ PanedWindowEventProc(clientData, eventPtr)
*
* PanedWindowCmdDeletedProc --
*
- * 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.
+ * This function 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.
@@ -1323,16 +1360,16 @@ PanedWindowEventProc(clientData, eventPtr)
*/
static void
-PanedWindowCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+PanedWindowCmdDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
PanedWindow *pwPtr = (PanedWindow *) clientData;
/*
- * This procedure could be invoked either because the window was
- * destroyed and the command was then deleted or because the command was
- * deleted, and then this procedure destroys the widget. The
- * WIDGET_DELETED flag distinguishes these cases.
+ * This function could be invoked either because the window was destroyed
+ * and the command was then deleted or because the command was deleted,
+ * and then this function destroys the widget. The WIDGET_DELETED flag
+ * distinguishes these cases.
*/
if (!(pwPtr->flags & WIDGET_DELETED)) {
@@ -1346,9 +1383,9 @@ PanedWindowCmdDeletedProc(clientData)
*
* DisplayPanedWindow --
*
- * This procedure redraws the contents of a paned window widget.
- * It is invoked as a do-when-idle handler, so it only runs
- * when there's nothing else for the application to do.
+ * This function redraws the contents of a paned window widget. It is
+ * invoked as a do-when-idle handler, so it only runs when there's
+ * nothing else for the application to do.
*
* Results:
* None.
@@ -1360,15 +1397,15 @@ PanedWindowCmdDeletedProc(clientData)
*/
static void
-DisplayPanedWindow(clientData)
- ClientData clientData; /* Information about window. */
+DisplayPanedWindow(
+ ClientData clientData) /* Information about window. */
{
PanedWindow *pwPtr = (PanedWindow *) clientData;
Slave *slavePtr;
Pixmap pixmap;
Tk_Window tkwin = pwPtr->tkwin;
int i, sashWidth, sashHeight;
- CONST int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);
+ const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);
pwPtr->flags &= ~REDRAW_PENDING;
if ((pwPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
@@ -1417,9 +1454,14 @@ DisplayPanedWindow(clientData)
for (i = 0; i < pwPtr->numSlaves - 1; i++) {
slavePtr = pwPtr->slaves[i];
- Tk_Fill3DRectangle(tkwin, pixmap, pwPtr->background,
- slavePtr->sashx, slavePtr->sashy,
- sashWidth, sashHeight, 1, pwPtr->sashRelief);
+ if (slavePtr->hide) {
+ continue;
+ }
+ if (sashWidth > 0 && sashHeight > 0) {
+ Tk_Fill3DRectangle(tkwin, pixmap, pwPtr->background,
+ slavePtr->sashx, slavePtr->sashy, sashWidth, sashHeight,
+ 1, pwPtr->sashRelief);
+ }
if (pwPtr->showHandle) {
Tk_Fill3DRectangle(tkwin, pixmap, pwPtr->background,
slavePtr->handlex, slavePtr->handley,
@@ -1430,13 +1472,12 @@ DisplayPanedWindow(clientData)
#ifndef TK_NO_DOUBLE_BUFFERING
/*
- * Copy the information from the off-screen pixmap onto the screen,
- * then delete the pixmap.
+ * Copy the information from the off-screen pixmap onto the screen, then
+ * delete the pixmap.
*/
- XCopyArea(Tk_Display(tkwin), pixmap, Tk_WindowId(tkwin), pwPtr->gc,
- 0, 0, (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin),
- 0, 0);
+ XCopyArea(Tk_Display(tkwin), pixmap, Tk_WindowId(tkwin), pwPtr->gc, 0, 0,
+ (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin), 0, 0);
Tk_FreePixmap(Tk_Display(tkwin), pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
}
@@ -1446,8 +1487,8 @@ DisplayPanedWindow(clientData)
*
* DestroyPanedWindow --
*
- * This procedure is invoked by PanedWindowEventProc to free the
- * internal structure of a paned window.
+ * This function is invoked by PanedWindowEventProc to free the internal
+ * structure of a paned window.
*
* Results:
* None.
@@ -1459,23 +1500,23 @@ DisplayPanedWindow(clientData)
*/
static void
-DestroyPanedWindow(pwPtr)
- PanedWindow *pwPtr; /* Info about paned window widget. */
+DestroyPanedWindow(
+ PanedWindow *pwPtr) /* Info about paned window widget. */
{
int i;
-
+
/*
- * First mark the widget as in the process of being deleted,
- * so that any code that causes calls to other paned window procedures
- * will abort.
+ * First mark the widget as in the process of being deleted, so that any
+ * code that causes calls to other paned window functions will abort.
*/
pwPtr->flags |= WIDGET_DELETED;
/*
- * Cancel idle callbacks for redrawing the widget and for rearranging
- * the panes.
+ * Cancel idle callbacks for redrawing the widget and for rearranging the
+ * panes.
*/
+
if (pwPtr->flags & REDRAW_PENDING) {
Tcl_CancelIdleCall(DisplayPanedWindow, (ClientData) pwPtr);
}
@@ -1489,7 +1530,7 @@ DestroyPanedWindow(pwPtr)
* o Cancel geometry management for the slave.
* o Free memory for the slave
*/
-
+
for (i = 0; i < pwPtr->numSlaves; i++) {
Tk_DeleteEventHandler(pwPtr->slaves[i]->tkwin, StructureNotifyMask,
SlaveStructureProc, (ClientData) pwPtr->slaves[i]);
@@ -1525,26 +1566,25 @@ DestroyPanedWindow(pwPtr)
*
* PanedWindowReqProc --
*
- * This procedure is invoked by Tk_GeometryRequest for
- * windows managed by a paned window.
+ * This function is invoked by Tk_GeometryRequest for windows managed by
+ * a paned window.
*
* Results:
* None.
*
* Side effects:
- * Arranges for tkwin, and all its managed siblings, to
- * be re-arranged at the next idle point.
+ * Arranges for tkwin, and all its managed siblings, to be re-arranged at
+ * the next idle point.
*
*--------------------------------------------------------------
*/
static void
-PanedWindowReqProc(clientData, tkwin)
- ClientData clientData; /* Paned window's information about
- * window that got new preferred
- * geometry. */
- Tk_Window tkwin; /* Other Tk-related information
- * about the window. */
+PanedWindowReqProc(
+ ClientData clientData, /* Paned window's information about window
+ * that got new preferred geometry. */
+ Tk_Window tkwin) /* Other Tk-related information about the
+ * window. */
{
Slave *slavePtr = (Slave *) clientData;
PanedWindow *pwPtr = (PanedWindow *) (slavePtr->masterPtr);
@@ -1555,6 +1595,7 @@ PanedWindowReqProc(clientData, tkwin)
}
} else {
int doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width;
+
if (slavePtr->width <= 0) {
slavePtr->paneWidth = Tk_ReqWidth(slavePtr->tkwin) + doubleBw;
}
@@ -1570,27 +1611,28 @@ PanedWindowReqProc(clientData, tkwin)
*
* PanedWindowLostSlaveProc --
*
- * This procedure is invoked by Tk whenever some other geometry
- * claims control over a slave that used to be managed by us.
+ * This function is invoked by Tk whenever some other geometry claims
+ * control over a slave that used to be managed by us.
*
* Results:
* None.
*
* Side effects:
- * Forgets all information about the slave. Causes geometry to
- * be recomputed for the panedwindow.
+ * Forgets all information about the slave. Causes geometry to be
+ * recomputed for the panedwindow.
*
*--------------------------------------------------------------
*/
static void
-PanedWindowLostSlaveProc(clientData, tkwin)
- ClientData clientData; /* Grid structure for slave window that
- * was stolen away. */
- Tk_Window tkwin; /* Tk's handle for the slave window. */
+PanedWindowLostSlaveProc(
+ ClientData clientData, /* Grid structure for slave window that was
+ * stolen away. */
+ Tk_Window tkwin) /* Tk's handle for the slave window. */
{
register Slave *slavePtr = (Slave *) clientData;
PanedWindow *pwPtr = (PanedWindow *) (slavePtr->masterPtr);
+
if (pwPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
Tk_UnmaintainGeometry(slavePtr->tkwin, pwPtr->tkwin);
}
@@ -1608,11 +1650,10 @@ PanedWindowLostSlaveProc(clientData, tkwin)
*
* ArrangePanes --
*
- * This procedure is invoked (using the Tcl_DoWhenIdle
- * mechanism) to re-layout a set of windows managed by
- * a paned window. It is invoked at idle time so that a
- * series of pane requests can be merged into a single
- * layout operation.
+ * This function is invoked (using the Tcl_DoWhenIdle mechanism) to
+ * re-layout a set of windows managed by a paned window. It is invoked at
+ * idle time so that a series of pane requests can be merged into a
+ * single layout operation.
*
* Results:
* None.
@@ -1624,8 +1665,8 @@ PanedWindowLostSlaveProc(clientData, tkwin)
*/
static void
-ArrangePanes(clientData)
- ClientData clientData; /* Structure describing parent whose slaves
+ArrangePanes(
+ ClientData clientData) /* Structure describing parent whose slaves
* are to be re-layed out. */
{
register PanedWindow *pwPtr = (PanedWindow *) clientData;
@@ -1638,16 +1679,17 @@ ArrangePanes(clientData)
int sashReserve, sxReserve, syReserve;
int internalBW;
int paneDynSize, paneDynMinSize, pwHeight, pwWidth, pwSize;
+ int first, last;
int stretchReserve, stretchAmount;
- CONST int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);
+ const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);
pwPtr->flags &= ~(REQUESTED_RELAYOUT|RESIZE_PENDING);
/*
- * If the parent has no slaves anymore, then don't do anything
- * at all: just leave the parent's size as-is. Otherwise there is
- * no way to "relinquish" control over the parent so another geometry
- * manager can take over.
+ * If the parent has no slaves anymore, then don't do anything at all:
+ * just leave the parent's size as-is. Otherwise there is no way to
+ * "relinquish" control over the parent so another geometry manager can
+ * take over.
*/
if (pwPtr->numSlaves == 0) {
@@ -1657,6 +1699,19 @@ ArrangePanes(clientData)
Tcl_Preserve((ClientData) pwPtr);
/*
+ * Find index of last visible pane.
+ */
+
+ for (i = 0, last = 0, first = -1; i < pwPtr->numSlaves; i++) {
+ if (pwPtr->slaves[i]->hide == 0) {
+ if (first < 0) {
+ first = i;
+ }
+ last = i;
+ }
+ }
+
+ /*
* First pass; compute sizes
*/
@@ -1668,8 +1723,8 @@ ArrangePanes(clientData)
stretchReserve = (horizontal ? pwWidth : pwHeight);
/*
- * Calculate the sash width, including handle and padding,
- * and the sash and handle offsets.
+ * Calculate the sash width, including handle and padding, and the sash
+ * and handle offsets.
*/
sashOffset = handleOffset = pwPtr->sashPad;
@@ -1682,14 +1737,17 @@ ArrangePanes(clientData)
handleOffset = ((pwPtr->sashWidth - pwPtr->handleSize) / 2)
+ pwPtr->sashPad;
}
- sashCount = pwPtr->numSlaves - 1;
- for (i = 0; i < pwPtr->numSlaves; i++) {
+ for (i = sashCount = 0; i < pwPtr->numSlaves; i++) {
slavePtr = pwPtr->slaves[i];
+ if (slavePtr->hide) {
+ continue;
+ }
+
/*
- * Compute the total size needed by all the slaves and the
- * left-over, or shortage of space available.
+ * Compute the total size needed by all the slaves and the left-over,
+ * or shortage of space available.
*/
if (horizontal) {
@@ -1699,11 +1757,14 @@ ArrangePanes(clientData)
paneSize = slavePtr->paneHeight;
stretchReserve -= paneSize + (2 * slavePtr->pady);
}
- if (i == sashCount) {
+ if (IsStretchable(slavePtr->stretch,i,first,last)
+ && Tk_IsMapped(pwPtr->tkwin)) {
paneDynSize += paneSize;
paneDynMinSize += slavePtr->minSize;
- } else {
+ }
+ if (i != last) {
stretchReserve -= sashWidth;
+ sashCount++;
}
}
@@ -1714,16 +1775,21 @@ ArrangePanes(clientData)
for (i = 0; i < pwPtr->numSlaves; i++) {
slavePtr = pwPtr->slaves[i];
+ if (slavePtr->hide) {
+ Tk_UnmaintainGeometry(slavePtr->tkwin, pwPtr->tkwin);
+ Tk_UnmapWindow(slavePtr->tkwin);
+ continue;
+ }
+
/*
- * Compute the size of this slave. The algorithm (assuming a
+ * Compute the size of this slave. The algorithm (assuming a
* horizontal paned window) is:
*
- * 1. Get "base" dimensions. If a width or height is specified
- * for this slave, use those values; else use the
- * ReqWidth/ReqHeight.
+ * 1. Get "base" dimensions. If a width or height is specified for
+ * this slave, use those values; else use the ReqWidth/ReqHeight.
* 2. Using base dimensions, pane dimensions, and sticky values,
- * determine the x and y, and actual width and height of the
- * widget.
+ * determine the x and y, and actual width and height of the
+ * widget.
*/
doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width;
@@ -1744,37 +1810,37 @@ ArrangePanes(clientData)
paneSize = slavePtr->paneHeight;
pwSize = pwHeight;
}
- if (Tk_IsMapped(pwPtr->tkwin)) {
- if (i == pwPtr->numSlaves - 1) {
- double frac;
- if (paneDynSize > 0) {
- frac = (double)paneSize / (double)paneDynSize;
- } else {
- frac = (double)paneSize / (double)pwSize;
- }
- paneDynSize -= paneSize;
- paneDynMinSize -= slavePtr->minSize;
- stretchAmount = (int) (frac * stretchReserve);
- if (paneSize + stretchAmount >= paneMinSize) {
- stretchReserve -= stretchAmount;
- paneSize += stretchAmount;
- } else {
- stretchReserve += paneSize - paneMinSize;
- paneSize = paneMinSize;
- }
- if (stretchReserve > 0) {
- paneSize += stretchReserve;
- stretchReserve = 0;
- }
- } else if (paneDynSize - paneDynMinSize + stretchReserve < 0) {
- if (paneSize + paneDynSize - paneDynMinSize + stretchReserve
- <= paneMinSize) {
- stretchReserve += paneSize - paneMinSize;
- paneSize = paneMinSize;
- } else {
- paneSize += paneDynSize - paneDynMinSize + stretchReserve;
- stretchReserve = paneDynMinSize - paneDynSize;
- }
+ if (IsStretchable(slavePtr->stretch, i, first, last)) {
+ double frac;
+
+ if (paneDynSize > 0) {
+ frac = (double)paneSize / (double)paneDynSize;
+ } else {
+ frac = (double)paneSize / (double)pwSize;
+ }
+
+ paneDynSize -= paneSize;
+ paneDynMinSize -= slavePtr->minSize;
+ stretchAmount = (int) (frac * stretchReserve);
+ if (paneSize + stretchAmount >= paneMinSize) {
+ stretchReserve -= stretchAmount;
+ paneSize += stretchAmount;
+ } else {
+ stretchReserve += paneSize - paneMinSize;
+ paneSize = paneMinSize;
+ }
+ if (i == last && stretchReserve > 0) {
+ paneSize += stretchReserve;
+ stretchReserve = 0;
+ }
+ } else if (paneDynSize - paneDynMinSize + stretchReserve < 0) {
+ if (paneSize + paneDynSize - paneDynMinSize + stretchReserve
+ <= paneMinSize) {
+ stretchReserve += paneSize - paneMinSize;
+ paneSize = paneMinSize;
+ } else {
+ paneSize += paneDynSize - paneDynMinSize + stretchReserve;
+ stretchReserve = paneDynMinSize - paneDynSize;
}
}
if (horizontal) {
@@ -1829,8 +1895,8 @@ ArrangePanes(clientData)
if (x < internalBW) {
x = internalBW;
}
- slavePtr->sashx = x + sashOffset;
- slavePtr->sashy = y;
+ slavePtr->sashx = x + sashOffset;
+ slavePtr->sashy = y;
slavePtr->handlex = x + handleOffset;
slavePtr->handley = y + pwPtr->handlePad;
x += sashWidth;
@@ -1839,8 +1905,8 @@ ArrangePanes(clientData)
if (y < internalBW) {
y = internalBW;
}
- slavePtr->sashx = x;
- slavePtr->sashy = y + sashOffset;
+ slavePtr->sashx = x;
+ slavePtr->sashy = y + sashOffset;
slavePtr->handlex = x + pwPtr->handlePad;
slavePtr->handley = y + handleOffset;
y += sashWidth;
@@ -1893,12 +1959,12 @@ ArrangePanes(clientData)
*/
static void
-Unlink(slavePtr)
- register Slave *slavePtr; /* Window to unlink. */
+Unlink(
+ register Slave *slavePtr) /* Window to unlink. */
{
register PanedWindow *masterPtr;
int i, j;
-
+
masterPtr = slavePtr->masterPtr;
if (masterPtr == NULL) {
return;
@@ -1921,6 +1987,7 @@ Unlink(slavePtr)
/*
* Clean out any -after or -before references to this slave
*/
+
for (i = 0; i < masterPtr->numSlaves; i++) {
if (masterPtr->slaves[i]->before == slavePtr->tkwin) {
masterPtr->slaves[i]->before = None;
@@ -1937,9 +2004,10 @@ Unlink(slavePtr)
}
/*
- * Set the slave's masterPtr to NULL, so that we can tell that the
- * slave is no longer attached to any panedwindow.
+ * Set the slave's masterPtr to NULL, so that we can tell that the slave
+ * is no longer attached to any panedwindow.
*/
+
slavePtr->masterPtr = NULL;
masterPtr->numSlaves--;
@@ -1950,12 +2018,12 @@ Unlink(slavePtr)
*
* GetPane --
*
- * Given a token to a Tk window, find the pane that corresponds to
- * that token in a given paned window.
+ * Given a token to a Tk window, find the pane that corresponds to that
+ * token in a given paned window.
*
* Results:
- * Pointer to the slave structure, or NULL if the window is not
- * managed by this paned window.
+ * Pointer to the slave structure, or NULL if the window is not managed
+ * by this paned window.
*
* Side effects:
* None.
@@ -1964,11 +2032,12 @@ Unlink(slavePtr)
*/
static Slave *
-GetPane(pwPtr, tkwin)
- PanedWindow *pwPtr; /* Pointer to the paned window info. */
- Tk_Window tkwin; /* Window to search for. */
+GetPane(
+ PanedWindow *pwPtr, /* Pointer to the paned window info. */
+ Tk_Window tkwin) /* Window to search for. */
{
int i;
+
for (i = 0; i < pwPtr->numSlaves; i++) {
if (pwPtr->slaves[i]->tkwin == tkwin) {
return pwPtr->slaves[i];
@@ -1982,10 +2051,9 @@ GetPane(pwPtr, tkwin)
*
* SlaveStructureProc --
*
- * This procedure is invoked whenever StructureNotify events
- * occur for a window that's managed by a paned window. This
- * procedure's only purpose is to clean up when windows are
- * deleted.
+ * This function is invoked whenever StructureNotify events occur for a
+ * window that's managed by a paned window. This function's only purpose
+ * is to clean up when windows are deleted.
*
* Results:
* None.
@@ -1999,13 +2067,13 @@ GetPane(pwPtr, tkwin)
*/
static void
-SlaveStructureProc(clientData, eventPtr)
- ClientData clientData; /* Pointer to record describing window item. */
- XEvent *eventPtr; /* Describes what just happened. */
+SlaveStructureProc(
+ ClientData clientData, /* Pointer to record describing window item. */
+ XEvent *eventPtr) /* Describes what just happened. */
{
Slave *slavePtr = (Slave *) clientData;
PanedWindow *pwPtr = slavePtr->masterPtr;
-
+
if (eventPtr->type == DestroyNotify) {
Unlink(slavePtr);
slavePtr->tkwin = NULL;
@@ -2019,8 +2087,8 @@ SlaveStructureProc(clientData, eventPtr)
*
* ComputeGeometry --
*
- * Compute geometry for the paned window, including coordinates of
- * all slave windows and each sash.
+ * Compute geometry for the paned window, including coordinates of all
+ * slave windows and each sash.
*
* Results:
* None.
@@ -2032,14 +2100,14 @@ SlaveStructureProc(clientData, eventPtr)
*/
static void
-ComputeGeometry(pwPtr)
- PanedWindow *pwPtr; /* Pointer to the Paned Window structure. */
+ComputeGeometry(
+ PanedWindow *pwPtr) /* Pointer to the Paned Window structure. */
{
int i, x, y, doubleBw, internalBw;
int sashWidth, sashOffset, handleOffset;
int reqWidth, reqHeight, dim;
Slave *slavePtr;
- CONST int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);
+ const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);
pwPtr->flags |= REQUESTED_RELAYOUT;
@@ -2047,10 +2115,10 @@ ComputeGeometry(pwPtr)
reqWidth = reqHeight = 0;
/*
- * Sashes and handles share space on the display. To simplify
- * processing below, precompute the x and y offsets of the handles and
- * sashes within the space occupied by their combination; later, just add
- * those offsets blindly (avoiding the extra showHandle, etc, checks).
+ * Sashes and handles share space on the display. To simplify processing
+ * below, precompute the x and y offsets of the handles and sashes within
+ * the space occupied by their combination; later, just add those offsets
+ * blindly (avoiding the extra showHandle, etc, checks).
*/
sashOffset = handleOffset = pwPtr->sashPad;
@@ -2067,6 +2135,10 @@ ComputeGeometry(pwPtr)
for (i = 0; i < pwPtr->numSlaves; i++) {
slavePtr = pwPtr->slaves[i];
+ if (slavePtr->hide) {
+ continue;
+ }
+
/*
* First set the coordinates for the top left corner of the slave's
* parcel.
@@ -2076,9 +2148,9 @@ ComputeGeometry(pwPtr)
slavePtr->y = y;
/*
- * Make sure the pane's paned dimension is at least minsize.
- * This check may be redundant, since the only way to change a pane's
- * size is by moving a sash, and that code checks the minsize.
+ * Make sure the pane's paned dimension is at least minsize. This
+ * check may be redundant, since the only way to change a pane's size
+ * is by moving a sash, and that code checks the minsize.
*/
if (horizontal) {
@@ -2098,15 +2170,15 @@ ComputeGeometry(pwPtr)
if (horizontal) {
x += slavePtr->paneWidth + (2 * slavePtr->padx);
- slavePtr->sashx = x + sashOffset;
- slavePtr->sashy = y;
+ slavePtr->sashx = x + sashOffset;
+ slavePtr->sashy = y;
slavePtr->handlex = x + handleOffset;
slavePtr->handley = y + pwPtr->handlePad;
x += sashWidth;
} else {
y += slavePtr->paneHeight + (2 * slavePtr->pady);
- slavePtr->sashx = x;
- slavePtr->sashy = y + sashOffset;
+ slavePtr->sashx = x;
+ slavePtr->sashy = y + sashOffset;
slavePtr->handlex = x + pwPtr->handlePad;
slavePtr->handley = y + handleOffset;
y += sashWidth;
@@ -2118,7 +2190,6 @@ ComputeGeometry(pwPtr)
*/
if (horizontal) {
-
/*
* If the slave has an explicit height set, use that; otherwise,
* use the slave's requested height.
@@ -2135,10 +2206,9 @@ ComputeGeometry(pwPtr)
reqHeight = dim;
}
} else {
-
/*
- * If the slave has an explicit width set use that; otherwise,
- * use the slave's requested width.
+ * If the slave has an explicit width set use that; otherwise, use
+ * the slave's requested width.
*/
if (slavePtr->width > 0) {
@@ -2155,21 +2225,21 @@ ComputeGeometry(pwPtr)
}
/*
- * The loop above should have left x (or y) equal to the sum of the
- * widths (or heights) of the widgets, plus the size of one sash and
- * the sash padding for each widget, plus the width of the left (or top)
- * border of the paned window.
+ * The loop above should have left x (or y) equal to the sum of the widths
+ * (or heights) of the widgets, plus the size of one sash and the sash
+ * padding for each widget, plus the width of the left (or top) border of
+ * the paned window.
*
* The requested width (or height) is therefore x (or y) minus the size of
- * one sash and padding, plus the width of the right (or bottom) border
- * of the paned window.
+ * one sash and padding, plus the width of the right (or bottom) border of
+ * the paned window.
*
- * The height (or width) is equal to the maximum height (or width) of
- * the slaves, plus the width of the border of the top and bottom (or left
- * and right) of the paned window.
+ * The height (or width) is equal to the maximum height (or width) of the
+ * slaves, plus the width of the border of the top and bottom (or left and
+ * right) of the paned window.
*
- * If the panedwindow has an explicit width/height set use that; otherwise,
- * use the requested width/height.
+ * If the panedwindow has an explicit width/height set use that;
+ * otherwise, use the requested width/height.
*/
if (horizontal) {
@@ -2195,8 +2265,8 @@ ComputeGeometry(pwPtr)
*
* DestroyOptionTables --
*
- * This procedure is registered as an exit callback when the paned window
- * command is first called. It cleans up the OptionTables structure
+ * This function is registered as an exit callback when the paned window
+ * command is first called. It cleans up the OptionTables structure
* allocated by that command.
*
* Results:
@@ -2209,9 +2279,9 @@ ComputeGeometry(pwPtr)
*/
static void
-DestroyOptionTables(clientData, interp)
- ClientData clientData; /* Pointer to the OptionTables struct */
- Tcl_Interp *interp; /* Pointer to the calling interp */
+DestroyOptionTables(
+ ClientData clientData, /* Pointer to the OptionTables struct */
+ Tcl_Interp *interp) /* Pointer to the calling interp */
{
ckfree((char *)clientData);
return;
@@ -2222,8 +2292,8 @@ DestroyOptionTables(clientData, interp)
*
* GetSticky -
*
- * Converts an internal boolean combination of "sticky" bits into a
- * a Tcl string obj containing zero or mor of n, s, e, or w.
+ * Converts an internal boolean combination of "sticky" bits into a Tcl
+ * string obj containing zero or more of n, s, e, or w.
*
* Results:
* Tcl_Obj containing the string representation of the sticky value.
@@ -2235,11 +2305,11 @@ DestroyOptionTables(clientData, interp)
*/
static Tcl_Obj *
-GetSticky(clientData, tkwin, recordPtr, internalOffset)
- ClientData clientData;
- Tk_Window tkwin;
- char *recordPtr; /* Pointer to widget record. */
- int internalOffset; /* Offset within *recordPtr containing the
+GetSticky(
+ ClientData clientData,
+ Tk_Window tkwin,
+ char *recordPtr, /* Pointer to widget record. */
+ int internalOffset) /* Offset within *recordPtr containing the
* sticky value. */
{
int sticky = *(int *)(recordPtr + internalOffset);
@@ -2247,16 +2317,16 @@ GetSticky(clientData, tkwin, recordPtr, internalOffset)
int count = 0;
if (sticky & STICK_NORTH) {
- buffer[count++] = 'n';
+ buffer[count++] = 'n';
}
if (sticky & STICK_EAST) {
- buffer[count++] = 'e';
+ buffer[count++] = 'e';
}
if (sticky & STICK_SOUTH) {
- buffer[count++] = 's';
+ buffer[count++] = 's';
}
if (sticky & STICK_WEST) {
- buffer[count++] = 'w';
+ buffer[count++] = 'w';
}
buffer[count] = '\0';
@@ -2268,64 +2338,70 @@ GetSticky(clientData, tkwin, recordPtr, internalOffset)
*
* SetSticky --
*
- * Converts a Tcl_Obj representing a widgets stickyness into an
- * integer value.
+ * Converts a Tcl_Obj representing a widgets stickyness into an integer
+ * value.
*
* Results:
* Standard Tcl result.
*
* Side effects:
- * May store the integer value into the internal representation
- * pointer. May change the pointer to the Tcl_Obj to NULL to indicate
- * that the specified string was empty and that is acceptable.
+ * May store the integer value into the internal representation pointer.
+ * May change the pointer to the Tcl_Obj to NULL to indicate that the
+ * specified string was empty and that is acceptable.
*
*----------------------------------------------------------------------
*/
static int
-SetSticky(clientData, interp, tkwin, value, recordPtr, internalOffset,
- oldInternalPtr, flags)
- ClientData clientData;
- Tcl_Interp *interp; /* Current interp; may be used for errors. */
- Tk_Window tkwin; /* Window for which option is being set. */
- Tcl_Obj **value; /* Pointer to the pointer to the value object.
- * We use a pointer to the pointer because
- * we may need to return a value (NULL). */
- char *recordPtr; /* Pointer to storage for the widget record. */
- int internalOffset; /* Offset within *recordPtr at which the
- internal value is to be stored. */
- char *oldInternalPtr; /* Pointer to storage for the old value. */
- int flags; /* Flags for the option, set Tk_SetOptions. */
+SetSticky(
+ ClientData clientData,
+ Tcl_Interp *interp, /* Current interp; may be used for errors. */
+ Tk_Window tkwin, /* Window for which option is being set. */
+ Tcl_Obj **value, /* Pointer to the pointer to the value object.
+ * We use a pointer to the pointer because we
+ * may need to return a value (NULL). */
+ char *recordPtr, /* Pointer to storage for the widget record. */
+ int internalOffset, /* Offset within *recordPtr at which the
+ * internal value is to be stored. */
+ char *oldInternalPtr, /* Pointer to storage for the old value. */
+ int flags) /* Flags for the option, set Tk_SetOptions. */
{
int sticky = 0;
char c, *string, *internalPtr;
internalPtr = ComputeSlotAddress(recordPtr, internalOffset);
-
+
if (flags & TK_OPTION_NULL_OK && ObjectIsEmpty(*value)) {
*value = NULL;
} else {
/*
* Convert the sticky specifier into an integer value.
*/
-
+
string = Tcl_GetString(*value);
-
+
while ((c = *string++) != '\0') {
switch (c) {
- case 'n': case 'N': sticky |= STICK_NORTH; break;
- case 'e': case 'E': sticky |= STICK_EAST; break;
- case 's': case 'S': sticky |= STICK_SOUTH; break;
- case 'w': case 'W': sticky |= STICK_WEST; break;
- case ' ': case ',': case '\t': case '\r': case '\n': break;
- default: {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad stickyness value \"",
- Tcl_GetString(*value), "\": must be a string ",
- "containing zero or more of n, e, s, and w",
- (char *)NULL);
- return TCL_ERROR;
- }
+ case 'n': case 'N':
+ sticky |= STICK_NORTH;
+ break;
+ case 'e': case 'E':
+ sticky |= STICK_EAST;
+ break;
+ case 's': case 'S':
+ sticky |= STICK_SOUTH;
+ break;
+ case 'w': case 'W':
+ sticky |= STICK_WEST;
+ break;
+ case ' ': case ',': case '\t': case '\r': case '\n':
+ break;
+ default:
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "bad stickyness value \"",
+ Tcl_GetString(*value), "\": must be a string ",
+ "containing zero or more of n, e, s, and w", NULL);
+ return TCL_ERROR;
}
}
}
@@ -2335,7 +2411,7 @@ SetSticky(clientData, interp, tkwin, value, recordPtr, internalOffset,
*((int *) internalPtr) = sticky;
}
return TCL_OK;
-}
+}
/*
*----------------------------------------------------------------------
@@ -2354,11 +2430,11 @@ SetSticky(clientData, interp, tkwin, value, recordPtr, internalOffset,
*/
static void
-RestoreSticky(clientData, tkwin, internalPtr, oldInternalPtr)
- ClientData clientData;
- Tk_Window tkwin;
- char *internalPtr; /* Pointer to storage for value. */
- char *oldInternalPtr; /* Pointer to old value. */
+RestoreSticky(
+ ClientData clientData,
+ Tk_Window tkwin,
+ char *internalPtr, /* Pointer to storage for value. */
+ char *oldInternalPtr) /* Pointer to old value. */
{
*(int *)internalPtr = *(int *)oldInternalPtr;
}
@@ -2368,14 +2444,13 @@ RestoreSticky(clientData, tkwin, internalPtr, oldInternalPtr)
*
* AdjustForSticky --
*
- * Given the x,y coords of the top-left corner of a pane, the
- * dimensions of that pane, and the dimensions of a slave, compute
- * the x,y coords and actual dimensions of the slave based on the slave's
- * sticky value.
+ * Given the x,y coords of the top-left corner of a pane, the dimensions
+ * of that pane, and the dimensions of a slave, compute the x,y coords
+ * and actual dimensions of the slave based on the slave's sticky value.
*
* Results:
- * No direct return; sets the x, y, slaveWidth and slaveHeight to
- * correct values.
+ * No direct return; sets the x, y, slaveWidth and slaveHeight to correct
+ * values.
*
* Side effects:
* None.
@@ -2384,19 +2459,19 @@ RestoreSticky(clientData, tkwin, internalPtr, oldInternalPtr)
*/
static void
-AdjustForSticky(sticky, cavityWidth, cavityHeight, xPtr, yPtr,
- slaveWidthPtr, slaveHeightPtr)
- int sticky; /* Sticky value; see top of file for definition. */
- int cavityWidth; /* Width of the cavity. */
- int cavityHeight; /* Height of the cavity. */
- int *xPtr, *yPtr; /* Initially, coordinates of the top-left
+AdjustForSticky(
+ int sticky, /* Sticky value; see top of file for
+ * definition. */
+ int cavityWidth, /* Width of the cavity. */
+ int cavityHeight, /* Height of the cavity. */
+ int *xPtr, int *yPtr, /* Initially, coordinates of the top-left
* corner of cavity; also return values for
* actual x, y coords of slave. */
- int *slaveWidthPtr; /* Slave width. */
- int *slaveHeightPtr; /* Slave height. */
+ int *slaveWidthPtr, /* Slave width. */
+ int *slaveHeightPtr) /* Slave height. */
{
- int diffx=0; /* Cavity width - slave width. */
- int diffy=0; /* Cavity hight - slave height. */
+ int diffx = 0; /* Cavity width - slave width. */
+ int diffy = 0; /* Cavity hight - slave height. */
if (cavityWidth > *slaveWidthPtr) {
diffx = cavityWidth - *slaveWidthPtr;
@@ -2413,10 +2488,10 @@ AdjustForSticky(sticky, cavityWidth, cavityHeight, xPtr, yPtr,
*slaveHeightPtr += diffy;
}
if (!(sticky & STICK_WEST)) {
- *xPtr += (sticky & STICK_EAST) ? diffx : diffx/2;
+ *xPtr += (sticky & STICK_EAST) ? diffx : diffx/2;
}
if (!(sticky & STICK_NORTH)) {
- *yPtr += (sticky & STICK_SOUTH) ? diffy : diffy/2;
+ *yPtr += (sticky & STICK_SOUTH) ? diffy : diffy/2;
}
}
@@ -2437,17 +2512,17 @@ AdjustForSticky(sticky, cavityWidth, cavityHeight, xPtr, yPtr,
*/
static void
-MoveSash(pwPtr, sash, diff)
- PanedWindow *pwPtr;
- int sash;
- int diff;
+MoveSash(
+ PanedWindow *pwPtr,
+ int sash,
+ int diff)
{
int i;
int expandPane, reduceFirst, reduceLast, reduceIncr, slaveSize, sashOffset;
Slave *slavePtr;
int stretchReserve = 0;
int nextSash = sash + 1;
- CONST int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);
+ const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);
if (diff == 0)
return;
@@ -2464,6 +2539,9 @@ MoveSash(pwPtr, sash, diff)
}
for (i = 0; i < pwPtr->numSlaves; i++) {
slavePtr = pwPtr->slaves[i];
+ if (slavePtr->hide) {
+ continue;
+ }
if (horizontal) {
slavePtr->paneWidth = slavePtr->width = slavePtr->sashx
- sashOffset - slavePtr->x - (2 * slavePtr->padx);
@@ -2474,6 +2552,16 @@ MoveSash(pwPtr, sash, diff)
}
/*
+ * There must be a next sash since it is only possible to enter this
+ * routine when moving an actual sash which implies there exists a visible
+ * pane to either side of the sash.
+ */
+
+ while (nextSash < pwPtr->numSlaves-1 && pwPtr->slaves[nextSash]->hide) {
+ nextSash++;
+ }
+
+ /*
* Consolidate +/-diff variables to reduce duplicate code.
*/
@@ -2491,12 +2579,15 @@ MoveSash(pwPtr, sash, diff)
}
/*
- * Calculate how much room we have to stretch in
- * and adjust diff value accordingly.
+ * Calculate how much room we have to stretch in and adjust diff value
+ * accordingly.
*/
for (i = reduceFirst; i != reduceLast; i += reduceIncr) {
slavePtr = pwPtr->slaves[i];
+ if (slavePtr->hide) {
+ continue;
+ }
if (horizontal) {
stretchReserve += slavePtr->width - slavePtr->minSize;
} else {
@@ -2527,6 +2618,9 @@ MoveSash(pwPtr, sash, diff)
for (i = reduceFirst; i != reduceLast; i += reduceIncr) {
slavePtr = pwPtr->slaves[i];
+ if (slavePtr->hide) {
+ continue;
+ }
if (horizontal) {
slaveSize = slavePtr->width;
} else {
@@ -2552,23 +2646,23 @@ MoveSash(pwPtr, sash, diff)
*
* ProxyWindowEventProc --
*
- * This procedure is invoked by the Tk dispatcher for various
- * events on paned window proxy windows.
+ * This function is invoked by the Tk dispatcher for various events on
+ * paned window proxy windows.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up. Whena
+ * it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-ProxyWindowEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- XEvent *eventPtr; /* Information about event. */
+ProxyWindowEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
PanedWindow *pwPtr = (PanedWindow *) clientData;
@@ -2585,9 +2679,9 @@ ProxyWindowEventProc(clientData, eventPtr)
*
* DisplayProxyWindow --
*
- * This procedure redraws a paned window proxy window.
- * It is invoked as a do-when-idle handler, so it only runs
- * when there's nothing else for the application to do.
+ * This function redraws a paned window proxy window. It is invoked as a
+ * do-when-idle handler, so it only runs when there's nothing else for
+ * the application to do.
*
* Results:
* None.
@@ -2599,8 +2693,8 @@ ProxyWindowEventProc(clientData, eventPtr)
*/
static void
-DisplayProxyWindow(clientData)
- ClientData clientData; /* Information about window. */
+DisplayProxyWindow(
+ ClientData clientData) /* Information about window. */
{
PanedWindow *pwPtr = (PanedWindow *) clientData;
Pixmap pixmap;
@@ -2624,6 +2718,7 @@ DisplayProxyWindow(clientData)
/*
* Redraw the widget's background and border.
*/
+
Tk_Fill3DRectangle(tkwin, pixmap, pwPtr->background, 0, 0,
Tk_Width(tkwin), Tk_Height(tkwin), 2, pwPtr->sashRelief);
@@ -2631,9 +2726,9 @@ DisplayProxyWindow(clientData)
/*
* Copy the pixmap to the display.
*/
- XCopyArea(Tk_Display(tkwin), pixmap, Tk_WindowId(tkwin), pwPtr->gc,
- 0, 0, (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin),
- 0, 0);
+
+ XCopyArea(Tk_Display(tkwin), pixmap, Tk_WindowId(tkwin), pwPtr->gc, 0, 0,
+ (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin), 0, 0);
Tk_FreePixmap(Tk_Display(tkwin), pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
}
@@ -2643,8 +2738,8 @@ DisplayProxyWindow(clientData)
*
* PanedWindowProxyCommand --
*
- * Handles the panedwindow proxy subcommand. See the user
- * documentation for details.
+ * Handles the panedwindow proxy subcommand. See the user documentation
+ * for details.
*
* Results:
* Standard Tcl result.
@@ -2656,18 +2751,21 @@ DisplayProxyWindow(clientData)
*/
static int
-PanedWindowProxyCommand(pwPtr, interp, objc, objv)
- PanedWindow *pwPtr; /* Pointer to paned window information. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj * CONST objv[]; /* Argument objects. */
+PanedWindowProxyCommand(
+ PanedWindow *pwPtr, /* Pointer to paned window information. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- static CONST char *optionStrings[] = { "coord", "forget", "place",
- (char *) NULL };
- enum options { PROXY_COORD, PROXY_FORGET, PROXY_PLACE };
+ static const char *optionStrings[] = {
+ "coord", "forget", "place", NULL
+ };
+ enum options {
+ PROXY_COORD, PROXY_FORGET, PROXY_PLACE
+ };
int index, x, y, sashWidth, sashHeight;
Tcl_Obj *coords[2];
-
+
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
return TCL_ERROR;
@@ -2679,85 +2777,92 @@ PanedWindowProxyCommand(pwPtr, interp, objc, objv)
}
switch ((enum options) index) {
- case PROXY_COORD:
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, NULL);
- return TCL_ERROR;
- }
+ case PROXY_COORD:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
+ return TCL_ERROR;
+ }
- coords[0] = Tcl_NewIntObj(pwPtr->proxyx);
- coords[1] = Tcl_NewIntObj(pwPtr->proxyy);
- Tcl_SetListObj(Tcl_GetObjResult(interp), 2, coords);
- break;
+ coords[0] = Tcl_NewIntObj(pwPtr->proxyx);
+ coords[1] = Tcl_NewIntObj(pwPtr->proxyy);
+ Tcl_SetListObj(Tcl_GetObjResult(interp), 2, coords);
+ break;
- case PROXY_FORGET:
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 3, objv, NULL);
- return TCL_ERROR;
- }
- if (Tk_IsMapped(pwPtr->proxywin)) {
- Tk_UnmapWindow(pwPtr->proxywin);
- Tk_UnmaintainGeometry(pwPtr->proxywin, pwPtr->tkwin);
- }
- break;
+ case PROXY_FORGET:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
+ return TCL_ERROR;
+ }
+ if (Tk_IsMapped(pwPtr->proxywin)) {
+ Tk_UnmapWindow(pwPtr->proxywin);
+ Tk_UnmaintainGeometry(pwPtr->proxywin, pwPtr->tkwin);
+ }
+ break;
- case PROXY_PLACE: {
- if (objc != 5) {
- Tcl_WrongNumArgs(interp, 3, objv, "x y");
- return TCL_ERROR;
- }
+ case PROXY_PLACE:
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "x y");
+ return TCL_ERROR;
+ }
- if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) {
- return TCL_ERROR;
- }
+ if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) {
+ return TCL_ERROR;
+ }
- if (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) {
- return TCL_ERROR;
- }
+ if (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) {
+ return TCL_ERROR;
+ }
- if (pwPtr->orient == ORIENT_HORIZONTAL) {
- if (x < 0) {
- x = 0;
- }
- y = Tk_InternalBorderWidth(pwPtr->tkwin);
- sashWidth = pwPtr->sashWidth;
- sashHeight = Tk_Height(pwPtr->tkwin) -
- (2 * Tk_InternalBorderWidth(pwPtr->tkwin));
- } else {
- if (y < 0) {
- y = 0;
- }
- x = Tk_InternalBorderWidth(pwPtr->tkwin);
- sashHeight = pwPtr->sashWidth;
- sashWidth = Tk_Width(pwPtr->tkwin) -
+ if (pwPtr->orient == ORIENT_HORIZONTAL) {
+ if (x < 0) {
+ x = 0;
+ }
+ y = Tk_InternalBorderWidth(pwPtr->tkwin);
+ sashWidth = pwPtr->sashWidth;
+ sashHeight = Tk_Height(pwPtr->tkwin) -
(2 * Tk_InternalBorderWidth(pwPtr->tkwin));
+ } else {
+ if (y < 0) {
+ y = 0;
}
+ x = Tk_InternalBorderWidth(pwPtr->tkwin);
+ sashHeight = pwPtr->sashWidth;
+ sashWidth = Tk_Width(pwPtr->tkwin) -
+ (2 * Tk_InternalBorderWidth(pwPtr->tkwin));
+ }
- /*
- * Stash the proxy coordinates for future "proxy coord" calls.
- */
+ if (sashWidth < 1) {
+ sashWidth = 1;
+ }
+ if (sashHeight < 1) {
+ sashHeight = 1;
+ }
- pwPtr->proxyx = x;
- pwPtr->proxyy = y;
-
- /*
- * Make sure the proxy window is higher in the stacking order
- * than the slaves, so that it will be visible when drawn.
- * It would be more correct to push the proxy window just high
- * enough to appear above the highest slave, but it's much easier
- * to just force it all the way to the top of the stacking order.
- */
-
- Tk_RestackWindow(pwPtr->proxywin, Above, NULL);
-
- /*
- * Let Tk_MaintainGeometry take care of placing the window at
- * the right coordinates.
- */
- Tk_MaintainGeometry(pwPtr->proxywin, pwPtr->tkwin,
- x, y, sashWidth, sashHeight);
- break;
- }
+ /*
+ * Stash the proxy coordinates for future "proxy coord" calls.
+ */
+
+ pwPtr->proxyx = x;
+ pwPtr->proxyy = y;
+
+ /*
+ * Make sure the proxy window is higher in the stacking order than the
+ * slaves, so that it will be visible when drawn. It would be more
+ * correct to push the proxy window just high enough to appear above
+ * the highest slave, but it's much easier to just force it all the
+ * way to the top of the stacking order.
+ */
+
+ Tk_RestackWindow(pwPtr->proxywin, Above, NULL);
+
+ /*
+ * Let Tk_MaintainGeometry take care of placing the window at the
+ * right coordinates.
+ */
+
+ Tk_MaintainGeometry(pwPtr->proxywin, pwPtr->tkwin, x, y,
+ sashWidth, sashHeight);
+ break;
}
return TCL_OK;
@@ -2768,12 +2873,11 @@ PanedWindowProxyCommand(pwPtr, interp, objc, objv)
*
* ObjectIsEmpty --
*
- * This procedure tests whether the string value of an object is
- * empty.
+ * This function tests whether the string value of an object is empty.
*
* Results:
- * The return value is 1 if the string value of objPtr has length
- * zero, and 0 otherwise.
+ * The return value is 1 if the string value of objPtr has length zero,
+ * and 0 otherwise.
*
* Side effects:
* May cause object shimmering, since this function can force a
@@ -2783,8 +2887,8 @@ PanedWindowProxyCommand(pwPtr, interp, objc, objv)
*/
static int
-ObjectIsEmpty(objPtr)
- Tcl_Obj *objPtr; /* Object to test. May be NULL. */
+ObjectIsEmpty(
+ Tcl_Obj *objPtr) /* Object to test. May be NULL. */
{
int length;
@@ -2807,8 +2911,8 @@ ObjectIsEmpty(objPtr)
* within that record, compute the address of that slot.
*
* Results:
- * If offset is non-negative, returns the computed address; else,
- * returns NULL.
+ * If offset is non-negative, returns the computed address; else, returns
+ * NULL.
*
* Side effects:
* None.
@@ -2817,9 +2921,9 @@ ObjectIsEmpty(objPtr)
*/
static char *
-ComputeSlotAddress(recordPtr, offset)
- char *recordPtr; /* Pointer to the start of a record. */
- int offset; /* Offset of a slot within that record; may be < 0. */
+ComputeSlotAddress(
+ char *recordPtr, /* Pointer to the start of a record. */
+ int offset) /* Offset of a slot within that record; may be < 0. */
{
if (offset >= 0) {
return recordPtr + offset;
@@ -2833,25 +2937,25 @@ ComputeSlotAddress(recordPtr, offset)
*
* PanedWindowIdentifyCoords --
*
- * Given a pair of x,y coordinates, identify the panedwindow component
- * at that point, if any.
+ * Given a pair of x,y coordinates, identify the panedwindow component at
+ * that point, if any.
*
* Results:
* Standard Tcl result.
*
* Side effects:
- * Modifies the interpreter's result to contain either an empty list,
- * or a two element list of the form {sash n} or {handle n} to indicate
- * that the point lies within the n'th sash or handle.
+ * Modifies the interpreter's result to contain either an empty list, or
+ * a two element list of the form {sash n} or {handle n} to indicate that
+ * the point lies within the n'th sash or handle.
*
*----------------------------------------------------------------------
*/
static int
-PanedWindowIdentifyCoords(pwPtr, interp, x, y)
- PanedWindow *pwPtr; /* Information about the widget. */
- Tcl_Interp *interp; /* Interpreter in which to store result. */
- int x, y; /* Coordinates of the point to identify. */
+PanedWindowIdentifyCoords(
+ PanedWindow *pwPtr, /* Information about the widget. */
+ Tcl_Interp *interp, /* Interpreter in which to store result. */
+ int x, int y) /* Coordinates of the point to identify. */
{
Tcl_Obj *list;
int i, sashHeight, sashWidth, thisx, thisy;
@@ -2860,45 +2964,48 @@ PanedWindowIdentifyCoords(pwPtr, interp, x, y)
if (pwPtr->orient == ORIENT_HORIZONTAL) {
if (Tk_IsMapped(pwPtr->tkwin)) {
- sashHeight = Tk_Height(pwPtr->tkwin);
+ sashHeight = Tk_Height(pwPtr->tkwin);
} else {
- sashHeight = Tk_ReqHeight(pwPtr->tkwin);
+ sashHeight = Tk_ReqHeight(pwPtr->tkwin);
}
- sashHeight -= 2 * Tk_InternalBorderWidth(pwPtr->tkwin);
+ sashHeight -= 2 * Tk_InternalBorderWidth(pwPtr->tkwin);
if (pwPtr->showHandle && pwPtr->handleSize > pwPtr->sashWidth) {
- sashWidth = pwPtr->handleSize;
- lpad = (pwPtr->handleSize - pwPtr->sashWidth) / 2;
- rpad = pwPtr->handleSize - lpad;
- lpad += pwPtr->sashPad;
- rpad += pwPtr->sashPad;
+ sashWidth = pwPtr->handleSize;
+ lpad = (pwPtr->handleSize - pwPtr->sashWidth) / 2;
+ rpad = pwPtr->handleSize - lpad;
+ lpad += pwPtr->sashPad;
+ rpad += pwPtr->sashPad;
} else {
- sashWidth = pwPtr->sashWidth;
+ sashWidth = pwPtr->sashWidth;
lpad = rpad = pwPtr->sashPad;
}
- tpad = bpad = 0;
+ tpad = bpad = 0;
} else {
if (pwPtr->showHandle && pwPtr->handleSize > pwPtr->sashWidth) {
- sashHeight = pwPtr->handleSize;
- tpad = (pwPtr->handleSize - pwPtr->sashWidth) / 2;
- bpad = pwPtr->handleSize - tpad;
- tpad += pwPtr->sashPad;
- bpad += pwPtr->sashPad;
+ sashHeight = pwPtr->handleSize;
+ tpad = (pwPtr->handleSize - pwPtr->sashWidth) / 2;
+ bpad = pwPtr->handleSize - tpad;
+ tpad += pwPtr->sashPad;
+ bpad += pwPtr->sashPad;
} else {
- sashHeight = pwPtr->sashWidth;
+ sashHeight = pwPtr->sashWidth;
tpad = bpad = pwPtr->sashPad;
}
if (Tk_IsMapped(pwPtr->tkwin)) {
- sashWidth = Tk_Width(pwPtr->tkwin);
+ sashWidth = Tk_Width(pwPtr->tkwin);
} else {
- sashWidth = Tk_ReqWidth(pwPtr->tkwin);
+ sashWidth = Tk_ReqWidth(pwPtr->tkwin);
}
- sashWidth -= 2 * Tk_InternalBorderWidth(pwPtr->tkwin);
- lpad = rpad = 0;
+ sashWidth -= 2 * Tk_InternalBorderWidth(pwPtr->tkwin);
+ lpad = rpad = 0;
}
-
+
isHandle = 0;
found = -1;
for (i = 0; i < pwPtr->numSlaves - 1; i++) {
+ if (pwPtr->slaves[i]->hide) {
+ continue;
+ }
thisx = pwPtr->slaves[i]->sashx;
thisy = pwPtr->slaves[i]->sashy;
@@ -2909,6 +3016,7 @@ PanedWindowIdentifyCoords(pwPtr, interp, x, y)
/*
* Determine if the point is over the handle or the sash.
*/
+
if (pwPtr->showHandle) {
thisx = pwPtr->slaves[i]->handlex;
thisy = pwPtr->slaves[i]->handley;
@@ -2929,17 +3037,21 @@ PanedWindowIdentifyCoords(pwPtr, interp, x, y)
/*
* Set results.
*/
+
if (found != -1) {
Tcl_ListObjAppendElement(interp, list, Tcl_NewIntObj(found));
- if (isHandle) {
- Tcl_ListObjAppendElement(interp, list,
- Tcl_NewStringObj("handle", -1));
- } else {
- Tcl_ListObjAppendElement(interp, list,
- Tcl_NewStringObj("sash", -1));
- }
+ Tcl_ListObjAppendElement(interp, list, Tcl_NewStringObj(
+ (isHandle ? "handle" : "sash"), -1));
}
-
+
Tcl_SetObjResult(interp, list);
return TCL_OK;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkPlace.c b/generic/tkPlace.c
index 4c7f0f4..2f527ba 100644
--- a/generic/tkPlace.c
+++ b/generic/tkPlace.c
@@ -1,85 +1,86 @@
-/*
+/*
* tkPlace.c --
*
- * This file contains code to implement a simple geometry manager
- * for Tk based on absolute placement or "rubber-sheet" placement.
+ * This file contains code to implement a simple geometry manager for Tk
+ * based on absolute placement or "rubber-sheet" placement.
*
* Copyright (c) 1992-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
-
/*
* Border modes for relative placement:
*
- * BM_INSIDE: relative distances computed using area inside
- * all borders of master window.
- * BM_OUTSIDE: relative distances computed using outside area
- * that includes all borders of master.
- * BM_IGNORE: border issues are ignored: place relative to
- * master's actual window size.
+ * BM_INSIDE: relative distances computed using area inside all
+ * borders of master window.
+ * BM_OUTSIDE: relative distances computed using outside area that
+ * includes all borders of master.
+ * BM_IGNORE: border issues are ignored: place relative to master's
+ * actual window size.
*/
static CONST char *borderModeStrings[] = {
- "inside", "outside", "ignore", (char *) NULL
+ "inside", "outside", "ignore", NULL
};
typedef enum {BM_INSIDE, BM_OUTSIDE, BM_IGNORE} BorderMode;
/*
- * For each window whose geometry is managed by the placer there is
- * a structure of the following type:
+ * For each window whose geometry is managed by the placer there is a
+ * structure of the following type:
*/
typedef struct Slave {
Tk_Window tkwin; /* Tk's token for window. */
Tk_Window inTkwin; /* Token for the -in window. */
- struct Master *masterPtr; /* Pointer to information for window
- * relative to which tkwin is placed.
- * This isn't necessarily the logical
- * parent of tkwin. NULL means the
- * master was deleted or never assigned. */
- struct Slave *nextPtr; /* Next in list of windows placed relative
- * to same master (NULL for end of list). */
+ struct Master *masterPtr; /* Pointer to information for window relative
+ * to which tkwin is placed. This isn't
+ * necessarily the logical parent of tkwin.
+ * NULL means the master was deleted or never
+ * assigned. */
+ struct Slave *nextPtr; /* Next in list of windows placed relative to
+ * same master (NULL for end of list). */
Tk_OptionTable optionTable; /* Table that defines configuration options
* available for this command. */
/*
- * Geometry information for window; where there are both relative
- * and absolute values for the same attribute (e.g. x and relX) only
- * one of them is actually used, depending on flags.
+ * Geometry information for window; where there are both relative and
+ * absolute values for the same attribute (e.g. x and relX) only one of
+ * them is actually used, depending on flags.
*/
int x, y; /* X and Y pixel coordinates for tkwin. */
- Tcl_Obj *xPtr, *yPtr; /* Tcl_Obj rep's of x, y coords, to keep
- * pixel spec. information */
+ Tcl_Obj *xPtr, *yPtr; /* Tcl_Obj rep's of x, y coords, to keep pixel
+ * spec. information. */
double relX, relY; /* X and Y coordinates relative to size of
* master. */
int width, height; /* Absolute dimensions for tkwin. */
- Tcl_Obj *widthPtr; /* Tcl_Obj rep of width, to keep pixel spec */
- Tcl_Obj *heightPtr; /* Tcl_Obj rep of height, to keep pixel spec */
+ Tcl_Obj *widthPtr; /* Tcl_Obj rep of width, to keep pixel
+ * spec. */
+ Tcl_Obj *heightPtr; /* Tcl_Obj rep of height, to keep pixel
+ * spec. */
double relWidth, relHeight; /* Dimensions for tkwin relative to size of
* master. */
Tcl_Obj *relWidthPtr;
Tcl_Obj *relHeightPtr;
- Tk_Anchor anchor; /* Which point on tkwin is placed at the
- * given position. */
+ Tk_Anchor anchor; /* Which point on tkwin is placed at the given
+ * position. */
BorderMode borderMode; /* How to treat borders of master window. */
- int flags; /* Various flags; see below for bit
+ int flags; /* Various flags; see below for bit
* definitions. */
} Slave;
/*
* Type masks for options:
*/
+
#define IN_MASK 1
-static CONST Tk_OptionSpec optionSpecs[] = {
+static const Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_ANCHOR, "-anchor", NULL, NULL, "nw", -1,
Tk_Offset(Slave, anchor), 0, 0, 0},
{TK_OPTION_STRING_TABLE, "-bordermode", NULL, NULL, "inside", -1,
@@ -104,10 +105,9 @@ static CONST Tk_OptionSpec optionSpecs[] = {
Tk_Offset(Slave, x), TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-y", NULL, NULL, "0", Tk_Offset(Slave, yPtr),
Tk_Offset(Slave, y), TK_OPTION_NULL_OK, 0, 0},
- {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, 0, 0}
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};
-
+
/*
* Flag definitions for Slave structures:
*
@@ -123,14 +123,14 @@ static CONST Tk_OptionSpec optionSpecs[] = {
#define CHILD_REL_HEIGHT 8
/*
- * For each master window that has a slave managed by the placer there
- * is a structure of the following form:
+ * For each master window that has a slave managed by the placer there is a
+ * structure of the following form:
*/
typedef struct Master {
Tk_Window tkwin; /* Tk's token for master window. */
- struct Slave *slavePtr; /* First in linked list of slaves
- * placed relative to this master. */
+ struct Slave *slavePtr; /* First in linked list of slaves placed
+ * relative to this master. */
int *abortPtr; /* If non-NULL, it means that there is a nested
* call to RecomputePlacement already working on
* this window. *abortPtr may be set to 1 to
@@ -143,58 +143,54 @@ typedef struct Master {
/*
* Flag definitions for masters:
*
- * PARENT_RECONFIG_PENDING - 1 means that a call to RecomputePlacement
- * is already pending via a Do_When_Idle handler.
+ * PARENT_RECONFIG_PENDING - 1 means that a call to RecomputePlacement is
+ * already pending via a Do_When_Idle handler.
*/
#define PARENT_RECONFIG_PENDING 1
/*
- * The following structure is the official type record for the
- * placer:
+ * The following structure is the official type record for the placer:
*/
-static void PlaceRequestProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin));
-static void PlaceLostSlaveProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin));
+static void PlaceRequestProc(ClientData clientData,
+ Tk_Window tkwin);
+static void PlaceLostSlaveProc(ClientData clientData,
+ Tk_Window tkwin);
-static Tk_GeomMgr placerType = {
- "place", /* name */
- PlaceRequestProc, /* requestProc */
- PlaceLostSlaveProc, /* lostSlaveProc */
+static const Tk_GeomMgr placerType = {
+ "place", /* name */
+ PlaceRequestProc, /* requestProc */
+ PlaceLostSlaveProc, /* lostSlaveProc */
};
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static void SlaveStructureProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static int ConfigureSlave _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, Tk_OptionTable table,
- int objc, Tcl_Obj *CONST objv[]));
-static int PlaceInfoCommand _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin));
-static Slave * CreateSlave _ANSI_ARGS_((Tk_Window tkwin,
- Tk_OptionTable table));
-static void FreeSlave _ANSI_ARGS_((Slave *slavePtr));
-static Slave * FindSlave _ANSI_ARGS_((Tk_Window tkwin));
-static Master * CreateMaster _ANSI_ARGS_((Tk_Window tkwin));
-static Master * FindMaster _ANSI_ARGS_((Tk_Window tkwin));
-static void MasterStructureProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void RecomputePlacement _ANSI_ARGS_((ClientData clientData));
-static void UnlinkSlave _ANSI_ARGS_((Slave *slavePtr));
+static void SlaveStructureProc(ClientData clientData,
+ XEvent *eventPtr);
+static int ConfigureSlave(Tcl_Interp *interp, Tk_Window tkwin,
+ Tk_OptionTable table, int objc,
+ Tcl_Obj *CONST objv[]);
+static int PlaceInfoCommand(Tcl_Interp *interp, Tk_Window tkwin);
+static Slave * CreateSlave(Tk_Window tkwin, Tk_OptionTable table);
+static void FreeSlave(Slave *slavePtr);
+static Slave * FindSlave(Tk_Window tkwin);
+static Master * CreateMaster(Tk_Window tkwin);
+static Master * FindMaster(Tk_Window tkwin);
+static void MasterStructureProc(ClientData clientData,
+ XEvent *eventPtr);
+static void RecomputePlacement(ClientData clientData);
+static void UnlinkSlave(Slave *slavePtr);
/*
*--------------------------------------------------------------
*
* Tk_PlaceObjCmd --
*
- * This procedure is invoked to process the "place" Tcl
- * commands. See the user documentation for details on
- * what it does.
+ * This function is invoked to process the "place" Tcl commands. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -206,11 +202,11 @@ static void UnlinkSlave _ANSI_ARGS_((Slave *slavePtr));
*/
int
-Tk_PlaceObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* NULL. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tk_PlaceObjCmd(
+ ClientData clientData, /* NULL. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tk_Window tkwin;
Slave *slavePtr;
@@ -218,23 +214,22 @@ Tk_PlaceObjCmd(clientData, interp, objc, objv)
TkDisplay *dispPtr;
Tk_OptionTable optionTable;
static CONST char *optionStrings[] = {
- "configure", "forget", "info", "slaves", (char *) NULL
+ "configure", "forget", "info", "slaves", NULL
};
enum options { PLACE_CONFIGURE, PLACE_FORGET, PLACE_INFO, PLACE_SLAVES };
int index;
-
-
+
if (objc < 3) {
Tcl_WrongNumArgs(interp, 1, objv, "option|pathName args");
return TCL_ERROR;
}
/*
- * Create the option table for this widget class. If it has already
- * been created, the cached pointer will be returned.
+ * Create the option table for this widget class. If it has already been
+ * created, the cached pointer will be returned.
*/
- optionTable = Tk_CreateOptionTable(interp, optionSpecs);
+ optionTable = Tk_CreateOptionTable(interp, optionSpecs);
/*
* Handle special shortcut where window name is first argument.
@@ -262,8 +257,8 @@ Tk_PlaceObjCmd(clientData, interp, objc, objv)
}
/*
- * Handle more general case of option followed by window name followed
- * by possible additional arguments.
+ * Handle more general case of option followed by window name followed by
+ * possible additional arguments.
*/
tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
@@ -289,81 +284,74 @@ Tk_PlaceObjCmd(clientData, interp, objc, objv)
}
switch ((enum options) index) {
- case PLACE_CONFIGURE: {
+ case PLACE_CONFIGURE:
+ if (objc == 3 || objc == 4) {
Tcl_Obj *objPtr;
- if (objc == 3 || objc == 4) {
- slavePtr = FindSlave(tkwin);
- if (slavePtr == NULL) {
- return TCL_OK;
- }
- objPtr = Tk_GetOptionInfo(interp, (char *) slavePtr,
- optionTable,
- (objc == 4) ? objv[3] : (Tcl_Obj *) NULL, tkwin);
- if (objPtr == NULL) {
- return TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, objPtr);
- return TCL_OK;
- }
- } else {
- return ConfigureSlave(interp, tkwin, optionTable, objc-3,
- objv+3);
- }
- }
-
- case PLACE_FORGET: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "pathName");
- return TCL_ERROR;
- }
+
slavePtr = FindSlave(tkwin);
if (slavePtr == NULL) {
return TCL_OK;
}
- if ((slavePtr->masterPtr != NULL) &&
- (slavePtr->masterPtr->tkwin !=
- Tk_Parent(slavePtr->tkwin))) {
- Tk_UnmaintainGeometry(slavePtr->tkwin,
- slavePtr->masterPtr->tkwin);
- }
- UnlinkSlave(slavePtr);
- Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
- (char *) tkwin));
- Tk_DeleteEventHandler(tkwin, StructureNotifyMask,
- SlaveStructureProc, (ClientData) slavePtr);
- Tk_ManageGeometry(tkwin, (Tk_GeomMgr *) NULL, (ClientData) NULL);
- Tk_UnmapWindow(tkwin);
- FreeSlave(slavePtr);
- break;
- }
-
- case PLACE_INFO: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "pathName");
+ objPtr = Tk_GetOptionInfo(interp, (char *) slavePtr, optionTable,
+ (objc == 4) ? objv[3] : NULL, tkwin);
+ if (objPtr == NULL) {
return TCL_ERROR;
}
- return PlaceInfoCommand(interp, tkwin);
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
}
+ return ConfigureSlave(interp, tkwin, optionTable, objc-3, objv+3);
- case PLACE_SLAVES: {
- Master *masterPtr;
- Tcl_Obj *listPtr;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "pathName");
- return TCL_ERROR;
- }
- masterPtr = FindMaster(tkwin);
- if (masterPtr != NULL) {
- listPtr = Tcl_NewObj();
- for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
- slavePtr = slavePtr->nextPtr) {
- Tcl_ListObjAppendElement(interp, listPtr,
- Tcl_NewStringObj(Tk_PathName(slavePtr->tkwin),-1));
- }
- Tcl_SetObjResult(interp, listPtr);
+ case PLACE_FORGET:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pathName");
+ return TCL_ERROR;
+ }
+ slavePtr = FindSlave(tkwin);
+ if (slavePtr == NULL) {
+ return TCL_OK;
+ }
+ if ((slavePtr->masterPtr != NULL) &&
+ (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) {
+ Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
+ }
+ UnlinkSlave(slavePtr);
+ Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
+ (char *) tkwin));
+ Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,
+ (ClientData) slavePtr);
+ Tk_ManageGeometry(tkwin, NULL, (ClientData) NULL);
+ Tk_UnmapWindow(tkwin);
+ FreeSlave(slavePtr);
+ break;
+
+ case PLACE_INFO:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pathName");
+ return TCL_ERROR;
+ }
+ return PlaceInfoCommand(interp, tkwin);
+
+ case PLACE_SLAVES: {
+ Master *masterPtr;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pathName");
+ return TCL_ERROR;
+ }
+ masterPtr = FindMaster(tkwin);
+ if (masterPtr != NULL) {
+ Tcl_Obj *listPtr = Tcl_NewObj();
+
+ for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
+ slavePtr = slavePtr->nextPtr) {
+ Tcl_ListObjAppendElement(interp, listPtr,
+ Tcl_NewStringObj(Tk_PathName(slavePtr->tkwin),-1));
}
- break;
+ Tcl_SetObjResult(interp, listPtr);
}
+ break;
+ }
}
return TCL_OK;
@@ -374,8 +362,8 @@ Tk_PlaceObjCmd(clientData, interp, objc, objv)
*
* CreateSlave --
*
- * Given a Tk_Window token, find the Slave structure corresponding
- * to that token, creating a new one if necessary.
+ * Given a Tk_Window token, find the Slave structure corresponding to
+ * that token, creating a new one if necessary.
*
* Results:
* Pointer to the Slave structure.
@@ -387,34 +375,37 @@ Tk_PlaceObjCmd(clientData, interp, objc, objv)
*/
static Slave *
-CreateSlave(tkwin, table)
- Tk_Window tkwin; /* Token for desired slave. */
- Tk_OptionTable table;
+CreateSlave(
+ Tk_Window tkwin, /* Token for desired slave. */
+ Tk_OptionTable table)
{
Tcl_HashEntry *hPtr;
register Slave *slavePtr;
- int new;
- TkDisplay * dispPtr = ((TkWindow *) tkwin)->dispPtr;
-
- hPtr = Tcl_CreateHashEntry(&dispPtr->slaveTable, (char *) tkwin, &new);
- if (new) {
- slavePtr = (Slave *) ckalloc(sizeof(Slave));
- memset(slavePtr, 0, sizeof(Slave));
- slavePtr->tkwin = tkwin;
- slavePtr->inTkwin = None;
- slavePtr->anchor = TK_ANCHOR_NW;
- slavePtr->borderMode = BM_INSIDE;
- slavePtr->optionTable = table;
- Tcl_SetHashValue(hPtr, slavePtr);
- Tk_CreateEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,
- (ClientData) slavePtr);
- Tk_ManageGeometry(tkwin, &placerType, (ClientData) slavePtr);
- } else {
- slavePtr = (Slave *) Tcl_GetHashValue(hPtr);
+ int isNew;
+ TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
+
+ hPtr = Tcl_CreateHashEntry(&dispPtr->slaveTable, (char *) tkwin, &isNew);
+ if (!isNew) {
+ return (Slave *) Tcl_GetHashValue(hPtr);
}
+
+ /*
+ * No preexisting slave structure for that window, so make a new one and
+ * populate it with some default values.
+ */
+
+ slavePtr = (Slave *) ckalloc(sizeof(Slave));
+ memset(slavePtr, 0, sizeof(Slave));
+ slavePtr->tkwin = tkwin;
+ slavePtr->inTkwin = None;
+ slavePtr->anchor = TK_ANCHOR_NW;
+ slavePtr->borderMode = BM_INSIDE;
+ slavePtr->optionTable = table;
+ Tcl_SetHashValue(hPtr, slavePtr);
+ Tk_CreateEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,
+ (ClientData) slavePtr);
return slavePtr;
}
-
/*
*----------------------------------------------------------------------
@@ -433,22 +424,22 @@ CreateSlave(tkwin, table)
*/
static void
-FreeSlave(Slave *slavePtr)
+FreeSlave(
+ Slave *slavePtr)
{
Tk_FreeConfigOptions((char *) slavePtr, slavePtr->optionTable,
slavePtr->tkwin);
ckfree((char *) slavePtr);
}
-
/*
*----------------------------------------------------------------------
*
* FindSlave --
*
- * Given a Tk_Window token, find the Slave structure corresponding
- * to that token. This is purely a lookup function; it will not
- * create a record if one does not yet exist.
+ * Given a Tk_Window token, find the Slave structure corresponding to
+ * that token. This is purely a lookup function; it will not create a
+ * record if one does not yet exist.
*
* Results:
* Pointer to Slave structure; NULL if none exists.
@@ -460,12 +451,12 @@ FreeSlave(Slave *slavePtr)
*/
static Slave *
-FindSlave(tkwin)
- Tk_Window tkwin; /* Token for desired slave. */
+FindSlave(
+ Tk_Window tkwin) /* Token for desired slave. */
{
Tcl_HashEntry *hPtr;
register Slave *slavePtr;
- TkDisplay * dispPtr = ((TkWindow *) tkwin)->dispPtr;
+ TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin);
if (hPtr == NULL) {
@@ -480,8 +471,8 @@ FindSlave(tkwin)
*
* UnlinkSlave --
*
- * This procedure removes a slave window from the chain of slaves
- * in its master.
+ * This function removes a slave window from the chain of slaves in its
+ * master.
*
* Results:
* None.
@@ -493,8 +484,8 @@ FindSlave(tkwin)
*/
static void
-UnlinkSlave(slavePtr)
- Slave *slavePtr; /* Slave structure to be unlinked. */
+UnlinkSlave(
+ Slave *slavePtr) /* Slave structure to be unlinked. */
{
register Master *masterPtr;
register Slave *prevPtr;
@@ -506,10 +497,9 @@ UnlinkSlave(slavePtr)
if (masterPtr->slavePtr == slavePtr) {
masterPtr->slavePtr = slavePtr->nextPtr;
} else {
- for (prevPtr = masterPtr->slavePtr; ;
- prevPtr = prevPtr->nextPtr) {
+ for (prevPtr = masterPtr->slavePtr; ; prevPtr = prevPtr->nextPtr) {
if (prevPtr == NULL) {
- panic("UnlinkSlave couldn't find slave to unlink");
+ Tcl_Panic("UnlinkSlave couldn't find slave to unlink");
}
if (prevPtr->nextPtr == slavePtr) {
prevPtr->nextPtr = slavePtr->nextPtr;
@@ -529,8 +519,8 @@ UnlinkSlave(slavePtr)
*
* CreateMaster --
*
- * Given a Tk_Window token, find the Master structure corresponding
- * to that token, creating a new one if necessary.
+ * Given a Tk_Window token, find the Master structure corresponding to
+ * that token, creating a new one if necessary.
*
* Results:
* Pointer to the Master structure.
@@ -542,21 +532,21 @@ UnlinkSlave(slavePtr)
*/
static Master *
-CreateMaster(tkwin)
- Tk_Window tkwin; /* Token for desired master. */
+CreateMaster(
+ Tk_Window tkwin) /* Token for desired master. */
{
Tcl_HashEntry *hPtr;
register Master *masterPtr;
- int new;
- TkDisplay * dispPtr = ((TkWindow *) tkwin)->dispPtr;
+ int isNew;
+ TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
- hPtr = Tcl_CreateHashEntry(&dispPtr->masterTable, (char *) tkwin, &new);
- if (new) {
+ hPtr = Tcl_CreateHashEntry(&dispPtr->masterTable, (char *) tkwin, &isNew);
+ if (isNew) {
masterPtr = (Master *) ckalloc(sizeof(Master));
- masterPtr->tkwin = tkwin;
- masterPtr->slavePtr = NULL;
- masterPtr->abortPtr = NULL;
- masterPtr->flags = 0;
+ masterPtr->tkwin = tkwin;
+ masterPtr->slavePtr = NULL;
+ masterPtr->abortPtr = NULL;
+ masterPtr->flags = 0;
Tcl_SetHashValue(hPtr, masterPtr);
Tk_CreateEventHandler(masterPtr->tkwin, StructureNotifyMask,
MasterStructureProc, (ClientData) masterPtr);
@@ -571,13 +561,13 @@ CreateMaster(tkwin)
*
* FindMaster --
*
- * Given a Tk_Window token, find the Master structure corresponding
- * to that token. This is simply a lookup procedure; a new record
- * will not be created if one does not already exist.
+ * Given a Tk_Window token, find the Master structure corresponding to
+ * that token. This is simply a lookup function; a new record will not be
+ * created if one does not already exist.
*
* Results:
- * Pointer to the Master structure; NULL if one does not exist for
- * the given Tk_Window token.
+ * Pointer to the Master structure; NULL if one does not exist for the
+ * given Tk_Window token.
*
* Side effects:
* None.
@@ -586,12 +576,12 @@ CreateMaster(tkwin)
*/
static Master *
-FindMaster(tkwin)
- Tk_Window tkwin; /* Token for desired master. */
+FindMaster(
+ Tk_Window tkwin) /* Token for desired master. */
{
Tcl_HashEntry *hPtr;
register Master *masterPtr;
- TkDisplay * dispPtr = ((TkWindow *) tkwin)->dispPtr;
+ TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
hPtr = Tcl_FindHashEntry(&dispPtr->masterTable, (char *) tkwin);
if (hPtr == NULL) {
@@ -606,38 +596,37 @@ FindMaster(tkwin)
*
* ConfigureSlave --
*
- * This procedure is called to process an argv/argc list to
- * reconfigure the placement of a window.
+ * This function is called to process an argv/argc list to reconfigure
+ * the placement of a window.
*
* Results:
- * A standard Tcl result. If an error occurs then a message is
- * left in the interp's result.
+ * A standard Tcl result. If an error occurs then a message is left in
+ * the interp's result.
*
* Side effects:
- * Information in slavePtr may change, and slavePtr's master is
- * scheduled for reconfiguration.
+ * Information in slavePtr may change, and slavePtr's master is scheduled
+ * for reconfiguration.
*
*----------------------------------------------------------------------
*/
static int
-ConfigureSlave(interp, tkwin, table, objc, objv)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Window tkwin; /* Token for the window to manipulate. */
- Tk_OptionTable table; /* Token for option table. */
- int objc; /* Number of config arguments. */
- Tcl_Obj *CONST objv[]; /* Object values for arguments. */
+ConfigureSlave(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_Window tkwin, /* Token for the window to manipulate. */
+ Tk_OptionTable table, /* Token for option table. */
+ int objc, /* Number of config arguments. */
+ Tcl_Obj *CONST objv[]) /* Object values for arguments. */
{
register Master *masterPtr;
Tk_SavedOptions savedOptions;
int mask;
- int result = TCL_OK;
Slave *slavePtr;
-
+ Tk_Window masterWin = (Tk_Window) NULL;
+
if (Tk_TopWinHierarchy(tkwin)) {
Tcl_AppendResult(interp, "can't use placer on top-level window \"",
- Tk_PathName(tkwin), "\"; use wm command instead",
- (char *) NULL);
+ Tk_PathName(tkwin), "\"; use wm command instead", NULL);
return TCL_ERROR;
}
@@ -645,24 +634,51 @@ ConfigureSlave(interp, tkwin, table, objc, objv)
if (Tk_SetOptions(interp, (char *) slavePtr, table, objc, objv,
slavePtr->tkwin, &savedOptions, &mask) != TCL_OK) {
- Tk_RestoreSavedOptions(&savedOptions);
- result = TCL_ERROR;
- goto done;
+ goto error;
+ }
+
+ /*
+ * Set slave flags. First clear the field, then add bits as needed.
+ */
+
+ slavePtr->flags = 0;
+ if (slavePtr->heightPtr) {
+ slavePtr->flags |= CHILD_HEIGHT;
+ }
+
+ if (slavePtr->relHeightPtr) {
+ slavePtr->flags |= CHILD_REL_HEIGHT;
+ }
+
+ if (slavePtr->relWidthPtr) {
+ slavePtr->flags |= CHILD_REL_WIDTH;
+ }
+
+ if (slavePtr->widthPtr) {
+ slavePtr->flags |= CHILD_WIDTH;
}
- if (mask & IN_MASK) {
+ if (((mask & IN_MASK) == 0) && (slavePtr->masterPtr != NULL)) {
+ /*
+ * If no -in option was passed and the slave is already placed then
+ * just recompute the placement.
+ */
+
+ masterPtr = slavePtr->masterPtr;
+ goto scheduleLayout;
+ } else if (mask & IN_MASK) {
/* -in changed */
Tk_Window tkwin;
Tk_Window ancestor;
-
+
tkwin = slavePtr->inTkwin;
-
+
/*
- * Make sure that the new master is either the logical parent
- * of the slave or a descendant of that window, and that the
- * master and slave aren't the same.
+ * Make sure that the new master is either the logical parent of the
+ * slave or a descendant of that window, and that the master and slave
+ * aren't the same.
*/
-
+
for (ancestor = tkwin; ; ancestor = Tk_Parent(ancestor)) {
if (ancestor == Tk_Parent(slavePtr->tkwin)) {
break;
@@ -670,80 +686,72 @@ ConfigureSlave(interp, tkwin, table, objc, objv)
if (Tk_TopWinHierarchy(ancestor)) {
Tcl_AppendResult(interp, "can't place ",
Tk_PathName(slavePtr->tkwin), " relative to ",
- Tk_PathName(tkwin), (char *) NULL);
- result = TCL_ERROR;
- Tk_RestoreSavedOptions(&savedOptions);
- goto done;
+ Tk_PathName(tkwin), NULL);
+ goto error;
}
}
if (slavePtr->tkwin == tkwin) {
Tcl_AppendResult(interp, "can't place ",
Tk_PathName(slavePtr->tkwin), " relative to itself",
- (char *) NULL);
- result = TCL_ERROR;
- Tk_RestoreSavedOptions(&savedOptions);
- goto done;
+ NULL);
+ goto error;
}
if ((slavePtr->masterPtr != NULL)
&& (slavePtr->masterPtr->tkwin == tkwin)) {
/*
- * Re-using same old master. Nothing to do.
+ * Re-using same old master. Nothing to do.
*/
- } else {
- if ((slavePtr->masterPtr != NULL)
- && (slavePtr->masterPtr->tkwin
- != Tk_Parent(slavePtr->tkwin))) {
- Tk_UnmaintainGeometry(slavePtr->tkwin,
- slavePtr->masterPtr->tkwin);
- }
- UnlinkSlave(slavePtr);
- slavePtr->masterPtr = CreateMaster(tkwin);
- slavePtr->nextPtr = slavePtr->masterPtr->slavePtr;
- slavePtr->masterPtr->slavePtr = slavePtr;
+
+ masterPtr = slavePtr->masterPtr;
+ goto scheduleLayout;
+ }
+ if ((slavePtr->masterPtr != NULL) &&
+ (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) {
+ Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
}
+ UnlinkSlave(slavePtr);
+ masterWin = tkwin;
}
/*
- * Set slave flags. First clear the field, then add bits as needed.
+ * If there's no master specified for this slave, use its Tk_Parent.
*/
- slavePtr->flags = 0;
- if (slavePtr->heightPtr) {
- slavePtr->flags |= CHILD_HEIGHT;
- }
-
- if (slavePtr->relHeightPtr) {
- slavePtr->flags |= CHILD_REL_HEIGHT;
+ if (masterWin == NULL) {
+ masterWin = Tk_Parent(slavePtr->tkwin);
+ slavePtr->inTkwin = masterWin;
}
- if (slavePtr->relWidthPtr) {
- slavePtr->flags |= CHILD_REL_WIDTH;
- }
+ /*
+ * Manage the slave window in this master.
+ */
- if (slavePtr->widthPtr) {
- slavePtr->flags |= CHILD_WIDTH;
- }
+ masterPtr = CreateMaster(masterWin);
+ slavePtr->masterPtr = masterPtr;
+ slavePtr->nextPtr = masterPtr->slavePtr;
+ masterPtr->slavePtr = slavePtr;
+ Tk_ManageGeometry(slavePtr->tkwin, &placerType, (ClientData) slavePtr);
/*
- * If there's no master specified for this slave, use its Tk_Parent.
- * Then arrange for a placement recalculation in the master.
+ * Arrange for the master to be re-arranged at the first idle moment.
*/
+ scheduleLayout:
Tk_FreeSavedOptions(&savedOptions);
- done:
- masterPtr = slavePtr->masterPtr;
- if (masterPtr == NULL) {
- masterPtr = CreateMaster(Tk_Parent(slavePtr->tkwin));
- slavePtr->masterPtr = masterPtr;
- slavePtr->nextPtr = masterPtr->slavePtr;
- masterPtr->slavePtr = slavePtr;
- }
- slavePtr->inTkwin = masterPtr->tkwin;
+
if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
masterPtr->flags |= PARENT_RECONFIG_PENDING;
Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);
}
- return result;
+ return TCL_OK;
+
+ /*
+ * Error while processing some option, cleanup and return.
+ */
+
+ error:
+ Tk_RestoreSavedOptions(&savedOptions);
+ return TCL_ERROR;
}
/*
@@ -751,27 +759,27 @@ ConfigureSlave(interp, tkwin, table, objc, objv)
*
* PlaceInfoCommand --
*
- * Implementation of the [place info] subcommand. See the user
+ * Implementation of the [place info] subcommand. See the user
* documentation for information on what it does.
*
* Results:
* Standard Tcl result.
*
* Side effects:
- * If the given tkwin is managed by the placer, this function will
- * put information about that placement in the interp's result.
+ * If the given tkwin is managed by the placer, this function will put
+ * information about that placement in the interp's result.
*
*----------------------------------------------------------------------
*/
static int
-PlaceInfoCommand(interp, tkwin)
- Tcl_Interp *interp; /* Interp into which to place result. */
- Tk_Window tkwin; /* Token for the window to get info on. */
+PlaceInfoCommand(
+ Tcl_Interp *interp, /* Interp into which to place result. */
+ Tk_Window tkwin) /* Token for the window to get info on. */
{
char buffer[32 + TCL_INTEGER_SPACE];
Slave *slavePtr;
-
+
slavePtr = FindSlave(tkwin);
if (slavePtr == NULL) {
return TCL_OK;
@@ -781,38 +789,38 @@ PlaceInfoCommand(interp, tkwin)
Tcl_AppendElement(interp, Tk_PathName(slavePtr->masterPtr->tkwin));
}
sprintf(buffer, " -x %d", slavePtr->x);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
sprintf(buffer, " -relx %.4g", slavePtr->relX);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
sprintf(buffer, " -y %d", slavePtr->y);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
sprintf(buffer, " -rely %.4g", slavePtr->relY);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
if (slavePtr->flags & CHILD_WIDTH) {
sprintf(buffer, " -width %d", slavePtr->width);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
} else {
- Tcl_AppendResult(interp, " -width {}", (char *) NULL);
+ Tcl_AppendResult(interp, " -width {}", NULL);
}
if (slavePtr->flags & CHILD_REL_WIDTH) {
sprintf(buffer, " -relwidth %.4g", slavePtr->relWidth);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
} else {
- Tcl_AppendResult(interp, " -relwidth {}", (char *) NULL);
+ Tcl_AppendResult(interp, " -relwidth {}", NULL);
}
if (slavePtr->flags & CHILD_HEIGHT) {
sprintf(buffer, " -height %d", slavePtr->height);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
} else {
- Tcl_AppendResult(interp, " -height {}", (char *) NULL);
+ Tcl_AppendResult(interp, " -height {}", NULL);
}
if (slavePtr->flags & CHILD_REL_HEIGHT) {
sprintf(buffer, " -relheight %.4g", slavePtr->relHeight);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
} else {
- Tcl_AppendResult(interp, " -relheight {}", (char *) NULL);
+ Tcl_AppendResult(interp, " -relheight {}", NULL);
}
-
+
Tcl_AppendElement(interp, "-anchor");
Tcl_AppendElement(interp, Tk_NameOfAnchor(slavePtr->anchor));
Tcl_AppendElement(interp, "-bordermode");
@@ -825,8 +833,8 @@ PlaceInfoCommand(interp, tkwin)
*
* RecomputePlacement --
*
- * This procedure is called as a when-idle handler. It recomputes
- * the geometries of all the slaves of a given master.
+ * This function is called as a when-idle handler. It recomputes the
+ * geometries of all the slaves of a given master.
*
* Results:
* None.
@@ -838,8 +846,8 @@ PlaceInfoCommand(interp, tkwin)
*/
static void
-RecomputePlacement(clientData)
- ClientData clientData; /* Pointer to Master record. */
+RecomputePlacement(
+ ClientData clientData) /* Pointer to Master record. */
{
register Master *masterPtr = (Master *) clientData;
register Slave *slavePtr;
@@ -866,18 +874,17 @@ RecomputePlacement(clientData)
Tcl_Preserve((ClientData) masterPtr);
/*
- * Iterate over all the slaves for the master. Each slave's
- * geometry can be computed independently of the other slaves.
- * Changes to the window's structure could cause almost anything
- * to happen, including deleting the parent or child. If this
- * happens, we'll be told to abort.
+ * Iterate over all the slaves for the master. Each slave's geometry can
+ * be computed independently of the other slaves. Changes to the window's
+ * structure could cause almost anything to happen, including deleting the
+ * parent or child. If this happens, we'll be told to abort.
*/
for (slavePtr = masterPtr->slavePtr; slavePtr != NULL && !abort;
- slavePtr = slavePtr->nextPtr) {
+ slavePtr = slavePtr->nextPtr) {
/*
- * Step 1: compute size and borderwidth of master, taking into
- * account desired border mode.
+ * Step 1: compute size and borderwidth of master, taking into account
+ * desired border mode.
*/
masterX = masterY = 0;
@@ -886,18 +893,18 @@ RecomputePlacement(clientData)
if (slavePtr->borderMode == BM_INSIDE) {
masterX = Tk_InternalBorderLeft(masterPtr->tkwin);
masterY = Tk_InternalBorderTop(masterPtr->tkwin);
- masterWidth -= masterX + Tk_InternalBorderRight(masterPtr->tkwin);
- masterHeight -= masterY +
+ masterWidth -= masterX + Tk_InternalBorderRight(masterPtr->tkwin);
+ masterHeight -= masterY +
Tk_InternalBorderBottom(masterPtr->tkwin);
} else if (slavePtr->borderMode == BM_OUTSIDE) {
masterX = masterY = -Tk_Changes(masterPtr->tkwin)->border_width;
- masterWidth -= 2 * masterX;
- masterHeight -= 2 * masterY;
+ masterWidth -= 2 * masterX;
+ masterHeight -= 2 * masterY;
}
/*
- * Step 2: compute size of slave (outside dimensions including
- * border) and location of anchor point within master.
+ * Step 2: compute size of slave (outside dimensions including border)
+ * and location of anchor point within master.
*/
x1 = slavePtr->x + masterX + (slavePtr->relX*masterWidth);
@@ -911,11 +918,11 @@ RecomputePlacement(clientData)
}
if (slavePtr->flags & CHILD_REL_WIDTH) {
/*
- * The code below is a bit tricky. In order to round
- * correctly when both relX and relWidth are specified,
- * compute the location of the right edge and round that,
- * then compute width. If we compute the width and round
- * it, rounding errors in relX and relWidth accumulate.
+ * The code below is a bit tricky. In order to round correctly
+ * when both relX and relWidth are specified, compute the
+ * location of the right edge and round that, then compute
+ * width. If we compute the width and round it, rounding
+ * errors in relX and relWidth accumulate.
*/
x2 = x1 + (slavePtr->relWidth*masterWidth);
@@ -932,7 +939,7 @@ RecomputePlacement(clientData)
height += slavePtr->height;
}
if (slavePtr->flags & CHILD_REL_HEIGHT) {
- /*
+ /*
* See note above for rounding errors in width computation.
*/
@@ -946,47 +953,47 @@ RecomputePlacement(clientData)
}
/*
- * Step 3: adjust the x and y positions so that the desired
- * anchor point on the slave appears at that position. Also
- * adjust for the border mode and master's border.
+ * Step 3: adjust the x and y positions so that the desired anchor
+ * point on the slave appears at that position. Also adjust for the
+ * border mode and master's border.
*/
switch (slavePtr->anchor) {
- case TK_ANCHOR_N:
- x -= width/2;
- break;
- case TK_ANCHOR_NE:
- x -= width;
- break;
- case TK_ANCHOR_E:
- x -= width;
- y -= height/2;
- break;
- case TK_ANCHOR_SE:
- x -= width;
- y -= height;
- break;
- case TK_ANCHOR_S:
- x -= width/2;
- y -= height;
- break;
- case TK_ANCHOR_SW:
- y -= height;
- break;
- case TK_ANCHOR_W:
- y -= height/2;
- break;
- case TK_ANCHOR_NW:
- break;
- case TK_ANCHOR_CENTER:
- x -= width/2;
- y -= height/2;
- break;
+ case TK_ANCHOR_N:
+ x -= width/2;
+ break;
+ case TK_ANCHOR_NE:
+ x -= width;
+ break;
+ case TK_ANCHOR_E:
+ x -= width;
+ y -= height/2;
+ break;
+ case TK_ANCHOR_SE:
+ x -= width;
+ y -= height;
+ break;
+ case TK_ANCHOR_S:
+ x -= width/2;
+ y -= height;
+ break;
+ case TK_ANCHOR_SW:
+ y -= height;
+ break;
+ case TK_ANCHOR_W:
+ y -= height/2;
+ break;
+ case TK_ANCHOR_NW:
+ break;
+ case TK_ANCHOR_CENTER:
+ x -= width/2;
+ y -= height/2;
+ break;
}
/*
* Step 4: adjust width and height again to reflect inside dimensions
- * of window rather than outside. Also make sure that the width and
+ * of window rather than outside. Also make sure that the width and
* height aren't zero.
*/
@@ -1000,11 +1007,10 @@ RecomputePlacement(clientData)
}
/*
- * Step 5: reconfigure the window and map it if needed. If the
- * slave is a child of the master, we do this ourselves. If the
- * slave isn't a child of the master, let Tk_MaintainGeometry do
- * the work (it will re-adjust things as relevant windows map,
- * unmap, and move).
+ * Step 5: reconfigure the window and map it if needed. If the slave
+ * is a child of the master, we do this ourselves. If the slave isn't
+ * a child of the master, let Tk_MaintainGeometry do the work (it will
+ * re-adjust things as relevant windows map, unmap, and move).
*/
if (masterPtr->tkwin == Tk_Parent(slavePtr->tkwin)) {
@@ -1019,8 +1025,8 @@ RecomputePlacement(clientData)
}
/*
- * Don't map the slave unless the master is mapped: the slave
- * will get mapped later, when the master is mapped.
+ * Don't map the slave unless the master is mapped: the slave will
+ * get mapped later, when the master is mapped.
*/
if (Tk_IsMapped(masterPtr->tkwin)) {
@@ -1046,24 +1052,24 @@ RecomputePlacement(clientData)
*
* MasterStructureProc --
*
- * This procedure is invoked by the Tk event handler when
- * StructureNotify events occur for a master window.
+ * This function is invoked by the Tk event handler when StructureNotify
+ * events occur for a master window.
*
* Results:
* None.
*
* Side effects:
- * Structures get cleaned up if the window was deleted. If the
- * window was resized then slave geometries get recomputed.
+ * Structures get cleaned up if the window was deleted. If the window was
+ * resized then slave geometries get recomputed.
*
*----------------------------------------------------------------------
*/
static void
-MasterStructureProc(clientData, eventPtr)
- ClientData clientData; /* Pointer to Master structure for window
+MasterStructureProc(
+ ClientData clientData, /* Pointer to Master structure for window
* referred to by eventPtr. */
- XEvent *eventPtr; /* Describes what just happened. */
+ XEvent *eventPtr) /* Describes what just happened. */
{
register Master *masterPtr = (Master *) clientData;
register Slave *slavePtr, *nextPtr;
@@ -1094,8 +1100,8 @@ MasterStructureProc(clientData, eventPtr)
Tcl_EventuallyFree((ClientData) masterPtr, TCL_DYNAMIC);
} else if (eventPtr->type == MapNotify) {
/*
- * When a master gets mapped, must redo the geometry computation
- * so that all of its slaves get remapped.
+ * When a master gets mapped, must redo the geometry computation so
+ * that all of its slaves get remapped.
*/
if ((masterPtr->slavePtr != NULL)
@@ -1105,8 +1111,8 @@ MasterStructureProc(clientData, eventPtr)
}
} else if (eventPtr->type == UnmapNotify) {
/*
- * Unmap all of the slaves when the master gets unmapped,
- * so that they don't keep redisplaying themselves.
+ * Unmap all of the slaves when the master gets unmapped, so that they
+ * don't keep redisplaying themselves.
*/
for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
@@ -1121,8 +1127,8 @@ MasterStructureProc(clientData, eventPtr)
*
* SlaveStructureProc --
*
- * This procedure is invoked by the Tk event handler when
- * StructureNotify events occur for a slave window.
+ * This function is invoked by the Tk event handler when StructureNotify
+ * events occur for a slave window.
*
* Results:
* None.
@@ -1134,16 +1140,18 @@ MasterStructureProc(clientData, eventPtr)
*/
static void
-SlaveStructureProc(clientData, eventPtr)
- ClientData clientData; /* Pointer to Slave structure for window
+SlaveStructureProc(
+ ClientData clientData, /* Pointer to Slave structure for window
* referred to by eventPtr. */
- XEvent *eventPtr; /* Describes what just happened. */
+ XEvent *eventPtr) /* Describes what just happened. */
{
register Slave *slavePtr = (Slave *) clientData;
- TkDisplay * dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr;
+ TkDisplay *dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr;
if (eventPtr->type == DestroyNotify) {
- UnlinkSlave(slavePtr);
+ if (slavePtr->masterPtr != NULL) {
+ UnlinkSlave(slavePtr);
+ }
Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
(char *) slavePtr->tkwin));
FreeSlave(slavePtr);
@@ -1155,25 +1163,24 @@ SlaveStructureProc(clientData, eventPtr)
*
* PlaceRequestProc --
*
- * This procedure is invoked by Tk whenever a slave managed by us
- * changes its requested geometry.
+ * This function is invoked by Tk whenever a slave managed by us changes
+ * its requested geometry.
*
* Results:
* None.
*
* Side effects:
- * The window will get relayed out, if its requested size has
- * anything to do with its actual size.
+ * The window will get relayed out, if its requested size has anything to
+ * do with its actual size.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static void
-PlaceRequestProc(clientData, tkwin)
- ClientData clientData; /* Pointer to our record for slave. */
- Tk_Window tkwin; /* Window that changed its desired
- * size. */
+PlaceRequestProc(
+ ClientData clientData, /* Pointer to our record for slave. */
+ Tk_Window tkwin) /* Window that changed its desired size. */
{
Slave *slavePtr = (Slave *) clientData;
Master *masterPtr;
@@ -1197,8 +1204,8 @@ PlaceRequestProc(clientData, tkwin)
*
* PlaceLostSlaveProc --
*
- * This procedure is invoked by Tk whenever some other geometry
- * claims control over a slave that used to be managed by us.
+ * This function is invoked by Tk whenever some other geometry claims
+ * control over a slave that used to be managed by us.
*
* Results:
* None.
@@ -1211,22 +1218,30 @@ PlaceRequestProc(clientData, tkwin)
/* ARGSUSED */
static void
-PlaceLostSlaveProc(clientData, tkwin)
- ClientData clientData; /* Slave structure for slave window that
- * was stolen away. */
- Tk_Window tkwin; /* Tk's handle for the slave window. */
+PlaceLostSlaveProc(
+ ClientData clientData, /* Slave structure for slave window that was
+ * stolen away. */
+ Tk_Window tkwin) /* Tk's handle for the slave window. */
{
register Slave *slavePtr = (Slave *) clientData;
- TkDisplay * dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr;
+ 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(&dispPtr->slaveTable,
- (char *) tkwin));
+ Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
+ (char *) tkwin));
Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,
(ClientData) slavePtr);
FreeSlave(slavePtr);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkPlatDecls.h b/generic/tkPlatDecls.h
index 509b4f5..549ae30 100644
--- a/generic/tkPlatDecls.h
+++ b/generic/tkPlatDecls.h
@@ -30,55 +30,101 @@
*/
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#ifndef Tk_AttachHWND_TCL_DECLARED
+#define Tk_AttachHWND_TCL_DECLARED
/* 0 */
-EXTERN Window Tk_AttachHWND _ANSI_ARGS_((Tk_Window tkwin,
- HWND hwnd));
+EXTERN Window Tk_AttachHWND(Tk_Window tkwin, HWND hwnd);
+#endif
+#ifndef Tk_GetHINSTANCE_TCL_DECLARED
+#define Tk_GetHINSTANCE_TCL_DECLARED
/* 1 */
-EXTERN HINSTANCE Tk_GetHINSTANCE _ANSI_ARGS_((void));
+EXTERN HINSTANCE Tk_GetHINSTANCE(void);
+#endif
+#ifndef Tk_GetHWND_TCL_DECLARED
+#define Tk_GetHWND_TCL_DECLARED
/* 2 */
-EXTERN HWND Tk_GetHWND _ANSI_ARGS_((Window window));
+EXTERN HWND Tk_GetHWND(Window window);
+#endif
+#ifndef Tk_HWNDToWindow_TCL_DECLARED
+#define Tk_HWNDToWindow_TCL_DECLARED
/* 3 */
-EXTERN Tk_Window Tk_HWNDToWindow _ANSI_ARGS_((HWND hwnd));
+EXTERN Tk_Window Tk_HWNDToWindow(HWND hwnd);
+#endif
+#ifndef Tk_PointerEvent_TCL_DECLARED
+#define Tk_PointerEvent_TCL_DECLARED
/* 4 */
-EXTERN void Tk_PointerEvent _ANSI_ARGS_((HWND hwnd, int x, int y));
+EXTERN void Tk_PointerEvent(HWND hwnd, int x, int y);
+#endif
+#ifndef Tk_TranslateWinEvent_TCL_DECLARED
+#define Tk_TranslateWinEvent_TCL_DECLARED
/* 5 */
-EXTERN int Tk_TranslateWinEvent _ANSI_ARGS_((HWND hwnd,
- UINT message, WPARAM wParam, LPARAM lParam,
- LRESULT *result));
+EXTERN int Tk_TranslateWinEvent(HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam,
+ LRESULT *result);
+#endif
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
+#ifndef Tk_MacOSXSetEmbedHandler_TCL_DECLARED
+#define Tk_MacOSXSetEmbedHandler_TCL_DECLARED
/* 0 */
-EXTERN void Tk_MacOSXSetEmbedHandler _ANSI_ARGS_((
+EXTERN void Tk_MacOSXSetEmbedHandler(
Tk_MacOSXEmbedRegisterWinProc *registerWinProcPtr,
Tk_MacOSXEmbedGetGrafPortProc *getPortProcPtr,
Tk_MacOSXEmbedMakeContainerExistProc *containerExistProcPtr,
Tk_MacOSXEmbedGetClipProc *getClipProc,
- Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc));
+ Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc);
+#endif
+#ifndef Tk_MacOSXTurnOffMenus_TCL_DECLARED
+#define Tk_MacOSXTurnOffMenus_TCL_DECLARED
/* 1 */
-EXTERN void Tk_MacOSXTurnOffMenus _ANSI_ARGS_((void));
+EXTERN void Tk_MacOSXTurnOffMenus(void);
+#endif
+#ifndef Tk_MacOSXTkOwnsCursor_TCL_DECLARED
+#define Tk_MacOSXTkOwnsCursor_TCL_DECLARED
/* 2 */
-EXTERN void Tk_MacOSXTkOwnsCursor _ANSI_ARGS_((int tkOwnsIt));
+EXTERN void Tk_MacOSXTkOwnsCursor(int tkOwnsIt);
+#endif
+#ifndef TkMacOSXInitMenus_TCL_DECLARED
+#define TkMacOSXInitMenus_TCL_DECLARED
/* 3 */
-EXTERN void TkMacOSXInitMenus _ANSI_ARGS_((Tcl_Interp *interp));
+EXTERN void TkMacOSXInitMenus(Tcl_Interp *interp);
+#endif
+#ifndef TkMacOSXInitAppleEvents_TCL_DECLARED
+#define TkMacOSXInitAppleEvents_TCL_DECLARED
/* 4 */
-EXTERN void TkMacOSXInitAppleEvents _ANSI_ARGS_((
- Tcl_Interp *interp));
+EXTERN void TkMacOSXInitAppleEvents(Tcl_Interp *interp);
+#endif
+#ifndef TkGenWMConfigureEvent_TCL_DECLARED
+#define TkGenWMConfigureEvent_TCL_DECLARED
/* 5 */
-EXTERN void TkGenWMConfigureEvent _ANSI_ARGS_((Tk_Window tkwin,
- int x, int y, int width, int height,
- int flags));
+EXTERN void TkGenWMConfigureEvent(Tk_Window tkwin, int x, int y,
+ int width, int height, int flags);
+#endif
+#ifndef TkMacOSXInvalClipRgns_TCL_DECLARED
+#define TkMacOSXInvalClipRgns_TCL_DECLARED
/* 6 */
-EXTERN void TkMacOSXInvalClipRgns _ANSI_ARGS_((Tk_Window tkwin));
+EXTERN void TkMacOSXInvalClipRgns(Tk_Window tkwin);
+#endif
+#ifndef TkMacOSXGetDrawablePort_TCL_DECLARED
+#define TkMacOSXGetDrawablePort_TCL_DECLARED
/* 7 */
-EXTERN GWorldPtr TkMacOSXGetDrawablePort _ANSI_ARGS_((
- Drawable drawable));
+EXTERN VOID * TkMacOSXGetDrawablePort(Drawable drawable);
+#endif
+#ifndef TkMacOSXGetRootControl_TCL_DECLARED
+#define TkMacOSXGetRootControl_TCL_DECLARED
/* 8 */
-EXTERN ControlRef TkMacOSXGetRootControl _ANSI_ARGS_((
- Drawable drawable));
+EXTERN VOID * TkMacOSXGetRootControl(Drawable drawable);
+#endif
+#ifndef Tk_MacOSXSetupTkNotifier_TCL_DECLARED
+#define Tk_MacOSXSetupTkNotifier_TCL_DECLARED
/* 9 */
-EXTERN void Tk_MacOSXSetupTkNotifier _ANSI_ARGS_((void));
+EXTERN void Tk_MacOSXSetupTkNotifier(void);
+#endif
+#ifndef Tk_MacOSXIsAppInFront_TCL_DECLARED
+#define Tk_MacOSXIsAppInFront_TCL_DECLARED
/* 10 */
-EXTERN int Tk_MacOSXIsAppInFront _ANSI_ARGS_((void));
+EXTERN int Tk_MacOSXIsAppInFront(void);
+#endif
#endif /* AQUA */
typedef struct TkPlatStubs {
@@ -86,25 +132,25 @@ typedef struct TkPlatStubs {
struct TkPlatStubHooks *hooks;
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
- Window (*tk_AttachHWND) _ANSI_ARGS_((Tk_Window tkwin, HWND hwnd)); /* 0 */
- HINSTANCE (*tk_GetHINSTANCE) _ANSI_ARGS_((void)); /* 1 */
- HWND (*tk_GetHWND) _ANSI_ARGS_((Window window)); /* 2 */
- Tk_Window (*tk_HWNDToWindow) _ANSI_ARGS_((HWND hwnd)); /* 3 */
- void (*tk_PointerEvent) _ANSI_ARGS_((HWND hwnd, int x, int y)); /* 4 */
- int (*tk_TranslateWinEvent) _ANSI_ARGS_((HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)); /* 5 */
+ Window (*tk_AttachHWND) (Tk_Window tkwin, HWND hwnd); /* 0 */
+ HINSTANCE (*tk_GetHINSTANCE) (void); /* 1 */
+ HWND (*tk_GetHWND) (Window window); /* 2 */
+ Tk_Window (*tk_HWNDToWindow) (HWND hwnd); /* 3 */
+ void (*tk_PointerEvent) (HWND hwnd, int x, int y); /* 4 */
+ int (*tk_TranslateWinEvent) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); /* 5 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
- void (*tk_MacOSXSetEmbedHandler) _ANSI_ARGS_((Tk_MacOSXEmbedRegisterWinProc *registerWinProcPtr, Tk_MacOSXEmbedGetGrafPortProc *getPortProcPtr, Tk_MacOSXEmbedMakeContainerExistProc *containerExistProcPtr, Tk_MacOSXEmbedGetClipProc *getClipProc, Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc)); /* 0 */
- void (*tk_MacOSXTurnOffMenus) _ANSI_ARGS_((void)); /* 1 */
- void (*tk_MacOSXTkOwnsCursor) _ANSI_ARGS_((int tkOwnsIt)); /* 2 */
- void (*tkMacOSXInitMenus) _ANSI_ARGS_((Tcl_Interp *interp)); /* 3 */
- void (*tkMacOSXInitAppleEvents) _ANSI_ARGS_((Tcl_Interp *interp)); /* 4 */
- void (*tkGenWMConfigureEvent) _ANSI_ARGS_((Tk_Window tkwin, int x, int y, int width, int height, int flags)); /* 5 */
- void (*tkMacOSXInvalClipRgns) _ANSI_ARGS_((Tk_Window tkwin)); /* 6 */
- GWorldPtr (*tkMacOSXGetDrawablePort) _ANSI_ARGS_((Drawable drawable)); /* 7 */
- ControlRef (*tkMacOSXGetRootControl) _ANSI_ARGS_((Drawable drawable)); /* 8 */
- void (*tk_MacOSXSetupTkNotifier) _ANSI_ARGS_((void)); /* 9 */
- int (*tk_MacOSXIsAppInFront) _ANSI_ARGS_((void)); /* 10 */
+ void (*tk_MacOSXSetEmbedHandler) (Tk_MacOSXEmbedRegisterWinProc *registerWinProcPtr, Tk_MacOSXEmbedGetGrafPortProc *getPortProcPtr, Tk_MacOSXEmbedMakeContainerExistProc *containerExistProcPtr, Tk_MacOSXEmbedGetClipProc *getClipProc, Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc); /* 0 */
+ void (*tk_MacOSXTurnOffMenus) (void); /* 1 */
+ void (*tk_MacOSXTkOwnsCursor) (int tkOwnsIt); /* 2 */
+ void (*tkMacOSXInitMenus) (Tcl_Interp *interp); /* 3 */
+ void (*tkMacOSXInitAppleEvents) (Tcl_Interp *interp); /* 4 */
+ void (*tkGenWMConfigureEvent) (Tk_Window tkwin, int x, int y, int width, int height, int flags); /* 5 */
+ void (*tkMacOSXInvalClipRgns) (Tk_Window tkwin); /* 6 */
+ VOID * (*tkMacOSXGetDrawablePort) (Drawable drawable); /* 7 */
+ VOID * (*tkMacOSXGetRootControl) (Drawable drawable); /* 8 */
+ void (*tk_MacOSXSetupTkNotifier) (void); /* 9 */
+ int (*tk_MacOSXIsAppInFront) (void); /* 10 */
#endif /* AQUA */
} TkPlatStubs;
diff --git a/generic/tkPointer.c b/generic/tkPointer.c
index 7b2408f..dd4f7e6 100644
--- a/generic/tkPointer.c
+++ b/generic/tkPointer.c
@@ -1,15 +1,15 @@
-/*
+/*
* tkPointer.c --
*
- * This file contains functions for emulating the X server
- * pointer and grab state machine. This file is used by the
- * Mac and Windows platforms to generate appropriate enter/leave
- * events, and to update the global grab window information.
+ * This file contains functions for emulating the X server pointer and
+ * grab state machine. This file is used by the Mac and Windows platforms
+ * to generate appropriate enter/leave events, and to update the global
+ * grab window information.
*
* Copyright (c) 1996 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
@@ -24,8 +24,8 @@
#endif
/*
- * Mask that selects any of the state bits corresponding to buttons,
- * plus masks that select individual buttons' bits:
+ * Mask that selects any of the state bits corresponding to buttons, plus
+ * masks that select individual buttons' bits:
*/
#define ALL_BUTTONS \
@@ -36,15 +36,15 @@ static unsigned int buttonMasks[] = {
#define ButtonMask(b) (buttonMasks[(b)-Button1])
typedef struct ThreadSpecificData {
- TkWindow *grabWinPtr; /* Window that defines the top of the
- * grab tree in a global grab. */
- 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. */
+ TkWindow *grabWinPtr; /* Window that defines the top of the grab
+ * tree in a global grab. */
+ 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;
@@ -52,12 +52,11 @@ static Tcl_ThreadDataKey dataKey;
* Forward declarations of procedures used in this file.
*/
-static int GenerateEnterLeave _ANSI_ARGS_((TkWindow *winPtr,
- int x, int y, int state));
-static void InitializeEvent _ANSI_ARGS_((XEvent* eventPtr,
- TkWindow *winPtr, int type, int x, int y,
- int state, int detail));
-static void UpdateCursor _ANSI_ARGS_((TkWindow *winPtr));
+static int GenerateEnterLeave(TkWindow *winPtr, int x, int y,
+ int state);
+static void InitializeEvent(XEvent* eventPtr, TkWindow *winPtr,
+ int type, int x, int y, int state, int detail);
+static void UpdateCursor(TkWindow *winPtr);
/*
*----------------------------------------------------------------------
@@ -76,13 +75,13 @@ static void UpdateCursor _ANSI_ARGS_((TkWindow *winPtr));
*/
static void
-InitializeEvent(eventPtr, winPtr, type, x, y, state, detail)
- XEvent* eventPtr; /* Event structure to initialize. */
- TkWindow *winPtr; /* Window to make event relative to. */
- int type; /* Message type. */
- int x, y; /* Root coords of event. */
- int state; /* State flags. */
- int detail; /* Detail value. */
+InitializeEvent(
+ XEvent *eventPtr, /* Event structure to initialize. */
+ TkWindow *winPtr, /* Window to make event relative to. */
+ int type, /* Message type. */
+ int x, int y, /* Root coords of event. */
+ int state, /* State flags. */
+ int detail) /* Detail value. */
{
eventPtr->type = type;
eventPtr->xany.serial = LastKnownRequestProcessed(winPtr->display);
@@ -95,22 +94,22 @@ InitializeEvent(eventPtr, winPtr, type, x, y, state, detail)
eventPtr->xcrossing.y_root = y;
switch (type) {
- case EnterNotify:
- case LeaveNotify:
- eventPtr->xcrossing.mode = NotifyNormal;
- eventPtr->xcrossing.state = state;
- eventPtr->xcrossing.detail = detail;
- eventPtr->xcrossing.focus = False;
- break;
- case MotionNotify:
- eventPtr->xmotion.state = state;
- eventPtr->xmotion.is_hint = detail;
- break;
- case ButtonPress:
- case ButtonRelease:
- eventPtr->xbutton.state = state;
- eventPtr->xbutton.button = detail;
- break;
+ case EnterNotify:
+ case LeaveNotify:
+ eventPtr->xcrossing.mode = NotifyNormal;
+ eventPtr->xcrossing.state = state;
+ eventPtr->xcrossing.detail = detail;
+ eventPtr->xcrossing.focus = False;
+ break;
+ case MotionNotify:
+ eventPtr->xmotion.state = state;
+ eventPtr->xmotion.is_hint = detail;
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ eventPtr->xbutton.state = state;
+ eventPtr->xbutton.button = detail;
+ break;
}
TkChangeEventWindow(eventPtr, winPtr);
}
@@ -120,8 +119,8 @@ InitializeEvent(eventPtr, winPtr, type, x, y, state, detail)
*
* GenerateEnterLeave --
*
- * Update the current mouse window and position, and generate
- * any enter/leave events that are needed.
+ * Update the current mouse window and position, and generate any
+ * enter/leave events that are needed.
*
* Results:
* Returns 1 if enter/leave events were generated.
@@ -133,14 +132,14 @@ InitializeEvent(eventPtr, winPtr, type, x, y, state, detail)
*/
static int
-GenerateEnterLeave(winPtr, x, y, state)
- TkWindow *winPtr; /* Current Tk window (or NULL). */
- int x,y; /* Current mouse position in root coords. */
- int state; /* State flags. */
+GenerateEnterLeave(
+ TkWindow *winPtr, /* Current Tk window (or NULL). */
+ int x, int y, /* Current mouse position in root coords. */
+ int state) /* State flags. */
{
int crossed = 0; /* 1 if mouse crossed a window boundary */
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
TkWindow *restrictWinPtr = tsdPtr->restrictWinPtr;
TkWindow *lastWinPtr = tsdPtr->lastWinPtr;
@@ -152,8 +151,8 @@ GenerateEnterLeave(winPtr, x, y, state)
oldPos = TkPositionInTree(lastWinPtr, restrictWinPtr);
/*
- * Check if the mouse crossed into or out of the restrict
- * window. If so, we need to generate an Enter or Leave event.
+ * Check if the mouse crossed into or out of the restrict window.
+ * If so, we need to generate an Enter or Leave event.
*/
if ((newPos != oldPos) && ((newPos == TK_GRAB_IN_TREE)
@@ -213,8 +212,8 @@ GenerateEnterLeave(winPtr, x, y, state)
*
* Tk_UpdatePointer --
*
- * This function updates the pointer state machine given an
- * the current window, position and modifier state.
+ * This function updates the pointer state machine given an the current
+ * window, position and modifier state.
*
* Results:
* None.
@@ -226,14 +225,14 @@ GenerateEnterLeave(winPtr, x, y, state)
*/
void
-Tk_UpdatePointer(tkwin, x, y, state)
- Tk_Window tkwin; /* Window to which pointer event
- * is reported. May be NULL. */
- int x, y; /* Pointer location in root coords. */
- int state; /* Modifier state mask. */
+Tk_UpdatePointer(
+ Tk_Window tkwin, /* Window to which pointer event is reported.
+ * May be NULL. */
+ int x, int y, /* Pointer location in root coords. */
+ int state) /* Modifier state mask. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
TkWindow *winPtr = (TkWindow *)tkwin;
TkWindow *targetWinPtr;
XPoint pos;
@@ -245,15 +244,15 @@ Tk_UpdatePointer(tkwin, x, y, state)
pos.y = y;
/*
- * Use the current keyboard state, but the old mouse button
- * state since we haven't generated the button events yet.
+ * Use the current keyboard state, but the old mouse button state since we
+ * haven't generated the button events yet.
*/
tsdPtr->lastState = (state & ~ALL_BUTTONS) | (tsdPtr->lastState
& ALL_BUTTONS);
/*
- * Generate Enter/Leave events. If the pointer has crossed window
+ * Generate Enter/Leave events. If the pointer has crossed window
* boundaries, update the current mouse position so we don't generate
* redundant motion events.
*/
@@ -267,20 +266,19 @@ Tk_UpdatePointer(tkwin, x, y, state)
* between the current button state and the last known button state.
*/
- for (b = Button1; b <= Button3; b++) {
+ for (b = Button1; b <= Button5; b++) {
mask = ButtonMask(b);
if (changes & mask) {
- if (state & mask) {
+ if (state & mask) {
type = ButtonPress;
- /*
+ /*
* ButtonPress - Set restrict window if we aren't grabbed, or
* if this is the first button down.
*/
if (!tsdPtr->restrictWinPtr) {
if (!tsdPtr->grabWinPtr) {
-
/*
* Mouse is not grabbed, so set a button grab.
*/
@@ -289,10 +287,9 @@ Tk_UpdatePointer(tkwin, x, y, state)
TkpSetCapture(tsdPtr->restrictWinPtr);
} else if ((tsdPtr->lastState & ALL_BUTTONS) == 0) {
-
/*
- * Mouse is in a non-button grab, so ensure
- * the button grab is inside the grab tree.
+ * Mouse is in a non-button grab, so ensure the button
+ * grab is inside the grab tree.
*/
if (TkPositionInTree(winPtr, tsdPtr->grabWinPtr)
@@ -308,7 +305,7 @@ Tk_UpdatePointer(tkwin, x, y, state)
} else {
type = ButtonRelease;
- /*
+ /*
* ButtonRelease - Release the mouse capture and clear the
* restrict window when the last button is released. If we
* are in a global grab, restore the grab window capture.
@@ -319,9 +316,9 @@ Tk_UpdatePointer(tkwin, x, y, state)
}
/*
- * If we are releasing a restrict window, then we need
- * to send the button event followed by mouse motion from
- * the restrict window to the current mouse position.
+ * If we are releasing a restrict window, then we need to send
+ * the button event followed by mouse motion from the restrict
+ * window to the current mouse position.
*/
if (tsdPtr->restrictWinPtr) {
@@ -335,14 +332,14 @@ Tk_UpdatePointer(tkwin, x, y, state)
GenerateEnterLeave(winPtr, x, y, tsdPtr->lastState);
tsdPtr->lastPos = pos;
continue;
- }
+ }
}
/*
- * If a restrict window is set, make sure the pointer event
- * is reported relative to that window. Otherwise, if a
- * global grab is in effect then events outside of windows
- * managed by Tk should be reported to the grab window.
+ * If a restrict window is set, make sure the pointer event is
+ * reported relative to that window. Otherwise, if a global grab
+ * is in effect then events outside of windows managed by Tk
+ * should be reported to the grab window.
*/
if (tsdPtr->restrictWinPtr) {
@@ -357,7 +354,7 @@ Tk_UpdatePointer(tkwin, x, y, state)
* If we still have a target window, send the event.
*/
- if (winPtr != NULL) {
+ if (targetWinPtr != NULL) {
InitializeEvent(&event, targetWinPtr, type, x, y,
tsdPtr->lastState, b);
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
@@ -368,7 +365,7 @@ Tk_UpdatePointer(tkwin, x, y, state)
*/
tsdPtr->lastState = (type == ButtonPress)
- ? (tsdPtr->lastState | mask) : (tsdPtr->lastState & ~mask);
+ ? (tsdPtr->lastState | mask) : (tsdPtr->lastState & ~mask);
tsdPtr->lastPos = pos;
}
}
@@ -388,8 +385,8 @@ Tk_UpdatePointer(tkwin, x, y, state)
UpdateCursor(targetWinPtr);
/*
- * If no other events caused the position to be updated,
- * generate a motion event.
+ * If no other events caused the position to be updated, generate a motion
+ * event.
*/
if (tsdPtr->lastPos.x != pos.x || tsdPtr->lastPos.y != pos.y) {
@@ -413,42 +410,41 @@ Tk_UpdatePointer(tkwin, x, y, state)
*
* XGrabPointer --
*
- * Capture the mouse so event are reported outside of toplevels.
- * Note that this is a very limited implementation that only
- * supports GrabModeAsync and owner_events True.
+ * Capture the mouse so event are reported outside of toplevels. Note
+ * that this is a very limited implementation that only supports
+ * GrabModeAsync and owner_events True.
*
* Results:
* Always returns GrabSuccess.
*
* Side effects:
- * Turns on mouse capture, sets the global grab pointer, and
- * clears any window restrictions.
+ * Turns on mouse capture, sets the global grab pointer, and clears any
+ * window restrictions.
*
*----------------------------------------------------------------------
*/
int
-XGrabPointer(display, grab_window, owner_events, event_mask, pointer_mode,
- keyboard_mode, confine_to, cursor, time)
- Display* display;
- Window grab_window;
- Bool owner_events;
- unsigned int event_mask;
- int pointer_mode;
- int keyboard_mode;
- Window confine_to;
- Cursor cursor;
- Time time;
+XGrabPointer(
+ Display *display,
+ Window grab_window,
+ Bool owner_events,
+ unsigned int event_mask,
+ int pointer_mode,
+ int keyboard_mode,
+ Window confine_to,
+ Cursor cursor,
+ Time time)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
display->request++;
tsdPtr->grabWinPtr = (TkWindow *) Tk_IdToWindow(display, grab_window);
tsdPtr->restrictWinPtr = NULL;
TkpSetCapture(tsdPtr->grabWinPtr);
- if (TkPositionInTree(tsdPtr->lastWinPtr, tsdPtr->grabWinPtr)
- != TK_GRAB_IN_TREE) {
+ if (TkPositionInTree(tsdPtr->lastWinPtr, tsdPtr->grabWinPtr)
+ != TK_GRAB_IN_TREE) {
UpdateCursor(tsdPtr->grabWinPtr);
}
return GrabSuccess;
@@ -471,12 +467,12 @@ XGrabPointer(display, grab_window, owner_events, event_mask, pointer_mode,
*/
int
-XUngrabPointer(display, time)
- Display* display;
- Time time;
+XUngrabPointer(
+ Display *display,
+ Time time)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
display->request++;
tsdPtr->grabWinPtr = NULL;
@@ -503,11 +499,11 @@ XUngrabPointer(display, time)
*/
void
-TkPointerDeadWindow(winPtr)
- TkWindow *winPtr;
+TkPointerDeadWindow(
+ TkWindow *winPtr)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (winPtr == tsdPtr->lastWinPtr) {
tsdPtr->lastWinPtr = NULL;
@@ -528,8 +524,8 @@ TkPointerDeadWindow(winPtr)
*
* UpdateCursor --
*
- * Set the windows global cursor to the cursor associated with
- * the given Tk window.
+ * Set the windows global cursor to the cursor associated with the given
+ * Tk window.
*
* Results:
* None.
@@ -541,17 +537,16 @@ TkPointerDeadWindow(winPtr)
*/
static void
-UpdateCursor(winPtr)
- TkWindow *winPtr;
+UpdateCursor(
+ TkWindow *winPtr)
{
Cursor cursor = None;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
- * A window inherits its cursor from its parent if it doesn't
- * have one of its own. Top level windows inherit the default
- * cursor.
+ * A window inherits its cursor from its parent if it doesn't have one of
+ * its own. Top level windows inherit the default cursor.
*/
tsdPtr->cursorWinPtr = winPtr;
@@ -572,10 +567,9 @@ UpdateCursor(winPtr)
*
* XDefineCursor --
*
- * This function is called to update the cursor on a window.
- * Since the mouse might be in the specified window, we need to
- * check the specified window against the current mouse position
- * and grab state.
+ * This function is called to update the cursor on a window. Since the
+ * mouse might be in the specified window, we need to check the specified
+ * window against the current mouse position and grab state.
*
* Results:
* None.
@@ -587,14 +581,14 @@ UpdateCursor(winPtr)
*/
int
-XDefineCursor(display, w, cursor)
- Display* display;
- Window w;
- Cursor cursor;
+XDefineCursor(
+ Display *display,
+ Window w,
+ Cursor cursor)
{
TkWindow *winPtr = (TkWindow *)Tk_IdToWindow(display, w);
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (tsdPtr->cursorWinPtr == winPtr) {
UpdateCursor(winPtr);
@@ -608,10 +602,10 @@ XDefineCursor(display, w, cursor)
*
* TkGenerateActivateEvents --
*
- * This function is called by the Mac and Windows window manager
- * routines when a toplevel window is activated or deactivated.
- * Activate/Deactivate events will be sent to every subwindow of
- * the toplevel followed by a FocusIn/FocusOut message.
+ * This function is called by the Mac and Windows window manager routines
+ * when a toplevel window is activated or deactivated.
+ * Activate/Deactivate events will be sent to every subwindow of the
+ * toplevel followed by a FocusIn/FocusOut message.
*
* Results:
* None.
@@ -623,16 +617,16 @@ XDefineCursor(display, w, cursor)
*/
void
-TkGenerateActivateEvents(winPtr, active)
- TkWindow *winPtr; /* Toplevel to activate. */
- int active; /* Non-zero if the window is being
- * activated, else 0.*/
+TkGenerateActivateEvents(
+ TkWindow *winPtr, /* Toplevel to activate. */
+ int active) /* Non-zero if the window is being activated,
+ * else 0.*/
{
XEvent event;
-
- /*
- * Generate Activate and Deactivate events. This event
- * is sent to every subwindow in a toplevel window.
+
+ /*
+ * Generate Activate and Deactivate events. This event is sent to every
+ * subwindow in a toplevel window.
*/
event.xany.serial = winPtr->display->request++;
@@ -642,5 +636,12 @@ TkGenerateActivateEvents(winPtr, active)
event.xany.type = active ? ActivateNotify : DeactivateNotify;
TkQueueEventForAllChildren(winPtr, &event);
-
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkRectOval.c b/generic/tkRectOval.c
index b7ab331..c9cd7cb 100644
--- a/generic/tkRectOval.c
+++ b/generic/tkRectOval.c
@@ -1,20 +1,17 @@
-/*
+/*
* tkRectOval.c --
*
- * This file implements rectangle and oval items for canvas
- * widgets.
+ * This file implements rectangle and oval items for canvas widgets.
*
* Copyright (c) 1991-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <stdio.h>
-#include "tk.h"
#include "tkInt.h"
-#include "tkPort.h"
#include "tkCanvas.h"
/*
@@ -23,18 +20,22 @@
typedef struct RectOvalItem {
Tk_Item header; /* Generic stuff that's the same for all
- * types. MUST BE FIRST IN STRUCTURE. */
+ * types. MUST BE FIRST IN STRUCTURE. */
Tk_Outline outline; /* Outline structure */
double bbox[4]; /* Coordinates of bounding box for rectangle
- * or oval (x1, y1, x2, y2). Item includes
- * x1 and x2 but not y1 and y2. */
+ * or oval (x1, y1, x2, y2). Item includes x1
+ * and x2 but not y1 and y2. */
Tk_TSOffset tsoffset;
XColor *fillColor; /* Color for filling rectangle/oval. */
- XColor *activeFillColor; /* Color for filling rectangle/oval if state is active. */
- XColor *disabledFillColor; /* Color for filling rectangle/oval if state is disabled. */
+ XColor *activeFillColor; /* Color for filling rectangle/oval if state
+ * is active. */
+ XColor *disabledFillColor; /* Color for filling rectangle/oval if state
+ * is disabled. */
Pixmap fillStipple; /* Stipple bitmap for filling item. */
- Pixmap activeFillStipple; /* Stipple bitmap for filling item if state is active. */
- Pixmap disabledFillStipple; /* Stipple bitmap for filling item if state is disabled. */
+ Pixmap activeFillStipple; /* Stipple bitmap for filling item if state is
+ * active. */
+ Pixmap disabledFillStipple; /* Stipple bitmap for filling item if state is
+ * disabled. */
GC fillGC; /* Graphics context for filling item. */
} RectOvalItem;
@@ -64,160 +65,150 @@ static Tk_CustomOption pixelOption = {
};
static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_CUSTOM, "-activedash", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(RectOvalItem, outline.activeDash),
+ {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
+ NULL, Tk_Offset(RectOvalItem, outline.activeDash),
TK_CONFIG_NULL_OK, &dashOption},
- {TK_CONFIG_COLOR, "-activefill", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(RectOvalItem, activeFillColor),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_COLOR, "-activeoutline", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(RectOvalItem, outline.activeColor),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-activeoutlinestipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(RectOvalItem, outline.activeStipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-activestipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(RectOvalItem, activeFillStipple),
+ {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
+ NULL, Tk_Offset(RectOvalItem, activeFillColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
+ NULL, Tk_Offset(RectOvalItem, outline.activeColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
+ NULL, Tk_Offset(RectOvalItem, outline.activeStipple),
TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-activewidth", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
+ NULL, Tk_Offset(RectOvalItem, activeFillStipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
"0.0", Tk_Offset(RectOvalItem, outline.activeWidth),
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
- {TK_CONFIG_CUSTOM, "-dash", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(RectOvalItem, outline.dash),
+ {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
+ NULL, Tk_Offset(RectOvalItem, outline.dash),
TK_CONFIG_NULL_OK, &dashOption},
- {TK_CONFIG_PIXELS, "-dashoffset", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
"0", Tk_Offset(RectOvalItem, outline.offset),
TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_CUSTOM, "-disableddash", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(RectOvalItem, outline.disabledDash),
+ {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
+ NULL, Tk_Offset(RectOvalItem, outline.disabledDash),
TK_CONFIG_NULL_OK, &dashOption},
- {TK_CONFIG_COLOR, "-disabledfill", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(RectOvalItem, disabledFillColor),
+ {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
+ NULL, Tk_Offset(RectOvalItem, disabledFillColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
+ NULL, Tk_Offset(RectOvalItem, outline.disabledColor),
TK_CONFIG_NULL_OK},
- {TK_CONFIG_COLOR, "-disabledoutline", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(RectOvalItem, outline.disabledColor),
+ {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
+ NULL, Tk_Offset(RectOvalItem, outline.disabledStipple),
TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-disabledoutlinestipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(RectOvalItem, outline.disabledStipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-disabledstipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(RectOvalItem, disabledFillStipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_PIXELS, "-disabledwidth", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
+ NULL, Tk_Offset(RectOvalItem, disabledFillStipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_PIXELS, "-disabledwidth", NULL, NULL,
"0.0", Tk_Offset(RectOvalItem, outline.disabledWidth),
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
- {TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(RectOvalItem, fillColor), TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-offset", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_COLOR, "-fill", NULL, NULL,
+ NULL, Tk_Offset(RectOvalItem, fillColor), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
"0,0", Tk_Offset(RectOvalItem, tsoffset),
TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
- {TK_CONFIG_COLOR, "-outline", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_COLOR, "-outline", NULL, NULL,
"black", Tk_Offset(RectOvalItem, outline.color), TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-outlineoffset", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
"0,0", Tk_Offset(RectOvalItem, outline.tsoffset),
TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
- {TK_CONFIG_BITMAP, "-outlinestipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(RectOvalItem, outline.stipple),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(Tk_Item, state),TK_CONFIG_NULL_OK,
- &stateOption},
- {TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(RectOvalItem, fillStipple), TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
- {TK_CONFIG_CUSTOM, "-width", (char *) NULL, (char *) NULL,
+ {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL,
+ NULL, Tk_Offset(RectOvalItem, outline.stipple), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
+ NULL, Tk_Offset(Tk_Item, state),TK_CONFIG_NULL_OK, &stateOption},
+ {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
+ NULL, Tk_Offset(RectOvalItem, fillStipple),TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
+ NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
+ {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
"1.0", Tk_Offset(RectOvalItem, outline.width),
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+ {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};
/*
- * Prototypes for procedures defined in this file:
+ * Prototypes for functions defined in this file:
*/
-static void ComputeRectOvalBbox _ANSI_ARGS_((Tk_Canvas canvas,
- RectOvalItem *rectOvalPtr));
-static int ConfigureRectOval _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
- Tcl_Obj *CONST objv[], int flags));
-static int CreateRectOval _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, struct Tk_Item *itemPtr,
- int objc, Tcl_Obj *CONST objv[]));
-static void DeleteRectOval _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, Display *display));
-static void DisplayRectOval _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, Display *display, Drawable dst,
- int x, int y, int width, int height));
-static int OvalToArea _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *areaPtr));
-static double OvalToPoint _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *pointPtr));
-static int RectOvalCoords _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
- Tcl_Obj *CONST objv[]));
-static int RectOvalToPostscript _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));
-static int RectToArea _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *areaPtr));
-static double RectToPoint _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double *pointPtr));
-static void ScaleRectOval _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double originX, double originY,
- double scaleX, double scaleY));
-static void TranslateRectOval _ANSI_ARGS_((Tk_Canvas canvas,
- Tk_Item *itemPtr, double deltaX, double deltaY));
+static void ComputeRectOvalBbox(Tk_Canvas canvas,
+ RectOvalItem *rectOvalPtr);
+static int ConfigureRectOval(Tcl_Interp *interp, Tk_Canvas canvas,
+ Tk_Item *itemPtr, int objc, Tcl_Obj *CONST objv[],
+ int flags);
+static int CreateRectOval(Tcl_Interp *interp, Tk_Canvas canvas,
+ Tk_Item *itemPtr, int objc, Tcl_Obj *CONST objv[]);
+static void DeleteRectOval(Tk_Canvas canvas, Tk_Item *itemPtr,
+ Display *display);
+static void DisplayRectOval(Tk_Canvas canvas, Tk_Item *itemPtr,
+ Display *display, Drawable dst, int x, int y,
+ int width, int height);
+static int OvalToArea(Tk_Canvas canvas, Tk_Item *itemPtr,
+ double *areaPtr);
+static double OvalToPoint(Tk_Canvas canvas, Tk_Item *itemPtr,
+ double *pointPtr);
+static int RectOvalCoords(Tcl_Interp *interp, Tk_Canvas canvas,
+ Tk_Item *itemPtr, int objc, Tcl_Obj *CONST objv[]);
+static int RectOvalToPostscript(Tcl_Interp *interp,
+ Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
+static int RectToArea(Tk_Canvas canvas, Tk_Item *itemPtr,
+ double *areaPtr);
+static double RectToPoint(Tk_Canvas canvas, Tk_Item *itemPtr,
+ double *pointPtr);
+static void ScaleRectOval(Tk_Canvas canvas, Tk_Item *itemPtr,
+ double originX, double originY,
+ double scaleX, double scaleY);
+static void TranslateRectOval(Tk_Canvas canvas, Tk_Item *itemPtr,
+ double deltaX, double deltaY);
/*
- * The structures below defines the rectangle and oval item types
- * by means of procedures that can be invoked by generic item code.
+ * The structures below defines the rectangle and oval item types by means of
+ * functions that can be invoked by generic item code.
*/
Tk_ItemType tkRectangleType = {
- "rectangle", /* name */
- sizeof(RectOvalItem), /* itemSize */
- CreateRectOval, /* createProc */
- configSpecs, /* configSpecs */
- ConfigureRectOval, /* configureProc */
- RectOvalCoords, /* coordProc */
- DeleteRectOval, /* deleteProc */
- DisplayRectOval, /* displayProc */
- TK_CONFIG_OBJS, /* flags */
- RectToPoint, /* pointProc */
- RectToArea, /* areaProc */
- RectOvalToPostscript, /* postscriptProc */
- ScaleRectOval, /* scaleProc */
- TranslateRectOval, /* translateProc */
- (Tk_ItemIndexProc *) NULL, /* indexProc */
- (Tk_ItemCursorProc *) NULL, /* icursorProc */
- (Tk_ItemSelectionProc *) NULL, /* selectionProc */
- (Tk_ItemInsertProc *) NULL, /* insertProc */
- (Tk_ItemDCharsProc *) NULL, /* dTextProc */
- (Tk_ItemType *) NULL, /* nextPtr */
+ "rectangle", /* name */
+ sizeof(RectOvalItem), /* itemSize */
+ CreateRectOval, /* createProc */
+ configSpecs, /* configSpecs */
+ ConfigureRectOval, /* configureProc */
+ RectOvalCoords, /* coordProc */
+ DeleteRectOval, /* deleteProc */
+ DisplayRectOval, /* displayProc */
+ TK_CONFIG_OBJS, /* flags */
+ RectToPoint, /* pointProc */
+ RectToArea, /* areaProc */
+ RectOvalToPostscript, /* postscriptProc */
+ ScaleRectOval, /* scaleProc */
+ TranslateRectOval, /* translateProc */
+ NULL, /* indexProc */
+ NULL, /* icursorProc */
+ NULL, /* selectionProc */
+ NULL, /* insertProc */
+ NULL, /* dTextProc */
+ NULL, /* nextPtr */
};
Tk_ItemType tkOvalType = {
- "oval", /* name */
- sizeof(RectOvalItem), /* itemSize */
- CreateRectOval, /* createProc */
- configSpecs, /* configSpecs */
- ConfigureRectOval, /* configureProc */
- RectOvalCoords, /* coordProc */
- DeleteRectOval, /* deleteProc */
- DisplayRectOval, /* displayProc */
- TK_CONFIG_OBJS, /* flags */
- OvalToPoint, /* pointProc */
- OvalToArea, /* areaProc */
- RectOvalToPostscript, /* postscriptProc */
- ScaleRectOval, /* scaleProc */
- TranslateRectOval, /* translateProc */
- (Tk_ItemIndexProc *) NULL, /* indexProc */
- (Tk_ItemCursorProc *) NULL, /* cursorProc */
- (Tk_ItemSelectionProc *) NULL, /* selectionProc */
- (Tk_ItemInsertProc *) NULL, /* insertProc */
- (Tk_ItemDCharsProc *) NULL, /* dTextProc */
- (Tk_ItemType *) NULL, /* nextPtr */
+ "oval", /* name */
+ sizeof(RectOvalItem), /* itemSize */
+ CreateRectOval, /* createProc */
+ configSpecs, /* configSpecs */
+ ConfigureRectOval, /* configureProc */
+ RectOvalCoords, /* coordProc */
+ DeleteRectOval, /* deleteProc */
+ DisplayRectOval, /* displayProc */
+ TK_CONFIG_OBJS, /* flags */
+ OvalToPoint, /* pointProc */
+ OvalToArea, /* areaProc */
+ RectOvalToPostscript, /* postscriptProc */
+ ScaleRectOval, /* scaleProc */
+ TranslateRectOval, /* translateProc */
+ NULL, /* indexProc */
+ NULL, /* cursorProc */
+ NULL, /* selectionProc */
+ NULL, /* insertProc */
+ NULL, /* dTextProc */
+ NULL, /* nextPtr */
};
/*
@@ -225,14 +216,14 @@ Tk_ItemType tkOvalType = {
*
* CreateRectOval --
*
- * This procedure is invoked to create a new rectangle
- * or oval item in a canvas.
+ * This function is invoked to create a new rectangle or oval item in a
+ * canvas.
*
* Results:
- * A standard Tcl return value. If an error occurred in
- * creating the item, then an error message is left in
- * the interp's result; in this case itemPtr is left uninitialized,
- * so it can be safely freed by the caller.
+ * A standard Tcl return value. If an error occurred in creating the
+ * item, then an error message is left in the interp's result; in this
+ * case itemPtr is left uninitialized, so it can be safely freed by the
+ * caller.
*
* Side effects:
* A new rectangle or oval item is created.
@@ -241,24 +232,24 @@ Tk_ItemType tkOvalType = {
*/
static int
-CreateRectOval(interp, canvas, itemPtr, objc, objv)
- Tcl_Interp *interp; /* 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 objc; /* Number of arguments in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing rectangle. */
+CreateRectOval(
+ Tcl_Interp *interp, /* 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 objc, /* Number of arguments in objv. */
+ Tcl_Obj *CONST objv[]) /* Arguments describing rectangle. */
{
RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
int i;
if (objc == 0) {
- panic("canvas did not pass any coords\n");
+ Tcl_Panic("canvas did not pass any coords\n");
}
/*
- * 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 function.
*/
Tk_CreateOutline(&(rectOvalPtr->outline));
@@ -279,6 +270,7 @@ CreateRectOval(interp, canvas, itemPtr, objc, objv)
for (i = 1; i < objc; i++) {
char *arg = Tcl_GetString(objv[i]);
+
if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) {
break;
}
@@ -291,7 +283,7 @@ CreateRectOval(interp, canvas, itemPtr, objc, objv)
return TCL_OK;
}
- error:
+ error:
DeleteRectOval(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
return TCL_ERROR;
}
@@ -301,9 +293,9 @@ CreateRectOval(interp, canvas, itemPtr, objc, objv)
*
* RectOvalCoords --
*
- * This procedure is invoked to process the "coords" widget
- * command on rectangles and ovals. See the user documentation
- * for details on what it does.
+ * This function is invoked to process the "coords" widget command on
+ * rectangles and ovals. See the user documentation for details on what
+ * it does.
*
* Results:
* Returns TCL_OK or TCL_ERROR, and sets the interp's result.
@@ -315,60 +307,73 @@ CreateRectOval(interp, canvas, itemPtr, objc, objv)
*/
static int
-RectOvalCoords(interp, canvas, itemPtr, objc, objv)
- 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 objc; /* Number of coordinates supplied in
- * objv. */
- Tcl_Obj *CONST objv[]; /* Array of coordinates: x1, y1,
- * x2, y2, ... */
+RectOvalCoords(
+ 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 objc, /* Number of coordinates supplied in objv. */
+ Tcl_Obj *CONST objv[]) /* Array of coordinates: x1,y1,x2,y2,... */
{
RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
+ /*
+ * If no coordinates, return the current coordinates (i.e. bounding box).
+ */
+
if (objc == 0) {
Tcl_Obj *obj = Tcl_NewObj();
- Tcl_Obj *subobj = Tcl_NewDoubleObj(rectOvalPtr->bbox[0]);
- Tcl_ListObjAppendElement(interp, obj, subobj);
- subobj = Tcl_NewDoubleObj(rectOvalPtr->bbox[1]);
- Tcl_ListObjAppendElement(interp, obj, subobj);
- subobj = Tcl_NewDoubleObj(rectOvalPtr->bbox[2]);
- Tcl_ListObjAppendElement(interp, obj, subobj);
- subobj = Tcl_NewDoubleObj(rectOvalPtr->bbox[3]);
- Tcl_ListObjAppendElement(interp, obj, subobj);
+
+ Tcl_ListObjAppendElement(NULL, obj,
+ Tcl_NewDoubleObj(rectOvalPtr->bbox[0]));
+ Tcl_ListObjAppendElement(NULL, obj,
+ Tcl_NewDoubleObj(rectOvalPtr->bbox[1]));
+ Tcl_ListObjAppendElement(NULL, obj,
+ Tcl_NewDoubleObj(rectOvalPtr->bbox[2]));
+ Tcl_ListObjAppendElement(NULL, obj,
+ Tcl_NewDoubleObj(rectOvalPtr->bbox[3]));
Tcl_SetObjResult(interp, obj);
- } else if ((objc == 1)||(objc == 4)) {
- if (objc==1) {
- if (Tcl_ListObjGetElements(interp, objv[0], &objc,
- (Tcl_Obj ***) &objv) != TCL_OK) {
- return TCL_ERROR;
- } else if (objc != 4) {
- char buf[64 + TCL_INTEGER_SPACE];
+ return TCL_OK;
+ }
- sprintf(buf, "wrong # coordinates: expected 0 or 4, got %d", objc);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
- return TCL_ERROR;
- }
- }
- if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
- &rectOvalPtr->bbox[0]) != TCL_OK)
- || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
- &rectOvalPtr->bbox[1]) != TCL_OK)
- || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[2],
- &rectOvalPtr->bbox[2]) != TCL_OK)
- || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[3],
- &rectOvalPtr->bbox[3]) != TCL_OK)) {
+ /*
+ * If one "coordinate", treat as list of coordinates.
+ */
+
+ if (objc == 1) {
+ if (Tcl_ListObjGetElements(interp, objv[0], &objc,
+ (Tcl_Obj ***) &objv) != TCL_OK) {
return TCL_ERROR;
}
- ComputeRectOvalBbox(canvas, rectOvalPtr);
- } else {
+ }
+
+ /*
+ * Better have four coordinates now. Spit out an error message otherwise.
+ */
+
+ if (objc != 4) {
char buf[64 + TCL_INTEGER_SPACE];
-
+
sprintf(buf, "wrong # coordinates: expected 0 or 4, got %d", objc);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_ERROR;
}
+
+ /*
+ * Parse the coordinates and update our bounding box.
+ */
+
+ if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
+ &rectOvalPtr->bbox[0]) != TCL_OK)
+ || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
+ &rectOvalPtr->bbox[1]) != TCL_OK)
+ || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[2],
+ &rectOvalPtr->bbox[2]) != TCL_OK)
+ || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[3],
+ &rectOvalPtr->bbox[3]) != TCL_OK)) {
+ return TCL_ERROR;
+ }
+ ComputeRectOvalBbox(canvas, rectOvalPtr);
return TCL_OK;
}
@@ -377,29 +382,28 @@ RectOvalCoords(interp, canvas, itemPtr, objc, objv)
*
* ConfigureRectOval --
*
- * This procedure is invoked to configure various aspects
- * of a rectangle or oval item, such as its border and
- * background colors.
+ * This function is invoked to configure various aspects of a rectangle
+ * or oval item, such as its border and background colors.
*
* Results:
- * A standard Tcl result code. If an error occurs, then
- * an error message is left in the interp's result.
+ * A standard Tcl result code. If an error occurs, then an error message
+ * is left in the interp's result.
*
* Side effects:
- * Configuration information, such as colors and stipple
- * patterns, may be set for itemPtr.
+ * Configuration information, such as colors and stipple patterns, may be
+ * set for itemPtr.
*
*--------------------------------------------------------------
*/
static int
-ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Canvas canvas; /* Canvas containing itemPtr. */
- Tk_Item *itemPtr; /* Rectangle item to reconfigure. */
- int objc; /* Number of elements in objv. */
- Tcl_Obj *CONST objv[]; /* Arguments describing things to configure. */
- int flags; /* Flags to pass to Tk_ConfigureWidget. */
+ConfigureRectOval(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tk_Canvas canvas, /* Canvas containing itemPtr. */
+ Tk_Item *itemPtr, /* Rectangle item to reconfigure. */
+ int objc, /* Number of elements in objv. */
+ Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */
+ int flags) /* Flags to pass to Tk_ConfigureWidget. */
{
RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
XGCValues gcValues;
@@ -414,14 +418,14 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags)
tkwin = Tk_CanvasTkwin(canvas);
if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
- (CONST char **) objv, (char *) rectOvalPtr, flags|TK_CONFIG_OBJS)) {
+ (CONST char **)objv, (char *) rectOvalPtr, flags|TK_CONFIG_OBJS)) {
return TCL_ERROR;
}
state = itemPtr->state;
/*
- * A few of the options require additional processing, such as
- * graphics contexts.
+ * A few of the options require additional processing, such as graphics
+ * contexts.
*/
if (rectOvalPtr->outline.activeWidth > rectOvalPtr->outline.width ||
@@ -440,27 +444,28 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags)
if (flags & TK_OFFSET_LEFT) {
tsoffset->xoffset = (int) (rectOvalPtr->bbox[0] + 0.5);
} else if (flags & TK_OFFSET_CENTER) {
- tsoffset->xoffset = (int) ((rectOvalPtr->bbox[0]+rectOvalPtr->bbox[2]+1)/2);
+ tsoffset->xoffset = (int)
+ ((rectOvalPtr->bbox[0]+rectOvalPtr->bbox[2]+1)/2);
} else if (flags & TK_OFFSET_RIGHT) {
tsoffset->xoffset = (int) (rectOvalPtr->bbox[2] + 0.5);
}
if (flags & TK_OFFSET_TOP) {
tsoffset->yoffset = (int) (rectOvalPtr->bbox[1] + 0.5);
} else if (flags & TK_OFFSET_MIDDLE) {
- tsoffset->yoffset = (int) ((rectOvalPtr->bbox[1]+rectOvalPtr->bbox[3]+1)/2);
+ tsoffset->yoffset = (int)
+ ((rectOvalPtr->bbox[1]+rectOvalPtr->bbox[3]+1)/2);
} else if (flags & TK_OFFSET_BOTTOM) {
tsoffset->yoffset = (int) (rectOvalPtr->bbox[2] + 0.5);
}
/*
- * Configure the outline graphics context. If mask is non-zero,
- * the gc has changed and must be reallocated, provided that the
- * new settings specify a valid outline (non-zero width and non-NULL
- * color)
+ * Configure the outline graphics context. If mask is non-zero, the gc has
+ * changed and must be reallocated, provided that the new settings specify
+ * a valid outline (non-zero width and non-NULL color)
*/
mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr,
- &(rectOvalPtr->outline));
+ &(rectOvalPtr->outline));
if (mask && \
rectOvalPtr->outline.width != 0 && \
rectOvalPtr->outline.color != NULL) {
@@ -475,10 +480,10 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags)
}
rectOvalPtr->outline.gc = newGC;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
- if (state==TK_STATE_HIDDEN) {
+ if (state == TK_STATE_HIDDEN) {
ComputeRectOvalBbox(canvas, rectOvalPtr);
return TCL_OK;
}
@@ -492,7 +497,7 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags)
if (rectOvalPtr->activeFillStipple!=None) {
stipple = rectOvalPtr->activeFillStipple;
}
- } else if (state==TK_STATE_DISABLED) {
+ } else if (state == TK_STATE_DISABLED) {
if (rectOvalPtr->disabledFillColor!=NULL) {
color = rectOvalPtr->disabledFillColor;
}
@@ -533,14 +538,16 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags)
if (flags & TK_OFFSET_LEFT) {
tsoffset->xoffset = (int) (rectOvalPtr->bbox[0] + 0.5);
} else if (flags & TK_OFFSET_CENTER) {
- tsoffset->xoffset = (int) ((rectOvalPtr->bbox[0]+rectOvalPtr->bbox[2]+1)/2);
+ tsoffset->xoffset = (int)
+ ((rectOvalPtr->bbox[0]+rectOvalPtr->bbox[2]+1)/2);
} else if (flags & TK_OFFSET_RIGHT) {
tsoffset->xoffset = (int) (rectOvalPtr->bbox[2] + 0.5);
}
if (flags & TK_OFFSET_TOP) {
tsoffset->yoffset = (int) (rectOvalPtr->bbox[1] + 0.5);
} else if (flags & TK_OFFSET_MIDDLE) {
- tsoffset->yoffset = (int) ((rectOvalPtr->bbox[1]+rectOvalPtr->bbox[3]+1)/2);
+ tsoffset->yoffset = (int)
+ ((rectOvalPtr->bbox[1]+rectOvalPtr->bbox[3]+1)/2);
} else if (flags & TK_OFFSET_BOTTOM) {
tsoffset->yoffset = (int) (rectOvalPtr->bbox[3] + 0.5);
}
@@ -555,8 +562,8 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags)
*
* DeleteRectOval --
*
- * This procedure is called to clean up the data structure
- * associated with a rectangle or oval item.
+ * This function is called to clean up the data structure associated with
+ * a rectangle or oval item.
*
* Results:
* None.
@@ -568,11 +575,10 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags)
*/
static void
-DeleteRectOval(canvas, itemPtr, display)
- Tk_Canvas canvas; /* Info about overall widget. */
- Tk_Item *itemPtr; /* Item that is being deleted. */
- Display *display; /* Display containing window for
- * canvas. */
+DeleteRectOval(
+ Tk_Canvas canvas, /* Info about overall widget. */
+ Tk_Item *itemPtr, /* Item that is being deleted. */
+ Display *display) /* Display containing window for canvas. */
{
RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
@@ -605,37 +611,34 @@ DeleteRectOval(canvas, itemPtr, display)
*
* ComputeRectOvalBbox --
*
- * This procedure is invoked to compute the bounding box of
- * all the pixels that may be drawn as part of a rectangle
- * or oval.
+ * This function is invoked to compute the bounding box of all the pixels
+ * that may be drawn as part of a rectangle or oval.
*
* Results:
* None.
*
* Side effects:
- * The fields x1, y1, x2, and y2 are updated in the header
- * for itemPtr.
+ * The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static void
-ComputeRectOvalBbox(canvas, rectOvalPtr)
- Tk_Canvas canvas; /* Canvas that contains item. */
- RectOvalItem *rectOvalPtr; /* Item whose bbox is to be
- * recomputed. */
+ComputeRectOvalBbox(
+ Tk_Canvas canvas, /* Canvas that contains item. */
+ RectOvalItem *rectOvalPtr) /* Item whose bbox is to be recomputed. */
{
int bloat, tmp;
double dtmp, width;
Tk_State state = rectOvalPtr->header.state;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
width = rectOvalPtr->outline.width;
- if (state==TK_STATE_HIDDEN) {
+ if (state == TK_STATE_HIDDEN) {
rectOvalPtr->header.x1 = rectOvalPtr->header.y1 =
rectOvalPtr->header.x2 = rectOvalPtr->header.y2 = -1;
return;
@@ -644,7 +647,7 @@ ComputeRectOvalBbox(canvas, rectOvalPtr)
if (rectOvalPtr->outline.activeWidth>width) {
width = rectOvalPtr->outline.activeWidth;
}
- } else if (state==TK_STATE_DISABLED) {
+ } else if (state == TK_STATE_DISABLED) {
if (rectOvalPtr->outline.disabledWidth>0) {
width = rectOvalPtr->outline.disabledWidth;
}
@@ -655,24 +658,25 @@ ComputeRectOvalBbox(canvas, rectOvalPtr)
*/
if (rectOvalPtr->bbox[1] > rectOvalPtr->bbox[3]) {
- double tmp;
- tmp = rectOvalPtr->bbox[3];
+ double tmpY = rectOvalPtr->bbox[3];
+
rectOvalPtr->bbox[3] = rectOvalPtr->bbox[1];
- rectOvalPtr->bbox[1] = tmp;
+ rectOvalPtr->bbox[1] = tmpY;
}
if (rectOvalPtr->bbox[0] > rectOvalPtr->bbox[2]) {
- double tmp;
- tmp = rectOvalPtr->bbox[2];
+ double tmpX = rectOvalPtr->bbox[2];
+
rectOvalPtr->bbox[2] = rectOvalPtr->bbox[0];
- rectOvalPtr->bbox[0] = tmp;
+ rectOvalPtr->bbox[0] = tmpX;
}
if (rectOvalPtr->outline.gc == None) {
/*
- * The Win32 switch was added for 8.3 to solve a problem
- * with ovals leaving traces on bottom and right of 1 pixel.
- * This may not be the correct place to solve it, but it works.
+ * The Win32 switch was added for 8.3 to solve a problem with ovals
+ * leaving traces on bottom and right of 1 pixel. This may not be the
+ * correct place to solve it, but it works.
*/
+
#ifdef __WIN32__
bloat = 1;
#else
@@ -680,9 +684,12 @@ ComputeRectOvalBbox(canvas, rectOvalPtr)
#endif
} else {
#ifdef MAC_OSX_TK
- /* Mac OS X CoreGraphics needs correct rounding here
- * otherwise it will draw outside the bounding box.
- * Probably correct on other platforms as well? */
+ /*
+ * Mac OS X CoreGraphics needs correct rounding here otherwise it will
+ * draw outside the bounding box. Probably correct on other platforms
+ * as well?
+ */
+
bloat = (int) (width+1.5)/2;
#else
bloat = (int) (width+1)/2;
@@ -690,9 +697,9 @@ ComputeRectOvalBbox(canvas, rectOvalPtr)
}
/*
- * Special note: the rectangle is always drawn at least 1x1 in
- * size, so round up the upper coordinates to be at least 1 unit
- * greater than the lower ones.
+ * Special note: the rectangle is always drawn at least 1x1 in size, so
+ * round up the upper coordinates to be at least 1 unit greater than the
+ * lower ones.
*/
tmp = (int) ((rectOvalPtr->bbox[0] >= 0) ? rectOvalPtr->bbox[0] + .5
@@ -720,28 +727,28 @@ ComputeRectOvalBbox(canvas, rectOvalPtr)
*
* DisplayRectOval --
*
- * This procedure is invoked to draw a rectangle or oval
- * item in a given drawable.
+ * This function is invoked to draw a rectangle or oval item in a given
+ * drawable.
*
* Results:
* None.
*
* Side effects:
- * ItemPtr is drawn in drawable using the transformation
- * information in canvas.
+ * ItemPtr is drawn in drawable using the transformation information in
+ * canvas.
*
*--------------------------------------------------------------
*/
static void
-DisplayRectOval(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). */
+DisplayRectOval(
+ 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, int y, int width, int height)
+ /* Describes region of canvas that must be
+ * redisplayed (not used). */
{
RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
short x1, y1, x2, y2;
@@ -749,9 +756,9 @@ DisplayRectOval(canvas, itemPtr, display, drawable, x, y, width, height)
Tk_State state = itemPtr->state;
/*
- * Compute the screen coordinates of the bounding box for the item.
- * Make sure that the bbox is at least one pixel large, since some
- * X servers will die if it isn't.
+ * Compute the screen coordinates of the bounding box for the item. Make
+ * sure that the bbox is at least one pixel large, since some X servers
+ * will die if it isn't.
*/
Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[0], rectOvalPtr->bbox[1],
@@ -766,22 +773,21 @@ DisplayRectOval(canvas, itemPtr, display, drawable, x, y, width, height)
}
/*
- * Display filled part first (if wanted), then outline. If we're
- * stippling, then modify the stipple offset in the GC. Be sure to
- * reset the offset when done, since the GC is supposed to be
- * read-only.
+ * Display filled part first (if wanted), then outline. If we're
+ * stippling, then modify the stipple offset in the GC. Be sure to reset
+ * the offset when done, since the GC is supposed to be read-only.
*/
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
fillStipple = rectOvalPtr->fillStipple;
if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)rectOvalPtr) {
- if (rectOvalPtr->activeFillStipple!=None) {
+ if (rectOvalPtr->activeFillStipple != None) {
fillStipple = rectOvalPtr->activeFillStipple;
}
- } else if (state==TK_STATE_DISABLED) {
- if (rectOvalPtr->disabledFillStipple!=None) {
+ } else if (state == TK_STATE_DISABLED) {
+ if (rectOvalPtr->disabledFillStipple != None) {
fillStipple = rectOvalPtr->disabledFillStipple;
}
}
@@ -789,10 +795,12 @@ DisplayRectOval(canvas, itemPtr, display, drawable, x, y, width, height)
if (rectOvalPtr->fillGC != None) {
if (fillStipple != None) {
Tk_TSOffset *tsoffset;
- int w=0; int h=0;
+ int w = 0, h = 0;
+
tsoffset = &rectOvalPtr->tsoffset;
if (tsoffset) {
int flags = tsoffset->flags;
+
if (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE)) {
Tk_SizeOfBitmap(display, fillStipple, &w, &h);
if (flags & TK_OFFSET_CENTER) {
@@ -827,6 +835,7 @@ DisplayRectOval(canvas, itemPtr, display, drawable, x, y, width, height)
XSetTSOrigin(display, rectOvalPtr->fillGC, 0, 0);
}
}
+
if (rectOvalPtr->outline.gc != None) {
Tk_ChangeOutlineGC(canvas, itemPtr, &(rectOvalPtr->outline));
if (rectOvalPtr->header.typePtr == &tkRectangleType) {
@@ -845,17 +854,16 @@ DisplayRectOval(canvas, itemPtr, display, drawable, x, y, width, height)
*
* RectToPoint --
*
- * Computes the distance from a given point to a given
- * rectangle, in canvas units.
+ * Computes the distance from a given point to a given rectangle, in
+ * canvas units.
*
* Results:
- * The return value is 0 if the point whose x and y coordinates
- * are coordPtr[0] and coordPtr[1] is inside the rectangle. If the
- * point isn't inside the rectangle then the return value is the
- * distance from the point to the rectangle. If itemPtr is filled,
- * then anywhere in the interior is considered "inside"; if
- * itemPtr isn't filled, then "inside" means only the area
- * occupied by the outline.
+ * The return value is 0 if the point whose x and y coordinates are
+ * coordPtr[0] and coordPtr[1] is inside the rectangle. If the point
+ * isn't inside the rectangle then the return value is the distance from
+ * the point to the rectangle. If itemPtr is filled, then anywhere in the
+ * interior is considered "inside"; if itemPtr isn't filled, then
+ * "inside" means only the area occupied by the outline.
*
* Side effects:
* None.
@@ -865,17 +873,17 @@ DisplayRectOval(canvas, itemPtr, display, drawable, x, y, width, height)
/* ARGSUSED */
static double
-RectToPoint(canvas, itemPtr, pointPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against point. */
- double *pointPtr; /* Pointer to x and y coordinates. */
+RectToPoint(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against point. */
+ double *pointPtr) /* Pointer to x and y coordinates. */
{
RectOvalItem *rectPtr = (RectOvalItem *) itemPtr;
double xDiff, yDiff, x1, y1, x2, y2, inc, tmp;
double width;
Tk_State state = itemPtr->state;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
@@ -884,15 +892,15 @@ RectToPoint(canvas, itemPtr, pointPtr)
if (rectPtr->outline.activeWidth>width) {
width = rectPtr->outline.activeWidth;
}
- } else if (state==TK_STATE_DISABLED) {
+ } else if (state == TK_STATE_DISABLED) {
if (rectPtr->outline.disabledWidth>0) {
width = rectPtr->outline.disabledWidth;
}
}
/*
- * Generate a new larger rectangle that includes the border
- * width, if there is one.
+ * Generate a new larger rectangle that includes the border width, if
+ * there is one.
*/
x1 = rectPtr->bbox[0];
@@ -908,14 +916,13 @@ RectToPoint(canvas, itemPtr, pointPtr)
}
/*
- * If the point is inside the rectangle, handle specially:
- * distance is 0 if rectangle is filled, otherwise compute
- * distance to nearest edge of rectangle and subtract width
- * of edge.
+ * If the point is inside the rectangle, handle specially: distance is 0
+ * if rectangle is filled, otherwise compute distance to nearest edge of
+ * rectangle and subtract width of edge.
*/
if ((pointPtr[0] >= x1) && (pointPtr[0] < x2)
- && (pointPtr[1] >= y1) && (pointPtr[1] < y2)) {
+ && (pointPtr[1] >= y1) && (pointPtr[1] < y2)) {
if ((rectPtr->fillGC != None) || (rectPtr->outline.gc == None)) {
return 0.0;
}
@@ -967,17 +974,16 @@ RectToPoint(canvas, itemPtr, pointPtr)
*
* OvalToPoint --
*
- * Computes the distance from a given point to a given
- * oval, in canvas units.
+ * Computes the distance from a given point to a given oval, in canvas
+ * units.
*
* Results:
- * The return value is 0 if the point whose x and y coordinates
- * are coordPtr[0] and coordPtr[1] is inside the oval. If the
- * point isn't inside the oval then the return value is the
- * distance from the point to the oval. If itemPtr is filled,
- * then anywhere in the interior is considered "inside"; if
- * itemPtr isn't filled, then "inside" means only the area
- * occupied by the outline.
+ * The return value is 0 if the point whose x and y coordinates are
+ * coordPtr[0] and coordPtr[1] is inside the oval. If the point isn't
+ * inside the oval then the return value is the distance from the point
+ * to the oval. If itemPtr is filled, then anywhere in the interior is
+ * considered "inside"; if itemPtr isn't filled, then "inside" means only
+ * the area occupied by the outline.
*
* Side effects:
* None.
@@ -987,17 +993,17 @@ RectToPoint(canvas, itemPtr, pointPtr)
/* ARGSUSED */
static double
-OvalToPoint(canvas, itemPtr, pointPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against point. */
- double *pointPtr; /* Pointer to x and y coordinates. */
+OvalToPoint(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against point. */
+ double *pointPtr) /* Pointer to x and y coordinates. */
{
RectOvalItem *ovalPtr = (RectOvalItem *) itemPtr;
double width;
int filled;
Tk_State state = itemPtr->state;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
@@ -1006,7 +1012,7 @@ OvalToPoint(canvas, itemPtr, pointPtr)
if (ovalPtr->outline.activeWidth>width) {
width = (double) ovalPtr->outline.activeWidth;
}
- } else if (state==TK_STATE_DISABLED) {
+ } else if (state == TK_STATE_DISABLED) {
if (ovalPtr->outline.disabledWidth>0) {
width = (double) ovalPtr->outline.disabledWidth;
}
@@ -1026,14 +1032,13 @@ OvalToPoint(canvas, itemPtr, pointPtr)
*
* RectToArea --
*
- * This procedure is called to determine whether an item
- * lies entirely inside, entirely outside, or overlapping
- * a given rectangle.
+ * This function is called to determine whether an item lies entirely
+ * inside, entirely outside, or overlapping a given rectangle.
*
* Results:
- * -1 is returned if the item is entirely outside the area
- * given by rectPtr, 0 if it overlaps, and 1 if it is entirely
- * inside the given area.
+ * -1 is returned if the item is entirely outside the area given by
+ * rectPtr, 0 if it overlaps, and 1 if it is entirely inside the given
+ * area.
*
* Side effects:
* None.
@@ -1043,19 +1048,18 @@ OvalToPoint(canvas, itemPtr, pointPtr)
/* ARGSUSED */
static int
-RectToArea(canvas, itemPtr, areaPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against rectangle. */
- double *areaPtr; /* Pointer to array of four coordinates
- * (x1, y1, x2, y2) describing rectangular
- * area. */
+RectToArea(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against rectangle. */
+ double *areaPtr) /* Pointer to array of four coordinates (x1,
+ * y1, x2, y2) describing rectangular area. */
{
RectOvalItem *rectPtr = (RectOvalItem *) itemPtr;
double halfWidth;
double width;
Tk_State state = itemPtr->state;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
@@ -1064,7 +1068,7 @@ RectToArea(canvas, itemPtr, areaPtr)
if (rectPtr->outline.activeWidth>width) {
width = rectPtr->outline.activeWidth;
}
- } else if (state==TK_STATE_DISABLED) {
+ } else if (state == TK_STATE_DISABLED) {
if (rectPtr->outline.disabledWidth>0) {
width = rectPtr->outline.disabledWidth;
}
@@ -1102,14 +1106,13 @@ RectToArea(canvas, itemPtr, areaPtr)
*
* OvalToArea --
*
- * This procedure is called to determine whether an item
- * lies entirely inside, entirely outside, or overlapping
- * a given rectangular area.
+ * This function is called to determine whether an item lies entirely
+ * inside, entirely outside, or overlapping a given rectangular area.
*
* Results:
- * -1 is returned if the item is entirely outside the area
- * given by rectPtr, 0 if it overlaps, and 1 if it is entirely
- * inside the given area.
+ * -1 is returned if the item is entirely outside the area given by
+ * rectPtr, 0 if it overlaps, and 1 if it is entirely inside the given
+ * area.
*
* Side effects:
* None.
@@ -1119,12 +1122,11 @@ RectToArea(canvas, itemPtr, areaPtr)
/* ARGSUSED */
static int
-OvalToArea(canvas, itemPtr, areaPtr)
- Tk_Canvas canvas; /* Canvas containing item. */
- Tk_Item *itemPtr; /* Item to check against oval. */
- double *areaPtr; /* Pointer to array of four coordinates
- * (x1, y1, x2, y2) describing rectangular
- * area. */
+OvalToArea(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item to check against oval. */
+ double *areaPtr) /* Pointer to array of four coordinates (x1,
+ * y1, x2, y2) describing rectangular area. */
{
RectOvalItem *ovalPtr = (RectOvalItem *) itemPtr;
double oval[4], halfWidth;
@@ -1132,7 +1134,7 @@ OvalToArea(canvas, itemPtr, areaPtr)
double width;
Tk_State state = itemPtr->state;
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
@@ -1141,7 +1143,7 @@ OvalToArea(canvas, itemPtr, areaPtr)
if (ovalPtr->outline.activeWidth>width) {
width = ovalPtr->outline.activeWidth;
}
- } else if (state==TK_STATE_DISABLED) {
+ } else if (state == TK_STATE_DISABLED) {
if (ovalPtr->outline.disabledWidth>0) {
width = ovalPtr->outline.disabledWidth;
}
@@ -1163,10 +1165,10 @@ OvalToArea(canvas, itemPtr, areaPtr)
result = TkOvalToArea(oval, areaPtr);
/*
- * If the rectangle appears to overlap the oval and the oval
- * isn't filled, do one more check to see if perhaps all four
- * of the rectangle's corners are totally inside the oval's
- * unfilled center, in which case we should return "outside".
+ * If the rectangle appears to overlap the oval and the oval isn't filled,
+ * do one more check to see if perhaps all four of the rectangle's corners
+ * are totally inside the oval's unfilled center, in which case we should
+ * return "outside".
*/
if ((result == 0) && (ovalPtr->outline.gc != None)
@@ -1201,16 +1203,14 @@ OvalToArea(canvas, itemPtr, areaPtr)
*
* ScaleRectOval --
*
- * This procedure is invoked to rescale a rectangle or oval
- * item.
+ * This function is invoked to rescale a rectangle or oval item.
*
* Results:
* None.
*
* Side effects:
- * The rectangle or oval referred to by itemPtr is rescaled
- * so that the following transformation is applied to all
- * point coordinates:
+ * The rectangle or oval referred to by itemPtr is rescaled so that the
+ * following transformation is applied to all point coordinates:
* x' = originX + scaleX*(x-originX)
* y' = originY + scaleY*(y-originY)
*
@@ -1218,12 +1218,13 @@ OvalToArea(canvas, itemPtr, areaPtr)
*/
static void
-ScaleRectOval(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. */
+ScaleRectOval(
+ Tk_Canvas canvas, /* Canvas containing rectangle. */
+ Tk_Item *itemPtr, /* Rectangle to be scaled. */
+ double originX, double originY,
+ /* Origin about which to scale rect. */
+ double scaleX, /* Amount to scale in X direction. */
+ double scaleY) /* Amount to scale in Y direction. */
{
RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
@@ -1239,26 +1240,25 @@ ScaleRectOval(canvas, itemPtr, originX, originY, scaleX, scaleY)
*
* TranslateRectOval --
*
- * This procedure is called to move a rectangle or oval by a
- * given amount.
+ * This function is called to move a rectangle or oval by a given amount.
*
* Results:
* None.
*
* Side effects:
- * The position of the rectangle or oval is offset by
- * (xDelta, yDelta), and the bounding box is updated in the
- * generic part of the item structure.
+ * The position of the rectangle or oval is offset by (xDelta, yDelta),
+ * and the bounding box is updated in the generic part of the item
+ * structure.
*
*--------------------------------------------------------------
*/
static void
-TranslateRectOval(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. */
+TranslateRectOval(
+ Tk_Canvas canvas, /* Canvas containing item. */
+ Tk_Item *itemPtr, /* Item that is being moved. */
+ double deltaX, double deltaY)
+ /* Amount by which item is to be moved. */
{
RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
@@ -1274,15 +1274,14 @@ TranslateRectOval(canvas, itemPtr, deltaX, deltaY)
*
* RectOvalToPostscript --
*
- * This procedure is called to generate Postscript for
- * rectangle and oval items.
+ * This function is called to generate Postscript for rectangle and oval
+ * items.
*
* Results:
- * The return value is a standard Tcl result. If an error
- * occurs in generating Postscript then an error message is
- * 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.
+ * The return value is a standard Tcl result. If an error occurs in
+ * generating Postscript then an error message is 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.
*
* Side effects:
* None.
@@ -1291,14 +1290,13 @@ TranslateRectOval(canvas, itemPtr, deltaX, deltaY)
*/
static int
-RectOvalToPostscript(interp, canvas, itemPtr, prepass)
- Tcl_Interp *interp; /* Interpreter for error reporting. */
- 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. */
+RectOvalToPostscript(
+ Tcl_Interp *interp, /* Interpreter for error reporting. */
+ 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. */
{
char pathCmd[500];
RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr;
@@ -1312,12 +1310,10 @@ RectOvalToPostscript(interp, canvas, itemPtr, prepass)
y2 = Tk_CanvasPsY(canvas, rectOvalPtr->bbox[3]);
/*
- * Generate a string that creates a path for the rectangle or oval.
- * This is the only part of the procedure's code that is type-
- * specific.
+ * Generate a string that creates a path for the rectangle or oval. This
+ * is the only part of the function's code that is type-specific.
*/
-
if (rectOvalPtr->header.typePtr == &tkRectangleType) {
sprintf(pathCmd, "%.15g %.15g moveto %.15g 0 rlineto 0 %.15g rlineto %.15g 0 rlineto closepath\n",
rectOvalPtr->bbox[0], y1,
@@ -1329,7 +1325,7 @@ RectOvalToPostscript(interp, canvas, itemPtr, prepass)
(rectOvalPtr->bbox[2] - rectOvalPtr->bbox[0])/2, (y1 - y2)/2);
}
- if(state == TK_STATE_NULL) {
+ if (state == TK_STATE_NULL) {
state = ((TkCanvas *)canvas)->canvas_state;
}
color = rectOvalPtr->outline.color;
@@ -1345,7 +1341,7 @@ RectOvalToPostscript(interp, canvas, itemPtr, prepass)
if (rectOvalPtr->activeFillStipple!=None) {
fillStipple = rectOvalPtr->activeFillStipple;
}
- } else if (state==TK_STATE_DISABLED) {
+ } else if (state == TK_STATE_DISABLED) {
if (rectOvalPtr->outline.disabledColor!=NULL) {
color = rectOvalPtr->outline.disabledColor;
}
@@ -1362,22 +1358,20 @@ RectOvalToPostscript(interp, canvas, itemPtr, prepass)
*/
if (fillColor != NULL) {
- Tcl_AppendResult(interp, pathCmd, (char *) NULL);
- if (Tk_CanvasPsColor(interp, canvas, fillColor)
- != TCL_OK) {
+ Tcl_AppendResult(interp, pathCmd, NULL);
+ if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) {
return TCL_ERROR;
}
if (fillStipple != None) {
- Tcl_AppendResult(interp, "clip ", (char *) NULL);
- if (Tk_CanvasPsStipple(interp, canvas, fillStipple)
- != TCL_OK) {
+ Tcl_AppendResult(interp, "clip ", NULL);
+ if (Tk_CanvasPsStipple(interp, canvas, fillStipple) != TCL_OK) {
return TCL_ERROR;
}
if (color != NULL) {
- Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);
+ Tcl_AppendResult(interp, "grestore gsave\n", NULL);
}
} else {
- Tcl_AppendResult(interp, "fill\n", (char *) NULL);
+ Tcl_AppendResult(interp, "fill\n", NULL);
}
}
@@ -1387,7 +1381,7 @@ RectOvalToPostscript(interp, canvas, itemPtr, prepass)
if (color != NULL) {
Tcl_AppendResult(interp, pathCmd, "0 setlinejoin 2 setlinecap\n",
- (char *) NULL);
+ NULL);
if (Tk_CanvasPsOutline(canvas, itemPtr,
&(rectOvalPtr->outline))!= TCL_OK) {
return TCL_ERROR;
@@ -1395,3 +1389,11 @@ RectOvalToPostscript(interp, canvas, itemPtr, prepass)
}
return TCL_OK;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkScale.c b/generic/tkScale.c
index 1c5c6f3..28e5b16 100644
--- a/generic/tkScale.c
+++ b/generic/tkScale.c
@@ -1,49 +1,45 @@
-/*
+/*
* tkScale.c --
*
- * This module implements a scale widgets for the Tk toolkit.
- * A scale displays a slider that can be adjusted to change a
- * value; it also displays numeric labels and a textual label,
- * if desired.
- *
- * The modifications to use floating-point values are based on
- * an implementation by Paul Mackerras. The -variable option
- * is due to Henning Schulzrinne. All of these are used with
- * permission.
+ * This module implements a scale widgets for the Tk toolkit. A scale
+ * displays a slider that can be adjusted to change a value; it also
+ * displays numeric labels and a textual label, if desired.
+ *
+ * The modifications to use floating-point values are based on an
+ * implementation by Paul Mackerras. The -variable option is due to
+ * Henning Schulzrinne. All of these are used with permission.
*
* Copyright (c) 1990-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
* Copyright (c) 1998-2000 by Scriptics Corporation.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "default.h"
#include "tkInt.h"
-#include "tclMath.h"
#include "tkScale.h"
/*
- * The following table defines the legal values for the -orient option.
- * It is used together with the "enum orient" declaration in tkScale.h.
+ * The following table defines the legal values for the -orient option. It is
+ * used together with the "enum orient" declaration in tkScale.h.
*/
-static CONST char *CONST orientStrings[] = {
- "horizontal", "vertical", (char *) NULL
+static const char *const orientStrings[] = {
+ "horizontal", "vertical", NULL
};
/*
- * The following table defines the legal values for the -state option.
- * It is used together with the "enum state" declaration in tkScale.h.
+ * The following table defines the legal values for the -state option. It is
+ * used together with the "enum state" declaration in tkScale.h.
*/
-static CONST char *CONST stateStrings[] = {
- "active", "disabled", "normal", (char *) NULL
+static const char *const stateStrings[] = {
+ "active", "disabled", "normal", NULL
};
-static CONST Tk_OptionSpec optionSpecs[] = {
+static const 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},
@@ -51,42 +47,42 @@ static CONST Tk_OptionSpec optionSpecs[] = {
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},
+ DEF_SCALE_BIG_INCREMENT, -1, Tk_Offset(TkScale, bigIncrement),
+ 0, 0, 0},
+ {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth", 0},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ 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},
+ DEF_SCALE_BORDER_WIDTH, -1, Tk_Offset(TkScale, borderWidth),
+ 0, 0, 0},
{TK_OPTION_STRING, "-command", "command", "Command",
DEF_SCALE_COMMAND, -1, Tk_Offset(TkScale, command),
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_INT, "-digits", "digits", "Digits",
+ DEF_SCALE_DIGITS, -1, Tk_Offset(TkScale, digits),
+ 0, 0, 0},
+ {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
+ 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},
+ 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},
+ -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,
+ "HighlightThickness", DEF_SCALE_HIGHLIGHT_WIDTH, -1,
Tk_Offset(TkScale, highlightWidth), 0, 0, 0},
{TK_OPTION_STRING, "-label", "label", "Label",
DEF_SCALE_LABEL, -1, Tk_Offset(TkScale, label),
@@ -94,59 +90,58 @@ static CONST Tk_OptionSpec optionSpecs[] = {
{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},
+ 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},
+ 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},
+ 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},
+ 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},
+ 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},
+ 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},
+ 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},
+ 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},
+ 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},
+ 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},
+ 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}
+ {TK_OPTION_END, NULL, NULL, NULL, 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.
+ * 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 CONST char *commandNames[] = {
- "cget", "configure", "coords", "get", "identify", "set", (char *) NULL
+static const char *commandNames[] = {
+ "cget", "configure", "coords", "get", "identify", "set", NULL
};
enum command {
@@ -158,25 +153,22 @@ enum command {
* Forward declarations for procedures defined later in this file:
*/
-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 objc,
- Tcl_Obj *CONST objv[]));
-static void DestroyScale _ANSI_ARGS_((char *memPtr));
-static void ScaleCmdDeletedProc _ANSI_ARGS_((
- ClientData clientData));
-static void ScaleEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static char * ScaleVarProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, CONST char *name1,
- CONST char *name2, int flags));
-static int ScaleWidgetObjCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static void ScaleWorldChanged _ANSI_ARGS_((
- ClientData instanceData));
-static void ScaleSetVariable _ANSI_ARGS_((TkScale *scalePtr));
+static void ComputeFormat(TkScale *scalePtr);
+static void ComputeScaleGeometry(TkScale *scalePtr);
+static int ConfigureScale(Tcl_Interp *interp, TkScale *scalePtr,
+ int objc, Tcl_Obj *const objv[]);
+static void DestroyScale(char *memPtr);
+static void ScaleCmdDeletedProc(ClientData clientData);
+static void ScaleEventProc(ClientData clientData,
+ XEvent *eventPtr);
+static char * ScaleVarProc(ClientData clientData,
+ Tcl_Interp *interp, const char *name1,
+ const char *name2, int flags);
+static int ScaleWidgetObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+static void ScaleWorldChanged(ClientData instanceData);
+static void ScaleSetVariable(TkScale *scalePtr);
/*
* The structure below defines scale class behavior by means of procedures
@@ -187,16 +179,14 @@ static Tk_ClassProcs scaleClass = {
sizeof(Tk_ClassProcs), /* size */
ScaleWorldChanged, /* worldChangedProc */
};
-
/*
*--------------------------------------------------------------
*
* Tk_ScaleObjCmd --
*
- * This procedure is invoked to process the "scale" Tcl
- * command. See the user documentation for details on what
- * it does.
+ * This procedure is invoked to process the "scale" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -208,11 +198,11 @@ static Tk_ClassProcs scaleClass = {
*/
int
-Tk_ScaleObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* NULL. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+Tk_ScaleObjCmd(
+ ClientData clientData, /* NULL. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument values. */
{
register TkScale *scalePtr;
Tk_OptionTable optionTable;
@@ -224,14 +214,14 @@ Tk_ScaleObjCmd(clientData, interp, objc, objv)
}
tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
- Tcl_GetString(objv[1]), (char *) NULL);
+ Tcl_GetString(objv[1]), NULL);
if (tkwin == NULL) {
return TCL_ERROR;
}
/*
- * Create the option table for this widget class. If it has already
- * been created, the cached pointer will be returned.
+ * Create the option table for this widget class. If it has already been
+ * created, the cached pointer will be returned.
*/
optionTable = Tk_CreateOptionTable(interp, optionSpecs);
@@ -240,9 +230,9 @@ Tk_ScaleObjCmd(clientData, interp, objc, objv)
scalePtr = TkpCreateScale(tkwin);
/*
- * Initialize fields that won't be initialized by ConfigureScale,
- * or which ConfigureScale expects to have reasonable values
- * (e.g. resource pointers).
+ * Initialize fields that won't be initialized by ConfigureScale, or which
+ * ConfigureScale expects to have reasonable values (e.g. resource
+ * pointers).
*/
scalePtr->tkwin = tkwin;
@@ -320,9 +310,9 @@ Tk_ScaleObjCmd(clientData, interp, objc, objv)
*
* ScaleWidgetObjCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to a widget managed by this module.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the Tcl command that corresponds
+ * to a widget managed by this module. See the user documentation for
+ * details on what it does.
*
* Results:
* A standard Tcl result.
@@ -334,157 +324,151 @@ Tk_ScaleObjCmd(clientData, interp, objc, objv)
*/
static int
-ScaleWidgetObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Information about scale
- * widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument strings. */
+ScaleWidgetObjCmd(
+ ClientData clientData, /* Information about scale widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
TkScale *scalePtr = (TkScale *) clientData;
Tcl_Obj *objPtr;
int index, result;
if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
+ Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
return TCL_ERROR;
}
result = Tcl_GetIndexFromObj(interp, objv[1], commandNames,
- "option", 0, &index);
+ "option", 0, &index);
if (result != TCL_OK) {
return result;
}
Tcl_Preserve((ClientData) scalePtr);
switch (index) {
- case COMMAND_CGET: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "cget option");
- goto error;
- }
- objPtr = Tk_GetOptionValue(interp, (char *) scalePtr,
- scalePtr->optionTable, objv[2], scalePtr->tkwin);
+ case COMMAND_CGET:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "cget option");
+ goto error;
+ }
+ objPtr = Tk_GetOptionValue(interp, (char *) scalePtr,
+ scalePtr->optionTable, objv[2], scalePtr->tkwin);
+ if (objPtr == NULL) {
+ goto error;
+ } else {
+ Tcl_SetObjResult(interp, objPtr);
+ }
+ break;
+ case COMMAND_CONFIGURE:
+ if (objc <= 3) {
+ objPtr = Tk_GetOptionInfo(interp, (char *) scalePtr,
+ scalePtr->optionTable,
+ (objc == 3) ? objv[2] : NULL, scalePtr->tkwin);
if (objPtr == NULL) {
- goto error;
+ goto error;
} else {
Tcl_SetObjResult(interp, objPtr);
}
- break;
+ } else {
+ result = ConfigureScale(interp, scalePtr, objc-2, objv+2);
}
- 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;
+ break;
+ 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;
}
- 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;
- }
- 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 = TkScaleValueToPixel(scalePtr, value);
- } else {
- x = TkScaleValueToPixel(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?");
+ if (objc == 3) {
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &value) != TCL_OK) {
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 = TkScalePixelToValue(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");
+ } else {
+ value = scalePtr->value;
+ }
+ if (scalePtr->orient == ORIENT_VERTICAL) {
+ x = scalePtr->vertTroughX + scalePtr->width/2
+ + scalePtr->borderWidth;
+ y = TkScaleValueToPixel(scalePtr, value);
+ } else {
+ x = TkScaleValueToPixel(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;
}
- 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;
+ value = TkScalePixelToValue(scalePtr, x, y);
+ }
+ sprintf(buf, scalePtr->format, value);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ break;
+ }
+ case COMMAND_IDENTIFY: {
+ int x, y, thing;
- 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) {
- TkScaleSetValue(scalePtr, value, 1, 1);
- }
+ 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 (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) {
+ TkScaleSetValue(scalePtr, value, 1, 1);
+ }
+ break;
+ }
}
Tcl_Release((ClientData) scalePtr);
return result;
- error:
+ error:
Tcl_Release((ClientData) scalePtr);
return TCL_ERROR;
}
@@ -494,9 +478,9 @@ ScaleWidgetObjCmd(clientData, interp, objc, objv)
*
* DestroyScale --
*
- * 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 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).
*
* Results:
* None.
@@ -508,8 +492,8 @@ ScaleWidgetObjCmd(clientData, interp, objc, objv)
*/
static void
-DestroyScale(memPtr)
- char *memPtr; /* Info about scale widget. */
+DestroyScale(
+ char *memPtr) /* Info about scale widget. */
{
register TkScale *scalePtr = (TkScale *) memPtr;
@@ -521,9 +505,8 @@ DestroyScale(memPtr)
}
/*
- * Free up all the stuff that requires special handling, then
- * let Tk_FreeOptions handle all the standard option-related
- * stuff.
+ * Free up all the stuff that requires special handling, then let
+ * Tk_FreeOptions handle all the standard option-related stuff.
*/
if (scalePtr->varNamePtr != NULL) {
@@ -551,29 +534,28 @@ DestroyScale(memPtr)
*
* ConfigureScale --
*
- * This procedure is called to process an argv/argc list, plus
- * the Tk option database, in order to configure (or
- * reconfigure) a scale widget.
+ * This procedure is called to process an argv/argc list, plus the Tk
+ * option database, in order to configure (or reconfigure) a scale
+ * widget.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message.
+ * 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 colors, border width,
- * etc. get set for scalePtr; old resources get freed,
- * if there were any.
+ * Configuration information, such as colors, border width, etc. get set
+ * for scalePtr; old resources get freed, if there were any.
*
*----------------------------------------------------------------------
*/
static int
-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 objc; /* Number of valid entries in objv. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+ConfigureScale(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ register TkScale *scalePtr, /* 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[]) /* Argument values. */
{
Tk_SavedOptions savedOptions;
Tcl_Obj *errorResult = NULL;
@@ -598,7 +580,7 @@ ConfigureScale(interp, scalePtr, objc, objv)
if (Tk_SetOptions(interp, (char *) scalePtr,
scalePtr->optionTable, objc, objv,
- scalePtr->tkwin, &savedOptions, (int *) NULL) != TCL_OK) {
+ scalePtr->tkwin, &savedOptions, NULL) != TCL_OK) {
continue;
}
} else {
@@ -612,9 +594,9 @@ ConfigureScale(interp, scalePtr, objc, objv)
}
/*
- * 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
- * and it holds a valid double value.
+ * 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 and it
+ * holds a valid double value.
*/
if (scalePtr->varNamePtr != NULL) {
@@ -634,11 +616,11 @@ ConfigureScale(interp, scalePtr, objc, objv)
* orientation and creating GCs.
*/
- scalePtr->fromValue = TkRoundToResolution(scalePtr,
- scalePtr->fromValue);
+ scalePtr->fromValue = TkRoundToResolution(scalePtr,
+ scalePtr->fromValue);
scalePtr->toValue = TkRoundToResolution(scalePtr, scalePtr->toValue);
scalePtr->tickInterval = TkRoundToResolution(scalePtr,
- scalePtr->tickInterval);
+ scalePtr->tickInterval);
/*
* Make sure that the tick interval has the right sign so that
@@ -646,13 +628,13 @@ ConfigureScale(interp, scalePtr, objc, objv)
*/
if ((scalePtr->tickInterval < 0)
- ^ ((scalePtr->toValue - scalePtr->fromValue) < 0)) {
- scalePtr->tickInterval = -scalePtr->tickInterval;
+ ^ ((scalePtr->toValue - scalePtr->fromValue) < 0)) {
+ scalePtr->tickInterval = -scalePtr->tickInterval;
}
ComputeFormat(scalePtr);
- scalePtr->labelLength = scalePtr->label ? strlen(scalePtr->label) : 0;
+ scalePtr->labelLength = scalePtr->label ? (int)strlen(scalePtr->label) : 0;
Tk_SetBackgroundFromBorder(scalePtr->tkwin, scalePtr->bgBorder);
@@ -663,14 +645,14 @@ ConfigureScale(interp, scalePtr, objc, objv)
break;
}
if (!error) {
- Tk_FreeSavedOptions(&savedOptions);
+ Tk_FreeSavedOptions(&savedOptions);
}
/*
- * 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. We don't set the var here because we need to make
- * special checks for possibly changed varNamePtr.
+ * 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. We
+ * don't set the var here because we need to make special checks for
+ * possibly changed varNamePtr.
*/
TkScaleSetValue(scalePtr, scalePtr->value, 0, 1);
@@ -683,36 +665,36 @@ ConfigureScale(interp, scalePtr, objc, objv)
Tcl_Obj *valuePtr;
/*
- * Set the associated variable only when the new value differs
- * from the current value, or the variable doesn't yet exist
+ * Set the associated variable only when the new value differs from
+ * the current value, or the variable doesn't yet exist.
*/
+
valuePtr = Tcl_ObjGetVar2(interp, scalePtr->varNamePtr, NULL,
TCL_GLOBAL_ONLY);
if ((valuePtr == NULL) || (Tcl_GetDoubleFromObj(NULL,
valuePtr, &varValue) != TCL_OK)) {
ScaleSetVariable(scalePtr);
} else {
- char varString[TCL_DOUBLE_SPACE];
- char scaleString[TCL_DOUBLE_SPACE];
+ char varString[TCL_DOUBLE_SPACE], scaleString[TCL_DOUBLE_SPACE];
+
sprintf(varString, scalePtr->format, varValue);
sprintf(scaleString, scalePtr->format, scalePtr->value);
if (strcmp(varString, scaleString)) {
ScaleSetVariable(scalePtr);
}
}
- Tcl_TraceVar(interp, Tcl_GetString(scalePtr->varNamePtr),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
- ScaleVarProc, (ClientData) scalePtr);
+ Tcl_TraceVar(interp, Tcl_GetString(scalePtr->varNamePtr),
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ ScaleVarProc, (ClientData) scalePtr);
}
ScaleWorldChanged((ClientData) scalePtr);
if (error) {
- Tcl_SetObjResult(interp, errorResult);
+ Tcl_SetObjResult(interp, errorResult);
Tcl_DecrRefCount(errorResult);
return TCL_ERROR;
- } else {
- return TCL_OK;
}
+ return TCL_OK;
}
/*
@@ -720,22 +702,22 @@ ConfigureScale(interp, scalePtr, objc, objv)
*
* ScaleWorldChanged --
*
- * This procedure is called when the world has changed in some
- * way and the widget needs to recompute all its graphics contexts
- * and determine its new geometry.
+ * This procedure is called when the world has changed in some way and
+ * the widget needs to recompute all its graphics contexts and determine
+ * its new geometry.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Scale will be relayed out and redisplayed.
+ * Scale will be relayed out and redisplayed.
*
*---------------------------------------------------------------------------
*/
-
+
static void
-ScaleWorldChanged(instanceData)
- ClientData instanceData; /* Information about widget. */
+ScaleWorldChanged(
+ ClientData instanceData) /* Information about widget. */
{
XGCValues gcValues;
GC gc;
@@ -761,13 +743,13 @@ ScaleWorldChanged(instanceData)
if (scalePtr->copyGC == None) {
gcValues.graphics_exposures = False;
scalePtr->copyGC = Tk_GetGC(scalePtr->tkwin, GCGraphicsExposures,
- &gcValues);
+ &gcValues);
}
scalePtr->inset = scalePtr->highlightWidth + scalePtr->borderWidth;
/*
- * Recompute display-related information, and let the geometry
- * manager know how much space is needed now.
+ * Recompute display-related information, and let the geometry manager
+ * know how much space is needed now.
*/
ComputeScaleGeometry(scalePtr);
@@ -780,9 +762,9 @@ ScaleWorldChanged(instanceData)
*
* ComputeFormat --
*
- * This procedure is invoked to recompute the "format" field
- * of a scale's widget record, which determines how the value
- * of the scale is converted to a string.
+ * This procedure is invoked to recompute the "format" field of a scale's
+ * widget record, which determines how the value of the scale is
+ * converted to a string.
*
* Results:
* None.
@@ -794,16 +776,16 @@ ScaleWorldChanged(instanceData)
*/
static void
-ComputeFormat(scalePtr)
- TkScale *scalePtr; /* Information about scale widget. */
+ComputeFormat(
+ TkScale *scalePtr) /* Information about scale widget. */
{
double maxValue, x;
int mostSigDigit, numDigits, leastSigDigit, afterDecimal;
int eDigits, fDigits;
/*
- * Compute the displacement from the decimal of the most significant
- * digit required for any number in the scale's range.
+ * Compute the displacement from the decimal of the most significant digit
+ * required for any number in the scale's range.
*/
maxValue = fabs(scalePtr->fromValue);
@@ -818,17 +800,16 @@ ComputeFormat(scalePtr)
/*
* If the number of significant digits wasn't specified explicitly,
- * compute it. It's the difference between the most significant
- * digit needed to represent any number on the scale and the
- * most significant digit of the smallest difference between
- * numbers on the scale. In other words, display enough digits so
- * that at least one digit will be different between any two adjacent
- * positions of the scale.
+ * compute it. It's the difference between the most significant digit
+ * needed to represent any number on the scale and the most significant
+ * digit of the smallest difference between numbers on the scale. In other
+ * words, display enough digits so that at least one digit will be
+ * different between any two adjacent positions of the scale.
*/
numDigits = scalePtr->digits;
if (numDigits <= 0) {
- if (scalePtr->resolution > 0) {
+ if (scalePtr->resolution > 0) {
/*
* A resolution was specified for the scale, so just use it.
*/
@@ -836,9 +817,9 @@ ComputeFormat(scalePtr)
leastSigDigit = (int) floor(log10(scalePtr->resolution));
} else {
/*
- * No resolution was specified, so compute the difference
- * in value between adjacent pixels and use it for the least
- * significant digit.
+ * No resolution was specified, so compute the difference in value
+ * between adjacent pixels and use it for the least significant
+ * digit.
*/
x = fabs(scalePtr->fromValue - scalePtr->toValue);
@@ -858,8 +839,8 @@ ComputeFormat(scalePtr)
}
/*
- * Compute the number of characters required using "e" format and
- * "f" format, and then choose whichever one takes fewer characters.
+ * Compute the number of characters required using "e" format and "f"
+ * format, and then choose whichever one takes fewer characters.
*/
eDigits = numDigits + 4;
@@ -889,23 +870,23 @@ ComputeFormat(scalePtr)
*
* ComputeScaleGeometry --
*
- * This procedure is called to compute various geometrical
- * information for a scale, such as where various things get
- * displayed. It's called when the window is reconfigured.
+ * This procedure is called to compute various geometrical information
+ * for a scale, such as where various things get displayed. It's called
+ * when the window is reconfigured.
*
* Results:
* None.
*
* Side effects:
- * Display-related numbers get changed in *scalePtr. The
- * geometry manager gets told about the window's preferred size.
+ * Display-related numbers get changed in *scalePtr. The geometry manager
+ * gets told about the window's preferred size.
*
*----------------------------------------------------------------------
*/
static void
-ComputeScaleGeometry(scalePtr)
- register TkScale *scalePtr; /* Information about widget. */
+ComputeScaleGeometry(
+ register TkScale *scalePtr) /* Information about widget. */
{
char valueString[PRINT_CHARS];
int tmp, valuePixels, x, y, extraSpace;
@@ -915,9 +896,9 @@ ComputeScaleGeometry(scalePtr)
scalePtr->fontHeight = fm.linespace + SPACING;
/*
- * Horizontal scales are simpler than vertical ones because
- * all sizes are the same (the height of a line of text);
- * handle them first and then quit.
+ * Horizontal scales are simpler than vertical ones because all sizes are
+ * the same (the height of a line of text); handle them first and then
+ * quit.
*/
if (scalePtr->orient == ORIENT_HORIZONTAL) {
@@ -949,9 +930,9 @@ ComputeScaleGeometry(scalePtr)
}
/*
- * Vertical scale: compute the amount of space needed to display
- * the scales value by formatting strings for the two end points;
- * use whichever length is longer.
+ * Vertical scale: compute the amount of space needed to display the
+ * scales value by formatting strings for the two end points; use
+ * whichever length is longer.
*/
sprintf(valueString, scalePtr->format, scalePtr->fromValue);
@@ -964,8 +945,8 @@ ComputeScaleGeometry(scalePtr)
}
/*
- * Assign x-locations to the elements of the scale, working from
- * left to right.
+ * Assign x-locations to the elements of the scale, working from left to
+ * right.
*/
x = scalePtr->inset;
@@ -1006,23 +987,23 @@ ComputeScaleGeometry(scalePtr)
*
* ScaleEventProc --
*
- * This procedure is invoked by the Tk dispatcher for various
- * events on scales.
+ * This procedure is invoked by the Tk dispatcher for various events on
+ * scales.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up.
+ * When it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-ScaleEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- XEvent *eventPtr; /* Information about event. */
+ScaleEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
TkScale *scalePtr = (TkScale *) clientData;
@@ -1055,9 +1036,9 @@ ScaleEventProc(clientData, eventPtr)
*
* ScaleCmdDeletedProc --
*
- * 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.
+ * 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.
@@ -1069,17 +1050,17 @@ ScaleEventProc(clientData, eventPtr)
*/
static void
-ScaleCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+ScaleCmdDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
TkScale *scalePtr = (TkScale *) clientData;
Tk_Window tkwin = scalePtr->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.
+ * 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.
*/
if (!(scalePtr->flags & SCALE_DELETED)) {
@@ -1093,25 +1074,25 @@ ScaleCmdDeletedProc(clientData)
*
* TkEventuallyRedrawScale --
*
- * Arrange for part or all of a scale widget to redrawn at
- * the next convenient time in the future.
+ * Arrange for part or all of a scale widget to redrawn at the next
+ * convenient time in the future.
*
* Results:
* None.
*
* Side effects:
- * If "what" is REDRAW_SLIDER then just the slider and the
- * value readout will be redrawn; if "what" is REDRAW_ALL
- * then the entire widget will be redrawn.
+ * If "what" is REDRAW_SLIDER then just the slider and the value readout
+ * will be redrawn; if "what" is REDRAW_ALL then the entire widget will
+ * be redrawn.
*
*--------------------------------------------------------------
*/
void
-TkEventuallyRedrawScale(scalePtr, what)
- register TkScale *scalePtr; /* Information about widget. */
- int what; /* What to redraw: REDRAW_SLIDER
- * or REDRAW_ALL. */
+TkEventuallyRedrawScale(
+ register TkScale *scalePtr, /* Information about widget. */
+ int what) /* What to redraw: REDRAW_SLIDER or
+ * REDRAW_ALL. */
{
if ((what == 0) || (scalePtr->tkwin == NULL)
|| !Tk_IsMapped(scalePtr->tkwin)) {
@@ -1129,8 +1110,8 @@ TkEventuallyRedrawScale(scalePtr, what)
*
* TkRoundToResolution --
*
- * Round a given floating-point value to the nearest multiple
- * of the scale's resolution.
+ * Round a given floating-point value to the nearest multiple of the
+ * scale's resolution.
*
* Results:
* The return value is the rounded result.
@@ -1142,28 +1123,28 @@ TkEventuallyRedrawScale(scalePtr, what)
*/
double
-TkRoundToResolution(scalePtr, value)
- TkScale *scalePtr; /* Information about scale widget. */
- double value; /* Value to round. */
+TkRoundToResolution(
+ TkScale *scalePtr, /* Information about scale widget. */
+ double value) /* Value to round. */
{
- double rem, new, tick;
+ double rem, rounded, tick;
if (scalePtr->resolution <= 0) {
return value;
}
tick = floor(value/scalePtr->resolution);
- new = scalePtr->resolution * tick;
- rem = value - new;
+ rounded = scalePtr->resolution * tick;
+ rem = value - rounded;
if (rem < 0) {
if (rem <= -scalePtr->resolution/2) {
- new = (tick - 1.0) * scalePtr->resolution;
+ rounded = (tick - 1.0) * scalePtr->resolution;
}
} else {
if (rem >= scalePtr->resolution/2) {
- new = (tick + 1.0) * scalePtr->resolution;
+ rounded = (tick + 1.0) * scalePtr->resolution;
}
}
- return new;
+ return rounded;
}
/*
@@ -1171,28 +1152,28 @@ TkRoundToResolution(scalePtr, value)
*
* ScaleVarProc --
*
- * This procedure is invoked by Tcl whenever someone modifies a
- * variable associated with a scale widget.
+ * This procedure is invoked by Tcl whenever someone modifies a variable
+ * associated with a scale widget.
*
* Results:
* NULL is always returned.
*
* Side effects:
- * The value displayed in the scale will change to match the
- * variable's new value. If the variable has a bogus value then
- * it is reset to the value of the scale.
+ * The value displayed in the scale will change to match the variable's
+ * new value. If the variable has a bogus value then it is reset to the
+ * value of the scale.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static char *
-ScaleVarProc(clientData, interp, name1, name2, flags)
- ClientData clientData; /* Information about button. */
- Tcl_Interp *interp; /* Interpreter containing variable. */
- CONST char *name1; /* Name of variable. */
- CONST char *name2; /* Second part of variable name. */
- int flags; /* Information about what happened. */
+ScaleVarProc(
+ ClientData clientData, /* Information about button. */
+ Tcl_Interp *interp, /* Interpreter containing variable. */
+ const char *name1, /* Name of variable. */
+ const char *name2, /* Second part of variable name. */
+ int flags) /* Information about what happened. */
{
register TkScale *scalePtr = (TkScale *) clientData;
char *resultStr;
@@ -1201,8 +1182,8 @@ ScaleVarProc(clientData, interp, name1, name2, flags)
int result;
/*
- * If the variable is unset, then immediately recreate it unless
- * the whole interpreter is going away.
+ * If the variable is unset, then immediately recreate it unless the whole
+ * interpreter is going away.
*/
if (flags & TCL_TRACE_UNSETS) {
@@ -1213,34 +1194,33 @@ ScaleVarProc(clientData, interp, name1, name2, flags)
scalePtr->flags |= NEVER_SET;
TkScaleSetValue(scalePtr, scalePtr->value, 1, 0);
}
- return (char *) NULL;
+ return NULL;
}
/*
* If we came here because we updated the variable (in TkScaleSetValue),
- * then ignore the trace. Otherwise update the scale with the value
- * of the variable.
+ * then ignore the trace. Otherwise update the scale with the value of the
+ * variable.
*/
if (scalePtr->flags & SETTING_VAR) {
- return (char *) NULL;
+ return NULL;
}
resultStr = NULL;
- valuePtr = Tcl_ObjGetVar2(interp, scalePtr->varNamePtr, NULL,
- TCL_GLOBAL_ONLY);
+ valuePtr = Tcl_ObjGetVar2(interp, scalePtr->varNamePtr, NULL,
+ TCL_GLOBAL_ONLY);
result = Tcl_GetDoubleFromObj(interp, valuePtr, &value);
if (result != TCL_OK) {
- resultStr = "can't assign non-numeric value to scale variable";
+ resultStr = "can't assign non-numeric value to scale variable";
ScaleSetVariable(scalePtr);
} else {
scalePtr->value = TkRoundToResolution(scalePtr, value);
/*
* This code is a bit tricky because it sets the scale's value before
- * calling TkScaleSetValue. This way, TkScaleSetValue 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.
+ * calling TkScaleSetValue. This way, TkScaleSetValue 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.
*/
TkScaleSetValue(scalePtr, scalePtr->value, 1, 0);
@@ -1255,28 +1235,28 @@ ScaleVarProc(clientData, interp, name1, name2, flags)
*
* TkScaleSetValue --
*
- * This procedure changes the value of a scale and invokes
- * a Tcl command to reflect the current position of a scale
+ * This procedure changes the value of a scale and invokes a Tcl command
+ * to reflect the current position of a scale
*
* Results:
* None.
*
* Side effects:
- * A Tcl command is invoked, and an additional error-processing
- * command may also be invoked. The scale's slider is redrawn.
+ * A Tcl command is invoked, and an additional error-processing command
+ * may also be invoked. The scale's slider is redrawn.
*
*--------------------------------------------------------------
*/
void
-TkScaleSetValue(scalePtr, value, setVar, invokeCommand)
- register TkScale *scalePtr; /* Info about widget. */
- double value; /* New value for scale. Gets adjusted
- * if it's off the scale. */
- int setVar; /* Non-zero means reflect new value through
- * to associated variable, if any. */
- int invokeCommand; /* Non-zero means invoked -command option
- * to notify of new value, 0 means don't. */
+TkScaleSetValue(
+ register TkScale *scalePtr, /* Info about widget. */
+ double value, /* New value for scale. Gets adjusted if it's
+ * off the scale. */
+ int setVar, /* Non-zero means reflect new value through to
+ * associated variable, if any. */
+ int invokeCommand) /* Non-zero means invoked -command option to
+ * notify of new value, 0 means don't. */
{
value = TkRoundToResolution(scalePtr, value);
if ((value < scalePtr->fromValue)
@@ -1320,11 +1300,12 @@ TkScaleSetValue(scalePtr, value, setVar, invokeCommand)
*/
static void
-ScaleSetVariable(scalePtr)
- register TkScale *scalePtr; /* Info about widget. */
+ScaleSetVariable(
+ register TkScale *scalePtr) /* Info about widget. */
{
if (scalePtr->varNamePtr != NULL) {
char string[PRINT_CHARS];
+
sprintf(string, scalePtr->format, scalePtr->value);
scalePtr->flags |= SETTING_VAR;
Tcl_ObjSetVar2(scalePtr->interp, scalePtr->varNamePtr, NULL,
@@ -1338,13 +1319,12 @@ ScaleSetVariable(scalePtr)
*
* TkScalePixelToValue --
*
- * Given a pixel within a scale window, return the scale
- * reading corresponding to that pixel.
+ * Given a pixel within a scale window, return the scale reading
+ * corresponding to that pixel.
*
* Results:
- * A double-precision scale reading. If the value is outside
- * the legal range for the scale then it's rounded to the nearest
- * end of the scale.
+ * A double-precision scale reading. If the value is outside the legal
+ * range for the scale then it's rounded to the nearest end of the scale.
*
* Side effects:
* None.
@@ -1353,10 +1333,9 @@ ScaleSetVariable(scalePtr)
*/
double
-TkScalePixelToValue(scalePtr, x, y)
- register TkScale *scalePtr; /* Information about widget. */
- int x, y; /* Coordinates of point within
- * window. */
+TkScalePixelToValue(
+ register TkScale *scalePtr, /* Information about widget. */
+ int x, int y) /* Coordinates of point within window. */
{
double value, pixelRange;
@@ -1372,14 +1351,14 @@ TkScalePixelToValue(scalePtr, x, y)
if (pixelRange <= 0) {
/*
- * Not enough room for the slider to actually slide: just return
- * the scale's current value.
+ * Not enough room for the slider to actually slide: just return the
+ * scale's current value.
*/
return scalePtr->value;
}
value -= scalePtr->sliderLength/2 + scalePtr->inset
- + scalePtr->borderWidth;
+ + scalePtr->borderWidth;
value /= pixelRange;
if (value < 0) {
value = 0;
@@ -1397,14 +1376,13 @@ TkScalePixelToValue(scalePtr, x, y)
*
* TkScaleValueToPixel --
*
- * Given a reading of the scale, return the x-coordinate or
- * y-coordinate corresponding to that reading, depending on
- * whether the scale is vertical or horizontal, respectively.
+ * Given a reading of the scale, return the x-coordinate or y-coordinate
+ * corresponding to that reading, depending on whether the scale is
+ * vertical or horizontal, respectively.
*
* Results:
- * An integer value giving the pixel location corresponding
- * to reading. The value is restricted to lie within the
- * defined range for the scale.
+ * An integer value giving the pixel location corresponding to reading.
+ * The value is restricted to lie within the defined range for the scale.
*
* Side effects:
* None.
@@ -1413,9 +1391,9 @@ TkScalePixelToValue(scalePtr, x, y)
*/
int
-TkScaleValueToPixel(scalePtr, value)
- register TkScale *scalePtr; /* Information about widget. */
- double value; /* Reading of the widget. */
+TkScaleValueToPixel(
+ register TkScale *scalePtr, /* Information about widget. */
+ double value) /* Reading of the widget. */
{
int y, pixelRange;
double valueRange;
@@ -1428,7 +1406,7 @@ TkScaleValueToPixel(scalePtr, value)
y = 0;
} else {
y = (int) ((value - scalePtr->fromValue) * pixelRange
- / valueRange + 0.5);
+ / valueRange + 0.5);
if (y < 0) {
y = 0;
} else if (y > pixelRange) {
@@ -1438,3 +1416,11 @@ TkScaleValueToPixel(scalePtr, value)
y += scalePtr->sliderLength/2 + scalePtr->inset + scalePtr->borderWidth;
return y;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkScale.h b/generic/tkScale.h
index 71d5d53..f406bf6 100644
--- a/generic/tkScale.h
+++ b/generic/tkScale.h
@@ -1,21 +1,21 @@
/*
* tkScale.h --
*
- * Declarations of types and functions used to implement
- * the scale widget.
+ * Declarations of types and functions used to implement the scale
+ * widget.
*
* Copyright (c) 1996 by Sun Microsystems, Inc.
* Copyright (c) 1999-2000 by Scriptics Corporation.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKSCALE
#define _TKSCALE
-#ifndef _TK
-#include "tk.h"
+#ifndef _TKINT
+#include "tkInt.h"
#endif
#ifdef BUILD_tk
@@ -40,16 +40,16 @@ enum state {
};
/*
- * A data structure of the following type is kept for each scale
- * widget managed by this file:
+ * A data structure of the following type is kept for each scale widget
+ * managed by this file:
*/
typedef struct TkScale {
- Tk_Window tkwin; /* Window that embodies the scale. NULL
- * means that the window has been destroyed
- * but the data structures haven't yet been
- * cleaned up.*/
- Display *display; /* Display containing widget. Used, among
+ Tk_Window tkwin; /* Window that embodies the scale. NULL means
+ * that the window has been destroyed but the
+ * data structures haven't yet been cleaned
+ * up.*/
+ Display *display; /* Display containing widget. Used, among
* other things, so that resources can be
* freed even after tkwin has gone away. */
Tcl_Interp *interp; /* Interpreter associated with scale. */
@@ -58,42 +58,41 @@ typedef struct TkScale {
* 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. */
+ int width; /* Desired narrow dimension of scale, in
+ * pixels. */
+ int length; /* Desired long dimension of scale, in
+ * pixels. */
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. */
+ Tcl_Obj *varNamePtr; /* Name of variable or NULL. If non-NULL,
+ * scale's value tracks the contents of this
+ * variable and vice versa. */
double fromValue; /* Value corresponding to left or top of
* scale. */
- double toValue; /* Value corresponding to right or bottom
- * of scale. */
- double tickInterval; /* Distance between tick marks;
- * 0 means don't display any tick marks. */
- double resolution; /* If > 0, all values are rounded to an
- * even multiple of this value. */
- int digits; /* Number of significant digits to print
- * in values. 0 means we get to choose the
- * number based on resolution and/or the
- * range of the scale. */
+ double toValue; /* Value corresponding to right or bottom of
+ * scale. */
+ double tickInterval; /* Distance between tick marks; 0 means don't
+ * display any tick marks. */
+ double resolution; /* If > 0, all values are rounded to an even
+ * multiple of this value. */
+ int digits; /* Number of significant digits to print in
+ * values. 0 means we get to choose the number
+ * based on resolution and/or the range of the
+ * scale. */
char format[10]; /* Sprintf conversion specifier computed from
* digits and other information. */
- double bigIncrement; /* Amount to use for large increments to
- * scale value. (0 means we pick a value). */
+ 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
* commands because the scale value changed.
* NULL means don't invoke commands. */
- int repeatDelay; /* How long to wait before auto-repeating
- * on scrolling actions (in ms). */
+ 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
- * scale; NULL means don't display a label. */
+ * scale; NULL means don't display a label. */
int labelLength; /* Number of non-NULL chars. in label. */
enum state state; /* Values are active, normal, or disabled.
- * Value of scale cannot be changed when
+ * Value of scale cannot be changed when
* disabled. */
/*
@@ -104,19 +103,19 @@ 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,
+ 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. */
+ GC copyGC; /* Used for copying from pixmap onto screen */
Tk_Font tkfont; /* Information about text font, or NULL. */
XColor *textColorPtr; /* Color for drawing text. */
GC textGC; /* GC for drawing text in normal mode. */
int relief; /* Indicates whether window as a whole is
* raised, sunken, or flat. */
- int highlightWidth; /* Width in pixels of highlight to draw
- * around widget when it has the focus.
- * <= 0 means don't draw a highlight. */
+ int highlightWidth; /* Width in pixels of highlight to draw around
+ * widget when it has the focus. <= 0 means
+ * don't draw a highlight. */
Tk_3DBorder highlightBorder;/* Value of -highlightbackground option:
* specifies background with which to draw 3-D
* default ring and focus highlight area when
@@ -124,18 +123,18 @@ typedef struct TkScale {
XColor *highlightColorPtr; /* 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. */
+ * Indicates how much interior stuff must be
+ * offset from outside edges to leave room for
+ * borders. */
int sliderLength; /* Length of slider, measured in pixels along
* long dimension of scale. */
int showValue; /* Non-zero means to display the scale value
- * below or to the left of the slider; zero
+ * below or to the left of the slider; zero
* means don't display the value. */
/*
- * Layout information for horizontal scales, assuming that window
- * gets the size it requested:
+ * Layout information for horizontal scales, assuming that window gets the
+ * size it requested:
*/
int horizLabelY; /* Y-coord at which to draw label. */
@@ -143,8 +142,8 @@ typedef struct TkScale {
int horizTroughY; /* Y-coord of top of slider trough. */
int horizTickY; /* Y-coord at which to draw tick text. */
/*
- * Layout information for vertical scales, assuming that window
- * gets the size it requested:
+ * Layout information for vertical scales, assuming that window gets the
+ * size it requested:
*/
int vertTickRightX; /* X-location of right side of tick-marks. */
@@ -158,37 +157,37 @@ typedef struct TkScale {
int fontHeight; /* Height of scale font. */
Tk_Cursor cursor; /* Current cursor for window, or None. */
- Tcl_Obj *takeFocusPtr; /* Value of -takefocus option; not used in
- * the C code, but used by keyboard traversal
- * scripts. May be NULL. */
- int flags; /* Various flags; see below for
+ Tcl_Obj *takeFocusPtr; /* Value of -takefocus option; not used in the
+ * C code, but used by keyboard traversal
+ * scripts. May be NULL. */
+ int flags; /* Various flags; see below for
* definitions. */
} TkScale;
/*
* Flag bits for scales:
*
- * REDRAW_SLIDER - 1 means slider (and numerical readout) need
- * to be redrawn.
+ * REDRAW_SLIDER - 1 means slider (and numerical readout) need to
+ * be redrawn.
* REDRAW_OTHER - 1 means other stuff besides slider and value
* need to be redrawn.
* REDRAW_ALL - 1 means the entire widget needs to be redrawn.
* REDRAW_PENDING - 1 means any sort of redraw is pending
- * ACTIVE - 1 means the widget is active (the mouse is
- * in its window).
+ * ACTIVE - 1 means the widget is active (the mouse is in
+ * its window).
* INVOKE_COMMAND - 1 means the scale's command needs to be
- * invoked during the next redisplay (the
- * value of the scale has changed since the
- * last time the command was invoked).
- * SETTING_VAR - 1 means that the associated variable is
- * being set by us, so there's no need for
- * ScaleVarProc to do anything.
- * NEVER_SET - 1 means that the scale's value has never
- * been set before (so must invoke -command and
- * set associated variable even if the value
- * doesn't appear to have changed).
- * GOT_FOCUS - 1 means that the focus is currently in
- * this widget.
+ * invoked during the next redisplay (the value
+ * of the scale has changed since the last time
+ * the command was invoked).
+ * SETTING_VAR - 1 means that the associated variable is being
+ * set by us, so there's no need for ScaleVarProc
+ * to do anything.
+ * NEVER_SET - 1 means that the scale's value has never been
+ * set before (so must invoke -command and set
+ * associated variable even if the value doesn't
+ * appear to have changed).
+ * GOT_FOCUS - 1 means that the focus is currently in this
+ * widget.
* SCALE_DELETED - 1 means the scale widget is being deleted
*/
@@ -204,8 +203,8 @@ typedef struct TkScale {
#define SCALE_DELETED (1<<8)
/*
- * Symbolic values for the active parts of a slider. These are
- * the values that may be returned by the ScaleElement procedure.
+ * Symbolic values for the active parts of a slider. These are the values that
+ * may be returned by the ScaleElement procedure.
*/
#define OTHER 0
@@ -214,39 +213,32 @@ typedef struct TkScale {
#define TROUGH2 3
/*
- * Space to leave between scale area and text, and between text and
- * edge of window.
+ * Space to leave between scale area and text, and between text and edge of
+ * window.
*/
#define SPACING 2
/*
- * How many characters of space to provide when formatting the
- * scale's value:
+ * How many characters of space to provide when formatting the scale's value:
*/
#define PRINT_CHARS 150
/*
- * Declaration of procedures used in the implementation of the scale
- * widget.
+ * Declaration of procedures used in the implementation of the scale widget.
*/
-EXTERN void TkEventuallyRedrawScale _ANSI_ARGS_((TkScale *scalePtr,
- int what));
-EXTERN double TkRoundToResolution _ANSI_ARGS_((TkScale *scalePtr,
- double value));
-EXTERN TkScale * TkpCreateScale _ANSI_ARGS_((Tk_Window tkwin));
-EXTERN void TkpDestroyScale _ANSI_ARGS_((TkScale *scalePtr));
-EXTERN void TkpDisplayScale _ANSI_ARGS_((ClientData clientData));
-EXTERN int TkpScaleElement _ANSI_ARGS_((TkScale *scalePtr,
- int x, int y));
-EXTERN void TkScaleSetValue _ANSI_ARGS_((TkScale *scalePtr,
- double value, int setVar, int invokeCommand));
-EXTERN double TkScalePixelToValue _ANSI_ARGS_((TkScale *scalePtr,
- int x, int y));
-EXTERN int TkScaleValueToPixel _ANSI_ARGS_((TkScale *scalePtr,
- double value));
+MODULE_SCOPE void TkEventuallyRedrawScale(TkScale *scalePtr, int what);
+MODULE_SCOPE double TkRoundToResolution(TkScale *scalePtr, double value);
+MODULE_SCOPE TkScale * TkpCreateScale(Tk_Window tkwin);
+MODULE_SCOPE void TkpDestroyScale(TkScale *scalePtr);
+MODULE_SCOPE void TkpDisplayScale(ClientData clientData);
+MODULE_SCOPE int TkpScaleElement(TkScale *scalePtr, int x, int y);
+MODULE_SCOPE void TkScaleSetValue(TkScale *scalePtr, double value,
+ int setVar, int invokeCommand);
+MODULE_SCOPE double TkScalePixelToValue(TkScale *scalePtr, int x, int y);
+MODULE_SCOPE int TkScaleValueToPixel(TkScale *scalePtr, double value);
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLIMPORT
diff --git a/generic/tkScrollbar.c b/generic/tkScrollbar.c
index d4f3d88..3fff58d 100644
--- a/generic/tkScrollbar.c
+++ b/generic/tkScrollbar.c
@@ -1,19 +1,18 @@
-/*
+/*
* tkScrollbar.c --
*
- * This module implements a scrollbar widgets for the Tk
- * toolkit. A scrollbar displays a slider and two arrows;
- * mouse clicks on features within the scrollbar cause
- * scrolling commands to be invoked.
+ * This module implements a scrollbar widgets for the Tk toolkit. A
+ * scrollbar displays a slider and two arrows; mouse clicks on features
+ * within the scrollbar cause scrolling commands to be invoked.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
+#include "tkInt.h"
#include "tkScrollbar.h"
#include "default.h"
@@ -27,11 +26,14 @@ static Tk_CustomOption orientOption = {
(ClientData) NULL
};
+/* non-const space for "-width" default value for scrollbars */
+char tkDefScrollbarWidth[TCL_INTEGER_SPACE] = DEF_SCROLLBAR_WIDTH;
+
/*
* Information used for argv parsing.
*/
-Tk_ConfigSpec tkpScrollbarConfigSpecs[] = {
+static Tk_ConfigSpec configSpecs[] = {
{TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground",
DEF_SCROLLBAR_ACTIVE_BG_COLOR, Tk_Offset(TkScrollbar, activeBorder),
TK_CONFIG_COLOR_ONLY},
@@ -46,10 +48,8 @@ Tk_ConfigSpec tkpScrollbarConfigSpecs[] = {
{TK_CONFIG_BORDER, "-background", "background", "Background",
DEF_SCROLLBAR_BG_MONO, Tk_Offset(TkScrollbar, 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_SYNONYM, "-bd", "borderWidth", NULL, NULL, 0, 0},
+ {TK_CONFIG_SYNONYM, "-bg", "background", NULL, NULL, 0, 0},
{TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
DEF_SCROLLBAR_BORDER_WIDTH, Tk_Offset(TkScrollbar, borderWidth), 0},
{TK_CONFIG_STRING, "-command", "command", "Command",
@@ -90,31 +90,28 @@ Tk_ConfigSpec tkpScrollbarConfigSpecs[] = {
DEF_SCROLLBAR_TROUGH_MONO, Tk_Offset(TkScrollbar, troughColorPtr),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_PIXELS, "-width", "width", "Width",
- DEF_SCROLLBAR_WIDTH, Tk_Offset(TkScrollbar, width), 0},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+ tkDefScrollbarWidth, Tk_Offset(TkScrollbar, width), 0},
+ {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
};
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static int ConfigureScrollbar _ANSI_ARGS_((Tcl_Interp *interp,
- TkScrollbar *scrollPtr, int argc, CONST char **argv,
- int flags));
-static void ScrollbarCmdDeletedProc _ANSI_ARGS_((
- ClientData clientData));
-static int ScrollbarWidgetCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *, int argc, CONST char **argv));
+static int ConfigureScrollbar(Tcl_Interp *interp,
+ TkScrollbar *scrollPtr, int argc,
+ CONST char **argv, int flags);
+static void ScrollbarCmdDeletedProc(ClientData clientData);
+static int ScrollbarWidgetCmd(ClientData clientData,
+ Tcl_Interp *, int argc, CONST char **argv);
/*
*--------------------------------------------------------------
*
* Tk_ScrollbarCmd --
*
- * This procedure is invoked to process the "scrollbar" Tcl
- * command. See the user documentation for details on what
- * it does.
+ * This function is invoked to process the "scrollbar" Tcl command. See
+ * the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -126,41 +123,40 @@ static int ScrollbarWidgetCmd _ANSI_ARGS_((ClientData clientData,
*/
int
-Tk_ScrollbarCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+Tk_ScrollbarCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ CONST char **argv) /* Argument strings. */
{
Tk_Window tkwin = (Tk_Window) clientData;
register TkScrollbar *scrollPtr;
- Tk_Window new;
+ Tk_Window newWin;
if (argc < 2) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " pathName ?options?\"", (char *) NULL);
+ argv[0], " pathName ?options?\"", NULL);
return TCL_ERROR;
}
- new = Tk_CreateWindowFromPath(interp, tkwin, argv[1], (char *) NULL);
- if (new == NULL) {
+ newWin = Tk_CreateWindowFromPath(interp, tkwin, argv[1], NULL);
+ if (newWin == NULL) {
return TCL_ERROR;
}
- Tk_SetClass(new, "Scrollbar");
- scrollPtr = TkpCreateScrollbar(new);
+ Tk_SetClass(newWin, "Scrollbar");
+ scrollPtr = TkpCreateScrollbar(newWin);
- Tk_SetClassProcs(new, &tkpScrollbarProcs, (ClientData) scrollPtr);
+ Tk_SetClassProcs(newWin, &tkpScrollbarProcs, (ClientData) scrollPtr);
/*
- * Initialize fields that won't be initialized by ConfigureScrollbar,
- * or which ConfigureScrollbar expects to have reasonable values
- * (e.g. resource pointers).
+ * Initialize fields that won't be initialized by ConfigureScrollbar, or
+ * which ConfigureScrollbar expects to have reasonable values (e.g.
+ * resource pointers).
*/
- scrollPtr->tkwin = new;
- scrollPtr->display = Tk_Display(new);
+ scrollPtr->tkwin = newWin;
+ scrollPtr->display = Tk_Display(newWin);
scrollPtr->interp = interp;
scrollPtr->widgetCmd = Tcl_CreateCommand(interp,
Tk_PathName(scrollPtr->tkwin), ScrollbarWidgetCmd,
@@ -210,9 +206,9 @@ Tk_ScrollbarCmd(clientData, interp, argc, argv)
*
* ScrollbarWidgetCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to a widget managed by this module.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the Tcl command that corresponds
+ * to a widget managed by this module. See the user documentation for
+ * details on what it does.
*
* Results:
* A standard Tcl result.
@@ -224,12 +220,11 @@ Tk_ScrollbarCmd(clientData, interp, argc, argv)
*/
static int
-ScrollbarWidgetCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Information about scrollbar
- * widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+ScrollbarWidgetCmd(
+ ClientData clientData, /* Information about scrollbar widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ CONST char **argv) /* Argument strings. */
{
register TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
int result = TCL_OK;
@@ -238,7 +233,7 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv)
if (argc < 2) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " option ?arg arg ...?\"", (char *) NULL);
+ argv[0], " option ?arg arg ...?\"", NULL);
return TCL_ERROR;
}
Tcl_Preserve((ClientData) scrollPtr);
@@ -248,21 +243,21 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv)
int oldActiveField;
if (argc == 2) {
switch (scrollPtr->activeField) {
- 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;
+ 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;
}
if (argc != 3) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " activate element\"", (char *) NULL);
+ argv[0], " activate element\"", NULL);
goto error;
}
c = argv[2][0];
@@ -285,20 +280,19 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv)
if (argc != 3) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
argv[0], " cget option\"",
- (char *) NULL);
+ NULL);
goto error;
}
result = Tk_ConfigureValue(interp, scrollPtr->tkwin,
- tkpScrollbarConfigSpecs, (char *) scrollPtr, argv[2], 0);
+ configSpecs, (char *) scrollPtr, argv[2], 0);
} else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)
&& (length >= 2)) {
if (argc == 2) {
result = Tk_ConfigureInfo(interp, scrollPtr->tkwin,
- tkpScrollbarConfigSpecs, (char *) scrollPtr,
- (char *) NULL, 0);
+ configSpecs, (char *) scrollPtr, NULL, 0);
} else if (argc == 3) {
result = Tk_ConfigureInfo(interp, scrollPtr->tkwin,
- tkpScrollbarConfigSpecs, (char *) scrollPtr, argv[2], 0);
+ configSpecs, (char *) scrollPtr, argv[2], 0);
} else {
result = ConfigureScrollbar(interp, scrollPtr, argc-2, argv+2,
TK_CONFIG_ARGV_ONLY);
@@ -310,7 +304,7 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv)
if (argc != 4) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " delta xDelta yDelta\"", (char *) NULL);
+ argv[0], " delta xDelta yDelta\"", NULL);
goto error;
}
if ((Tcl_GetInt(interp, argv[2], &xDelta) != TCL_OK)
@@ -331,7 +325,7 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv)
} else {
fraction = ((double) pixels / (double) length);
}
- sprintf(buf, "%g", fraction);
+ Tcl_PrintDouble(NULL, fraction, buf);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
} else if ((c == 'f') && (strncmp(argv[1], "fraction", length) == 0)) {
int x, y, pos, length;
@@ -340,7 +334,7 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv)
if (argc != 4) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " fraction x y\"", (char *) NULL);
+ argv[0], " fraction x y\"", NULL);
goto error;
}
if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK)
@@ -366,12 +360,12 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv)
} else if (fraction > 1.0) {
fraction = 1.0;
}
- sprintf(buf, "%g", fraction);
+ Tcl_PrintDouble(NULL, fraction, buf);
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 \"",
- argv[0], " get\"", (char *) NULL);
+ argv[0], " get\"", NULL);
goto error;
}
if (scrollPtr->flags & NEW_STYLE_COMMANDS) {
@@ -379,7 +373,7 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv)
Tcl_PrintDouble(interp, scrollPtr->firstFraction, first);
Tcl_PrintDouble(interp, scrollPtr->lastFraction, last);
- Tcl_AppendResult(interp, first, " ", last, (char *) NULL);
+ Tcl_AppendResult(interp, first, " ", last, NULL);
} else {
char buf[TCL_INTEGER_SPACE * 4];
@@ -393,7 +387,7 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv)
if (argc != 4) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " identify x y\"", (char *) NULL);
+ argv[0], " identify x y\"", NULL);
goto error;
}
if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK)
@@ -402,21 +396,21 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv)
}
thing = TkpScrollbarPosition(scrollPtr, x,y);
switch (thing) {
- 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;
+ 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;
@@ -487,8 +481,7 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv)
Tcl_AppendResult(interp, "wrong # args: should be \"",
argv[0], " set firstFraction lastFraction\" or \"",
argv[0],
- " set totalUnits windowUnits firstUnit lastUnit\"",
- (char *) NULL);
+ " set totalUnits windowUnits firstUnit lastUnit\"", NULL);
goto error;
}
TkpComputeScrollbarGeometry(scrollPtr);
@@ -496,14 +489,15 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv)
} else {
Tcl_AppendResult(interp, "bad option \"", argv[1],
"\": must be activate, cget, configure, delta, fraction, ",
- "get, identify, or set", (char *) NULL);
+ "get, identify, or set", NULL);
goto error;
}
- done:
+
+ done:
Tcl_Release((ClientData) scrollPtr);
return result;
- error:
+ error:
Tcl_Release((ClientData) scrollPtr);
return TCL_ERROR;
}
@@ -513,45 +507,43 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv)
*
* ConfigureScrollbar --
*
- * This procedure is called to process an argv/argc list, plus
- * the Tk option database, in order to configure (or
- * reconfigure) a scrollbar widget.
+ * This function is called to process an argv/argc list, plus the Tk
+ * option database, in order to configure (or reconfigure) a scrollbar
+ * widget.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message.
+ * 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 colors, border width,
- * etc. get set for scrollPtr; old resources get freed,
- * if there were any.
+ * Configuration information, such as colors, border width, etc. get set
+ * for scrollPtr; old resources get freed, if there were any.
*
*----------------------------------------------------------------------
*/
static int
-ConfigureScrollbar(interp, scrollPtr, argc, argv, flags)
- Tcl_Interp *interp; /* Used for error reporting. */
- register TkScrollbar *scrollPtr; /* Information about widget; may or
- * may not already have values for
- * some fields. */
- int argc; /* Number of valid entries in argv. */
- CONST char **argv; /* Arguments. */
- int flags; /* Flags to pass to
- * Tk_ConfigureWidget. */
+ConfigureScrollbar(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ register TkScrollbar *scrollPtr,
+ /* Information about widget; may or may not
+ * already have values for some fields. */
+ int argc, /* Number of valid entries in argv. */
+ CONST char **argv, /* Arguments. */
+ int flags) /* Flags to pass to Tk_ConfigureWidget. */
{
- if (Tk_ConfigureWidget(interp, scrollPtr->tkwin, tkpScrollbarConfigSpecs,
+ if (Tk_ConfigureWidget(interp, scrollPtr->tkwin, configSpecs,
argc, argv, (char *) scrollPtr, flags) != TCL_OK) {
return TCL_ERROR;
}
/*
- * A few options need special processing, such as setting the
- * background from a 3-D border.
+ * A few options need special processing, such as setting the background
+ * from a 3-D border.
*/
if (scrollPtr->command != NULL) {
- scrollPtr->commandSize = strlen(scrollPtr->command);
+ scrollPtr->commandSize = (int)strlen(scrollPtr->command);
} else {
scrollPtr->commandSize = 0;
}
@@ -563,10 +555,9 @@ ConfigureScrollbar(interp, scrollPtr, argc, argv, flags)
TkpConfigureScrollbar(scrollPtr);
/*
- * Register the desired geometry for the window (leave enough space
- * for the two arrows plus a minimum-size slider, plus border around
- * the whole window, if any). Then arrange for the window to be
- * redisplayed.
+ * Register the desired geometry for the window (leave enough space for
+ * the two arrows plus a minimum-size slider, plus border around the whole
+ * window, if any). Then arrange for the window to be redisplayed.
*/
TkpComputeScrollbarGeometry(scrollPtr);
@@ -579,23 +570,23 @@ ConfigureScrollbar(interp, scrollPtr, argc, argv, flags)
*
* TkScrollbarEventProc --
*
- * This procedure is invoked by the Tk dispatcher for various
- * events on scrollbars.
+ * This function is invoked by the Tk dispatcher for various events on
+ * scrollbars.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up.
+ * When it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
void
-TkScrollbarEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- XEvent *eventPtr; /* Information about event. */
+TkScrollbarEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
@@ -606,18 +597,17 @@ TkScrollbarEventProc(clientData, eventPtr)
if (scrollPtr->tkwin != NULL) {
scrollPtr->tkwin = NULL;
Tcl_DeleteCommandFromToken(scrollPtr->interp,
- scrollPtr->widgetCmd);
+ scrollPtr->widgetCmd);
}
if (scrollPtr->flags & REDRAW_PENDING) {
Tcl_CancelIdleCall(TkpDisplayScrollbar, (ClientData) scrollPtr);
}
/*
- * Free up all the stuff that requires special handling, then
- * let Tk_FreeOptions handle all the standard option-related
- * stuff.
+ * Free up all the stuff that requires special handling, then let
+ * Tk_FreeOptions handle all the standard option-related stuff.
*/
-
- Tk_FreeOptions(tkpScrollbarConfigSpecs, (char *) scrollPtr,
+
+ Tk_FreeOptions(configSpecs, (char *) scrollPtr,
scrollPtr->display, 0);
Tcl_EventuallyFree((ClientData) scrollPtr, TCL_DYNAMIC);
} else if (eventPtr->type == ConfigureNotify) {
@@ -645,9 +635,9 @@ TkScrollbarEventProc(clientData, eventPtr)
*
* ScrollbarCmdDeletedProc --
*
- * 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.
+ * This function 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.
@@ -659,17 +649,17 @@ TkScrollbarEventProc(clientData, eventPtr)
*/
static void
-ScrollbarCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+ScrollbarCmdDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
Tk_Window tkwin = scrollPtr->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.
+ * This function 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 function destroys the
+ * widget.
*/
if (tkwin != NULL) {
@@ -683,8 +673,7 @@ ScrollbarCmdDeletedProc(clientData)
*
* TkScrollbarEventuallyRedraw --
*
- * Arrange for one or more of the fields of a scrollbar
- * to be redrawn.
+ * Arrange for one or more of the fields of a scrollbar to be redrawn.
*
* Results:
* None.
@@ -696,8 +685,8 @@ ScrollbarCmdDeletedProc(clientData)
*/
void
-TkScrollbarEventuallyRedraw(scrollPtr)
- register TkScrollbar *scrollPtr; /* Information about widget. */
+TkScrollbarEventuallyRedraw(
+ TkScrollbar *scrollPtr) /* Information about widget. */
{
if ((scrollPtr->tkwin == NULL) || (!Tk_IsMapped(scrollPtr->tkwin))) {
return;
@@ -707,3 +696,11 @@ TkScrollbarEventuallyRedraw(scrollPtr)
scrollPtr->flags |= REDRAW_PENDING;
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkScrollbar.h b/generic/tkScrollbar.h
index 6b7f2dc..126d590 100644
--- a/generic/tkScrollbar.h
+++ b/generic/tkScrollbar.h
@@ -1,13 +1,13 @@
/*
* tkScrollbar.h --
*
- * Declarations of types and functions used to implement
- * the scrollbar widget.
+ * Declarations of types and functions used to implement the scrollbar
+ * widget.
*
* Copyright (c) 1996 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKSCROLLBAR
@@ -17,36 +17,30 @@
#include "tkInt.h"
#endif
-#ifdef BUILD_tk
-# undef TCL_STORAGE_CLASS
-# define TCL_STORAGE_CLASS DLLEXPORT
-#endif
-
/*
- * A data structure of the following type is kept for each scrollbar
- * widget.
+ * A data structure of the following type is kept for each scrollbar widget.
*/
typedef struct TkScrollbar {
- Tk_Window tkwin; /* Window that embodies the scrollbar. NULL
+ Tk_Window tkwin; /* Window that embodies the scrollbar. NULL
* means that the window has been destroyed
* but the data structures haven't yet been
* cleaned up.*/
- Display *display; /* Display containing widget. Used, among
+ Display *display; /* Display containing widget. Used, among
* other things, so that resources can be
* freed even after tkwin has gone away. */
Tcl_Interp *interp; /* Interpreter associated with scrollbar. */
Tcl_Command widgetCmd; /* Token for scrollbar's widget command. */
int vertical; /* Non-zero means vertical orientation
* requested, zero means horizontal. */
- int width; /* Desired narrow dimension of scrollbar,
- * in pixels. */
+ int width; /* Desired narrow dimension of scrollbar, in
+ * pixels. */
char *command; /* Command prefix to use when invoking
- * scrolling commands. NULL means don't
- * invoke commands. Malloc'ed. */
+ * scrolling commands. NULL means don't invoke
+ * commands. Malloc'ed. */
int commandSize; /* Number of non-NULL bytes in command. */
- int repeatDelay; /* How long to wait before auto-repeating
- * on scrolling actions (in ms). */
+ int repeatDelay; /* How long to wait before auto-repeating on
+ * scrolling actions (in ms). */
int repeatInterval; /* Interval between autorepeats (in ms). */
int jump; /* Value of -jump option. */
@@ -62,60 +56,58 @@ typedef struct TkScrollbar {
XColor *troughColorPtr; /* Color for drawing trough. */
int relief; /* Indicates whether window as a whole is
* raised, sunken, or flat. */
- int highlightWidth; /* Width in pixels of highlight to draw
- * around widget when it has the focus.
- * <= 0 means don't draw a highlight. */
+ 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. */
+ /* Color for drawing traversal 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.
- * Indicates how much interior stuff must
- * be offset from outside edges to leave
- * room for borders. */
+ * Indicates how much interior stuff must be
+ * offset from outside edges to leave room for
+ * borders. */
int elementBorderWidth; /* Width of border to draw around elements
- * inside scrollbar (arrows and slider).
- * -1 means use borderWidth. */
+ * inside scrollbar (arrows and slider). -1
+ * means use borderWidth. */
int arrowLength; /* Length of arrows along long dimension of
* scrollbar, including space for a small gap
* between the arrow and the slider.
* Recomputed on window size changes. */
- int sliderFirst; /* Pixel coordinate of top or left edge
- * of slider area, including border. */
- int sliderLast; /* Coordinate of pixel just after bottom
- * or right edge of slider area, including
+ int sliderFirst; /* Pixel coordinate of top or left edge of
+ * slider area, including border. */
+ int sliderLast; /* Coordinate of pixel just after bottom or
+ * right edge of slider area, including
* border. */
int activeField; /* Names field to be displayed in active
- * colors, such as TOP_ARROW, or 0 for
- * no field. */
- int activeRelief; /* Value of -activeRelief option: relief
- * to use for active element. */
+ * colors, such as TOP_ARROW, or 0 for no
+ * field. */
+ int activeRelief; /* Value of -activeRelief option: relief to
+ * use for active element. */
/*
- * Information describing the application related to the scrollbar.
- * This information is provided by the application by invoking the
- * "set" widget command. This information can now be provided in
- * two ways: the "old" form (totalUnits, windowUnits, firstUnit,
- * and lastUnit), or the "new" form (firstFraction and lastFraction).
- * FirstFraction and lastFraction will always be valid, but
- * the old-style information is only valid if the NEW_STYLE_COMMANDS
- * flag is 0.
+ * Information describing the application related to the scrollbar. This
+ * information is provided by the application by invoking the "set" widget
+ * command. This information can now be provided in two ways: the "old"
+ * form (totalUnits, windowUnits, firstUnit, and lastUnit), or the "new"
+ * form (firstFraction and lastFraction). FirstFraction and lastFraction
+ * will always be valid, but the old-style information is only valid if
+ * the NEW_STYLE_COMMANDS flag is 0.
*/
- int totalUnits; /* Total dimension of application, in
- * units. Valid only if the NEW_STYLE_COMMANDS
- * flag isn't set. */
+ int totalUnits; /* Total dimension of application, in units.
+ * Valid only if the NEW_STYLE_COMMANDS flag
+ * isn't set. */
int windowUnits; /* Maximum number of units that can be
- * displayed in the window at once. Valid
- * only if the NEW_STYLE_COMMANDS flag isn't
- * set. */
+ * displayed in the window at once. Valid only
+ * if the NEW_STYLE_COMMANDS flag isn't set. */
int firstUnit; /* Number of last unit visible in
- * application's window. Valid only if the
+ * application's window. Valid only if the
* NEW_STYLE_COMMANDS flag isn't set. */
int lastUnit; /* Index of last unit visible in window.
- * Valid only if the NEW_STYLE_COMMANDS
- * flag isn't set. */
+ * Valid only if the NEW_STYLE_COMMANDS flag
+ * isn't set. */
double firstFraction; /* Position of first visible thing in window,
* specified as a fraction between 0 and
* 1.0. */
@@ -128,16 +120,16 @@ typedef struct TkScrollbar {
*/
Tk_Cursor cursor; /* Current cursor for window, or None. */
- char *takeFocus; /* Value of -takefocus option; not used in
- * the C code, but used by keyboard traversal
- * scripts. Malloc'ed, but may be NULL. */
- int flags; /* Various flags; see below for
+ char *takeFocus; /* Value of -takefocus option; not used in the
+ * C code, but used by keyboard traversal
+ * scripts. Malloc'ed, but may be NULL. */
+ int flags; /* Various flags; see below for
* definitions. */
} TkScrollbar;
/*
- * Legal values for "activeField" field of Scrollbar structures. These
- * are also the return values from the ScrollbarPosition procedure.
+ * Legal values for "activeField" field of Scrollbar structures. These are
+ * also the return values from the ScrollbarPosition function.
*/
#define OUTSIDE 0
@@ -149,14 +141,13 @@ typedef struct TkScrollbar {
/*
* Flag bits for scrollbars:
- *
- * REDRAW_PENDING: Non-zero means a DoWhenIdle handler
- * has already been queued to redraw
- * this window.
+ *
+ * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has
+ * already been queued to redraw this window.
* NEW_STYLE_COMMANDS: Non-zero means the new style of commands
- * should be used to communicate with the
- * widget: ".t yview scroll 2 lines", instead
- * of ".t yview 40", for example.
+ * should be used to communicate with the widget:
+ * ".t yview scroll 2 lines", instead of
+ * ".t yview 40", for example.
* GOT_FOCUS: Non-zero means this window has the input
* focus.
*/
@@ -166,39 +157,27 @@ typedef struct TkScrollbar {
#define GOT_FOCUS 4
/*
- * Declaration of scrollbar class procedures structure.
+ * Declaration of scrollbar class functions structure
+ * and default scrollbar width, for use in configSpec.
*/
-extern Tk_ClassProcs tkpScrollbarProcs;
+MODULE_SCOPE Tk_ClassProcs tkpScrollbarProcs;
+MODULE_SCOPE char tkDefScrollbarWidth[TCL_INTEGER_SPACE];
/*
- * Declaration of scrollbar configuration options.
- */
-
-extern Tk_ConfigSpec tkpScrollbarConfigSpecs[];
-
-/*
- * Declaration of procedures used in the implementation of the scrollbar
- * widget.
+ * Declaration of functions used in the implementation of the scrollbar
+ * widget.
*/
-EXTERN void TkScrollbarEventProc _ANSI_ARGS_((
- ClientData clientData, XEvent *eventPtr));
-EXTERN void TkScrollbarEventuallyRedraw _ANSI_ARGS_((
- TkScrollbar *scrollPtr));
-EXTERN void TkpComputeScrollbarGeometry _ANSI_ARGS_((
- TkScrollbar *scrollPtr));
-EXTERN TkScrollbar * TkpCreateScrollbar _ANSI_ARGS_((Tk_Window tkwin));
-EXTERN void TkpDestroyScrollbar _ANSI_ARGS_((
- TkScrollbar *scrollPtr));
-EXTERN void TkpDisplayScrollbar _ANSI_ARGS_((
- ClientData clientData));
-EXTERN void TkpConfigureScrollbar _ANSI_ARGS_((
- TkScrollbar *scrollPtr));
-EXTERN int TkpScrollbarPosition _ANSI_ARGS_((
- TkScrollbar *scrollPtr, int x, int y));
-
-# undef TCL_STORAGE_CLASS
-# define TCL_STORAGE_CLASS DLLIMPORT
+MODULE_SCOPE void TkScrollbarEventProc(ClientData clientData,
+ XEvent *eventPtr);
+MODULE_SCOPE void TkScrollbarEventuallyRedraw(TkScrollbar *scrollPtr);
+MODULE_SCOPE void TkpComputeScrollbarGeometry(TkScrollbar *scrollPtr);
+MODULE_SCOPE TkScrollbar *TkpCreateScrollbar(Tk_Window tkwin);
+MODULE_SCOPE void TkpDestroyScrollbar(TkScrollbar *scrollPtr);
+MODULE_SCOPE void TkpDisplayScrollbar(ClientData clientData);
+MODULE_SCOPE void TkpConfigureScrollbar(TkScrollbar *scrollPtr);
+MODULE_SCOPE int TkpScrollbarPosition(TkScrollbar *scrollPtr,
+ int x, int y);
#endif /* _TKSCROLLBAR */
diff --git a/generic/tkSelect.c b/generic/tkSelect.c
index 1b65c42..7c96b94 100644
--- a/generic/tkSelect.c
+++ b/generic/tkSelect.c
@@ -1,24 +1,23 @@
-/*
+/*
* tkSelect.c --
*
- * This file manages the selection for the Tk toolkit,
- * translating between the standard X ICCCM conventions
- * and Tcl commands.
+ * This file manages the selection for the Tk toolkit, translating
+ * between the standard X ICCCM conventions and Tcl commands.
*
* Copyright (c) 1990-1993 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
#include "tkSelect.h"
/*
- * When a selection handler is set up by invoking "selection handle",
- * one of the following data structures is set up to hold information
- * about the command to invoke and its interpreter.
+ * When a selection handler is set up by invoking "selection handle", one of
+ * the following data structures is set up to hold information about the
+ * command to invoke and its interpreter.
*/
typedef struct {
@@ -28,109 +27,105 @@ typedef struct {
int byteOffset; /* The expected byte offset of the next
* chunk. */
char buffer[TCL_UTF_MAX]; /* A buffer to hold part of a UTF character
- * that is split across chunks.*/
- char command[4]; /* Command to invoke. Actual space is
- * allocated as large as necessary. This
- * must be the last entry in the structure. */
+ * that is split across chunks. */
+ char command[4]; /* Command to invoke. Actual space is
+ * allocated as large as necessary. This must
+ * be the last entry in the structure. */
} CommandInfo;
/*
* When selection ownership is claimed with the "selection own" Tcl command,
- * one of the following structures is created to record the Tcl command
- * to be executed when the selection is lost again.
+ * one of the following structures is created to record the Tcl command to be
+ * executed when the selection is lost again.
*/
typedef struct LostCommand {
Tcl_Interp *interp; /* Interpreter in which to invoke command. */
- char command[4]; /* Command to invoke. Actual space is
- * allocated as large as necessary. This
- * must be the last entry in the structure. */
+ char command[4]; /* Command to invoke. Actual space is
+ * allocated as large as necessary. This must
+ * be the last entry in the structure. */
} LostCommand;
/*
- * The structure below is used to keep each thread's pending list
- * separate.
+ * The structure below is used to keep each thread's pending list separate.
*/
typedef struct ThreadSpecificData {
TkSelInProgress *pendingPtr;
- /* Topmost search in progress, or
- * NULL if none. */
+ /* Topmost search in progress, or NULL if
+ * none. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
/*
- * Forward declarations for procedures defined in this file:
+ * Forward declarations for functions defined in this file:
*/
-static int HandleTclCommand _ANSI_ARGS_((ClientData clientData,
- int offset, char *buffer, int maxBytes));
-static void LostSelection _ANSI_ARGS_((ClientData clientData));
-static int SelGetProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, char *portion));
+static int HandleTclCommand(ClientData clientData,
+ int offset, char *buffer, int maxBytes);
+static void LostSelection(ClientData clientData);
+static int SelGetProc(ClientData clientData,
+ Tcl_Interp *interp, char *portion);
/*
*--------------------------------------------------------------
*
* Tk_CreateSelHandler --
*
- * This procedure is called to register a procedure
- * as the handler for selection requests of a particular
- * target type on a particular window for a particular
- * selection.
+ * This function is called to register a function as the handler for
+ * selection requests of a particular target type on a particular window
+ * for a particular selection.
*
* Results:
* None.
*
* Side effects:
- * In the future, whenever the selection is in tkwin's
- * window and someone requests the selection in the
- * form given by target, proc will be invoked to provide
- * part or all of the selection in the given form. If
- * there was already a handler declared for the given
- * window, target and selection type, then it is replaced.
- * Proc should have the following form:
+
+ * In the future, whenever the selection is in tkwin's window and someone
+ * requests the selection in the form given by target, proc will be
+ * invoked to provide part or all of the selection in the given form. If
+ * there was already a handler declared for the given window, target and
+ * selection type, then it is replaced. Proc should have the following
+ * form:
*
* int
- * proc(clientData, offset, buffer, maxBytes)
- * ClientData clientData;
- * int offset;
- * char *buffer;
- * int maxBytes;
+ * proc(
+ * ClientData clientData,
+ * int offset,
+ * char *buffer,
+ * int maxBytes)
* {
* }
*
- * The clientData argument to proc will be the same as
- * the clientData argument to this procedure. The offset
- * argument indicates which portion of the selection to
- * return: skip the first offset bytes. Buffer is a
- * pointer to an area in which to place the converted
- * selection, and maxBytes gives the number of bytes
- * available at buffer. Proc should place the selection
- * in buffer as a string, and return a count of the number
- * of bytes of selection actually placed in buffer (not
- * including the terminating NULL character). If the
- * return value equals maxBytes, this is a sign that there
- * is probably still more selection information available.
+ * The clientData argument to proc will be the same as the clientData
+ * argument to this function. The offset argument indicates which portion
+ * of the selection to return: skip the first offset bytes. Buffer is a
+ * pointer to an area in which to place the converted selection, and
+ * maxBytes gives the number of bytes available at buffer. Proc should
+ * place the selection in buffer as a string, and return a count of the
+ * number of bytes of selection actually placed in buffer (not including
+ * the terminating NULL character). If the return value equals maxBytes,
+ * this is a sign that there is probably still more selection information
+ * available.
*
*--------------------------------------------------------------
*/
void
-Tk_CreateSelHandler(tkwin, selection, target, proc, clientData, format)
- Tk_Window tkwin; /* Token for window. */
- Atom selection; /* Selection to be handled. */
- Atom target; /* The kind of selection conversions
- * that can be handled by proc,
- * e.g. TARGETS or STRING. */
- Tk_SelectionProc *proc; /* Procedure to invoke to convert
- * selection to type "target". */
- ClientData clientData; /* Value to pass to proc. */
- Atom format; /* Format in which the selection
- * information should be returned to
- * the requestor. XA_STRING is best by
- * far, but anything listed in the ICCCM
- * will be tolerated (blech). */
+Tk_CreateSelHandler(
+ Tk_Window tkwin, /* Token for window. */
+ Atom selection, /* Selection to be handled. */
+ Atom target, /* The kind of selection conversions that can
+ * be handled by proc, e.g. TARGETS or
+ * STRING. */
+ Tk_SelectionProc *proc, /* Function to invoke to convert selection to
+ * type "target". */
+ ClientData clientData, /* Value to pass to proc. */
+ Atom format) /* Format in which the selection information
+ * should be returned to the requestor.
+ * XA_STRING is best by far, but anything
+ * listed in the ICCCM will be tolerated
+ * (blech). */
{
register TkSelHandler *selPtr;
TkWindow *winPtr = (TkWindow *) tkwin;
@@ -140,8 +135,8 @@ Tk_CreateSelHandler(tkwin, selection, target, proc, clientData, format)
}
/*
- * See if there's already a handler for this target and selection on
- * this window. If so, re-use it. If not, create a new one.
+ * See if there's already a handler for this target and selection on this
+ * window. If so, re-use it. If not, create a new one.
*/
for (selPtr = winPtr->selHandlerList; ; selPtr = selPtr->nextPtr) {
@@ -152,11 +147,10 @@ Tk_CreateSelHandler(tkwin, selection, target, proc, clientData, format)
break;
}
if ((selPtr->selection == selection) && (selPtr->target == target)) {
-
/*
- * Special case: when replacing handler created by
- * "selection handle", free up memory. Should there be a
- * callback to allow other clients to do this too?
+ * Special case: when replacing handler created by "selection
+ * handle", free up memory. Should there be a callback to allow
+ * other clients to do this too?
*/
if (selPtr->proc == HandleTclCommand) {
@@ -176,15 +170,14 @@ Tk_CreateSelHandler(tkwin, selection, target, proc, clientData, format)
selPtr->size = 32;
}
- if ((target == XA_STRING) && (winPtr->dispPtr->utf8Atom != (Atom) NULL)) {
+ if ((target == XA_STRING) && (winPtr->dispPtr->utf8Atom != (Atom) 0)) {
/*
* If the user asked for a STRING handler and we understand
* UTF8_STRING, we implicitly create a UTF8_STRING handler for them.
*/
target = winPtr->dispPtr->utf8Atom;
- for (selPtr = winPtr->selHandlerList; ;
- selPtr = selPtr->nextPtr) {
+ for (selPtr = winPtr->selHandlerList; ; selPtr = selPtr->nextPtr) {
if (selPtr == NULL) {
selPtr = (TkSelHandler *) ckalloc(sizeof(TkSelHandler));
selPtr->nextPtr = winPtr->selHandlerList;
@@ -195,11 +188,13 @@ Tk_CreateSelHandler(tkwin, selection, target, proc, clientData, format)
selPtr->proc = proc;
if (selPtr->proc == HandleTclCommand) {
/*
- * The clientData is selection controlled memory, so
- * we should make a copy for this selPtr.
+ * The clientData is selection controlled memory, so we
+ * should make a copy for this selPtr.
*/
- unsigned cmdInfoLen = sizeof(CommandInfo) +
+
+ unsigned cmdInfoLen = sizeof(CommandInfo) +
((CommandInfo*)clientData)->cmdLength - 3;
+
selPtr->clientData = (ClientData)ckalloc(cmdInfoLen);
memcpy(selPtr->clientData, clientData, cmdInfoLen);
} else {
@@ -208,10 +203,9 @@ Tk_CreateSelHandler(tkwin, selection, target, proc, clientData, format)
selPtr->size = 8;
break;
}
- if ((selPtr->selection == selection)
- && (selPtr->target == target)) {
+ if (selPtr->selection==selection && selPtr->target==target) {
/*
- * Looks like we had a utf-8 target already. Leave it alone.
+ * Looks like we had a utf-8 target already. Leave it alone.
*/
break;
@@ -232,30 +226,30 @@ Tk_CreateSelHandler(tkwin, selection, target, proc, clientData, format)
* None.
*
* Side effects:
- * The selection handler for tkwin and target is removed. If there
- * is no such handler then nothing happens.
+ * The selection handler for tkwin and target is removed. If there is no
+ * such handler then nothing happens.
*
*----------------------------------------------------------------------
*/
void
-Tk_DeleteSelHandler(tkwin, selection, target)
- Tk_Window tkwin; /* Token for window. */
- Atom selection; /* The selection whose handler
- * is to be removed. */
- Atom target; /* The target whose selection
- * handler is to be removed. */
+Tk_DeleteSelHandler(
+ Tk_Window tkwin, /* Token for window. */
+ Atom selection, /* The selection whose handler is to be
+ * removed. */
+ Atom target) /* The target whose selection handler is to be
+ * removed. */
{
TkWindow *winPtr = (TkWindow *) tkwin;
register TkSelHandler *selPtr, *prevPtr;
register TkSelInProgress *ipPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
* Find the selection handler to be deleted, or return if it doesn't
* exist.
- */
+ */
for (selPtr = winPtr->selHandlerList, prevPtr = NULL; ;
prevPtr = selPtr, selPtr = selPtr->nextPtr) {
@@ -272,8 +266,8 @@ Tk_DeleteSelHandler(tkwin, selection, target)
* handler is dead.
*/
- for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL;
- ipPtr = ipPtr->nextPtr) {
+ for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL;
+ ipPtr = ipPtr->nextPtr) {
if (ipPtr->selPtr == selPtr) {
ipPtr->selPtr = NULL;
}
@@ -289,17 +283,18 @@ Tk_DeleteSelHandler(tkwin, selection, target)
prevPtr->nextPtr = selPtr->nextPtr;
}
- if ((target == XA_STRING) && (winPtr->dispPtr->utf8Atom != (Atom) NULL)) {
+ if ((target == XA_STRING) && (winPtr->dispPtr->utf8Atom != (Atom) 0)) {
/*
* If the user asked for a STRING handler and we understand
* UTF8_STRING, we may have implicitly created a UTF8_STRING handler
- * for them. Look for it and delete it as necessary.
+ * for them. Look for it and delete it as necessary.
*/
+
TkSelHandler *utf8selPtr;
target = winPtr->dispPtr->utf8Atom;
for (utf8selPtr = winPtr->selHandlerList; utf8selPtr != NULL;
- utf8selPtr = utf8selPtr->nextPtr) {
+ utf8selPtr = utf8selPtr->nextPtr) {
if ((utf8selPtr->selection == selection)
&& (utf8selPtr->target == target)) {
break;
@@ -310,9 +305,10 @@ Tk_DeleteSelHandler(tkwin, selection, target)
&& (utf8selPtr->proc == selPtr->proc)
&& (utf8selPtr->size == selPtr->size)) {
/*
- * This recursive call is OK, because we've
- * changed the value of 'target'
+ * This recursive call is OK, because we've changed the value
+ * of 'target'.
*/
+
Tk_DeleteSelHandler(tkwin, selection, target);
}
}
@@ -340,49 +336,45 @@ Tk_DeleteSelHandler(tkwin, selection, target)
* None.
*
* Side effects:
- * From now on, requests for the selection will be directed
- * to procedures associated with tkwin (they must have been
- * declared with calls to Tk_CreateSelHandler). When the
- * selection is lost by this window, proc will be invoked
- * (see the manual entry for details). This procedure may
- * invoke callbacks, including Tcl scripts, so any calling
- * function should be reentrant at the point where
- * Tk_OwnSelection is invoked.
+ * From now on, requests for the selection will be directed to functions
+ * associated with tkwin (they must have been declared with calls to
+ * Tk_CreateSelHandler). When the selection is lost by this window, proc
+ * will be invoked (see the manual entry for details). This function may
+ * invoke callbacks, including Tcl scripts, so any calling function
+ * should be reentrant at the point where Tk_OwnSelection is invoked.
*
*--------------------------------------------------------------
*/
void
-Tk_OwnSelection(tkwin, selection, proc, clientData)
- Tk_Window tkwin; /* Window to become new selection
- * owner. */
- Atom selection; /* Selection that window should own. */
- Tk_LostSelProc *proc; /* Procedure to call when selection
- * is taken away from tkwin. */
- ClientData clientData; /* Arbitrary one-word argument to
- * pass to proc. */
+Tk_OwnSelection(
+ Tk_Window tkwin, /* Window to become new selection owner. */
+ Atom selection, /* Selection that window should own. */
+ Tk_LostSelProc *proc, /* Function to call when selection is taken
+ * away from tkwin. */
+ ClientData clientData) /* Arbitrary one-word argument to pass to
+ * proc. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
TkDisplay *dispPtr = winPtr->dispPtr;
TkSelectionInfo *infoPtr;
Tk_LostSelProc *clearProc = NULL;
- ClientData clearData = NULL; /* Initialization needed only to
- * prevent compiler warning. */
-
-
+ ClientData clearData = NULL;/* Initialization needed only to prevent
+ * compiler warning. */
+
if (dispPtr->multipleAtom == None) {
TkSelInit(tkwin);
}
Tk_MakeWindowExist(tkwin);
/*
- * This code is somewhat tricky. First, we find the specified selection
- * on the selection list. If the previous owner is in this process, and
- * is a different window, then we need to invoke the clearProc. However,
- * it's dangerous to call the clearProc right now, because it could
- * invoke a Tcl script that wrecks the current state (e.g. it could
- * delete the window). To be safe, defer the call until the end of the
- * procedure when we no longer care about the state.
+ * This code is somewhat tricky. First, we find the specified selection on
+ * the selection list. If the previous owner is in this process, and is a
+ * different window, then we need to invoke the clearProc. However, it's
+ * dangerous to call the clearProc right now, because it could invoke a
+ * Tcl script that wrecks the current state (e.g. it could delete the
+ * window). To be safe, defer the call until the end of the function when
+ * we no longer care about the state.
*/
for (infoPtr = dispPtr->selectionInfoPtr; infoPtr != NULL;
@@ -402,9 +394,9 @@ Tk_OwnSelection(tkwin, selection, proc, clientData)
clearData = infoPtr->clearData;
} else if (infoPtr->clearProc == LostSelection) {
/*
- * If the selection handler is one created by "selection own",
- * be sure to free the record for it; otherwise there will be
- * a memory leak.
+ * If the selection handler is one created by "selection own", be
+ * sure to free the record for it; otherwise there will be a
+ * memory leak.
*/
ckfree((char *) infoPtr->clearData);
@@ -417,10 +409,10 @@ Tk_OwnSelection(tkwin, selection, proc, clientData)
infoPtr->clearData = clientData;
/*
- * Note that we are using CurrentTime, even though ICCCM recommends against
- * this practice (the problem is that we don't necessarily have a valid
- * time to use). We will not be able to retrieve a useful timestamp for
- * the TIMESTAMP target later.
+ * Note that we are using CurrentTime, even though ICCCM recommends
+ * against this practice (the problem is that we don't necessarily have a
+ * valid time to use). We will not be able to retrieve a useful timestamp
+ * for the TIMESTAMP target later.
*/
infoPtr->time = CurrentTime;
@@ -456,18 +448,19 @@ Tk_OwnSelection(tkwin, selection, proc, clientData)
* None.
*
* Side effects:
- * The specified selection is cleared, so that future requests to retrieve
- * it will fail until some application owns it again. This procedure
- * invokes callbacks, possibly including Tcl scripts, so any calling
- * function should be reentrant at the point Tk_ClearSelection is invoked.
+ * The specified selection is cleared, so that future requests to
+ * retrieve it will fail until some application owns it again. This
+ * function invokes callbacks, possibly including Tcl scripts, so any
+ * calling function should be reentrant at the point Tk_ClearSelection is
+ * invoked.
*
*----------------------------------------------------------------------
*/
void
-Tk_ClearSelection(tkwin, selection)
- Tk_Window tkwin; /* Window that selects a display. */
- Atom selection; /* Selection to be cancelled. */
+Tk_ClearSelection(
+ Tk_Window tkwin, /* Window that selects a display. */
+ Atom selection) /* Selection to be cancelled. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
TkDisplay *dispPtr = winPtr->dispPtr;
@@ -475,15 +468,15 @@ Tk_ClearSelection(tkwin, selection)
TkSelectionInfo *prevPtr;
TkSelectionInfo *nextPtr;
Tk_LostSelProc *clearProc = NULL;
- ClientData clearData = NULL; /* Initialization needed only to
- * prevent compiler warning. */
+ ClientData clearData = NULL;/* Initialization needed only to prevent
+ * compiler warning. */
if (dispPtr->multipleAtom == None) {
TkSelInit(tkwin);
}
for (infoPtr = dispPtr->selectionInfoPtr, prevPtr = NULL;
- infoPtr != NULL; infoPtr = nextPtr) {
+ infoPtr != NULL; infoPtr = nextPtr) {
nextPtr = infoPtr->nextPtr;
if (infoPtr->selection == selection) {
if (prevPtr == NULL) {
@@ -495,7 +488,7 @@ Tk_ClearSelection(tkwin, selection)
}
prevPtr = infoPtr;
}
-
+
if (infoPtr != NULL) {
clearProc = infoPtr->clearProc;
clearData = infoPtr->clearData;
@@ -513,80 +506,77 @@ Tk_ClearSelection(tkwin, selection)
*
* Tk_GetSelection --
*
- * Retrieve the value of a selection and pass it off (in
- * pieces, possibly) to a given procedure.
+ * Retrieve the value of a selection and pass it off (in pieces,
+ * possibly) to a given function.
*
* 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 the interp's result.
+ * 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 the
+ * interp's result.
*
* Side effects:
- * The standard X11 protocols are used to retrieve the
- * selection. When it arrives, it is passed to proc. If
- * the selection is very large, it will be passed to proc
- * in several pieces. Proc should have the following
+ * The standard X11 protocols are used to retrieve the selection. When it
+ * arrives, it is passed to proc. If the selection is very large, it will
+ * be passed to proc in several pieces. Proc should have the following
* structure:
*
* int
- * proc(clientData, interp, portion)
- * ClientData clientData;
- * Tcl_Interp *interp;
- * char *portion;
+ * proc(
+ * ClientData clientData,
+ * Tcl_Interp *interp,
+ * char *portion)
* {
* }
*
- * The interp and clientData arguments to proc will be the
- * same as the corresponding arguments to Tk_GetSelection.
- * The portion argument points to a character string
- * containing part of the selection, and numBytes indicates
- * the length of the portion, not including the terminating
- * NULL character. If the selection arrives in several pieces,
- * 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 the interp's result; the
- * remainder of the selection retrieval will be aborted.
+ * The interp and clientData arguments to proc will be the same as the
+ * corresponding arguments to Tk_GetSelection. The portion argument
+ * points to a character string containing part of the selection, and
+ * numBytes indicates the length of the portion, not including the
+ * terminating NULL character. If the selection arrives in several
+ * pieces, 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 the interp's result; the remainder of the selection
+ * retrieval will be aborted.
*
*--------------------------------------------------------------
*/
int
-Tk_GetSelection(interp, tkwin, selection, target, proc, clientData)
- Tcl_Interp *interp; /* Interpreter to use for reporting
- * errors. */
- Tk_Window tkwin; /* Window on whose behalf to retrieve
- * the selection (determines display
- * from which to retrieve). */
- Atom selection; /* Selection to retrieve. */
- Atom target; /* Desired form in which selection
- * is to be returned. */
- Tk_GetSelProc *proc; /* Procedure to call to process the
- * selection, once it has been retrieved. */
- ClientData clientData; /* Arbitrary value to pass to proc. */
+Tk_GetSelection(
+ Tcl_Interp *interp, /* Interpreter to use for reporting errors. */
+ Tk_Window tkwin, /* Window on whose behalf to retrieve the
+ * selection (determines display from which to
+ * retrieve). */
+ Atom selection, /* Selection to retrieve. */
+ Atom target, /* Desired form in which selection is to be
+ * returned. */
+ Tk_GetSelProc *proc, /* Function to call to process the selection,
+ * once it has been retrieved. */
+ ClientData clientData) /* Arbitrary value to pass to proc. */
{
TkWindow *winPtr = (TkWindow *) tkwin;
TkDisplay *dispPtr = winPtr->dispPtr;
TkSelectionInfo *infoPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (dispPtr->multipleAtom == None) {
TkSelInit(tkwin);
}
/*
- * If the selection is owned by a window managed by this
- * process, then call the retrieval procedure directly,
- * rather than going through the X server (it's dangerous
- * to go through the X server in this case because it could
- * result in deadlock if an INCR-style selection results).
+ * If the selection is owned by a window managed by this process, then
+ * call the retrieval function directly, rather than going through the X
+ * server (it's dangerous to go through the X server in this case because
+ * it could result in deadlock if an INCR-style selection results).
*/
for (infoPtr = dispPtr->selectionInfoPtr; infoPtr != NULL;
infoPtr = infoPtr->nextPtr) {
- if (infoPtr->selection == selection)
+ if (infoPtr->selection == selection) {
break;
+ }
}
if (infoPtr != NULL) {
register TkSelHandler *selPtr;
@@ -595,9 +585,8 @@ Tk_GetSelection(interp, tkwin, selection, target, proc, clientData)
TkSelInProgress ip;
for (selPtr = ((TkWindow *) infoPtr->owner)->selHandlerList;
- selPtr != NULL; selPtr = selPtr->nextPtr) {
- if ((selPtr->target == target)
- && (selPtr->selection == selection)) {
+ selPtr != NULL; selPtr = selPtr->nextPtr) {
+ if (selPtr->target==target && selPtr->selection==selection) {
break;
}
}
@@ -607,7 +596,7 @@ Tk_GetSelection(interp, tkwin, selection, target, proc, clientData)
count = TkSelDefaultSelection(infoPtr, target, buffer,
TK_SEL_BYTES_AT_ONCE, &type);
if (count > TK_SEL_BYTES_AT_ONCE) {
- panic("selection handler returned too many bytes");
+ Tcl_Panic("selection handler returned too many bytes");
}
if (count < 0) {
goto cantget;
@@ -628,7 +617,7 @@ Tk_GetSelection(interp, tkwin, selection, target, proc, clientData)
goto cantget;
}
if (count > TK_SEL_BYTES_AT_ONCE) {
- panic("selection handler returned too many bytes");
+ Tcl_Panic("selection handler returned too many bytes");
}
buffer[count] = '\0';
result = (*proc)(clientData, interp, buffer);
@@ -650,10 +639,10 @@ Tk_GetSelection(interp, tkwin, selection, target, proc, clientData)
return TkSelGetSelection(interp, tkwin, selection, target, proc,
clientData);
- cantget:
+ cantget:
Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection),
- " selection doesn't exist or form \"", Tk_GetAtomName(tkwin, target),
- "\" not defined", (char *) NULL);
+ " selection doesn't exist or form \"",
+ Tk_GetAtomName(tkwin, target), "\" not defined", NULL);
return TCL_ERROR;
}
@@ -662,9 +651,8 @@ Tk_GetSelection(interp, tkwin, selection, target, proc, clientData)
*
* Tk_SelectionObjCmd --
*
- * This procedure is invoked to process the "selection" Tcl
- * command. See the user documentation for details on what
- * it does.
+ * This function is invoked to process the "selection" Tcl command. See
+ * the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -676,12 +664,12 @@ Tk_GetSelection(interp, tkwin, selection, target, proc, clientData)
*/
int
-Tk_SelectionObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with
+Tk_SelectionObjCmd(
+ ClientData clientData, /* Main window associated with
* interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tk_Window tkwin = (Tk_Window) clientData;
char *path = NULL;
@@ -690,11 +678,12 @@ Tk_SelectionObjCmd(clientData, interp, objc, objv)
int count, index;
Tcl_Obj **objs;
static CONST char *optionStrings[] = {
- "clear", "get", "handle", "own", (char *) NULL
+ "clear", "get", "handle", "own", NULL
};
- enum options { SELECTION_CLEAR, SELECTION_GET, SELECTION_HANDLE,
- SELECTION_OWN };
-
+ enum options {
+ SELECTION_CLEAR, SELECTION_GET, SELECTION_HANDLE, SELECTION_OWN
+ };
+
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
return TCL_ERROR;
@@ -706,319 +695,323 @@ Tk_SelectionObjCmd(clientData, interp, objc, objv)
}
switch ((enum options) index) {
- case SELECTION_CLEAR: {
- static CONST char *clearOptionStrings[] = {
- "-displayof", "-selection", (char *) NULL
- };
- enum clearOptions { CLEAR_DISPLAYOF, CLEAR_SELECTION };
- int clearIndex;
-
- for (count = objc-2, objs = ((Tcl_Obj **)objv)+2; count > 0;
- count-=2, objs+=2) {
- string = Tcl_GetString(objs[0]);
- if (string[0] != '-') {
- break;
- }
- if (count < 2) {
- Tcl_AppendResult(interp, "value for \"", string,
- "\" missing", (char *) NULL);
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objs[0], clearOptionStrings,
- "option", 0, &clearIndex) != TCL_OK) {
- return TCL_ERROR;
- }
- switch ((enum clearOptions) clearIndex) {
- case CLEAR_DISPLAYOF:
- path = Tcl_GetString(objs[1]);
- break;
- case CLEAR_SELECTION:
- selName = Tcl_GetString(objs[1]);
- break;
- }
+ case SELECTION_CLEAR: {
+ static CONST char *clearOptionStrings[] = {
+ "-displayof", "-selection", NULL
+ };
+ enum clearOptions { CLEAR_DISPLAYOF, CLEAR_SELECTION };
+ int clearIndex;
+
+ for (count = objc-2, objs = ((Tcl_Obj **)objv)+2; count > 0;
+ count-=2, objs+=2) {
+ string = Tcl_GetString(objs[0]);
+ if (string[0] != '-') {
+ break;
}
- if (count == 1) {
- path = Tcl_GetString(objs[0]);
- } else if (count > 1) {
- Tcl_WrongNumArgs(interp, 2, objv, "?options?");
+ if (count < 2) {
+ Tcl_AppendResult(interp, "value for \"", string,
+ "\" missing", NULL);
return TCL_ERROR;
}
- if (path != NULL) {
- tkwin = Tk_NameToWindow(interp, path, tkwin);
- }
- if (tkwin == NULL) {
+
+ if (Tcl_GetIndexFromObj(interp, objs[0], clearOptionStrings,
+ "option", 0, &clearIndex) != TCL_OK) {
return TCL_ERROR;
}
- if (selName != NULL) {
- selection = Tk_InternAtom(tkwin, selName);
- } else {
- selection = XA_PRIMARY;
+ switch ((enum clearOptions) clearIndex) {
+ case CLEAR_DISPLAYOF:
+ path = Tcl_GetString(objs[1]);
+ break;
+ case CLEAR_SELECTION:
+ selName = Tcl_GetString(objs[1]);
+ break;
}
-
- Tk_ClearSelection(tkwin, selection);
- break;
}
- case SELECTION_GET: {
- Atom target;
- char *targetName = NULL;
- Tcl_DString selBytes;
- int result;
- static CONST char *getOptionStrings[] = {
- "-displayof", "-selection", "-type", (char *) NULL
- };
- enum getOptions { GET_DISPLAYOF, GET_SELECTION, GET_TYPE };
- int getIndex;
-
- for (count = objc-2, objs = ((Tcl_Obj **)objv)+2; count>0;
- count-=2, objs+=2) {
- string = Tcl_GetString(objs[0]);
- if (string[0] != '-') {
- break;
- }
- if (count < 2) {
- Tcl_AppendResult(interp, "value for \"", string,
- "\" missing", (char *) NULL);
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objs[0], getOptionStrings,
- "option", 0, &getIndex) != TCL_OK) {
- return TCL_ERROR;
- }
+ if (count == 1) {
+ path = Tcl_GetString(objs[0]);
+ } else if (count > 1) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?options?");
+ return TCL_ERROR;
+ }
+ if (path != NULL) {
+ tkwin = Tk_NameToWindow(interp, path, tkwin);
+ }
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+ if (selName != NULL) {
+ selection = Tk_InternAtom(tkwin, selName);
+ } else {
+ selection = XA_PRIMARY;
+ }
- switch ((enum getOptions) getIndex) {
- case GET_DISPLAYOF:
- path = Tcl_GetString(objs[1]);
- break;
- case GET_SELECTION:
- selName = Tcl_GetString(objs[1]);
- break;
- case GET_TYPE:
- targetName = Tcl_GetString(objs[1]);
- break;
- }
- }
- if (path != NULL) {
- tkwin = Tk_NameToWindow(interp, path, tkwin);
+ Tk_ClearSelection(tkwin, selection);
+ break;
+ }
+
+ case SELECTION_GET: {
+ Atom target;
+ char *targetName = NULL;
+ Tcl_DString selBytes;
+ int result;
+ static CONST char *getOptionStrings[] = {
+ "-displayof", "-selection", "-type", NULL
+ };
+ enum getOptions { GET_DISPLAYOF, GET_SELECTION, GET_TYPE };
+ int getIndex;
+
+ for (count = objc-2, objs = ((Tcl_Obj **)objv)+2; count>0;
+ count-=2, objs+=2) {
+ string = Tcl_GetString(objs[0]);
+ if (string[0] != '-') {
+ break;
}
- if (tkwin == NULL) {
+ if (count < 2) {
+ Tcl_AppendResult(interp, "value for \"", string,
+ "\" missing", NULL);
return TCL_ERROR;
}
- if (selName != NULL) {
- selection = Tk_InternAtom(tkwin, selName);
- } else {
- selection = XA_PRIMARY;
- }
- if (count > 1) {
- Tcl_WrongNumArgs(interp, 2, objv, "?options?");
+
+ if (Tcl_GetIndexFromObj(interp, objs[0], getOptionStrings,
+ "option", 0, &getIndex) != TCL_OK) {
return TCL_ERROR;
- } else if (count == 1) {
- target = Tk_InternAtom(tkwin, Tcl_GetString(objs[0]));
- } else if (targetName != NULL) {
- target = Tk_InternAtom(tkwin, targetName);
- } else {
- target = XA_STRING;
}
- Tcl_DStringInit(&selBytes);
- result = Tk_GetSelection(interp, tkwin, selection, target,
- SelGetProc, (ClientData) &selBytes);
- if (result == TCL_OK) {
- Tcl_DStringResult(interp, &selBytes);
- } else {
- Tcl_DStringFree(&selBytes);
+ switch ((enum getOptions) getIndex) {
+ case GET_DISPLAYOF:
+ path = Tcl_GetString(objs[1]);
+ break;
+ case GET_SELECTION:
+ selName = Tcl_GetString(objs[1]);
+ break;
+ case GET_TYPE:
+ targetName = Tcl_GetString(objs[1]);
+ break;
}
- return result;
}
- case SELECTION_HANDLE: {
- Atom target, format;
- char *targetName = NULL;
- char *formatName = NULL;
- register CommandInfo *cmdInfoPtr;
- int cmdLength;
- static CONST char *handleOptionStrings[] = {
- "-format", "-selection", "-type", (char *) NULL
- };
- enum handleOptions { HANDLE_FORMAT, HANDLE_SELECTION,
- HANDLE_TYPE };
- int handleIndex;
-
- for (count = objc-2, objs = ((Tcl_Obj **)objv)+2; count > 0;
- count-=2, objs+=2) {
- string = Tcl_GetString(objs[0]);
- if (string[0] != '-') {
- break;
- }
- if (count < 2) {
- Tcl_AppendResult(interp, "value for \"", string,
- "\" missing", (char *) NULL);
- return TCL_ERROR;
- }
+ if (path != NULL) {
+ tkwin = Tk_NameToWindow(interp, path, tkwin);
+ }
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+ if (selName != NULL) {
+ selection = Tk_InternAtom(tkwin, selName);
+ } else {
+ selection = XA_PRIMARY;
+ }
+ if (count > 1) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?options?");
+ return TCL_ERROR;
+ } else if (count == 1) {
+ target = Tk_InternAtom(tkwin, Tcl_GetString(objs[0]));
+ } else if (targetName != NULL) {
+ target = Tk_InternAtom(tkwin, targetName);
+ } else {
+ target = XA_STRING;
+ }
- if (Tcl_GetIndexFromObj(interp, objs[0],handleOptionStrings,
- "option", 0, &handleIndex) != TCL_OK) {
- return TCL_ERROR;
- }
+ Tcl_DStringInit(&selBytes);
+ result = Tk_GetSelection(interp, tkwin, selection, target,
+ SelGetProc, (ClientData) &selBytes);
+ if (result == TCL_OK) {
+ Tcl_DStringResult(interp, &selBytes);
+ } else {
+ Tcl_DStringFree(&selBytes);
+ }
+ return result;
+ }
- switch ((enum handleOptions) handleIndex) {
- case HANDLE_FORMAT:
- formatName = Tcl_GetString(objs[1]);
- break;
- case HANDLE_SELECTION:
- selName = Tcl_GetString(objs[1]);
- break;
- case HANDLE_TYPE:
- targetName = Tcl_GetString(objs[1]);
- break;
- }
+ case SELECTION_HANDLE: {
+ Atom target, format;
+ char *targetName = NULL;
+ char *formatName = NULL;
+ register CommandInfo *cmdInfoPtr;
+ int cmdLength;
+ static CONST char *handleOptionStrings[] = {
+ "-format", "-selection", "-type", NULL
+ };
+ enum handleOptions {
+ HANDLE_FORMAT, HANDLE_SELECTION, HANDLE_TYPE
+ };
+ int handleIndex;
+
+ for (count = objc-2, objs = ((Tcl_Obj **)objv)+2; count > 0;
+ count-=2, objs+=2) {
+ string = Tcl_GetString(objs[0]);
+ if (string[0] != '-') {
+ break;
}
-
- if ((count < 2) || (count > 4)) {
- Tcl_WrongNumArgs(interp, 2, objv, "?options? window command");
+ if (count < 2) {
+ Tcl_AppendResult(interp, "value for \"", string,
+ "\" missing", NULL);
return TCL_ERROR;
}
- tkwin = Tk_NameToWindow(interp, Tcl_GetString(objs[0]), tkwin);
- if (tkwin == NULL) {
+
+ if (Tcl_GetIndexFromObj(interp, objs[0],handleOptionStrings,
+ "option", 0, &handleIndex) != TCL_OK) {
return TCL_ERROR;
}
- if (selName != NULL) {
- selection = Tk_InternAtom(tkwin, selName);
- } else {
- selection = XA_PRIMARY;
- }
-
- if (count > 2) {
- target = Tk_InternAtom(tkwin, Tcl_GetString(objs[2]));
- } else if (targetName != NULL) {
- target = Tk_InternAtom(tkwin, targetName);
- } else {
- target = XA_STRING;
- }
- if (count > 3) {
- format = Tk_InternAtom(tkwin, Tcl_GetString(objs[3]));
- } else if (formatName != NULL) {
- format = Tk_InternAtom(tkwin, formatName);
- } else {
- format = XA_STRING;
- }
- string = Tcl_GetStringFromObj(objs[1], &cmdLength);
- if (cmdLength == 0) {
- Tk_DeleteSelHandler(tkwin, selection, target);
- } else {
- cmdInfoPtr = (CommandInfo *) ckalloc((unsigned) (
- sizeof(CommandInfo) - 3 + cmdLength));
- cmdInfoPtr->interp = interp;
- cmdInfoPtr->charOffset = 0;
- cmdInfoPtr->byteOffset = 0;
- cmdInfoPtr->buffer[0] = '\0';
- cmdInfoPtr->cmdLength = cmdLength;
- memcpy(cmdInfoPtr->command, string, cmdLength + 1);
- Tk_CreateSelHandler(tkwin, selection, target, HandleTclCommand,
- (ClientData) cmdInfoPtr, format);
+
+ switch ((enum handleOptions) handleIndex) {
+ case HANDLE_FORMAT:
+ formatName = Tcl_GetString(objs[1]);
+ break;
+ case HANDLE_SELECTION:
+ selName = Tcl_GetString(objs[1]);
+ break;
+ case HANDLE_TYPE:
+ targetName = Tcl_GetString(objs[1]);
+ break;
}
- return TCL_OK;
}
-
- case SELECTION_OWN: {
- register LostCommand *lostPtr;
- char *script = NULL;
- int cmdLength;
- static CONST char *ownOptionStrings[] = {
- "-command", "-displayof", "-selection", (char *) NULL
- };
- enum ownOptions { OWN_COMMAND, OWN_DISPLAYOF, OWN_SELECTION };
- int ownIndex;
-
- for (count = objc-2, objs = ((Tcl_Obj **)objv)+2; count > 0;
- count-=2, objs+=2) {
- string = Tcl_GetString(objs[0]);
- if (string[0] != '-') {
- break;
- }
- if (count < 2) {
- Tcl_AppendResult(interp, "value for \"", string,
- "\" missing", (char *) NULL);
- return TCL_ERROR;
- }
- if (Tcl_GetIndexFromObj(interp, objs[0], ownOptionStrings,
- "option", 0, &ownIndex) != TCL_OK) {
- return TCL_ERROR;
- }
+ if ((count < 2) || (count > 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?options? window command");
+ return TCL_ERROR;
+ }
+ tkwin = Tk_NameToWindow(interp, Tcl_GetString(objs[0]), tkwin);
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+ if (selName != NULL) {
+ selection = Tk_InternAtom(tkwin, selName);
+ } else {
+ selection = XA_PRIMARY;
+ }
- switch ((enum ownOptions) ownIndex) {
- case OWN_COMMAND:
- script = Tcl_GetString(objs[1]);
- break;
- case OWN_DISPLAYOF:
- path = Tcl_GetString(objs[1]);
- break;
- case OWN_SELECTION:
- selName = Tcl_GetString(objs[1]);
- break;
- }
+ if (count > 2) {
+ target = Tk_InternAtom(tkwin, Tcl_GetString(objs[2]));
+ } else if (targetName != NULL) {
+ target = Tk_InternAtom(tkwin, targetName);
+ } else {
+ target = XA_STRING;
+ }
+ if (count > 3) {
+ format = Tk_InternAtom(tkwin, Tcl_GetString(objs[3]));
+ } else if (formatName != NULL) {
+ format = Tk_InternAtom(tkwin, formatName);
+ } else {
+ format = XA_STRING;
+ }
+ string = Tcl_GetStringFromObj(objs[1], &cmdLength);
+ if (cmdLength == 0) {
+ Tk_DeleteSelHandler(tkwin, selection, target);
+ } else {
+ cmdInfoPtr = (CommandInfo *) ckalloc((unsigned) (
+ sizeof(CommandInfo) - 3 + cmdLength));
+ cmdInfoPtr->interp = interp;
+ cmdInfoPtr->charOffset = 0;
+ cmdInfoPtr->byteOffset = 0;
+ cmdInfoPtr->buffer[0] = '\0';
+ cmdInfoPtr->cmdLength = cmdLength;
+ memcpy(cmdInfoPtr->command, string, cmdLength + 1);
+ Tk_CreateSelHandler(tkwin, selection, target, HandleTclCommand,
+ (ClientData) cmdInfoPtr, format);
+ }
+ return TCL_OK;
+ }
+
+ case SELECTION_OWN: {
+ register LostCommand *lostPtr;
+ char *script = NULL;
+ int cmdLength;
+ static CONST char *ownOptionStrings[] = {
+ "-command", "-displayof", "-selection", NULL
+ };
+ enum ownOptions { OWN_COMMAND, OWN_DISPLAYOF, OWN_SELECTION };
+ int ownIndex;
+
+ for (count = objc-2, objs = ((Tcl_Obj **)objv)+2; count > 0;
+ count-=2, objs+=2) {
+ string = Tcl_GetString(objs[0]);
+ if (string[0] != '-') {
+ break;
}
-
- if (count > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?options? ?window?");
+ if (count < 2) {
+ Tcl_AppendResult(interp, "value for \"", string,
+ "\" missing", NULL);
return TCL_ERROR;
}
- if (selName != NULL) {
- selection = Tk_InternAtom(tkwin, selName);
- } else {
- selection = XA_PRIMARY;
+
+ if (Tcl_GetIndexFromObj(interp, objs[0], ownOptionStrings,
+ "option", 0, &ownIndex) != TCL_OK) {
+ return TCL_ERROR;
}
- if (count == 0) {
- TkSelectionInfo *infoPtr;
- TkWindow *winPtr;
- if (path != NULL) {
- tkwin = Tk_NameToWindow(interp, path, tkwin);
- }
- if (tkwin == NULL) {
- return TCL_ERROR;
- }
- winPtr = (TkWindow *)tkwin;
- for (infoPtr = winPtr->dispPtr->selectionInfoPtr;
- infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
- if (infoPtr->selection == selection)
- break;
- }
-
- /*
- * Ignore the internal clipboard window.
- */
-
- if ((infoPtr != NULL)
- && (infoPtr->owner != winPtr->dispPtr->clipWindow)) {
- Tcl_SetResult(interp, Tk_PathName(infoPtr->owner),
- TCL_STATIC);
- }
- return TCL_OK;
+
+ switch ((enum ownOptions) ownIndex) {
+ case OWN_COMMAND:
+ script = Tcl_GetString(objs[1]);
+ break;
+ case OWN_DISPLAYOF:
+ path = Tcl_GetString(objs[1]);
+ break;
+ case OWN_SELECTION:
+ selName = Tcl_GetString(objs[1]);
+ break;
+ }
+ }
+
+ if (count > 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?options? ?window?");
+ return TCL_ERROR;
+ }
+ if (selName != NULL) {
+ selection = Tk_InternAtom(tkwin, selName);
+ } else {
+ selection = XA_PRIMARY;
+ }
+
+ if (count == 0) {
+ TkSelectionInfo *infoPtr;
+ TkWindow *winPtr;
+
+ if (path != NULL) {
+ tkwin = Tk_NameToWindow(interp, path, tkwin);
}
- tkwin = Tk_NameToWindow(interp, Tcl_GetString(objs[0]), tkwin);
if (tkwin == NULL) {
return TCL_ERROR;
}
- if (count == 2) {
- script = Tcl_GetString(objs[1]);
+ winPtr = (TkWindow *)tkwin;
+ for (infoPtr = winPtr->dispPtr->selectionInfoPtr;
+ infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
+ if (infoPtr->selection == selection) {
+ break;
+ }
}
- if (script == NULL) {
- Tk_OwnSelection(tkwin, selection, (Tk_LostSelProc *) NULL,
- (ClientData) NULL);
- return TCL_OK;
+
+ /*
+ * Ignore the internal clipboard window.
+ */
+
+ if ((infoPtr != NULL)
+ && (infoPtr->owner != winPtr->dispPtr->clipWindow)) {
+ Tcl_SetResult(interp, Tk_PathName(infoPtr->owner), TCL_STATIC);
}
- cmdLength = strlen(script);
- lostPtr = (LostCommand *) ckalloc((unsigned) (sizeof(LostCommand)
- -3 + cmdLength));
- lostPtr->interp = interp;
- memcpy(lostPtr->command, script, cmdLength + 1);
- Tk_OwnSelection(tkwin, selection, LostSelection,
- (ClientData) lostPtr);
return TCL_OK;
}
+
+ tkwin = Tk_NameToWindow(interp, Tcl_GetString(objs[0]), tkwin);
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+ if (count == 2) {
+ script = Tcl_GetString(objs[1]);
+ }
+ if (script == NULL) {
+ Tk_OwnSelection(tkwin, selection, NULL, (ClientData) NULL);
+ return TCL_OK;
+ }
+ cmdLength = strlen(script);
+ lostPtr = (LostCommand *) ckalloc((unsigned) (sizeof(LostCommand)
+ -3 + cmdLength));
+ lostPtr->interp = interp;
+ strcpy(lostPtr->command, script);
+ Tk_OwnSelection(tkwin, selection, LostSelection, (ClientData) lostPtr);
+ return TCL_OK;
+ }
}
return TCL_OK;
}
@@ -1028,12 +1021,12 @@ Tk_SelectionObjCmd(clientData, interp, objc, objv)
*
* TkSelGetInProgress --
*
- * This procedure returns a pointer to the thread-local
- * list of pending searches.
+ * This function 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.
+ * The return value is a pointer to the first search in progress, or NULL
+ * if there are none.
*
* Side effects:
* None.
@@ -1042,10 +1035,10 @@ Tk_SelectionObjCmd(clientData, interp, objc, objv)
*/
TkSelInProgress *
-TkSelGetInProgress _ANSI_ARGS_((void))
+TkSelGetInProgress(void)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
return tsdPtr->pendingPtr;
}
@@ -1055,9 +1048,9 @@ TkSelGetInProgress _ANSI_ARGS_((void))
*
* 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.
+ * This function 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.
@@ -1068,13 +1061,13 @@ TkSelGetInProgress _ANSI_ARGS_((void))
*----------------------------------------------------------------------
*/
void
-TkSelSetInProgress(pendingPtr)
- TkSelInProgress *pendingPtr;
+TkSelSetInProgress(
+ TkSelInProgress *pendingPtr)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- tsdPtr->pendingPtr = pendingPtr;
+ tsdPtr->pendingPtr = pendingPtr;
}
/*
@@ -1082,8 +1075,8 @@ TkSelSetInProgress(pendingPtr)
*
* TkSelDeadWindow --
*
- * This procedure is invoked just before a TkWindow is deleted.
- * It performs selection-related cleanup.
+ * This function is invoked just before a TkWindow is deleted. It
+ * performs selection-related cleanup.
*
* Results:
* None.
@@ -1095,14 +1088,14 @@ TkSelSetInProgress(pendingPtr)
*/
void
-TkSelDeadWindow(winPtr)
- register TkWindow *winPtr; /* Window that's being deleted. */
+TkSelDeadWindow(
+ register TkWindow *winPtr) /* Window that's being deleted. */
{
register TkSelHandler *selPtr;
register TkSelInProgress *ipPtr;
TkSelectionInfo *infoPtr, *prevPtr, *nextPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
* While deleting all the handlers, be careful to check whether
@@ -1113,8 +1106,8 @@ TkSelDeadWindow(winPtr)
while (winPtr->selHandlerList != NULL) {
selPtr = winPtr->selHandlerList;
winPtr->selHandlerList = selPtr->nextPtr;
- for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL;
- ipPtr = ipPtr->nextPtr) {
+ for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL;
+ ipPtr = ipPtr->nextPtr) {
if (ipPtr->selPtr == selPtr) {
ipPtr->selPtr = NULL;
}
@@ -1135,7 +1128,7 @@ TkSelDeadWindow(winPtr)
*/
for (infoPtr = winPtr->dispPtr->selectionInfoPtr, prevPtr = NULL;
- infoPtr != NULL; infoPtr = nextPtr) {
+ infoPtr != NULL; infoPtr = nextPtr) {
nextPtr = infoPtr->nextPtr;
if (infoPtr->owner == (Tk_Window) winPtr) {
if (infoPtr->clearProc == LostSelection) {
@@ -1170,9 +1163,9 @@ TkSelDeadWindow(winPtr)
*/
void
-TkSelInit(tkwin)
- Tk_Window tkwin; /* Window token (used to find
- * display to initialize). */
+TkSelInit(
+ Tk_Window tkwin) /* Window token (used to find display to
+ * initialize). */
{
register TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
@@ -1191,17 +1184,16 @@ TkSelInit(tkwin)
dispPtr->clipboardAtom = Tk_InternAtom(tkwin, "CLIPBOARD");
/*
- * Using UTF8_STRING instead of the XA_UTF8_STRING macro allows us
- * to support older X servers that didn't have UTF8_STRING yet.
- * This is necessary on Unix systems.
- * For more information, see:
- * http://www.cl.cam.ac.uk/~mgk25/unicode.html#x11
+ * Using UTF8_STRING instead of the XA_UTF8_STRING macro allows us to
+ * support older X servers that didn't have UTF8_STRING yet. This is
+ * necessary on Unix systems. For more information, see:
+ * http://www.cl.cam.ac.uk/~mgk25/unicode.html#x11
*/
#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
dispPtr->utf8Atom = Tk_InternAtom(tkwin, "UTF8_STRING");
#else
- dispPtr->utf8Atom = (Atom) NULL;
+ dispPtr->utf8Atom = (Atom) 0;
#endif
}
@@ -1210,22 +1202,22 @@ TkSelInit(tkwin)
*
* TkSelClearSelection --
*
- * This procedure is invoked to process a SelectionClear event.
+ * This function is invoked to process a SelectionClear event.
*
* Results:
* None.
*
* Side effects:
- * Invokes the clear procedure for the window which lost the
+ * Invokes the clear function for the window which lost the
* selection.
*
*----------------------------------------------------------------------
*/
void
-TkSelClearSelection(tkwin, eventPtr)
- Tk_Window tkwin; /* Window for which event was targeted. */
- register XEvent *eventPtr; /* X SelectionClear event. */
+TkSelClearSelection(
+ Tk_Window tkwin, /* Window for which event was targeted. */
+ register XEvent *eventPtr) /* X SelectionClear event. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
TkDisplay *dispPtr = winPtr->dispPtr;
@@ -1233,24 +1225,24 @@ TkSelClearSelection(tkwin, eventPtr)
TkSelectionInfo *prevPtr;
/*
- * Invoke clear procedure for window that just lost the selection. This
+ * Invoke clear function for window that just lost the selection. This
* code is a bit tricky, because any callbacks due to selection changes
- * between windows managed by the process have already been made. Thus,
+ * between windows managed by the process have already been made. Thus,
* ignore the event unless it refers to the window that's currently the
* selection owner and the event was generated after the server saw the
* SetSelectionOwner request.
*/
for (infoPtr = dispPtr->selectionInfoPtr, prevPtr = NULL;
- infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
+ infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
if (infoPtr->selection == eventPtr->xselectionclear.selection) {
break;
}
prevPtr = infoPtr;
}
- if (infoPtr != NULL && (infoPtr->owner == tkwin)
- && (eventPtr->xselectionclear.serial >= (unsigned) infoPtr->serial)) {
+ if (infoPtr != NULL && (infoPtr->owner == tkwin) &&
+ (eventPtr->xselectionclear.serial >= (unsigned) infoPtr->serial)) {
if (prevPtr == NULL) {
dispPtr->selectionInfoPtr = infoPtr->nextPtr;
} else {
@@ -1259,9 +1251,9 @@ TkSelClearSelection(tkwin, eventPtr)
/*
* Because of reentrancy problems, calling clearProc must be done
- * after the infoPtr has been removed from the selectionInfoPtr
- * list (clearProc could modify the list, e.g. by creating
- * a new selection).
+ * after the infoPtr has been removed from the selectionInfoPtr list
+ * (clearProc could modify the list, e.g. by creating a new
+ * selection).
*/
if (infoPtr->clearProc != NULL) {
@@ -1276,27 +1268,27 @@ TkSelClearSelection(tkwin, eventPtr)
*
* SelGetProc --
*
- * This procedure is invoked to process pieces of the selection
- * as they arrive during "selection get" commands.
+ * This function is invoked to process pieces of the selection as they
+ * arrive during "selection get" commands.
*
* Results:
* Always returns TCL_OK.
*
* Side effects:
- * Bytes get appended to the dynamic string pointed to by the
- * clientData argument.
+ * Bytes get appended to the dynamic string pointed to by the clientData
+ * argument.
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static int
-SelGetProc(clientData, interp, portion)
- ClientData clientData; /* Dynamic string holding partially
- * assembled selection. */
- Tcl_Interp *interp; /* Interpreter used for error
- * reporting (not used). */
- char *portion; /* New information to be appended. */
+SelGetProc(
+ ClientData clientData, /* Dynamic string holding partially assembled
+ * selection. */
+ Tcl_Interp *interp, /* Interpreter used for error reporting (not
+ * used). */
+ char *portion) /* New information to be appended. */
{
Tcl_DStringAppend((Tcl_DString *) clientData, portion, -1);
return TCL_OK;
@@ -1307,14 +1299,14 @@ SelGetProc(clientData, interp, portion)
*
* HandleTclCommand --
*
- * This procedure acts as selection handler for handlers created
- * by the "selection handle" command. It invokes a Tcl command to
- * retrieve the selection.
+ * This function acts as selection handler for handlers created by the
+ * "selection handle" command. It invokes a Tcl command to retrieve the
+ * selection.
*
* Results:
- * The return value is a count of the number of bytes actually
- * stored at buffer, or -1 if an error occurs while executing
- * the Tcl command to retrieve the selection.
+ * The return value is a count of the number of bytes actually stored at
+ * buffer, or -1 if an error occurs while executing the Tcl command to
+ * retrieve the selection.
*
* Side effects:
* None except for things done by the Tcl command.
@@ -1323,12 +1315,12 @@ SelGetProc(clientData, interp, portion)
*/
static int
-HandleTclCommand(clientData, offset, buffer, maxBytes)
- ClientData clientData; /* Information about command to execute. */
- int offset; /* Return selection bytes starting at this
+HandleTclCommand(
+ ClientData clientData, /* Information about command to execute. */
+ int offset, /* Return selection bytes starting at this
* offset. */
- char *buffer; /* Place to store converted selection. */
- int maxBytes; /* Maximum # of bytes to store at buffer. */
+ char *buffer, /* Place to store converted selection. */
+ int maxBytes) /* Maximum # of bytes to store at buffer. */
{
CommandInfo *cmdInfoPtr = (CommandInfo *) clientData;
int spaceNeeded, length;
@@ -1342,16 +1334,16 @@ HandleTclCommand(clientData, offset, buffer, maxBytes)
CONST char *p;
/*
- * We must also protect the interpreter and the command from being
- * deleted too soon.
+ * We must also protect the interpreter and the command from being deleted
+ * too soon.
*/
Tcl_Preserve(clientData);
Tcl_Preserve((ClientData) interp);
/*
- * Compute the proper byte offset in the case where the last chunk
- * split a character.
+ * Compute the proper byte offset in the case where the last chunk split a
+ * character.
*/
if (offset == cmdInfoPtr->byteOffset) {
@@ -1370,8 +1362,8 @@ HandleTclCommand(clientData, offset, buffer, maxBytes)
}
/*
- * First, generate a command by taking the command string
- * and appending the offset and maximum # of bytes.
+ * First, generate a command by taking the command string and appending
+ * the offset and maximum # of bytes.
*/
spaceNeeded = cmdInfoPtr->cmdLength + 30;
@@ -1383,8 +1375,8 @@ HandleTclCommand(clientData, offset, buffer, maxBytes)
sprintf(command, "%s %d %d", cmdInfoPtr->command, charOffset, maxBytes);
/*
- * Execute the command. Be sure to restore the state of the
- * interpreter after executing the command.
+ * Execute the command. Be sure to restore the state of the interpreter
+ * after executing the command.
*/
Tcl_DStringInit(&oldResult);
@@ -1393,12 +1385,12 @@ HandleTclCommand(clientData, offset, buffer, maxBytes)
objPtr = Tcl_GetObjResult(interp);
string = Tcl_GetStringFromObj(objPtr, &length);
count = (length > maxBytes) ? maxBytes : length;
- memcpy((VOID *) buffer, (VOID *) string, (size_t) count);
+ memcpy(buffer, string, (size_t) count);
buffer[count] = '\0';
/*
- * Update the partial character information for the next
- * retrieval if the command has not been deleted.
+ * Update the partial character information for the next retrieval if
+ * the command has not been deleted.
*/
if (cmdInfoPtr->interp != NULL) {
@@ -1419,7 +1411,7 @@ HandleTclCommand(clientData, offset, buffer, maxBytes)
strncpy(cmdInfoPtr->buffer, string, (size_t) length);
}
cmdInfoPtr->buffer[length] = '\0';
- }
+ }
cmdInfoPtr->byteOffset += count + extraBytes;
}
count += extraBytes;
@@ -1432,7 +1424,6 @@ HandleTclCommand(clientData, offset, buffer, maxBytes)
ckfree(command);
}
-
Tcl_Release(clientData);
Tcl_Release((ClientData) interp);
return count;
@@ -1443,20 +1434,18 @@ HandleTclCommand(clientData, offset, buffer, maxBytes)
*
* TkSelDefaultSelection --
*
- * This procedure is called to generate selection information
- * for a few standard targets such as TIMESTAMP and TARGETS.
- * It is invoked only if no handler has been declared by the
- * application.
+ * This function is called to generate selection information for a few
+ * standard targets such as TIMESTAMP and TARGETS. It is invoked only if
+ * no handler has been declared by the application.
*
* Results:
- * If "target" is a standard target understood by this procedure,
- * the selection is converted to that form and stored as a
- * character string in buffer. The type of the selection (e.g.
- * STRING or ATOM) is stored in *typePtr, and the return value is
- * a count of the # of non-NULL bytes at buffer. If the target
- * wasn't understood, or if there isn't enough space at buffer
- * to hold the entire selection (no INCR-mode transfers for this
- * stuff!), then -1 is returned.
+ * If "target" is a standard target understood by this function, the
+ * selection is converted to that form and stored as a character string
+ * in buffer. The type of the selection (e.g. STRING or ATOM) is stored
+ * in *typePtr, and the return value is a count of the # of non-NULL
+ * bytes at buffer. If the target wasn't understood, or if there isn't
+ * enough space at buffer to hold the entire selection (no INCR-mode
+ * transfers for this stuff!), then -1 is returned.
*
* Side effects:
* None.
@@ -1465,13 +1454,13 @@ HandleTclCommand(clientData, offset, buffer, maxBytes)
*/
int
-TkSelDefaultSelection(infoPtr, target, buffer, maxBytes, typePtr)
- TkSelectionInfo *infoPtr; /* Info about selection being retrieved. */
- Atom target; /* Desired form of selection. */
- char *buffer; /* Place to put selection characters. */
- int maxBytes; /* Maximum # of bytes to store at buffer. */
- Atom *typePtr; /* Store here the type of the selection,
- * for use in converting to proper X format. */
+TkSelDefaultSelection(
+ TkSelectionInfo *infoPtr, /* Info about selection being retrieved. */
+ Atom target, /* Desired form of selection. */
+ char *buffer, /* Place to put selection characters. */
+ int maxBytes, /* Maximum # of bytes to store at buffer. */
+ Atom *typePtr) /* Store here the type of the selection, for
+ * use in converting to proper X format. */
{
register TkWindow *winPtr = (TkWindow *) infoPtr->owner;
TkDisplay *dispPtr = winPtr->dispPtr;
@@ -1551,22 +1540,22 @@ TkSelDefaultSelection(infoPtr, target, buffer, maxBytes, typePtr)
*
* LostSelection --
*
- * This procedure is invoked when a window has lost ownership of
- * the selection and the ownership was claimed with the command
- * "selection own".
+ * This function is invoked when a window has lost ownership of the
+ * selection and the ownership was claimed with the command "selection
+ * own".
*
* Results:
* None.
*
* Side effects:
- * A Tcl script is executed; it can do almost anything.
+ * A Tcl script is executed; it can do almost anything.
*
*----------------------------------------------------------------------
*/
static void
-LostSelection(clientData)
- ClientData clientData; /* Pointer to LostCommand structure. */
+LostSelection(
+ ClientData clientData) /* Pointer to LostCommand structure. */
{
LostCommand *lostPtr = (LostCommand *) clientData;
Tcl_Obj *objPtr;
@@ -1574,10 +1563,10 @@ LostSelection(clientData)
interp = lostPtr->interp;
Tcl_Preserve((ClientData) interp);
-
+
/*
- * Execute the command. Save the interpreter's result, if any, and
- * restore it after executing the command.
+ * Execute the command. Save the interpreter's result, if any, and restore
+ * it after executing the command.
*/
objPtr = Tcl_GetObjResult(interp);
@@ -1592,10 +1581,18 @@ LostSelection(clientData)
Tcl_DecrRefCount(objPtr);
Tcl_Release((ClientData) interp);
-
+
/*
* Free the storage for the command, since we're done with it now.
*/
ckfree((char *) lostPtr);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkSelect.h b/generic/tkSelect.h
index 4d1c9d0..b9d7d2d 100644
--- a/generic/tkSelect.h
+++ b/generic/tkSelect.h
@@ -1,13 +1,13 @@
/*
* tkSelect.h --
*
- * Declarations of types shared among the files that implement
- * selection support.
+ * Declarations of types shared among the files that implement selection
+ * support.
*
* Copyright (c) 1995 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKSELECT
@@ -16,142 +16,134 @@
/*
* When a selection is owned by a window on a given display, one of the
* following structures is present on a list of current selections in the
- * display structure. The structure is used to record the current owner of
- * a selection for use in later retrieval requests. There is a list of
- * such structures because a display can have multiple different selections
- * active at the same time.
+ * display structure. The structure is used to record the current owner of a
+ * selection for use in later retrieval requests. There is a list of such
+ * structures because a display can have multiple different selections active
+ * at the same time.
*/
typedef struct TkSelectionInfo {
Atom selection; /* Selection name, e.g. XA_PRIMARY. */
Tk_Window owner; /* Current owner of this selection. */
int serial; /* Serial number of last XSelectionSetOwner
- * request made to server for this
- * selection (used to filter out redundant
+ * request made to server for this selection
+ * (used to filter out redundant
* SelectionClear events). */
Time time; /* Timestamp used to acquire selection. */
Tk_LostSelProc *clearProc; /* Procedure to call when owner loses
* selection. */
ClientData clearData; /* Info to pass to clearProc. */
struct TkSelectionInfo *nextPtr;
- /* Next in list of current selections on
- * this display. NULL means end of list */
+ /* Next in list of current selections on this
+ * display. NULL means end of list. */
} TkSelectionInfo;
/*
- * One of the following structures exists for each selection handler
- * created for a window by calling Tk_CreateSelHandler. The handlers
- * are linked in a list rooted in the TkWindow structure.
+ * One of the following structures exists for each selection handler created
+ * for a window by calling Tk_CreateSelHandler. The handlers are linked in a
+ * list rooted in the TkWindow structure.
*/
typedef struct TkSelHandler {
- Atom selection; /* Selection name, e.g. XA_PRIMARY */
- Atom target; /* Target type for selection
- * conversion, such as TARGETS or
- * STRING. */
- Atom format; /* Format in which selection
- * info will be returned, such
- * as STRING or ATOM. */
- Tk_SelectionProc *proc; /* Procedure to generate selection
- * in this format. */
+ Atom selection; /* Selection name, e.g. XA_PRIMARY. */
+ Atom target; /* Target type for selection conversion, such
+ * as TARGETS or STRING. */
+ Atom format; /* Format in which selection info will be
+ * returned, such as STRING or ATOM. */
+ Tk_SelectionProc *proc; /* Procedure to generate selection in this
+ * format. */
ClientData clientData; /* Argument to pass to proc. */
- int size; /* Size of units returned by proc
- * (8 for STRING, 32 for almost
- * anything else). */
+ int size; /* Size of units returned by proc (8 for
+ * STRING, 32 for almost anything else). */
struct TkSelHandler *nextPtr;
- /* Next selection handler associated
- * with same window (NULL for end of
- * list). */
+ /* Next selection handler associated with same
+ * window (NULL for end of list). */
} TkSelHandler;
/*
- * When the selection is being retrieved, one of the following
- * structures is present on a list of pending selection retrievals.
- * The structure is used to communicate between the background
- * procedure that requests the selection and the foreground
- * event handler that processes the events in which the selection
- * is returned. There is a list of such structures so that there
- * can be multiple simultaneous selection retrievals (e.g. on
- * different displays).
+ * When the selection is being retrieved, one of the following structures is
+ * present on a list of pending selection retrievals. The structure is used to
+ * communicate between the background procedure that requests the selection
+ * and the foreground event handler that processes the events in which the
+ * selection is returned. There is a list of such structures so that there can
+ * be multiple simultaneous selection retrievals (e.g. on different displays).
*/
typedef struct TkSelRetrievalInfo {
Tcl_Interp *interp; /* Interpreter for error reporting. */
- TkWindow *winPtr; /* Window used as requestor for
- * selection. */
+ TkWindow *winPtr; /* Window used as requestor for selection. */
Atom selection; /* Selection being requested. */
Atom property; /* Property where selection will appear. */
Atom target; /* Desired form for selection. */
int (*proc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp,
- char *portion)); /* Procedure to call to handle pieces
- * of selection. */
+ char *portion)); /* Procedure to call to handle pieces of
+ * selection. */
ClientData clientData; /* Argument for proc. */
- int result; /* Initially -1. Set to a Tcl
- * return value once the selection
- * has been retrieved. */
+ int result; /* Initially -1. Set to a Tcl return value
+ * once the selection has been retrieved. */
Tcl_TimerToken timeout; /* Token for current timeout procedure. */
- int idleTime; /* Number of seconds that have gone by
- * without hearing anything from the
- * selection owner. */
+ int idleTime; /* Number of seconds that have gone by without
+ * hearing anything from the selection
+ * owner. */
Tcl_EncodingState encState; /* Holds intermediate state during translations
* of data that cross buffer boundaries. */
int encFlags; /* Encoding translation state flags. */
Tcl_DString buf; /* Buffer to hold translation data. */
struct TkSelRetrievalInfo *nextPtr;
- /* Next in list of all pending
- * selection retrievals. NULL means
- * end of list. */
+ /* Next in list of all pending selection
+ * retrievals. NULL means end of list. */
} TkSelRetrievalInfo;
/*
- * The clipboard contains a list of buffers of various types and formats.
- * All of the buffers of a given type will be returned in sequence when the
- * CLIPBOARD selection is retrieved. All buffers of a given type on the
- * same clipboard must have the same format. The TkClipboardTarget structure
- * is used to record the information about a chain of buffers of the same
- * type.
+ * The clipboard contains a list of buffers of various types and formats. All
+ * of the buffers of a given type will be returned in sequence when the
+ * CLIPBOARD selection is retrieved. All buffers of a given type on the same
+ * clipboard must have the same format. The TkClipboardTarget structure is
+ * used to record the information about a chain of buffers of the same type.
*/
typedef struct TkClipboardBuffer {
- char *buffer; /* Null terminated data buffer. */
- long length; /* Length of string in buffer. */
- struct TkClipboardBuffer *nextPtr; /* Next in list of buffers. NULL
- * means end of list . */
+ char *buffer; /* Null terminated data buffer. */
+ long length; /* Length of string in buffer. */
+ struct TkClipboardBuffer *nextPtr;
+ /* Next in list of buffers. NULL means end of
+ * list . */
} TkClipboardBuffer;
typedef struct TkClipboardTarget {
- Atom type; /* Type conversion supported. */
- Atom format; /* Representation used for data. */
- TkClipboardBuffer *firstBufferPtr; /* First in list of data buffers. */
- TkClipboardBuffer *lastBufferPtr; /* Last in list of clipboard buffers.
- * Used to speed up appends. */
- struct TkClipboardTarget *nextPtr; /* Next in list of targets on
- * clipboard. NULL means end of
- * list. */
+ Atom type; /* Type conversion supported. */
+ Atom format; /* Representation used for data. */
+ TkClipboardBuffer *firstBufferPtr;
+ /* First in list of data buffers. */
+ TkClipboardBuffer *lastBufferPtr;
+ /* Last in list of clipboard buffers. Used to
+ * speed up appends. */
+ struct TkClipboardTarget *nextPtr;
+ /* Next in list of targets on clipboard. NULL
+ * means end of list. */
} TkClipboardTarget;
/*
* It is possible for a Tk_SelectionProc to delete the handler that it
- * represents. If this happens, the code that is retrieving the selection
- * needs to know about it so it doesn't use the now-defunct handler
- * structure. One structure of the following form is created for each
- * retrieval in progress, so that the retriever can find out if its
- * handler is deleted. All of the pending retrievals (if there are more
- * than one) are linked into a list.
+ * represents. If this happens, the code that is retrieving the selection
+ * needs to know about it so it doesn't use the now-defunct handler structure.
+ * One structure of the following form is created for each retrieval in
+ * progress, so that the retriever can find out if its handler is deleted. All
+ * of the pending retrievals (if there are more than one) are linked into a
+ * list.
*/
typedef struct TkSelInProgress {
- TkSelHandler *selPtr; /* Handler being executed. If this handler
- * is deleted, the field is set to NULL. */
+ TkSelHandler *selPtr; /* Handler being executed. If this handler is
+ * deleted, the field is set to NULL. */
struct TkSelInProgress *nextPtr;
/* Next higher nested search. */
} TkSelInProgress;
/*
- * 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
- * has an extra character for the terminating NULL.
+ * 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 has an extra character for the terminating NULL.
*/
#define TK_SEL_BYTES_AT_ONCE 4000
@@ -162,22 +154,18 @@ typedef struct TkSelInProgress {
* 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_((
- TkSelectionInfo *infoPtr, Atom target,
- char *buffer, int maxBytes, Atom *typePtr));
-extern int TkSelGetSelection _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, Atom selection, Atom target,
- Tk_GetSelProc *proc, ClientData clientData));
+MODULE_SCOPE TkSelInProgress *TkSelGetInProgress(void);
+MODULE_SCOPE void TkSelSetInProgress(TkSelInProgress *pendingPtr);
+MODULE_SCOPE void TkSelClearSelection(Tk_Window tkwin, XEvent *eventPtr);
+MODULE_SCOPE int TkSelDefaultSelection(TkSelectionInfo *infoPtr,
+ Atom target, char *buffer, int maxBytes,
+ Atom *typePtr);
+MODULE_SCOPE int TkSelGetSelection(Tcl_Interp *interp, Tk_Window tkwin,
+ Atom selection, Atom target, Tk_GetSelProc *proc,
+ ClientData clientData);
#ifndef TkSelUpdateClipboard
-extern void TkSelUpdateClipboard _ANSI_ARGS_((TkWindow *winPtr,
- TkClipboardTarget *targetPtr));
+MODULE_SCOPE void TkSelUpdateClipboard(TkWindow *winPtr,
+ TkClipboardTarget *targetPtr);
#endif
#endif /* _TKSELECT */
diff --git a/generic/tkSquare.c b/generic/tkSquare.c
index 9f07b27..a35832a 100644
--- a/generic/tkSquare.c
+++ b/generic/tkSquare.c
@@ -1,32 +1,32 @@
-/*
+/*
* tkSquare.c --
*
- * 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".
+ * 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) 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
+#if 0
#define __NO_OLD_CONFIG
-#include "tk.h"
+#endif
#include "tkInt.h"
/*
- * A data structure of the following type is kept for each square
- * widget managed by this file:
+ * A data structure of the following type is kept for each square widget
+ * managed by this file:
*/
typedef struct {
- Tk_Window tkwin; /* Window that embodies the square. NULL
- * means window has been deleted but
- * widget record hasn't been cleaned up yet. */
+ Tk_Window tkwin; /* Window that embodies the square. NULL means
+ * window has been deleted but widget record
+ * hasn't been cleaned up yet. */
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. */
@@ -47,31 +47,31 @@ typedef struct {
Tcl_Obj *reliefPtr;
GC gc; /* Graphics context for copying from
* off-screen pixmap onto screen. */
- 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
- * has already been scheduled. */
+ 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 has
+ * already been scheduled. */
} Square;
/*
* Information used for argv parsing.
*/
-static CONST Tk_OptionSpec optionSpecs[] = {
+static const Tk_OptionSpec optionSpecs[] = {
{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_SYNONYM, "-bd", NULL, NULL, NULL, 0, -1, 0,
+ (ClientData) "-borderwidth"},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL, 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_SYNONYM, "-fg", NULL, NULL, NULL, 0, -1, 0,
+ (ClientData) "-foreground"},
{TK_OPTION_BORDER, "-foreground", "foreground", "Foreground",
"#b03060", Tk_Offset(Square, fgBorderPtr), -1, 0,
(ClientData) "black"},
@@ -90,28 +90,26 @@ static CONST Tk_OptionSpec optionSpecs[] = {
* Forward declarations for procedures defined later in this file:
*/
-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));
-static void SquareDestroy _ANSI_ARGS_((char *memPtr));
-static void SquareDisplay _ANSI_ARGS_((ClientData clientData));
-static void KeepInWindow _ANSI_ARGS_((Square *squarePtr));
-static void SquareObjEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static int SquareWidgetObjCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *, int objc, Tcl_Obj * CONST objv[]));
+int SquareObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj * CONST objv[]);
+static void SquareDeletedProc(ClientData clientData);
+static int SquareConfigure(Tcl_Interp *interp, Square *squarePtr);
+static void SquareDestroy(char *memPtr);
+static void SquareDisplay(ClientData clientData);
+static void KeepInWindow(Square *squarePtr);
+static void SquareObjEventProc(ClientData clientData,
+ XEvent *eventPtr);
+static int SquareWidgetObjCmd(ClientData clientData,
+ Tcl_Interp *, int objc, Tcl_Obj * CONST objv[]);
/*
*--------------------------------------------------------------
*
* SquareCmd --
*
- * This procedure is invoked to process the "square" Tcl
- * command. It creates a new "square" widget.
+ * This procedure is invoked to process the "square" Tcl command. It
+ * creates a new "square" widget.
*
* Results:
* A standard Tcl result.
@@ -123,11 +121,11 @@ static int SquareWidgetObjCmd _ANSI_ARGS_((ClientData clientData,
*/
int
-SquareObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* NULL. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj * CONST objv[]; /* Argument objects. */
+SquareObjCmd(
+ ClientData clientData, /* NULL. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Square *squarePtr;
Tk_Window tkwin;
@@ -138,39 +136,38 @@ SquareObjCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
- tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
- Tcl_GetStringFromObj(objv[1], NULL), (char *) NULL);
+ tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
+ Tcl_GetString(objv[1]), NULL);
if (tkwin == NULL) {
return TCL_ERROR;
}
Tk_SetClass(tkwin, "Square");
/*
- * Create the option table for this widget class. If it has
- * already been created, the refcount will get bumped and just
- * the pointer will be returned. The refcount getting bumped
- * does not concern us, because Tk will ensure the table is
- * deleted when the interpreter is destroyed.
+ * Create the option table for this widget class. If it has already been
+ * created, the refcount will get bumped and just the pointer will be
+ * returned. The refcount getting bumped does not concern us, because Tk
+ * will ensure the table is deleted when the interpreter is destroyed.
*/
optionTable = Tk_CreateOptionTable(interp, optionSpecs);
/*
- * Allocate and initialize the widget record. The memset allows
- * us to set just the non-NULL/0 items.
+ * Allocate and initialize the widget record. The memset allows us to set
+ * just the non-NULL/0 items.
*/
- squarePtr = (Square *) ckalloc(sizeof(Square));
+ squarePtr = (Square *) ckalloc(sizeof(Square));
memset((void *) squarePtr, 0, (sizeof(Square)));
- squarePtr->tkwin = tkwin;
- squarePtr->display = Tk_Display(tkwin);
- squarePtr->interp = interp;
- squarePtr->widgetCmd = Tcl_CreateObjCommand(interp,
+ squarePtr->tkwin = tkwin;
+ squarePtr->display = Tk_Display(tkwin);
+ squarePtr->interp = interp;
+ squarePtr->widgetCmd = Tcl_CreateObjCommand(interp,
Tk_PathName(squarePtr->tkwin), SquareWidgetObjCmd,
(ClientData) squarePtr, SquareDeletedProc);
- squarePtr->gc = None;
- squarePtr->optionTable = optionTable;
+ squarePtr->gc = None;
+ squarePtr->optionTable = optionTable;
if (Tk_InitOptions(interp, (char *) squarePtr, optionTable, tkwin)
!= TCL_OK) {
@@ -182,7 +179,7 @@ SquareObjCmd(clientData, interp, objc, objv)
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) {
+ objv + 2, tkwin, NULL, NULL) != TCL_OK) {
goto error;
}
if (SquareConfigure(interp, squarePtr) != TCL_OK) {
@@ -193,7 +190,7 @@ SquareObjCmd(clientData, interp, objc, objv)
Tcl_NewStringObj(Tk_PathName(squarePtr->tkwin), -1));
return TCL_OK;
-error:
+ error:
Tk_DestroyWindow(squarePtr->tkwin);
return TCL_ERROR;
}
@@ -203,9 +200,9 @@ error:
*
* SquareWidgetObjCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to a widget managed by this module.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the Tcl command that corresponds
+ * to a widget managed by this module. See the user documentation for
+ * details on what it does.
*
* Results:
* A standard Tcl result.
@@ -217,15 +214,15 @@ error:
*/
static int
-SquareWidgetObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Information about square widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj * CONST objv[]; /* Argument objects. */
+SquareWidgetObjCmd(
+ ClientData clientData, /* Information about square widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj * CONST objv[]) /* Argument objects. */
{
Square *squarePtr = (Square *) clientData;
int result = TCL_OK;
- static CONST char *squareOptions[] = {"cget", "configure", (char *) NULL};
+ static CONST char *squareOptions[] = {"cget", "configure", NULL};
enum {
SQUARE_CGET, SQUARE_CONFIGURE
};
@@ -243,58 +240,55 @@ SquareWidgetObjCmd(clientData, interp, objc, objv)
}
Tcl_Preserve((ClientData) squarePtr);
-
+
switch (index) {
- case SQUARE_CGET: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "option");
- goto error;
+ case SQUARE_CGET:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option");
+ 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;
+ case SQUARE_CONFIGURE:
+ resultObjPtr = NULL;
+ if (objc == 2) {
+ resultObjPtr = Tk_GetOptionInfo(interp, (char *) squarePtr,
+ squarePtr->optionTable, NULL, squarePtr->tkwin);
+ if (resultObjPtr == NULL) {
+ result = TCL_ERROR;
}
- resultObjPtr = Tk_GetOptionValue(interp, (char *) squarePtr,
+ } else if (objc == 3) {
+ resultObjPtr = Tk_GetOptionInfo(interp, (char *) squarePtr,
squarePtr->optionTable, objv[2], squarePtr->tkwin);
if (resultObjPtr == NULL) {
result = TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, resultObjPtr);
}
- break;
- }
- 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;
- }
+ } else {
+ result = Tk_SetOptions(interp, (char *) squarePtr,
+ squarePtr->optionTable, objc - 2, objv + 2,
+ squarePtr->tkwin, NULL, NULL);
+ if (result == TCL_OK) {
+ result = SquareConfigure(interp, squarePtr);
}
- if (resultObjPtr != NULL) {
- Tcl_SetObjResult(interp, resultObjPtr);
+ if (!squarePtr->updatePending) {
+ Tcl_DoWhenIdle(SquareDisplay, (ClientData) squarePtr);
+ squarePtr->updatePending = 1;
}
}
+ if (resultObjPtr != NULL) {
+ Tcl_SetObjResult(interp, resultObjPtr);
+ }
}
Tcl_Release((ClientData) squarePtr);
return result;
- error:
+ error:
Tcl_Release((ClientData) squarePtr);
return TCL_ERROR;
}
@@ -304,37 +298,36 @@ SquareWidgetObjCmd(clientData, interp, objc, objv)
*
* SquareConfigure --
*
- * This procedure is called to process an argv/argc list in
- * conjunction with the Tk option database to configure (or
- * reconfigure) a square widget.
+ * This procedure is called to process an argv/argc list in conjunction
+ * with the Tk option database to configure (or reconfigure) a square
+ * widget.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message.
+ * 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 colors, border width,
- * etc. get set for squarePtr; old resources get freed,
- * if there were any.
+ * Configuration information, such as colors, border width, etc. get set
+ * for squarePtr; old resources get freed, if there were any.
*
*----------------------------------------------------------------------
*/
static int
-SquareConfigure(interp, squarePtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Square *squarePtr; /* Information about widget. */
+SquareConfigure(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Square *squarePtr) /* Information about widget. */
{
int borderWidth;
Tk_3DBorder bgBorder;
int doubleBuffer;
/*
- * Set the background for the window and create a graphics context
- * for use during redisplay.
+ * Set the background for the window and create a graphics context for use
+ * during redisplay.
*/
- bgBorder = Tk_Get3DBorderFromObj(squarePtr->tkwin,
+ bgBorder = Tk_Get3DBorderFromObj(squarePtr->tkwin,
squarePtr->bgBorderPtr);
Tk_SetWindowBackground(squarePtr->tkwin,
Tk_3DBorderColor(bgBorder)->pixel);
@@ -348,8 +341,8 @@ SquareConfigure(interp, squarePtr)
}
/*
- * Register the desired geometry for the window. Then arrange for
- * the window to be redisplayed.
+ * Register the desired geometry for the window. Then arrange for the
+ * window to be redisplayed.
*/
Tk_GeometryRequest(squarePtr->tkwin, 200, 150);
@@ -369,23 +362,23 @@ SquareConfigure(interp, squarePtr)
*
* SquareObjEventProc --
*
- * This procedure is invoked by the Tk dispatcher for various
- * events on squares.
+ * This procedure is invoked by the Tk dispatcher for various events on
+ * squares.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up. When
+ * it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-SquareObjEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- XEvent *eventPtr; /* Information about event. */
+SquareObjEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
Square *squarePtr = (Square *) clientData;
@@ -423,9 +416,9 @@ SquareObjEventProc(clientData, eventPtr)
*
* SquareDeletedProc --
*
- * 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.
+ * 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.
@@ -437,17 +430,17 @@ SquareObjEventProc(clientData, eventPtr)
*/
static void
-SquareDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+SquareDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
Square *squarePtr = (Square *) clientData;
Tk_Window tkwin = squarePtr->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.
+ * 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.
*/
if (tkwin != NULL) {
@@ -460,9 +453,9 @@ SquareDeletedProc(clientData)
*
* SquareDisplay --
*
- * This procedure redraws the contents of a square window.
- * It is invoked as a do-when-idle handler, so it only runs
- * when there's nothing else for the application to do.
+ * This procedure redraws the contents of a square window. It is invoked
+ * as a do-when-idle handler, so it only runs when there's nothing else
+ * for the application to do.
*
* Results:
* None.
@@ -474,8 +467,8 @@ SquareDeletedProc(clientData)
*/
static void
-SquareDisplay(clientData)
- ClientData clientData; /* Information about window. */
+SquareDisplay(
+ ClientData clientData) /* Information about window. */
{
Square *squarePtr = (Square *) clientData;
Tk_Window tkwin = squarePtr->tkwin;
@@ -510,7 +503,7 @@ SquareDisplay(clientData)
Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->borderWidthPtr,
&borderWidth);
- bgBorder = Tk_Get3DBorderFromObj(squarePtr->tkwin,
+ bgBorder = Tk_Get3DBorderFromObj(squarePtr->tkwin,
squarePtr->bgBorderPtr);
Tk_GetReliefFromObj(NULL, squarePtr->reliefPtr, &relief);
Tk_Fill3DRectangle(tkwin, d, bgBorder, 0, 0, Tk_Width(tkwin),
@@ -521,9 +514,9 @@ SquareDisplay(clientData)
*/
Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->sizeObjPtr, &size);
- fgBorder = Tk_Get3DBorderFromObj(squarePtr->tkwin,
+ fgBorder = Tk_Get3DBorderFromObj(squarePtr->tkwin,
squarePtr->fgBorderPtr);
- Tk_Fill3DRectangle(tkwin, d, fgBorder, squarePtr->x, squarePtr->y, size,
+ Tk_Fill3DRectangle(tkwin, d, fgBorder, squarePtr->x, squarePtr->y, size,
size, borderWidth, TK_RELIEF_RAISED);
/*
@@ -543,9 +536,9 @@ SquareDisplay(clientData)
*
* SquareDestroy --
*
- * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release
- * to clean up the internal structure of a square at a safe time
- * (when no-one is using it anymore).
+ * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to
+ * clean up the internal structure of a square at a safe time (when
+ * no-one is using it anymore).
*
* Results:
* None.
@@ -557,11 +550,11 @@ SquareDisplay(clientData)
*/
static void
-SquareDestroy(memPtr)
- char *memPtr; /* Info about square widget. */
+SquareDestroy(
+ char *memPtr) /* Info about square widget. */
{
Square *squarePtr = (Square *) memPtr;
-
+
ckfree((char *) squarePtr);
}
@@ -570,31 +563,31 @@ SquareDestroy(memPtr)
*
* KeepInWindow --
*
- * Adjust the position of the square if necessary to keep it in
- * the widget's window.
+ * Adjust the position of the square if necessary to keep it in the
+ * widget's window.
*
* Results:
* None.
*
* Side effects:
- * The x and y position of the square are adjusted if necessary
- * to keep the square in the window.
+ * The x and y position of the square are adjusted if necessary to keep
+ * the square in the window.
*
*----------------------------------------------------------------------
*/
static void
-KeepInWindow(squarePtr)
- register Square *squarePtr; /* Pointer to widget record. */
+KeepInWindow(
+ register Square *squarePtr) /* Pointer to widget record. */
{
int i, bd, relief;
int borderWidth, size;
Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->borderWidthPtr,
&borderWidth);
- Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->xPtr,
+ Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->xPtr,
&squarePtr->x);
- Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->yPtr,
+ Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->yPtr,
&squarePtr->y);
Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->sizeObjPtr, &size);
Tk_GetReliefFromObj(NULL, squarePtr->reliefPtr, &relief);
@@ -617,3 +610,11 @@ KeepInWindow(squarePtr)
squarePtr->y = bd;
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkStubImg.c b/generic/tkStubImg.c
deleted file mode 100644
index 608d627..0000000
--- a/generic/tkStubImg.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * tkStubImg.c --
- *
- * Stub object that will be statically linked into extensions that wish
- * to access Tk.
- *
- * Copyright (c) 1999 Jan Nijtmans.
- * 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.
- */
-
-#include "tcl.h"
-
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_InitImageArgs --
- *
- * Performs the necessary conversion from Tcl_Obj's to strings
- * in the createProc for Tcl_CreateImageType. If running under
- * Tk 8.2 or earlier without the Img-patch, this function has
- * no effect.
- *
- * Results:
- * argvPtr will point to an argument list which is guaranteed to
- * contain strings, no matter what Tk version is running.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-#ifdef Tk_InitImageArgs
-#undef Tk_InitImageArgs
-#endif
-
-void
-Tk_InitImageArgs(interp, argc, argvPtr)
- Tcl_Interp *interp;
- int argc;
- char ***argvPtr;
-{
- static int useNewImage = -1;
- static char **argv = NULL;
-
- if (argv) {
- tclStubsPtr->tcl_Free((char *) argv);
- argv = NULL;
- }
-
- if (useNewImage < 0) {
- Tcl_CmdInfo cmdInfo;
- if (!tclStubsPtr->tcl_GetCommandInfo(interp,"image", &cmdInfo)) {
- tclStubsPtr->tcl_Panic("cannot find the \"image\" command");
- }
- if (cmdInfo.isNativeObjectProc == 1) {
- useNewImage = 1; /* Tk uses the new image interface */
- } else {
- useNewImage = 0; /* Tk uses old image interface */
- }
- }
- if (useNewImage && (argc > 0)) {
- int i;
- argv = (char **) tclStubsPtr->tcl_Alloc(argc * sizeof(char *));
- for (i = 0; i < argc; i++) {
- argv[i] = tclStubsPtr->tcl_GetString((Tcl_Obj *)(*argvPtr)[i]);
- }
- *argvPtr = (char **) argv;
- }
-}
diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c
index dc22008..c2ef290 100644
--- a/generic/tkStubInit.c
+++ b/generic/tkStubInit.c
@@ -10,11 +10,11 @@
*/
#include "tkInt.h"
-#include "tkPort.h"
-#if !(defined(__WIN32__) && defined(MAC_OSX_TK))
+#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
/* UNIX */
#define UNIX_TK
+#include "tkUnixInt.h"
#endif
#ifdef __WIN32__
@@ -22,14 +22,12 @@
#endif
#if defined(MAC_OSX_TK)
-/* set this locally .. we could have used _TKMACINT */
+/* we could have used _TKMACINT */
#include "tkMacOSXInt.h"
#endif
-#include "tkDecls.h"
+/* TODO: These ought to come in some other way */
#include "tkPlatDecls.h"
-#include "tkIntDecls.h"
-#include "tkIntPlatDecls.h"
#include "tkIntXlibDecls.h"
#ifdef __WIN32__
@@ -86,6 +84,7 @@ XVisualIDFromVisual(Visual *visual)
# define TkUnixSetMenubar 0
# define TkWmCleanup (void (*) (TkDisplay *)) doNothing
# define TkSendCleanup (void (*) (TkDisplay *)) doNothing
+# define TkpTestsendCmd 0
# define XFlush (int (*) (Display *)) doNothing
# define XGrabServer (int (*) (Display *)) doNothing
# define XUngrabServer (int (*) (Display *)) doNothing
@@ -247,14 +246,14 @@ void TkSubtractRegion (TkRegion a, TkRegion b, TkRegion c)
# undef TkUnionRectWithRegion
# undef TkSubtractRegion
-# define TkClipBox (void (*) _ANSI_ARGS_((TkRegion, XRectangle *))) XClipBox
+# define TkClipBox (void (*) (TkRegion, XRectangle *)) XClipBox
# define TkCreateRegion (TkRegion (*) ()) XCreateRegion
-# define TkDestroyRegion (void (*) _ANSI_ARGS_((TkRegion))) XDestroyRegion
-# define TkIntersectRegion (void (*) _ANSI_ARGS_((TkRegion, TkRegion, TkRegion))) XIntersectRegion
-# define TkRectInRegion (int (*) _ANSI_ARGS_((TkRegion, int, int, unsigned int, unsigned int))) XRectInRegion
-# define TkSetRegion (void (*) _ANSI_ARGS_((Display *, GC, TkRegion))) XSetRegion
-# define TkUnionRectWithRegion (void (*) _ANSI_ARGS_((XRectangle *, TkRegion, TkRegion))) XUnionRectWithRegion
-# define TkSubtractRegion (void (*) _ANSI_ARGS_((TkRegion, TkRegion, TkRegion))) XSubtractRegion
+# define TkDestroyRegion (void (*) (TkRegion)) XDestroyRegion
+# define TkIntersectRegion (void (*) (TkRegion, TkRegion, TkRegion)) XIntersectRegion
+# define TkRectInRegion (int (*) (TkRegion, int, int, unsigned int, unsigned int)) XRectInRegion
+# define TkSetRegion (void (*) (Display *, GC, TkRegion)) XSetRegion
+# define TkUnionRectWithRegion (void (*) (XRectangle *, TkRegion, TkRegion)) XUnionRectWithRegion
+# define TkSubtractRegion (void (*) (TkRegion, TkRegion, TkRegion)) XSubtractRegion
# endif
#endif /* !__WIN32__ */
@@ -446,9 +445,37 @@ TkIntStubs tkIntStubs = {
TkStylePkgFree, /* 147 */
TkToplevelWindowForCommand, /* 148 */
TkGetOptionSpec, /* 149 */
- NULL, /* 150 */
- NULL, /* 151 */
+ TkMakeRawCurve, /* 150 */
+ TkMakeRawCurvePostscript, /* 151 */
TkpDrawFrame, /* 152 */
+ TkCreateThreadExitHandler, /* 153 */
+ TkDeleteThreadExitHandler, /* 154 */
+ NULL, /* 155 */
+ TkpTestembedCmd, /* 156 */
+ TkpTesttextCmd, /* 157 */
+ NULL, /* 158 */
+ NULL, /* 159 */
+ NULL, /* 160 */
+ NULL, /* 161 */
+ NULL, /* 162 */
+ NULL, /* 163 */
+ NULL, /* 164 */
+ NULL, /* 165 */
+ NULL, /* 166 */
+ NULL, /* 167 */
+ NULL, /* 168 */
+ TkStateParseProc, /* 169 */
+ TkStatePrintProc, /* 170 */
+ TkCanvasDashParseProc, /* 171 */
+ TkCanvasDashPrintProc, /* 172 */
+ TkOffsetParseProc, /* 173 */
+ TkOffsetPrintProc, /* 174 */
+ TkPixelParseProc, /* 175 */
+ TkPixelPrintProc, /* 176 */
+ TkOrientParseProc, /* 177 */
+ TkOrientPrintProc, /* 178 */
+ TkSmoothParseProc, /* 179 */
+ TkSmoothPrintProc, /* 180 */
};
TkIntPlatStubs tkIntPlatStubs = {
@@ -500,6 +527,7 @@ TkIntPlatStubs tkIntPlatStubs = {
TkUnixSetMenubar, /* 42 */
TkWmCleanup, /* 43 */
TkSendCleanup, /* 44 */
+ TkpTestsendCmd, /* 45 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
TkGenerateActivateEvents, /* 0 */
@@ -556,6 +584,7 @@ TkIntPlatStubs tkIntPlatStubs = {
TkGenWMDestroyEvent, /* 51 */
NULL, /* 52 */
TkpGetMS, /* 53 */
+ TkMacOSXDrawable, /* 54 */
#endif /* AQUA */
#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
TkCreateXEventSource, /* 0 */
@@ -571,6 +600,7 @@ TkIntPlatStubs tkIntPlatStubs = {
TkSendCleanup, /* 10 */
TkFreeXId, /* 11 */
TkpWmSetState, /* 12 */
+ TkpTestsendCmd, /* 13 */
#endif /* X11 */
};
@@ -974,9 +1004,9 @@ TkStubs tkStubs = {
Tk_PhotoPutZoomedBlock_NoComposite, /* 145 */
Tk_PhotoGetImage, /* 146 */
Tk_PhotoBlank, /* 147 */
- Tk_PhotoExpand, /* 148 */
+ Tk_PhotoExpand_Panic, /* 148 */
Tk_PhotoGetSize, /* 149 */
- Tk_PhotoSetSize, /* 150 */
+ Tk_PhotoSetSize_Panic, /* 150 */
Tk_PointToChar, /* 151 */
Tk_PostscriptFontName, /* 152 */
Tk_PreserveColormap, /* 153 */
@@ -1072,8 +1102,8 @@ TkStubs tkStubs = {
Tk_SetInternalBorderEx, /* 243 */
Tk_SetMinimumRequestSize, /* 244 */
Tk_SetCaretPos, /* 245 */
- Tk_PhotoPutBlock, /* 246 */
- Tk_PhotoPutZoomedBlock, /* 247 */
+ Tk_PhotoPutBlock_Panic, /* 246 */
+ Tk_PhotoPutZoomedBlock_Panic, /* 247 */
Tk_CollapseMotionEvents, /* 248 */
Tk_RegisterStyleEngine, /* 249 */
Tk_GetStyleEngine, /* 250 */
@@ -1091,10 +1121,18 @@ TkStubs tkStubs = {
Tk_GetElementBox, /* 262 */
Tk_GetElementBorderWidth, /* 263 */
Tk_DrawElement, /* 264 */
+ Tk_PhotoExpand, /* 265 */
+ Tk_PhotoPutBlock, /* 266 */
+ Tk_PhotoPutZoomedBlock, /* 267 */
+ Tk_PhotoSetSize, /* 268 */
+ Tk_GetUserInactiveTime, /* 269 */
+ Tk_ResetUserInactiveTime, /* 270 */
+ Tk_Interp, /* 271 */
+ Tk_CreateOldImageType, /* 272 */
+ Tk_CreateOldPhotoImageFormat, /* 273 */
};
/* !END!: Do not edit above this line. */
#undef UNIX_TK
-#undef MAC_TK
#undef MAC_OSX_TK
diff --git a/generic/tkStubLib.c b/generic/tkStubLib.c
index f803e49..f605b5d 100644
--- a/generic/tkStubLib.c
+++ b/generic/tkStubLib.c
@@ -11,7 +11,6 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
#ifdef __WIN32__
@@ -22,10 +21,12 @@
#include "tkMacOSXInt.h"
#endif
-#include "tkDecls.h"
-#include "tkIntDecls.h"
+#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
+#include "tkUnixInt.h"
+#endif
+
+/* TODO: These ought to come in some other way */
#include "tkPlatDecls.h"
-#include "tkIntPlatDecls.h"
#include "tkIntXlibDecls.h"
TkStubs *tkStubsPtr = NULL;
@@ -39,8 +40,7 @@ TkIntXlibStubs *tkIntXlibStubsPtr = NULL;
*/
static int
-isDigit(c)
- CONST int c;
+isDigit(const int c)
{
return (c >= '0' && c <= '9');
}
@@ -64,13 +64,13 @@ isDigit(c)
*/
#undef Tk_InitStubs
CONST char *
-Tk_InitStubs(interp, version, exact)
- Tcl_Interp *interp;
- char *version;
- int exact;
+Tk_InitStubs(
+ Tcl_Interp *interp,
+ CONST char *version,
+ int exact)
{
- CONST char *packageName = "Tk";
- CONST char *errMsg = NULL;
+ const char *packageName = "Tk";
+ const char *errMsg = NULL;
ClientData clientData = NULL;
CONST char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
packageName, version, 0, &clientData);
@@ -96,11 +96,11 @@ Tk_InitStubs(interp, version, exact)
}
if (*p || isDigit(*q)) {
/* Construct error message */
- tclStubsPtr->tcl_PkgRequireEx(interp, packageName, version, 1, NULL);
+ tclStubsPtr->tcl_PkgRequireEx(interp, "Tk", version, 1, NULL);
return NULL;
}
} else {
- actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp, packageName,
+ actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp, "Tk",
version, 1, NULL);
if (actualVersion == NULL) {
return NULL;
diff --git a/generic/tkStyle.c b/generic/tkStyle.c
index e802dde..dd3b2e8 100644
--- a/generic/tkStyle.c
+++ b/generic/tkStyle.c
@@ -1,4 +1,4 @@
-/*
+/*
* tkStyle.c --
*
* This file implements the widget styles and themes support.
@@ -6,96 +6,91 @@
* Copyright (c) 1990-1993 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
/*
- * The following structure is used to cache widget option specs matching an
+ * The following structure is used to cache widget option specs matching an
* element's required options defined by Tk_ElementOptionSpecs. It also holds
* information behind Tk_StyledElement opaque tokens.
*/
typedef struct StyledWidgetSpec {
- struct StyledElement *elementPtr; /* Pointer to the element holding this
- * structure. */
- Tk_OptionTable optionTable; /* Option table for the widget class
- * using the element. */
- CONST Tk_OptionSpec **optionsPtr; /* Table of option spec pointers,
- * matching the option list provided
- * during element registration.
- * Malloc'd. */
+ struct StyledElement *elementPtr;
+ /* Pointer to the element holding this
+ * structure. */
+ Tk_OptionTable optionTable; /* Option table for the widget class using the
+ * element. */
+ const Tk_OptionSpec **optionsPtr;
+ /* Table of option spec pointers, matching the
+ * option list provided during element
+ * registration. Malloc'd. */
} StyledWidgetSpec;
/*
- * Elements are declared using static templates. But static
- * information must be completed by dynamic information only
- * accessible at runtime. For each registered element, an instance of
- * the following structure is stored in each style engine and used to
- * cache information about the widget types (identified by their
- * optionTable) that use the given element.
+ * Elements are declared using static templates. But static information must
+ * be completed by dynamic information only accessible at runtime. For each
+ * registered element, an instance of the following structure is stored in
+ * each style engine and used to cache information about the widget types
+ * (identified by their optionTable) that use the given element.
*/
typedef struct StyledElement {
- struct Tk_ElementSpec *specPtr;
- /* Filled with template provided during
- * registration. NULL means no implementation
- * is available for the current engine. */
- int nbWidgetSpecs; /* Size of the array below. Number of distinct
- * widget classes (actually, distinct option
+ struct Tk_ElementSpec *specPtr;
+ /* Filled with template provided during
+ * registration. NULL means no implementation
+ * is available for the current engine. */
+ int nbWidgetSpecs; /* Size of the array below. Number of distinct
+ * widget classes (actually, distinct option
* tables) that used the element so far. */
- StyledWidgetSpec *widgetSpecs;
+ StyledWidgetSpec *widgetSpecs;
/* See above for the structure definition.
- * Table grows dynamically as new widgets
- * use the element. Malloc'd. */
+ * Table grows dynamically as new widgets use
+ * the element. Malloc'd. */
} StyledElement;
/*
- * The following structure holds information behind Tk_StyleEngine opaque
+ * The following structure holds information behind Tk_StyleEngine opaque
* tokens.
*/
typedef struct StyleEngine {
- CONST char *name; /* Name of engine. Points to a hash key. */
- StyledElement *elements; /* Table of widget element descriptors. Each
- * element is indexed by a unique system-wide
- * ID. Table grows dynamically as new elements
+ const char *name; /* Name of engine. Points to a hash key. */
+ StyledElement *elements; /* Table of widget element descriptors. Each
+ * element is indexed by a unique system-wide
+ * ID. Table grows dynamically as new elements
* are registered. Malloc'd*/
- struct StyleEngine *parentPtr;
- /* Parent engine. Engines may be layered to form
- * a fallback chain, terminated by the default
- * system engine. */
+ struct StyleEngine *parentPtr;
+ /* Parent engine. Engines may be layered to
+ * form a fallback chain, terminated by the
+ * default system engine. */
} StyleEngine;
/*
- * Styles are instances of style engines. The following structure holds
+ * Styles are instances of style engines. The following structure holds
* information behind Tk_Style opaque tokens.
*/
typedef struct Style {
- int refCount; /* Number of active uses of this style.
- * If this count is 0, then this Style
- * structure is no longer valid. */
- Tcl_HashEntry *hashPtr; /* Entry in style table for this structure,
- * used when deleting it. */
- CONST char *name; /* Name of style. Points to a hash key. */
- StyleEngine *enginePtr; /* Style engine of which the style is an
+ const char *name; /* Name of style. Points to a hash key. */
+ StyleEngine *enginePtr; /* Style engine of which the style is an
* instance. */
ClientData clientData; /* Data provided during registration. */
} Style;
/*
- * Each registered element uses an instance of the following structure.
+ * Each registered element uses an instance of the following structure.
*/
typedef struct Element {
- CONST char *name; /* Name of element. Points to a hash key. */
+ const char *name; /* Name of element. Points to a hash key. */
int id; /* Id of element. */
int genericId; /* Id of generic element. */
- int created; /* Boolean, whether the element was created
- * explicitly (was registered) or implicitly
+ int created; /* Boolean, whether the element was created
+ * explicitly (was registered) or implicitly
* (by a derived element). */
} Element;
@@ -105,66 +100,54 @@ typedef struct Element {
typedef struct ThreadSpecificData {
int nbInit; /* Number of calls to the init proc. */
- Tcl_HashTable engineTable; /* Map a name to a style engine. Keys are
- * strings, values are Tk_StyleEngine
+ Tcl_HashTable engineTable; /* Map a name to a style engine. Keys are
+ * strings, values are Tk_StyleEngine
* pointers. */
- StyleEngine *defaultEnginePtr;
- /* Default, core-defined style engine. Global
+ StyleEngine *defaultEnginePtr;
+ /* Default, core-defined style engine. Global
* fallback for all engines. */
- Tcl_HashTable styleTable; /* Map a name to a style. Keys are strings,
+ Tcl_HashTable styleTable; /* Map a name to a style. Keys are strings,
* values are Tk_Style pointers.*/
int nbElements; /* Size of the below tables. */
- Tcl_HashTable elementTable; /* Map a name to an element Id. Keys are
+ Tcl_HashTable elementTable; /* Map a name to an element Id. Keys are
* strings, values are integer element IDs. */
- Element *elements; /* Array of Elements. */
+ Element *elements; /* Array of Elements. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-/* TODO: sort alpha. */
-static int CreateElement _ANSI_ARGS_((CONST char *name,
- int create));
-static void DupStyleObjProc _ANSI_ARGS_((Tcl_Obj *srcObjPtr,
- Tcl_Obj *dupObjPtr));
-static void FreeElement _ANSI_ARGS_((Element *elementPtr));
-static void FreeStyle _ANSI_ARGS_((Style *stylePtr));
-static void FreeStyledElement _ANSI_ARGS_((
- StyledElement *elementPtr));
-static void FreeStyleEngine _ANSI_ARGS_((
- StyleEngine *enginePtr));
-static void FreeStyleObjProc _ANSI_ARGS_((Tcl_Obj *objPtr));
-static void FreeWidgetSpec _ANSI_ARGS_((
- StyledWidgetSpec *widgetSpecPtr));
-static StyledElement * GetStyledElement _ANSI_ARGS_((
- StyleEngine *enginePtr, int elementId));
-static StyledWidgetSpec * GetWidgetSpec _ANSI_ARGS_((StyledElement *elementPtr,
- Tk_OptionTable optionTable));
-static void InitElement _ANSI_ARGS_((Element *elementPtr,
- CONST char *name, int id, int genericId,
- int created));
-static void InitStyle _ANSI_ARGS_((Style *stylePtr,
- Tcl_HashEntry *hashPtr, CONST char *name,
- StyleEngine *enginePtr, ClientData clientData));
-static void InitStyledElement _ANSI_ARGS_((
- StyledElement *elementPtr));
-static void InitStyleEngine _ANSI_ARGS_((StyleEngine *enginePtr,
- CONST char *name, StyleEngine *parentPtr));
-static void InitWidgetSpec _ANSI_ARGS_((
- StyledWidgetSpec *widgetSpecPtr,
- StyledElement *elementPtr,
- Tk_OptionTable optionTable));
-static int SetStyleFromAny _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Obj *objPtr));
+static int CreateElement(const char *name, int create);
+static void DupStyleObjProc(Tcl_Obj *srcObjPtr,
+ Tcl_Obj *dupObjPtr);
+static void FreeElement(Element *elementPtr);
+static void FreeStyledElement(StyledElement *elementPtr);
+static void FreeStyleEngine(StyleEngine *enginePtr);
+static void FreeStyleObjProc(Tcl_Obj *objPtr);
+static void FreeWidgetSpec(StyledWidgetSpec *widgetSpecPtr);
+static StyledElement * GetStyledElement(StyleEngine *enginePtr,
+ int elementId);
+static StyledWidgetSpec*GetWidgetSpec(StyledElement *elementPtr,
+ Tk_OptionTable optionTable);
+static void InitElement(Element *elementPtr, const char *name,
+ int id, int genericId, int created);
+static void InitStyle(Style *stylePtr, const char *name,
+ StyleEngine *enginePtr, ClientData clientData);
+static void InitStyledElement(StyledElement *elementPtr);
+static void InitStyleEngine(StyleEngine *enginePtr,
+ const char *name, StyleEngine *parentPtr);
+static void InitWidgetSpec(StyledWidgetSpec *widgetSpecPtr,
+ StyledElement *elementPtr,
+ Tk_OptionTable optionTable);
+static int SetStyleFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
/*
* The following structure defines the implementation of the "style" Tcl
- * object, used for drawing. The internalRep.otherValuePtr field of
- * each style object points to the Style structure for the stylefont, or
- * NULL.
+ * object, used for drawing. The internalRep.otherValuePtr field of each style
+ * object points to the Style structure for the stylefont, or NULL.
*/
static Tcl_ObjType styleObjType = {
@@ -180,9 +163,9 @@ static Tcl_ObjType styleObjType = {
*
* TkStylePkgInit --
*
- * This procedure is called when an application is created. It
- * initializes all the structures that are used by the style
- * package on a per application basis.
+ * This function is called when an application is created. It initializes
+ * all the structures that are used by the style package on a per
+ * application basis.
*
* Results:
* Stores data in thread-local storage.
@@ -194,13 +177,15 @@ static Tcl_ObjType styleObjType = {
*/
void
-TkStylePkgInit(mainPtr)
- TkMainInfo *mainPtr; /* The application being created. */
+TkStylePkgInit(
+ TkMainInfo *mainPtr) /* The application being created. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- if (tsdPtr->nbInit != 0) return;
+ if (tsdPtr->nbInit != 0) {
+ return;
+ }
/*
* Initialize tables.
@@ -215,15 +200,15 @@ TkStylePkgInit(mainPtr)
/*
* Create the default system engine.
*/
-
- tsdPtr->defaultEnginePtr =
- (StyleEngine *) Tk_RegisterStyleEngine(NULL, NULL);
+
+ tsdPtr->defaultEnginePtr = (StyleEngine *)
+ Tk_RegisterStyleEngine(NULL, NULL);
/*
* Create the default system style.
*/
- Tk_CreateStyle(NULL, (Tk_StyleEngine) tsdPtr->defaultEnginePtr,
+ Tk_CreateStyle(NULL, (Tk_StyleEngine) tsdPtr->defaultEnginePtr,
(ClientData) 0);
tsdPtr->nbInit++;
@@ -234,9 +219,9 @@ TkStylePkgInit(mainPtr)
*
* TkStylePkgFree --
*
- * This procedure is called when an application is deleted. It
- * deletes all the structures that were used by the style package
- * for this application.
+ * This function is called when an application is deleted. It deletes all
+ * the structures that were used by the style package for this
+ * application.
*
* Results:
* None.
@@ -248,18 +233,20 @@ TkStylePkgInit(mainPtr)
*/
void
-TkStylePkgFree(mainPtr)
- TkMainInfo *mainPtr; /* The application being deleted. */
+TkStylePkgFree(
+ TkMainInfo *mainPtr) /* The application being deleted. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Tcl_HashSearch search;
Tcl_HashEntry *entryPtr;
StyleEngine *enginePtr;
int i;
tsdPtr->nbInit--;
- if (tsdPtr->nbInit != 0) return;
+ if (tsdPtr->nbInit != 0) {
+ return;
+ }
/*
* Free styles.
@@ -301,11 +288,12 @@ TkStylePkgFree(mainPtr)
*
* Tk_RegisterStyleEngine --
*
- * This procedure is called to register a new style engine. Style engines
+ * This function is called to register a new style engine. Style engines
* are stored in thread-local space.
*
* Results:
- * The newly allocated engine.
+ * The newly allocated engine, or NULL if an engine with the same name
+ * exists.
*
* Side effects:
* Memory allocated. Data added to thread-local table.
@@ -314,24 +302,24 @@ TkStylePkgFree(mainPtr)
*/
Tk_StyleEngine
-Tk_RegisterStyleEngine(name, parent)
- CONST char *name; /* Name of the engine to create. NULL or empty
+Tk_RegisterStyleEngine(
+ const char *name, /* Name of the engine to create. NULL or empty
* means the default system engine. */
- Tk_StyleEngine parent; /* The engine's parent. NULL means the default
+ Tk_StyleEngine parent) /* The engine's parent. NULL means the default
* system engine. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Tcl_HashEntry *entryPtr;
int newEntry;
StyleEngine *enginePtr;
/*
- * Attempt to create a new entry in the engine table.
+ * Attempt to create a new entry in the engine table.
*/
- entryPtr = Tcl_CreateHashEntry(&tsdPtr->engineTable, (name?name:""),
- &newEntry);
+ entryPtr = Tcl_CreateHashEntry(&tsdPtr->engineTable,
+ (name != NULL ? name : ""), &newEntry);
if (!newEntry) {
/*
* An engine was already registered by that name.
@@ -369,16 +357,16 @@ Tk_RegisterStyleEngine(name, parent)
*/
static void
-InitStyleEngine(enginePtr, name, parentPtr)
- StyleEngine *enginePtr; /* Points to an uninitialized engine. */
- CONST char *name; /* Name of the registered engine. NULL or empty
+InitStyleEngine(
+ StyleEngine *enginePtr, /* Points to an uninitialized engine. */
+ const char *name, /* Name of the registered engine. NULL or empty
* means the default system engine. Usually
* points to the hash key. */
- StyleEngine *parentPtr; /* The engine's parent. NULL means the default
+ StyleEngine *parentPtr) /* The engine's parent. NULL means the default
* system engine. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
int elementId;
if (name == NULL || *name == '\0') {
@@ -399,8 +387,8 @@ InitStyleEngine(enginePtr, name, parentPtr)
enginePtr->parentPtr = parentPtr;
}
- /*
- * Allocate and initialize elements array.
+ /*
+ * Allocate and initialize elements array.
*/
if (tsdPtr->nbElements > 0) {
@@ -431,11 +419,11 @@ InitStyleEngine(enginePtr, name, parentPtr)
*/
static void
-FreeStyleEngine(enginePtr)
- StyleEngine *enginePtr; /* The style engine to free. */
+FreeStyleEngine(
+ StyleEngine *enginePtr) /* The style engine to free. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
int elementId;
/*
@@ -465,19 +453,19 @@ FreeStyleEngine(enginePtr)
*/
Tk_StyleEngine
-Tk_GetStyleEngine(name)
- CONST char *name; /* Name of the engine to retrieve. NULL or
+Tk_GetStyleEngine(
+ const char *name) /* Name of the engine to retrieve. NULL or
* empty means the default system engine. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Tcl_HashEntry *entryPtr;
if (name == NULL) {
return (Tk_StyleEngine) tsdPtr->defaultEnginePtr;
}
- entryPtr = Tcl_FindHashEntry(&tsdPtr->engineTable, (name?name:""));
+ entryPtr = Tcl_FindHashEntry(&tsdPtr->engineTable, (name!=NULL?name:""));
if (!entryPtr) {
return NULL;
}
@@ -502,14 +490,14 @@ Tk_GetStyleEngine(name)
*/
static void
-InitElement(elementPtr, name, id, genericId, created)
- Element *elementPtr; /* Points to an uninitialized element.*/
- CONST char *name; /* Name of the registered element. Usually
+InitElement(
+ Element *elementPtr, /* Points to an uninitialized element.*/
+ const char *name, /* Name of the registered element. Usually
* points to the hash key. */
- int id; /* Unique element ID. */
- int genericId; /* ID of generic element. -1 means none. */
- int created; /* Boolean, whether the element was created
- * explicitly (was registered) or implicitly
+ int id, /* Unique element ID. */
+ int genericId, /* ID of generic element. -1 means none. */
+ int created) /* Boolean, whether the element was created
+ * explicitly (was registered) or implicitly
* (by a derived element). */
{
elementPtr->name = name;
@@ -535,8 +523,8 @@ InitElement(elementPtr, name, id, genericId, created)
*/
static void
-FreeElement(elementPtr)
- Element *elementPtr; /* The element to free. */
+FreeElement(
+ Element *elementPtr) /* The element to free. */
{
/* Nothing to do. */
}
@@ -558,8 +546,8 @@ FreeElement(elementPtr)
*/
static void
-InitStyledElement(elementPtr)
- StyledElement *elementPtr; /* Points to an uninitialized element.*/
+InitStyledElement(
+ StyledElement *elementPtr) /* Points to an uninitialized element.*/
{
memset(elementPtr, 0, sizeof(StyledElement));
}
@@ -581,8 +569,8 @@ InitStyledElement(elementPtr)
*/
static void
-FreeStyledElement(elementPtr)
- StyledElement *elementPtr; /* The styled element to free. */
+FreeStyledElement(
+ StyledElement *elementPtr) /* The styled element to free. */
{
int i;
@@ -613,14 +601,14 @@ FreeStyledElement(elementPtr)
*/
static int
-CreateElement(name, create)
- CONST char *name; /* Name of the element. */
- int create; /* Boolean, whether the element is being created
- * explicitly (being registered) or implicitly (by a
+CreateElement(
+ const char *name, /* Name of the element. */
+ int create) /* Boolean, whether the element is being created
+ * explicitly (being registered) or implicitly (by a
* derived element). */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Tcl_HashEntry *entryPtr, *engineEntryPtr;
Tcl_HashSearch search;
int newEntry;
@@ -634,7 +622,7 @@ CreateElement(name, create)
entryPtr = Tcl_CreateHashEntry(&tsdPtr->elementTable, name, &newEntry);
if (!newEntry) {
- elementId = (int) Tcl_GetHashValue(entryPtr);
+ elementId = PTR2INT(Tcl_GetHashValue(entryPtr));
if (create) {
tsdPtr->elements[elementId].created = 1;
}
@@ -642,8 +630,8 @@ CreateElement(name, create)
}
/*
- * The element didn't exist. If it's a derived element, find or
- * create its generic element ID.
+ * The element didn't exist. If it's a derived element, find or create its
+ * generic element ID.
*/
dot = strchr(name, '.');
@@ -652,15 +640,15 @@ CreateElement(name, create)
}
elementId = tsdPtr->nbElements++;
- Tcl_SetHashValue(entryPtr, (ClientData) elementId);
+ Tcl_SetHashValue(entryPtr, (ClientData) INT2PTR(elementId));
/*
* Reallocate element table.
*/
- tsdPtr->elements = (Element *) ckrealloc((char *) tsdPtr->elements,
+ tsdPtr->elements = (Element *) ckrealloc((char *) tsdPtr->elements,
sizeof(Element) * tsdPtr->nbElements);
- InitElement(tsdPtr->elements+elementId,
+ InitElement(tsdPtr->elements+elementId,
Tcl_GetHashKey(&tsdPtr->elementTable, entryPtr), elementId,
genericId, create);
@@ -673,7 +661,7 @@ CreateElement(name, create)
enginePtr = (StyleEngine *) Tcl_GetHashValue(engineEntryPtr);
enginePtr->elements = (StyledElement *) ckrealloc(
- (char *) enginePtr->elements,
+ (char *) enginePtr->elements,
sizeof(StyledElement) * tsdPtr->nbElements);
InitStyledElement(enginePtr->elements+elementId);
@@ -700,11 +688,11 @@ CreateElement(name, create)
*/
int
-Tk_GetElementId(name)
- CONST char *name; /* Name of the element. */
+Tk_GetElementId(
+ const char *name) /* Name of the element. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Tcl_HashEntry *entryPtr;
int genericId = -1;
char *dot;
@@ -715,11 +703,11 @@ Tk_GetElementId(name)
entryPtr = Tcl_FindHashEntry(&tsdPtr->elementTable, name);
if (entryPtr) {
- return (int) Tcl_GetHashValue(entryPtr);
+ return PTR2INT(Tcl_GetHashValue(entryPtr));
}
/*
- * Element not found. If the given name was derived, then first search for
+ * Element not found. If the given name was derived, then first search for
* the generic element. If found, create the new derived element.
*/
@@ -732,7 +720,7 @@ Tk_GetElementId(name)
return -1;
}
if (!tsdPtr->elements[genericId].created) {
- /*
+ /*
* The generic element was created implicitly and thus has no real
* existence.
*/
@@ -753,8 +741,8 @@ Tk_GetElementId(name)
*
* Tk_RegisterStyledElement --
*
- * Register an implementation of a new or existing element for the
- * given style engine.
+ * Register an implementation of a new or existing element for the given
+ * style engine.
*
* Results:
* The unique ID for the created or found element.
@@ -766,11 +754,11 @@ Tk_GetElementId(name)
*/
int
-Tk_RegisterStyledElement(engine, templatePtr)
- Tk_StyleEngine engine; /* Style engine providing the
- * implementation. */
- Tk_ElementSpec *templatePtr; /* Static template information about
- * the element. */
+Tk_RegisterStyledElement(
+ Tk_StyleEngine engine, /* Style engine providing the
+ * implementation. */
+ Tk_ElementSpec *templatePtr)/* Static template information about the
+ * element. */
{
int elementId;
StyledElement *elementPtr;
@@ -791,7 +779,7 @@ Tk_RegisterStyledElement(engine, templatePtr)
}
/*
- * Register the element, allocating storage in the various engines if
+ * Register the element, allocating storage in the various engines if
* necessary.
*/
@@ -809,13 +797,13 @@ Tk_RegisterStyledElement(engine, templatePtr)
strcpy(specPtr->name, templatePtr->name);
nbOptions = 0;
for (nbOptions = 0, srcOptions = templatePtr->options;
- srcOptions->name != NULL;
- nbOptions++, srcOptions++);
- specPtr->options = (Tk_ElementOptionSpec *) ckalloc(
- sizeof(Tk_ElementOptionSpec) * (nbOptions+1));
+ srcOptions->name != NULL; nbOptions++, srcOptions++) {
+ /* empty body */
+ }
+ specPtr->options = (Tk_ElementOptionSpec *)
+ ckalloc(sizeof(Tk_ElementOptionSpec) * (nbOptions+1));
for (srcOptions = templatePtr->options, dstOptions = specPtr->options;
- /* End condition within loop */;
- srcOptions++, dstOptions++) {
+ /* End condition within loop */; srcOptions++, dstOptions++) {
if (srcOptions->name == NULL) {
dstOptions->name = NULL;
break;
@@ -842,8 +830,8 @@ Tk_RegisterStyledElement(engine, templatePtr)
*
* GetStyledElement --
*
- * Get a registered implementation of an existing element for the
- * given style engine.
+ * Get a registered implementation of an existing element for the given
+ * style engine.
*
* Results:
* The styled element descriptor, or NULL if not found.
@@ -855,12 +843,13 @@ Tk_RegisterStyledElement(engine, templatePtr)
*/
static StyledElement *
-GetStyledElement(enginePtr, elementId)
- StyleEngine *enginePtr; /* Style engine providing the implementation.
+GetStyledElement(
+ StyleEngine *enginePtr, /* Style engine providing the implementation.
* NULL means the default system engine. */
- int elementId; /* Unique element ID */{
+ int elementId) /* Unique element ID */
+{
StyledElement *elementPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
StyleEngine *enginePtr2;
@@ -913,45 +902,44 @@ GetStyledElement(enginePtr, elementId)
*/
static void
-InitWidgetSpec(widgetSpecPtr, elementPtr, optionTable)
- StyledWidgetSpec *widgetSpecPtr; /* Points to an uninitialized widget
- * spec. */
- StyledElement *elementPtr; /* Styled element descriptor. */
- Tk_OptionTable optionTable; /* The widget's option table. */
+InitWidgetSpec(
+ StyledWidgetSpec *widgetSpecPtr,
+ /* Points to an uninitialized widget spec. */
+ StyledElement *elementPtr, /* Styled element descriptor. */
+ Tk_OptionTable optionTable) /* The widget's option table. */
{
int i, nbOptions;
Tk_ElementOptionSpec *elementOptionPtr;
- CONST Tk_OptionSpec *widgetOptionPtr;
+ const Tk_OptionSpec *widgetOptionPtr;
widgetSpecPtr->elementPtr = elementPtr;
widgetSpecPtr->optionTable = optionTable;
-
+
/*
* Count the number of options.
*/
- for (nbOptions = 0, elementOptionPtr = elementPtr->specPtr->options;
- elementOptionPtr->name != NULL;
- nbOptions++, elementOptionPtr++) {
+ for (nbOptions = 0, elementOptionPtr = elementPtr->specPtr->options;
+ elementOptionPtr->name != NULL; nbOptions++, elementOptionPtr++) {
+ /* empty body */
}
/*
* Build the widget option list.
*/
- widgetSpecPtr->optionsPtr = (CONST Tk_OptionSpec **) ckalloc(
- sizeof(Tk_OptionSpec *) * nbOptions);
- for (i = 0, elementOptionPtr = elementPtr->specPtr->options;
- i < nbOptions;
- i++, elementOptionPtr++) {
+ widgetSpecPtr->optionsPtr = (const Tk_OptionSpec **)
+ ckalloc(sizeof(Tk_OptionSpec *) * nbOptions);
+ for (i = 0, elementOptionPtr = elementPtr->specPtr->options;
+ i < nbOptions; i++, elementOptionPtr++) {
widgetOptionPtr = TkGetOptionSpec(elementOptionPtr->name, optionTable);
/*
- * Check that the widget option type is compatible with one of the
+ * Check that the widget option type is compatible with one of the
* element's required types.
*/
- if ( elementOptionPtr->type == TK_OPTION_END
+ if (elementOptionPtr->type == TK_OPTION_END
|| elementOptionPtr->type == widgetOptionPtr->type) {
widgetSpecPtr->optionsPtr[i] = widgetOptionPtr;
} else {
@@ -977,8 +965,9 @@ InitWidgetSpec(widgetSpecPtr, elementPtr, optionTable)
*/
static void
-FreeWidgetSpec(widgetSpecPtr)
- StyledWidgetSpec *widgetSpecPtr; /* The widget spec to free. */
+FreeWidgetSpec(
+ StyledWidgetSpec *widgetSpecPtr)
+ /* The widget spec to free. */
{
ckfree((char *) widgetSpecPtr->optionsPtr);
}
@@ -988,8 +977,8 @@ FreeWidgetSpec(widgetSpecPtr)
*
* GetWidgetSpec --
*
- * Return a new or existing widget spec for the given element and
- * widget type (identified by its option table).
+ * Return a new or existing widget spec for the given element and widget
+ * type (identified by its option table).
*
* Results:
* A pointer to the matching widget spec.
@@ -1001,9 +990,9 @@ FreeWidgetSpec(widgetSpecPtr)
*/
static StyledWidgetSpec *
-GetWidgetSpec(elementPtr, optionTable)
- StyledElement *elementPtr; /* Styled element descriptor. */
- Tk_OptionTable optionTable; /* The widget's option table. */
+GetWidgetSpec(
+ StyledElement *elementPtr, /* Styled element descriptor. */
+ Tk_OptionTable optionTable) /* The widget's option table. */
{
StyledWidgetSpec *widgetSpecPtr;
int i;
@@ -1025,7 +1014,7 @@ GetWidgetSpec(elementPtr, optionTable)
i = elementPtr->nbWidgetSpecs++;
elementPtr->widgetSpecs = (StyledWidgetSpec *) ckrealloc(
- (char *) elementPtr->widgetSpecs,
+ (char *) elementPtr->widgetSpecs,
sizeof(StyledWidgetSpec) * elementPtr->nbWidgetSpecs);
widgetSpecPtr = elementPtr->widgetSpecs+i;
InitWidgetSpec(widgetSpecPtr, elementPtr, optionTable);
@@ -1038,7 +1027,7 @@ GetWidgetSpec(elementPtr, optionTable)
*
* Tk_GetStyledElement --
*
- * This procedure returns a styled instance of the given element.
+ * This function returns a styled instance of the given element.
*
* Results:
* None.
@@ -1050,10 +1039,10 @@ GetWidgetSpec(elementPtr, optionTable)
*/
Tk_StyledElement
-Tk_GetStyledElement(style, elementId, optionTable)
- Tk_Style style; /* The widget style. */
- int elementId; /* Unique element ID. */
- Tk_OptionTable optionTable; /* Option table for the widget. */
+Tk_GetStyledElement(
+ Tk_Style style, /* The widget style. */
+ int elementId, /* Unique element ID. */
+ Tk_OptionTable optionTable) /* Option table for the widget. */
{
Style *stylePtr = (Style *) style;
StyledElement *elementPtr;
@@ -1062,7 +1051,7 @@ Tk_GetStyledElement(style, elementId, optionTable)
* Get an element implementation and call corresponding hook.
*/
- elementPtr = GetStyledElement((stylePtr?stylePtr->enginePtr:NULL),
+ elementPtr = GetStyledElement((stylePtr?stylePtr->enginePtr:NULL),
elementId);
if (!elementPtr) {
return NULL;
@@ -1076,7 +1065,7 @@ Tk_GetStyledElement(style, elementId, optionTable)
*
* Tk_GetElementSize --
*
- * This procedure computes the size of the given widget element according
+ * This function computes the size of the given widget element according
* to its style.
*
* Results:
@@ -1089,26 +1078,25 @@ Tk_GetStyledElement(style, elementId, optionTable)
*/
void
-Tk_GetElementSize(style, element, recordPtr, tkwin, width, height, inner, widthPtr,
- heightPtr)
- Tk_Style style; /* The widget style. */
- Tk_StyledElement element; /* The styled element, previously
- * returned by Tk_GetStyledElement. */
- char *recordPtr; /* The widget record. */
- Tk_Window tkwin; /* The widget window. */
- int width, height; /* Requested size. */
- int inner; /* Boolean. If TRUE, compute the outer
- * size according to the requested
- * minimum inner size. If FALSE, compute
- * the inner size according to the
- * requested maximum outer size. */
- int *widthPtr, *heightPtr; /* Returned size. */
+Tk_GetElementSize(
+ Tk_Style style, /* The widget style. */
+ Tk_StyledElement element, /* The styled element, previously returned by
+ * Tk_GetStyledElement. */
+ char *recordPtr, /* The widget record. */
+ Tk_Window tkwin, /* The widget window. */
+ int width, int height, /* Requested size. */
+ int inner, /* If TRUE, compute the outer size according
+ * to the requested minimum inner size. If
+ * FALSE, compute the inner size according to
+ * the requested maximum outer size. */
+ int *widthPtr, int *heightPtr)
+ /* Returned size. */
{
Style *stylePtr = (Style *) style;
StyledWidgetSpec *widgetSpecPtr = (StyledWidgetSpec *) element;
- widgetSpecPtr->elementPtr->specPtr->getSize(stylePtr->clientData,
- recordPtr, widgetSpecPtr->optionsPtr, tkwin, width, height, inner,
+ widgetSpecPtr->elementPtr->specPtr->getSize(stylePtr->clientData,
+ recordPtr, widgetSpecPtr->optionsPtr, tkwin, width, height, inner,
widthPtr, heightPtr);
}
@@ -1117,9 +1105,9 @@ Tk_GetElementSize(style, element, recordPtr, tkwin, width, height, inner, widthP
*
* Tk_GetElementBox --
*
- * This procedure computes the bounding or inscribed box coordinates
- * of the given widget element according to its style and within the
- * given limits.
+ * This function computes the bounding or inscribed box coordinates of
+ * the given widget element according to its style and within the given
+ * limits.
*
* Results:
* None.
@@ -1131,29 +1119,27 @@ Tk_GetElementSize(style, element, recordPtr, tkwin, width, height, inner, widthP
*/
void
-Tk_GetElementBox(style, element, recordPtr, tkwin, x, y, width, height, inner,
- xPtr, yPtr, widthPtr, heightPtr)
- Tk_Style style; /* The widget style. */
- Tk_StyledElement element; /* The styled element, previously
- * returned by Tk_GetStyledElement. */
- char *recordPtr; /* The widget record. */
- Tk_Window tkwin; /* The widget window. */
- int x, y; /* Top left corner of available area. */
- int width, height; /* Size of available area. */
- int inner; /* Boolean. If TRUE, compute the
- * bounding box according to the
- * requested inscribed box size. If
- * FALSE, compute the inscribed box
- * according to the requested bounding
- * box. */
- int *xPtr, *yPtr; /* Returned top left corner. */
- int *widthPtr, *heightPtr; /* Returned size. */
+Tk_GetElementBox(
+ Tk_Style style, /* The widget style. */
+ Tk_StyledElement element, /* The styled element, previously returned by
+ * Tk_GetStyledElement. */
+ char *recordPtr, /* The widget record. */
+ Tk_Window tkwin, /* The widget window. */
+ int x, int y, /* Top left corner of available area. */
+ int width, int height, /* Size of available area. */
+ int inner, /* Boolean. If TRUE, compute the bounding box
+ * according to the requested inscribed box
+ * size. If FALSE, compute the inscribed box
+ * according to the requested bounding box. */
+ int *xPtr, int *yPtr, /* Returned top left corner. */
+ int *widthPtr, int *heightPtr)
+ /* Returned size. */
{
Style *stylePtr = (Style *) style;
StyledWidgetSpec *widgetSpecPtr = (StyledWidgetSpec *) element;
- widgetSpecPtr->elementPtr->specPtr->getBox(stylePtr->clientData,
- recordPtr, widgetSpecPtr->optionsPtr, tkwin, x, y, width, height,
+ widgetSpecPtr->elementPtr->specPtr->getBox(stylePtr->clientData,
+ recordPtr, widgetSpecPtr->optionsPtr, tkwin, x, y, width, height,
inner, xPtr, yPtr, widthPtr, heightPtr);
}
@@ -1162,7 +1148,7 @@ Tk_GetElementBox(style, element, recordPtr, tkwin, x, y, width, height, inner,
*
* Tk_GetElementBorderWidth --
*
- * This procedure computes the border widthof the given widget element
+ * This function computes the border widthof the given widget element
* according to its style and within the given limits.
*
* Results:
@@ -1175,12 +1161,12 @@ Tk_GetElementBox(style, element, recordPtr, tkwin, x, y, width, height, inner,
*/
int
-Tk_GetElementBorderWidth(style, element, recordPtr, tkwin)
- Tk_Style style; /* The widget style. */
- Tk_StyledElement element; /* The styled element, previously
- * returned by Tk_GetStyledElement. */
- char *recordPtr; /* The widget record. */
- Tk_Window tkwin; /* The widget window. */
+Tk_GetElementBorderWidth(
+ Tk_Style style, /* The widget style. */
+ Tk_StyledElement element, /* The styled element, previously returned by
+ * Tk_GetStyledElement. */
+ char *recordPtr, /* The widget record. */
+ Tk_Window tkwin) /* The widget window. */
{
Style *stylePtr = (Style *) style;
StyledWidgetSpec *widgetSpecPtr = (StyledWidgetSpec *) element;
@@ -1194,7 +1180,7 @@ Tk_GetElementBorderWidth(style, element, recordPtr, tkwin)
*
* Tk_DrawElement --
*
- * This procedure draw the given widget element in a given drawable area.
+ * This function draw the given widget element in a given drawable area.
*
* Results:
* None
@@ -1206,22 +1192,22 @@ Tk_GetElementBorderWidth(style, element, recordPtr, tkwin)
*/
void
-Tk_DrawElement(style, element, recordPtr, tkwin, d, x, y, width, height, state)
- Tk_Style style; /* The widget style. */
- Tk_StyledElement element; /* The styled element, previously
- * returned by Tk_GetStyledElement. */
- char *recordPtr; /* The widget record. */
- Tk_Window tkwin; /* The widget window. */
- Drawable d; /* Where to draw element. */
- int x, y; /* Top left corner of element. */
- int width, height; /* Size of element. */
- int state; /* Drawing state flags. */
+Tk_DrawElement(
+ Tk_Style style, /* The widget style. */
+ Tk_StyledElement element, /* The styled element, previously returned by
+ * Tk_GetStyledElement. */
+ char *recordPtr, /* The widget record. */
+ Tk_Window tkwin, /* The widget window. */
+ Drawable d, /* Where to draw element. */
+ int x, int y, /* Top left corner of element. */
+ int width, int height, /* Size of element. */
+ int state) /* Drawing state flags. */
{
Style *stylePtr = (Style *) style;
StyledWidgetSpec *widgetSpecPtr = (StyledWidgetSpec *) element;
- widgetSpecPtr->elementPtr->specPtr->draw(stylePtr->clientData,
- recordPtr, widgetSpecPtr->optionsPtr, tkwin, d, x, y, width,
+ widgetSpecPtr->elementPtr->specPtr->draw(stylePtr->clientData,
+ recordPtr, widgetSpecPtr->optionsPtr, tkwin, d, x, y, width,
height, state);
}
@@ -1230,37 +1216,36 @@ Tk_DrawElement(style, element, recordPtr, tkwin, d, x, y, width, height, state)
*
* Tk_CreateStyle --
*
- * This procedure is called to create a new style as an instance of the
+ * This function is called to create a new style as an instance of the
* given engine. Styles are stored in thread-local space.
*
* Results:
- * The newly allocated style.
+ * The newly allocated style, or NULL if the style already exists.
*
* Side effects:
- * Memory allocated. Data added to thread-local table. The style's
- * refCount is incremented.
+ * Memory allocated. Data added to thread-local table.
*
*---------------------------------------------------------------------------
*/
Tk_Style
-Tk_CreateStyle(name, engine, clientData)
- CONST char *name; /* Name of the style to create. NULL or empty
+Tk_CreateStyle(
+ const char *name, /* Name of the style to create. NULL or empty
* means the default system style. */
- Tk_StyleEngine engine; /* The style engine. */
- ClientData clientData; /* Private data passed as is to engine code. */
+ Tk_StyleEngine engine, /* The style engine. */
+ ClientData clientData) /* Private data passed as is to engine code. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Tcl_HashEntry *entryPtr;
int newEntry;
Style *stylePtr;
/*
- * Attempt to create a new entry in the style table.
+ * Attempt to create a new entry in the style table.
*/
- entryPtr = Tcl_CreateHashEntry(&tsdPtr->styleTable, (name?name:""),
+ entryPtr = Tcl_CreateHashEntry(&tsdPtr->styleTable, (name?name:""),
&newEntry);
if (!newEntry) {
/*
@@ -1275,10 +1260,11 @@ Tk_CreateStyle(name, engine, clientData)
*/
stylePtr = (Style *) ckalloc(sizeof(Style));
- InitStyle(stylePtr, entryPtr, Tcl_GetHashKey(&tsdPtr->styleTable, entryPtr),
- (engine?(StyleEngine *) engine:tsdPtr->defaultEnginePtr), clientData);
+ InitStyle(stylePtr, Tcl_GetHashKey(&tsdPtr->styleTable, entryPtr),
+ (engine != NULL ? (StyleEngine *) engine :
+ tsdPtr->defaultEnginePtr),
+ clientData);
Tcl_SetHashValue(entryPtr, (ClientData) stylePtr);
- stylePtr->refCount++;
return (Tk_Style) stylePtr;
}
@@ -1291,9 +1277,9 @@ Tk_CreateStyle(name, engine, clientData)
* Given a style, return its registered name.
*
* Results:
- * The return value is the name that was passed to Tk_CreateStyle() to
- * create the style. The storage for the returned string is private
- * (it points to the corresponding hash key) The caller should not modify
+ * The return value is the name that was passed to Tk_CreateStyle() to
+ * create the style. The storage for the returned string is private (it
+ * points to the corresponding hash key) The caller should not modify
* this string.
*
* Side effects:
@@ -1302,9 +1288,9 @@ Tk_CreateStyle(name, engine, clientData)
*---------------------------------------------------------------------------
*/
-CONST char *
-Tk_NameOfStyle(style)
- Tk_Style style; /* Style whose name is desired. */
+const char *
+Tk_NameOfStyle(
+ Tk_Style style) /* Style whose name is desired. */
{
Style *stylePtr = (Style *) style;
@@ -1328,17 +1314,14 @@ Tk_NameOfStyle(style)
*/
static void
-InitStyle(stylePtr, hashPtr, name, enginePtr, clientData)
- Style *stylePtr; /* Points to an uninitialized style. */
- Tcl_HashEntry *hashPtr; /* Hash entry for the registered style. */
- CONST char *name; /* Name of the registered style. NULL or empty
+InitStyle(
+ Style *stylePtr, /* Points to an uninitialized style. */
+ const char *name, /* Name of the registered style. NULL or empty
* means the default system style. Usually
* points to the hash key. */
- StyleEngine *enginePtr; /* The style engine. */
- ClientData clientData; /* Private data passed as is to engine code. */
+ StyleEngine *enginePtr, /* The style engine. */
+ ClientData clientData) /* Private data passed as is to engine code. */
{
- stylePtr->refCount = 0;
- stylePtr->hashPtr = hashPtr;
stylePtr->name = name;
stylePtr->enginePtr = enginePtr;
stylePtr->clientData = clientData;
@@ -1347,36 +1330,13 @@ InitStyle(stylePtr, hashPtr, name, enginePtr, clientData)
/*
*---------------------------------------------------------------------------
*
- * FreeStyle --
- *
- * Free a style and its associated data.
- *
- * Results:
- * None
- *
- * Side effects:
- * None.
- *
- *---------------------------------------------------------------------------
- */
-
-static void
-FreeStyle(stylePtr)
- Style *stylePtr; /* The style to free. */
-{
- /* Nothing to do. */
-}
-
-/*
- *---------------------------------------------------------------------------
- *
* Tk_GetStyle --
*
* Retrieve a registered style by its name.
*
* Results:
- * A pointer to the style engine, or NULL if none found. In the latter
- * case and if the interp is not NULL, an error message is left in the
+ * A pointer to the style engine, or NULL if none found. In the latter
+ * case and if the interp is not NULL, an error message is left in the
* interp's result.
*
* Side effects:
@@ -1386,29 +1346,29 @@ FreeStyle(stylePtr)
*/
Tk_Style
-Tk_GetStyle(interp, name)
- Tcl_Interp *interp; /* Interp for error return. */
- CONST char *name; /* Name of the style to retrieve. NULL or empty
+Tk_GetStyle(
+ Tcl_Interp *interp, /* Interp for error return. */
+ const char *name) /* Name of the style to retrieve. NULL or empty
* means the default system style. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Tcl_HashEntry *entryPtr;
Style *stylePtr;
/*
- * Search for a corresponding entry in the style table.
+ * Search for a corresponding entry in the style table.
*/
- entryPtr = Tcl_FindHashEntry(&tsdPtr->styleTable, (name?name:""));
+ entryPtr = Tcl_FindHashEntry(&tsdPtr->styleTable, (name!=NULL?name:""));
if (entryPtr == NULL) {
if (interp != NULL) {
- Tcl_AppendResult(interp, "style \"", name, "\" doesn't exist", NULL);
+ Tcl_AppendResult(interp, "style \"", name, "\" doesn't exist",
+ NULL);
}
return (Tk_Style) NULL;
}
stylePtr = (Style *) Tcl_GetHashValue(entryPtr);
- stylePtr->refCount++;
return (Tk_Style) stylePtr;
}
@@ -1418,72 +1378,37 @@ Tk_GetStyle(interp, name)
*
* Tk_FreeStyle --
*
- * Free a style previously created by Tk_CreateStyle.
- *
- * Results:
- * None
- *
- * Side effects:
- * The style's refCount is decremented. If it reaches zero, the style
- * is freed.
+ * No-op. Present only for stubs compatibility.
*
*---------------------------------------------------------------------------
*/
-void
-Tk_FreeStyle(style)
- Tk_Style style; /* The style to free. */
+void
+Tk_FreeStyle(
+ Tk_Style style)
{
- Style *stylePtr = (Style *) style;
-
- if (stylePtr == NULL) {
- return;
- }
- stylePtr->refCount--;
- if (stylePtr->refCount > 0) {
- return;
- }
-
- /*
- * Keep the default style alive.
- */
-
- if (*stylePtr->name == '\0') {
- stylePtr->refCount = 1;
- return;
- }
-
- Tcl_DeleteHashEntry(stylePtr->hashPtr);
- FreeStyle(stylePtr);
- ckfree((char *) stylePtr);
}
/*
*---------------------------------------------------------------------------
*
- * Tk_AllocStyleFromObj --
+ * Tk_AllocStyleFromObj --
*
- * Map the string name of a style to a corresponding Tk_Style. The style
+ * Map the string name of a style to a corresponding Tk_Style. The style
* must have already been created by Tk_CreateStyle.
*
* Results:
- * The return value is a token for the style that matches objPtr, or
- * NULL if none found. If NULL is returned, an error message will be
- * left in interp's result object.
- *
- * Side effects:
- * The style's reference count is incremented. For each call to this
- * procedure, there should eventually be a call to Tk_FreeStyle() or
- * Tk_FreeStyleFromObj() so that the database is cleaned up when styles
- * aren't in use anymore.
+ * The return value is a token for the style that matches objPtr, or NULL
+ * if none found. If NULL is returned, an error message will be left in
+ * interp's result object.
*
*---------------------------------------------------------------------------
*/
Tk_Style
-Tk_AllocStyleFromObj(interp, objPtr)
- Tcl_Interp *interp; /* Interp for error return. */
- Tcl_Obj *objPtr; /* Object containing name of the style to
+Tk_AllocStyleFromObj(
+ Tcl_Interp *interp, /* Interp for error return. */
+ Tcl_Obj *objPtr) /* Object containing name of the style to
* retrieve. */
{
Style *stylePtr;
@@ -1493,7 +1418,6 @@ Tk_AllocStyleFromObj(interp, objPtr)
stylePtr = (Style *) objPtr->internalRep.otherValuePtr;
} else {
stylePtr = (Style *) objPtr->internalRep.otherValuePtr;
- stylePtr->refCount++;
}
return (Tk_Style) stylePtr;
@@ -1504,26 +1428,26 @@ Tk_AllocStyleFromObj(interp, objPtr)
*
* Tk_GetStyleFromObj --
*
- * Find the style that corresponds to a given object. The style must
- * have already been created by Tk_CreateStyle.
+ * Find the style that corresponds to a given object. The style must have
+ * already been created by Tk_CreateStyle.
*
* Results:
- * The return value is a token for the style that matches objPtr, or
- * NULL if none found.
+ * The return value is a token for the style that matches objPtr, or NULL
+ * if none found.
*
* Side effects:
- * If the object is not already a style ref, the conversion will free
- * any old internal representation.
+ * If the object is not already a style ref, the conversion will free any
+ * old internal representation.
*
*----------------------------------------------------------------------
*/
Tk_Style
-Tk_GetStyleFromObj(objPtr)
- Tcl_Obj *objPtr; /* The object from which to get the style. */
+Tk_GetStyleFromObj(
+ Tcl_Obj *objPtr) /* The object from which to get the style. */
{
if (objPtr->typePtr != &styleObjType) {
- SetStyleFromAny((Tcl_Interp *) NULL, objPtr);
+ SetStyleFromAny(NULL, objPtr);
}
return (Tk_Style) objPtr->internalRep.otherValuePtr;
@@ -1532,27 +1456,16 @@ Tk_GetStyleFromObj(objPtr)
/*
*---------------------------------------------------------------------------
*
- * Tk_FreeStyleFromObj --
+ * Tk_FreeStyleFromObj --
*
- * Called to release a style inside a Tcl_Obj *.
- *
- * Results:
- * None.
- *
- * Side effects:
- * If the object is a style ref, the conversion will free its
- * internal representation.
+ * No-op. Present only for stubs compatibility.
*
*---------------------------------------------------------------------------
*/
-
void
-Tk_FreeStyleFromObj(objPtr)
- Tcl_Obj *objPtr; /* The Tcl_Obj * to be freed. */
+Tk_FreeStyleFromObj(
+ Tcl_Obj *objPtr)
{
- if (objPtr->typePtr == &styleObjType) {
- FreeStyleObjProc(objPtr);
- }
}
/*
@@ -1560,31 +1473,29 @@ Tk_FreeStyleFromObj(objPtr)
*
* SetStyleFromAny --
*
- * Convert the internal representation of a Tcl object to the
- * style internal form.
+ * Convert the internal representation of a Tcl object to the style
+ * internal form.
*
* Results:
- * Always returns TCL_OK. If an error occurs is returned (e.g. the
- * style doesn't exist), an error message will be left in interp's
- * result.
+ * Always returns TCL_OK. If an error occurs is returned (e.g. the style
+ * doesn't exist), an error message will be left in interp's result.
*
* Side effects:
* The object is left with its typePtr pointing to styleObjType.
- * The reference count is incremented (in Tk_GetStyle()).
*
*----------------------------------------------------------------------
*/
static int
-SetStyleFromAny(interp, objPtr)
- Tcl_Interp *interp; /* Used for error reporting if not NULL. */
- Tcl_Obj *objPtr; /* The object to convert. */
+SetStyleFromAny(
+ Tcl_Interp *interp, /* Used for error reporting if not NULL. */
+ Tcl_Obj *objPtr) /* The object to convert. */
{
- Tcl_ObjType *typePtr;
- char *name;
+ const Tcl_ObjType *typePtr;
+ const char *name;
/*
- * Free the old internalRep before setting the new one.
+ * Free the old internalRep before setting the new one.
*/
name = Tcl_GetString(objPtr);
@@ -1602,61 +1513,49 @@ SetStyleFromAny(interp, objPtr)
/*
*---------------------------------------------------------------------------
*
- * FreeStyleObjProc --
+ * FreeStyleObjProc --
*
- * This proc is called to release an object reference to a style.
- * Called when the object's internal rep is released.
+ * This proc is called to release an object reference to a style. Called
+ * when the object's internal rep is released.
*
* Results:
* None.
*
- * Side effects:
- * The reference count is decremented (in Tk_FreeStyle()).
- *
*---------------------------------------------------------------------------
*/
static void
-FreeStyleObjProc(objPtr)
- Tcl_Obj *objPtr; /* The object we are releasing. */
+FreeStyleObjProc(
+ Tcl_Obj *objPtr) /* The object we are releasing. */
{
- Style *stylePtr = (Style *) objPtr->internalRep.otherValuePtr;
-
- if (stylePtr != NULL) {
- Tk_FreeStyle((Tk_Style) stylePtr);
- objPtr->internalRep.otherValuePtr = NULL;
- }
+ objPtr->internalRep.otherValuePtr = NULL;
+ objPtr->typePtr = NULL;
}
/*
*---------------------------------------------------------------------------
*
- * DupStyleObjProc --
+ * DupStyleObjProc --
*
- * When a cached style object is duplicated, this is called to
- * update the internal reps.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The style's refCount is incremented and the internal rep of the copy
- * is set to point to it.
+ * When a cached style object is duplicated, this is called to update the
+ * internal reps.
*
*---------------------------------------------------------------------------
*/
static void
-DupStyleObjProc(srcObjPtr, dupObjPtr)
- Tcl_Obj *srcObjPtr; /* The object we are copying from. */
- Tcl_Obj *dupObjPtr; /* The object we are copying to. */
+DupStyleObjProc(
+ Tcl_Obj *srcObjPtr, /* The object we are copying from. */
+ Tcl_Obj *dupObjPtr) /* The object we are copying to. */
{
- Style *stylePtr = (Style *) srcObjPtr->internalRep.otherValuePtr;
-
dupObjPtr->typePtr = srcObjPtr->typePtr;
- dupObjPtr->internalRep.otherValuePtr = (VOID *) stylePtr;
-
- if (stylePtr != NULL) {
- stylePtr->refCount++;
- }
+ dupObjPtr->internalRep.otherValuePtr=srcObjPtr->internalRep.otherValuePtr;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkTest.c b/generic/tkTest.c
index e8d8d88..9fe2222 100644
--- a/generic/tkTest.c
+++ b/generic/tkTest.c
@@ -1,21 +1,20 @@
-/*
+/*
* tkTest.c --
*
- * This file contains C command procedures for a bunch of additional
- * Tcl commands that are used for testing out Tcl's C interfaces.
- * These commands are not normally included in Tcl applications;
- * they're only used for testing.
+ * This file contains C command functions for a bunch of additional Tcl
+ * commands that are used for testing out Tcl's C interfaces. These
+ * commands are not normally included in Tcl applications; they're only
+ * used for testing.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
-#include "tkPort.h"
#include "tkText.h"
#ifdef __WIN32__
@@ -23,6 +22,7 @@
#endif
#if defined(MAC_OSX_TK)
+#include "tkMacOSXInt.h"
#include "tkScrollbar.h"
#endif
@@ -31,8 +31,7 @@
#endif
/*
- * The following data structure represents the master for a test
- * image:
+ * The following data structure represents the master for a test image:
*/
typedef struct TImageMaster {
@@ -40,13 +39,13 @@ typedef struct TImageMaster {
Tcl_Interp *interp; /* Interpreter for application. */
int width, height; /* Dimensions of image. */
char *imageName; /* Name of image (malloc-ed). */
- char *varName; /* Name of variable in which to log
- * events for image (malloc-ed). */
+ char *varName; /* Name of variable in which to log events for
+ * image (malloc-ed). */
} TImageMaster;
/*
- * The following data structure represents a particular use of a
- * particular test image.
+ * The following data structure represents a particular use of a particular
+ * test image.
*/
typedef struct TImageInstance {
@@ -59,43 +58,34 @@ typedef struct TImageInstance {
* The type record for test images:
*/
-#ifdef USE_OLD_IMAGE
-static int ImageCreate _ANSI_ARGS_((Tcl_Interp *interp,
- char *name, int argc, char **argv,
- Tk_ImageType *typePtr, Tk_ImageMaster master,
- ClientData *clientDataPtr));
-#else
-static int ImageCreate _ANSI_ARGS_((Tcl_Interp *interp,
- char *name, int argc, Tcl_Obj *CONST objv[],
+static int ImageCreate(Tcl_Interp *interp,
+ char *name, int argc, Tcl_Obj *const objv[],
Tk_ImageType *typePtr, Tk_ImageMaster master,
- ClientData *clientDataPtr));
-#endif
-static ClientData ImageGet _ANSI_ARGS_((Tk_Window tkwin,
- ClientData clientData));
-static void ImageDisplay _ANSI_ARGS_((ClientData clientData,
- Display *display, Drawable drawable,
+ ClientData *clientDataPtr);
+static ClientData ImageGet(Tk_Window tkwin, ClientData clientData);
+static void ImageDisplay(ClientData clientData,
+ Display *display, Drawable drawable,
int imageX, int imageY, int width,
int height, int drawableX,
- int drawableY));
-static void ImageFree _ANSI_ARGS_((ClientData clientData,
- Display *display));
-static void ImageDelete _ANSI_ARGS_((ClientData clientData));
+ int drawableY);
+static void ImageFree(ClientData clientData, Display *display);
+static void ImageDelete(ClientData clientData);
static Tk_ImageType imageType = {
"test", /* name */
- (Tk_ImageCreateProc *) ImageCreate, /* createProc */
+ ImageCreate, /* createProc */
ImageGet, /* getProc */
ImageDisplay, /* displayProc */
ImageFree, /* freeProc */
ImageDelete, /* deleteProc */
- (Tk_ImagePostscriptProc *) NULL,/* postscriptPtr */
- (Tk_ImageType *) NULL /* nextPtr */
+ NULL, /* postscriptPtr */
+ NULL /* nextPtr */
};
/*
- * One of the following structures describes each of the interpreters
- * created by the "testnewapp" command. This information is used by
- * the "testdeleteinterps" command to destroy all of those interpreters.
+ * One of the following structures describes each of the interpreters created
+ * by the "testnewapp" command. This information is used by the
+ * "testdeleteinterps" command to destroy all of those interpreters.
*/
typedef struct NewApp {
@@ -103,15 +93,15 @@ typedef struct NewApp {
struct NewApp *nextPtr; /* Next in list of new interpreters. */
} NewApp;
-static NewApp *newAppPtr = NULL;
- /* First in list of all new interpreters. */
+static NewApp *newAppPtr = NULL;/* First in list of all new interpreters. */
/*
- * Declaration for the square widget's class command procedure:
+ * Declaration for the square widget's class command function:
*/
-extern int SquareObjCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]));
+extern int SquareObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj * const objv[]);
typedef struct CBinding {
Tcl_Interp *interp;
@@ -128,118 +118,114 @@ typedef struct CBinding {
enum {
NONE,
- ODD_TYPE,
+ 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. */
+ 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:
+ * Forward declarations for functions defined later in this file:
*/
-static int CBindingEvalProc _ANSI_ARGS_((ClientData clientData,
+static int CBindingEvalProc(ClientData clientData,
Tcl_Interp *interp, XEvent *eventPtr,
- Tk_Window tkwin, KeySym keySym));
-static void CBindingFreeProc _ANSI_ARGS_((ClientData clientData));
-int Tktest_Init _ANSI_ARGS_((Tcl_Interp *interp));
-static int ImageCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int argc, CONST char **argv));
-static int TestcbindCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int argc, CONST char **argv));
-static int TestbitmapObjCmd _ANSI_ARGS_((ClientData dummy,
+ Tk_Window tkwin, KeySym keySym);
+static void CBindingFreeProc(ClientData clientData);
+int Tktest_Init(Tcl_Interp *interp);
+static int ImageCmd(ClientData dummy,
+ Tcl_Interp *interp, int argc, const char **argv);
+static int TestcbindCmd(ClientData dummy,
+ Tcl_Interp *interp, int argc, const char **argv);
+static int TestbitmapObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
- Tcl_Obj * CONST objv[]));
-static int TestborderObjCmd _ANSI_ARGS_((ClientData dummy,
+ Tcl_Obj * const objv[]);
+static int TestborderObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
- Tcl_Obj * CONST objv[]));
-static int TestcolorObjCmd _ANSI_ARGS_((ClientData dummy,
+ Tcl_Obj * const objv[]);
+static int TestcolorObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
- Tcl_Obj * CONST objv[]));
-static int TestcursorObjCmd _ANSI_ARGS_((ClientData dummy,
+ Tcl_Obj * const objv[]);
+static int TestcursorObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
- Tcl_Obj * CONST objv[]));
-static int TestdeleteappsCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int argc, CONST char **argv));
-static int TestfontObjCmd _ANSI_ARGS_((ClientData dummy,
+ Tcl_Obj * const objv[]);
+static int TestdeleteappsCmd(ClientData dummy,
+ Tcl_Interp *interp, int argc, const char **argv);
+static int TestfontObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int TestmakeexistCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int argc, CONST char **argv));
+ Tcl_Obj *const objv[]);
+static int TestmakeexistCmd(ClientData dummy,
+ Tcl_Interp *interp, int argc, const char **argv);
#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
-static int TestmenubarCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int argc, CONST char **argv));
+static int TestmenubarCmd(ClientData dummy,
+ Tcl_Interp *interp, int argc, const char **argv);
#endif
#if defined(__WIN32__) || defined(MAC_OSX_TK)
-static int TestmetricsCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int argc, CONST char **argv));
+static int TestmetricsCmd(ClientData dummy,
+ Tcl_Interp *interp, int argc, const char **argv);
#endif
-static int TestobjconfigObjCmd _ANSI_ARGS_((ClientData dummy,
+static int TestobjconfigObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
- Tcl_Obj * CONST objv[]));
-static int CustomOptionSet _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, Tk_Window tkwin,
- Tcl_Obj **value, char *recordPtr, int internalOffset,
- char *saveInternalPtr, int flags));
-static Tcl_Obj *CustomOptionGet _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin, char *recordPtr, int internalOffset));
-static void CustomOptionRestore _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin, char *internalPtr,
- char *saveInternalPtr));
-static void CustomOptionFree _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin, char *internalPtr));
-static int TestpropCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int argc, CONST char **argv));
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
-static int TestsendCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int argc, CONST char **argv));
-#endif
-static int TesttextCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int argc, CONST char **argv));
+ Tcl_Obj * const objv[]);
+static int CustomOptionSet(ClientData clientData,
+ Tcl_Interp *interp, Tk_Window tkwin,
+ Tcl_Obj **value, char *recordPtr,
+ int internalOffset, char *saveInternalPtr,
+ int flags);
+static Tcl_Obj * CustomOptionGet(ClientData clientData,
+ Tk_Window tkwin, char *recordPtr,
+ int internalOffset);
+static void CustomOptionRestore(ClientData clientData,
+ Tk_Window tkwin, char *internalPtr,
+ char *saveInternalPtr);
+static void CustomOptionFree(ClientData clientData,
+ Tk_Window tkwin, char *internalPtr);
+static int TestpropCmd(ClientData dummy,
+ Tcl_Interp *interp, int argc, const char **argv);
#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
-static int TestwrapperCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int argc, CONST char **argv));
+static int TestwrapperCmd(ClientData dummy,
+ Tcl_Interp *interp, int argc, const char **argv);
#endif
-static void TrivialCmdDeletedProc _ANSI_ARGS_((
- ClientData clientData));
-static int TrivialConfigObjCmd _ANSI_ARGS_((ClientData dummy,
+static void TrivialCmdDeletedProc(ClientData clientData);
+static int TrivialConfigObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
- Tcl_Obj * CONST objv[]));
-static void TrivialEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
+ Tcl_Obj * const objv[]);
+static void TrivialEventProc(ClientData clientData,
+ XEvent *eventPtr);
/*
* External (platform specific) initialization routine:
*/
-extern int TkplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp));
-
#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
#define TkplatformtestInit(x) TCL_OK
+#else
+MODULE_SCOPE int TkplatformtestInit(Tcl_Interp *interp);
#endif
+
+/*
+ * External legacy testing initialization routine:
+ */
+MODULE_SCOPE int TkOldTestInit(Tcl_Interp *interp);
/*
*----------------------------------------------------------------------
*
* Tktest_Init --
*
- * This procedure performs intialization for the Tk test
- * suite exensions.
+ * This function performs intialization for the Tk test suite exensions.
*
* Results:
- * Returns a standard Tcl completion code, and leaves an error
- * message in the interp's result if an error occurs.
+ * Returns a standard Tcl completion code, and leaves an error message in
+ * the interp's result if an error occurs.
*
* Side effects:
* Creates several test commands.
@@ -248,8 +234,8 @@ extern int TkplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp));
*/
int
-Tktest_Init(interp)
- Tcl_Interp *interp; /* Interpreter for application. */
+Tktest_Init(
+ Tcl_Interp *interp) /* Interpreter for application. */
{
static int initialized = 0;
@@ -262,47 +248,43 @@ Tktest_Init(interp)
}
Tcl_CreateObjCommand(interp, "square", SquareObjCmd,
- (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
+ (ClientData) NULL, NULL);
Tcl_CreateCommand(interp, "testcbind", TestcbindCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
+ (ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateObjCommand(interp, "testbitmap", TestbitmapObjCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
+ (ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateObjCommand(interp, "testborder", TestborderObjCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
+ (ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateObjCommand(interp, "testcolor", TestcolorObjCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
+ (ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateObjCommand(interp, "testcursor", TestcursorObjCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
+ (ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateCommand(interp, "testdeleteapps", TestdeleteappsCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
+ (ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateCommand(interp, "testembed", TkpTestembedCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
+ (ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateObjCommand(interp, "testobjconfig", TestobjconfigObjCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
+ (ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateObjCommand(interp, "testfont", TestfontObjCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
+ (ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateCommand(interp, "testmakeexist", TestmakeexistCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
- Tcl_CreateCommand(interp, "testmenubar", TestmenubarCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
-#endif
+ (ClientData) Tk_MainWindow(interp), NULL);
+ Tcl_CreateCommand(interp, "testprop", TestpropCmd,
+ (ClientData) Tk_MainWindow(interp), NULL);
+ Tcl_CreateCommand(interp, "testtext", TkpTesttextCmd,
+ (ClientData) Tk_MainWindow(interp), NULL);
+
#if defined(__WIN32__) || defined(MAC_OSX_TK)
Tcl_CreateCommand(interp, "testmetrics", TestmetricsCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
-#endif
- Tcl_CreateCommand(interp, "testprop", TestpropCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
- Tcl_CreateCommand(interp, "testsend", TestsendCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
-#endif
- Tcl_CreateCommand(interp, "testtext", TesttextCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
+ (ClientData) Tk_MainWindow(interp), NULL);
+#else
+ Tcl_CreateCommand(interp, "testmenubar", TestmenubarCmd,
+ (ClientData) Tk_MainWindow(interp), NULL);
+ Tcl_CreateCommand(interp, "testsend", TkpTestsendCmd,
+ (ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateCommand(interp, "testwrapper", TestwrapperCmd,
- (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL);
-#endif
+ (ClientData) Tk_MainWindow(interp), NULL);
+#endif /* __WIN32__ || MAC_OSX_TK */
/*
* Create test image type.
@@ -314,9 +296,17 @@ Tktest_Init(interp)
}
/*
+ * Enable testing of legacy interfaces.
+ */
+
+ if (TkOldTestInit(interp) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /*
* And finally add any platform specific test commands.
*/
-
+
return TkplatformtestInit(interp);
}
@@ -325,34 +315,34 @@ Tktest_Init(interp)
*
* TestcbindCmd --
*
- * This procedure implements the "testcbinding" command. It provides
- * a set of functions for testing C bindings in tkBind.c.
+ * This function implements the "testcbinding" command. It provides a set
+ * of functions for testing C bindings in tkBind.c.
*
* Results:
* A standard Tcl result.
*
* Side effects:
- * Depends on option; see below.
+ * Depends on option; see below.
*
*----------------------------------------------------------------------
*/
static int
-TestcbindCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Main window for application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+TestcbindCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ const char **argv) /* Argument strings. */
{
TkWindow *winPtr;
Tk_Window tkwin;
ClientData object;
CBinding *cbindPtr;
-
-
+
+
if (argc < 4 || argc > 5) {
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " bindtag pattern command ?deletecommand?", (char *) NULL);
+ " bindtag pattern command ?deletecommand?", NULL);
return TCL_ERROR;
}
@@ -399,26 +389,26 @@ TestcbindCmd(clientData, interp, argc, argv)
}
static int
-CBindingEvalProc(clientData, interp, eventPtr, tkwin, keySym)
- ClientData clientData;
- Tcl_Interp *interp;
- XEvent *eventPtr;
- Tk_Window tkwin;
- KeySym keySym;
+CBindingEvalProc(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ XEvent *eventPtr,
+ Tk_Window tkwin,
+ KeySym keySym)
{
CBinding *cbindPtr;
cbindPtr = (CBinding *) clientData;
-
+
return Tcl_EvalEx(interp, cbindPtr->command, -1, TCL_EVAL_GLOBAL);
}
static void
-CBindingFreeProc(clientData)
- ClientData clientData;
+CBindingFreeProc(
+ ClientData clientData)
{
CBinding *cbindPtr = (CBinding *) clientData;
-
+
if (cbindPtr->delete != NULL) {
Tcl_EvalEx(cbindPtr->interp, cbindPtr->delete, -1, TCL_EVAL_GLOBAL);
ckfree((char *) cbindPtr->delete);
@@ -432,8 +422,8 @@ CBindingFreeProc(clientData)
*
* TestbitmapObjCmd --
*
- * This procedure implements the "testbitmap" command, which is used
- * to test color resource handling in tkBitmap tmp.c.
+ * This function implements the "testbitmap" command, which is used to
+ * test color resource handling in tkBitmap tmp.c.
*
* Results:
* A standard Tcl result.
@@ -446,11 +436,11 @@ CBindingFreeProc(clientData)
/* 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. */
+TestbitmapObjCmd(
+ 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) {
@@ -467,8 +457,8 @@ TestbitmapObjCmd(clientData, interp, objc, objv)
*
* TestborderObjCmd --
*
- * This procedure implements the "testborder" command, which is used
- * to test color resource handling in tkBorder.c.
+ * This function implements the "testborder" command, which is used to
+ * test color resource handling in tkBorder.c.
*
* Results:
* A standard Tcl result.
@@ -481,11 +471,11 @@ TestbitmapObjCmd(clientData, interp, objc, objv)
/* 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. */
+TestborderObjCmd(
+ 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) {
@@ -502,8 +492,8 @@ TestborderObjCmd(clientData, interp, objc, objv)
*
* TestcolorObjCmd --
*
- * This procedure implements the "testcolor" command, which is used
- * to test color resource handling in tkColor.c.
+ * This function implements the "testcolor" command, which is used to
+ * test color resource handling in tkColor.c.
*
* Results:
* A standard Tcl result.
@@ -516,13 +506,12 @@ TestborderObjCmd(clientData, interp, objc, objv)
/* 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. */
+TestcolorObjCmd(
+ 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;
@@ -537,8 +526,8 @@ TestcolorObjCmd(clientData, interp, objc, objv)
*
* TestcursorObjCmd --
*
- * This procedure implements the "testcursor" command, which is used
- * to test color resource handling in tkCursor.c.
+ * This function implements the "testcursor" command, which is used to
+ * test color resource handling in tkCursor.c.
*
* Results:
* A standard Tcl result.
@@ -551,13 +540,12 @@ TestcolorObjCmd(clientData, interp, objc, objv)
/* 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. */
+TestcursorObjCmd(
+ 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;
@@ -572,26 +560,26 @@ TestcursorObjCmd(clientData, interp, objc, objv)
*
* TestdeleteappsCmd --
*
- * This procedure implements the "testdeleteapps" command. It cleans
- * up all the interpreters left behind by the "testnewapp" command.
+ * This function implements the "testdeleteapps" command. It cleans up
+ * all the interpreters left behind by the "testnewapp" command.
*
* Results:
* A standard Tcl result.
*
* Side effects:
- * All the intepreters created by previous calls to "testnewapp"
- * get deleted.
+ * All the intepreters created by previous calls to "testnewapp" get
+ * deleted.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static int
-TestdeleteappsCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Main window for application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+TestdeleteappsCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ const char **argv) /* Argument strings. */
{
NewApp *nextPtr;
@@ -610,8 +598,8 @@ TestdeleteappsCmd(clientData, interp, argc, argv)
*
* TestobjconfigObjCmd --
*
- * This procedure implements the "testobjconfig" command,
- * which is used to test the procedures in tkConfig.c.
+ * This function implements the "testobjconfig" command, which is used to
+ * test the functions in tkConfig.c.
*
* Results:
* A standard Tcl result.
@@ -624,46 +612,40 @@ TestdeleteappsCmd(clientData, interp, argc, argv)
/* 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. */
+TestobjconfigObjCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- static CONST char *options[] = {"alltypes", "chain1", "chain2",
- "configerror", "delete", "info", "internal", "new",
- "notenoughparams", "twowindows", (char *) NULL};
+ static const char *options[] = {
+ "alltypes", "chain1", "chain2", "configerror", "delete", "info",
+ "internal", "new", "notenoughparams", "twowindows", NULL
+ };
enum {
- ALL_TYPES,
- CHAIN1,
- CHAIN2,
- CONFIG_ERROR,
+ ALL_TYPES, CHAIN1, CHAIN2, CONFIG_ERROR,
DEL, /* Can't use DELETE: VC++ compiler barfs. */
- INFO,
- INTERNAL,
- NEW,
- NOT_ENOUGH_PARAMS,
- TWO_WINDOWS
+ 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. */
- static CONST Tk_ObjCustomOption CustomOption = {
+ static Tk_OptionTable tables[11];
+ /* Holds pointers to option tables created by
+ * commands below; indexed with same values as
+ * "options" array. */
+ static const Tk_ObjCustomOption CustomOption = {
"custom option",
- CustomOptionSet,
- CustomOptionGet,
- CustomOptionRestore,
- CustomOptionFree,
- (ClientData) 1
+ CustomOptionSet,
+ CustomOptionGet,
+ CustomOptionRestore,
+ CustomOptionFree,
+ (ClientData) 1
};
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:
+ * Structures used by the "chain1" subcommand and also shared by the
+ * "chain2" subcommand:
*/
typedef struct ExtensionWidgetRecord {
@@ -674,12 +656,10 @@ TestobjconfigObjCmd(clientData, interp, objc, objv)
Tcl_Obj *extension4ObjPtr;
Tcl_Obj *extension5ObjPtr;
} ExtensionWidgetRecord;
- static CONST Tk_OptionSpec baseSpecs[] = {
- {TK_OPTION_STRING,
- "-one", "one", "One", "one",
+ static const Tk_OptionSpec baseSpecs[] = {
+ {TK_OPTION_STRING, "-one", "one", "One", "one",
Tk_Offset(ExtensionWidgetRecord, base1ObjPtr), -1},
- {TK_OPTION_STRING,
- "-two", "two", "Two", "two",
+ {TK_OPTION_STRING, "-two", "two", "Two", "two",
Tk_Offset(ExtensionWidgetRecord, base2ObjPtr), -1},
{TK_OPTION_END}
};
@@ -695,633 +675,550 @@ TestobjconfigObjCmd(clientData, interp, objc, objv)
}
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;
- Tcl_Obj *customPtr;
- } TypesRecord;
- TypesRecord *recordPtr;
- static CONST char *CONST stringTable[] = {"one", "two", "three", "four",
- (char *) NULL};
- static CONST 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_CUSTOM,
- "-custom", (char *) NULL, (char *) NULL,
- "", Tk_Offset(TypesRecord, customPtr), -1,
- TK_CONFIG_NULL_OK, (ClientData)&CustomOption, 0x4000},
- {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;
- recordPtr->customPtr = 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 {
+ 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;
+ Tcl_Obj *customPtr;
+ } TypesRecord;
+ TypesRecord *recordPtr;
+ static const char *stringTable[] = {
+ "one", "two", "three", "four", NULL
+ };
+ static const 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", NULL, NULL, "left",
+ Tk_Offset(TypesRecord, justifyPtr), -1,
+ TK_CONFIG_NULL_OK, 0, 0x800},
+ {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", 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_CUSTOM, "-custom", NULL, NULL,
+ "", Tk_Offset(TypesRecord, customPtr), -1,
+ TK_CONFIG_NULL_OK, (ClientData)&CustomOption, 0x4000},
+ {TK_OPTION_SYNONYM, "-synonym", NULL, NULL,
+ 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_GetString(objv[2]), 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;
+ recordPtr->customPtr = NULL;
+ result = Tk_InitOptions(interp, (char *) recordPtr, optionTable,
+ tkwin);
+ if (result == TCL_OK) {
+ recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
+ Tcl_GetString(objv[2]), TrivialConfigObjCmd,
+ (ClientData) recordPtr, TrivialCmdDeletedProc);
+ Tk_CreateEventHandler(tkwin, StructureNotifyMask,
+ TrivialEventProc, (ClientData) recordPtr);
+ result = Tk_SetOptions(interp, (char *) recordPtr, optionTable,
+ objc-3, objv+3, tkwin, NULL, NULL);
+ if (result != TCL_OK) {
Tk_DestroyWindow(tkwin);
- ckfree((char *) recordPtr);
- }
- if (result == TCL_OK) {
- Tcl_SetObjResult(interp, objv[2]);
}
- break;
+ } 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;
+ 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);
- }
+ tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window) clientData,
+ Tcl_GetString(objv[2]), 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, NULL, 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]);
+ }
+ if (result == TCL_OK) {
+ recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
+ Tcl_GetString(objv[2]), TrivialConfigObjCmd,
+ (ClientData) recordPtr, TrivialCmdDeletedProc);
+ Tk_CreateEventHandler(tkwin, StructureNotifyMask,
+ TrivialEventProc, (ClientData) recordPtr);
+ Tcl_SetObjResult(interp, objv[2]);
+ }
+ break;
+ }
+
+ case CHAIN2: {
+ ExtensionWidgetRecord *recordPtr;
+ static const 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, NULL, NULL, NULL, NULL, 0, -1, 0,
+ (ClientData) baseSpecs}
+ };
+ Tk_Window tkwin;
+ Tk_OptionTable optionTable;
+
+ tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window) clientData,
+ Tcl_GetString(objv[2]), 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, NULL, NULL);
+ if (result != TCL_OK) {
+ Tk_FreeConfigOptions((char *) recordPtr, optionTable, tkwin);
}
- break;
}
+ if (result == TCL_OK) {
+ recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
+ Tcl_GetString(objv[2]), TrivialConfigObjCmd,
+ (ClientData) recordPtr, TrivialCmdDeletedProc);
+ Tk_CreateEventHandler(tkwin, StructureNotifyMask,
+ TrivialEventProc, (ClientData) recordPtr);
+ Tcl_SetObjResult(interp, objv[2]);
+ }
+ break;
+ }
- case CHAIN2: {
- ExtensionWidgetRecord *recordPtr;
- static CONST 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;
+ case CONFIG_ERROR: {
+ typedef struct ErrorWidgetRecord {
+ Tcl_Obj *intPtr;
+ } ErrorWidgetRecord;
+ ErrorWidgetRecord widgetRecord;
+ static const 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);
+ }
- 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 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 CONFIG_ERROR: {
- typedef struct ErrorWidgetRecord {
- Tcl_Obj *intPtr;
- } ErrorWidgetRecord;
- ErrorWidgetRecord widgetRecord;
- static CONST 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 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 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]);
+ 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;
+ char *custom;
+ } InternalRecord;
+ InternalRecord *recordPtr;
+ static const char *const internalStringTable[] = {
+ "one", "two", "three", "four", NULL
+ };
+ static const 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", NULL, NULL, "left",
+ -1, Tk_Offset(InternalRecord, justify),
+ TK_CONFIG_NULL_OK, 0, 0x800},
+ {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", 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", NULL,
+ -1, Tk_Offset(InternalRecord, tkwin),
+ TK_CONFIG_NULL_OK, 0, 0},
+ {TK_OPTION_CUSTOM, "-custom", NULL, NULL, "",
+ -1, Tk_Offset(InternalRecord, custom),
+ TK_CONFIG_NULL_OK, (ClientData)&CustomOption, 0x4000},
+ {TK_OPTION_SYNONYM, "-synonym", NULL, NULL,
+ 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_GetString(objv[2]), 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;
+ recordPtr->custom = NULL;
+ result = Tk_InitOptions(interp, (char *) recordPtr, optionTable,
+ tkwin);
+ if (result == TCL_OK) {
+ recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
+ Tcl_GetString(objv[2]), TrivialConfigObjCmd,
+ (ClientData) recordPtr, TrivialCmdDeletedProc);
+ Tk_CreateEventHandler(tkwin, StructureNotifyMask,
+ TrivialEventProc, (ClientData) recordPtr);
+ result = Tk_SetOptions(interp, (char *) recordPtr, optionTable,
+ objc - 3, objv + 3, tkwin, NULL, NULL);
+ if (result != TCL_OK) {
+ Tk_DestroyWindow(tkwin);
}
- break;
+ } else {
+ Tk_DestroyWindow(tkwin);
+ ckfree((char *) recordPtr);
}
+ if (result == TCL_OK) {
+ Tcl_SetObjResult(interp, objv[2]);
+ }
+ 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 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 const 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;
}
- 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;
- char *custom;
- } InternalRecord;
- InternalRecord *recordPtr;
- static CONST char *internalStringTable[] = {
- "one", "two", "three", "four", (char *) NULL
- };
- static CONST 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_CUSTOM,
- "-custom", (char *) NULL, (char *) NULL,
- "", -1, Tk_Offset(InternalRecord, custom),
- TK_CONFIG_NULL_OK, (ClientData)&CustomOption, 0x4000},
- {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;
- recordPtr->custom = NULL;
- result = Tk_InitOptions(interp, (char *) recordPtr, optionTable,
- tkwin);
+ 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, NULL, 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);
- result = Tk_SetOptions(interp, (char *) recordPtr,
- optionTable, objc - 3, objv + 3, tkwin,
- (Tk_SavedOptions *) NULL, (int *) NULL);
- if (result != TCL_OK) {
- Tk_DestroyWindow(tkwin);
- }
+ Tcl_GetString(objv[2]), TrivialConfigObjCmd,
+ (ClientData) recordPtr, TrivialCmdDeletedProc);
} else {
- Tk_DestroyWindow(tkwin);
- ckfree((char *) recordPtr);
- }
- if (result == TCL_OK) {
- Tcl_SetObjResult(interp, objv[2]);
+ Tk_FreeConfigOptions((char *) recordPtr,
+ recordPtr->header.optionTable, (Tk_Window) NULL);
}
- break;
+ }
+ if (result != TCL_OK) {
+ ckfree((char *) recordPtr);
}
- 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 CONST 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;
- }
+ break;
+ }
+ case NOT_ENOUGH_PARAMS: {
+ typedef struct NotEnoughRecord {
+ Tcl_Obj *fooObjPtr;
+ } NotEnoughRecord;
+ NotEnoughRecord record;
+ static const 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", 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, NULL, NULL) != TCL_OK) {
+ result = TCL_ERROR;
+ }
+ Tcl_DecrRefCount(newObjPtr);
+ Tk_FreeConfigOptions( (char *) &record, optionTable, tkwin);
+ Tk_DestroyWindow(tkwin);
+ return result;
+ }
- 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);
- }
+ case TWO_WINDOWS: {
+ typedef struct SlaveRecord {
+ TrivialCommandHeader header;
+ Tcl_Obj *windowPtr;
+ } SlaveRecord;
+ SlaveRecord *recordPtr;
+ static const 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_GetString(objv[2]), NULL);
- break;
- }
- case NOT_ENOUGH_PARAMS: {
- typedef struct NotEnoughRecord {
- Tcl_Obj *fooObjPtr;
- } NotEnoughRecord;
- NotEnoughRecord record;
- static CONST 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;
+ if (tkwin == NULL) {
+ return TCL_ERROR;
}
-
- case TWO_WINDOWS: {
- typedef struct SlaveRecord {
- TrivialCommandHeader header;
- Tcl_Obj *windowPtr;
- } SlaveRecord;
- SlaveRecord *recordPtr;
- static CONST 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);
+ 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, NULL, NULL);
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);
+ recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
+ Tcl_GetString(objv[2]), 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;
@@ -1346,15 +1243,15 @@ TestobjconfigObjCmd(clientData, interp, objc, objv)
/* 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. */
+TrivialConfigObjCmd(
+ 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 CONST char *options[] = {
- "cget", "configure", "csave", (char *) NULL
+ static const char *options[] = {
+ "cget", "configure", "csave", NULL
};
enum {
CGET, CONFIGURE, CSAVE
@@ -1370,69 +1267,66 @@ TrivialConfigObjCmd(clientData, interp, objc, objv)
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], options, "command",
- 0, &index) != TCL_OK) {
+ 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");
+ 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, NULL, tkwin);
+ if (resultObjPtr == NULL) {
result = TCL_ERROR;
- goto done;
+ } else {
+ Tcl_SetObjResult(interp, resultObjPtr);
}
- resultObjPtr = Tk_GetOptionValue(interp, (char *) clientData,
+ } else if (objc == 3) {
+ resultObjPtr = Tk_GetOptionInfo(interp, (char *) clientData,
headerPtr->optionTable, objv[2], tkwin);
- if (resultObjPtr != NULL) {
- Tcl_SetObjResult(interp, resultObjPtr);
- result = TCL_OK;
- } else {
+ if (resultObjPtr == NULL) {
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);
- }
+ Tcl_SetObjResult(interp, resultObjPtr);
}
- break;
- }
- case CSAVE: {
+ } else {
result = Tk_SetOptions(interp, (char *) clientData,
- headerPtr->optionTable, objc - 2, objv + 2,
- tkwin, &saved, &mask);
- Tk_FreeSavedOptions(&saved);
+ headerPtr->optionTable, objc - 2, objv + 2,
+ tkwin, NULL, &mask);
if (result == TCL_OK) {
Tcl_SetIntObj(Tcl_GetObjResult(interp), mask);
}
- break;
}
+ 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:
+ done:
Tcl_Release(clientData);
return result;
}
@@ -1442,9 +1336,9 @@ done:
*
* 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.
+ * This function 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.
@@ -1456,8 +1350,8 @@ done:
*/
static void
-TrivialCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+TrivialCmdDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
TrivialCommandHeader *headerPtr = (TrivialCommandHeader *) clientData;
Tk_Window tkwin = headerPtr->tkwin;
@@ -1466,9 +1360,9 @@ TrivialCmdDeletedProc(clientData)
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.
+ * This is a "new" object, which doesn't have a window, so we can't
+ * depend on cleaning up in the event function. Free its resources
+ * here.
*/
Tk_FreeConfigOptions((char *) clientData,
@@ -1488,16 +1382,15 @@ TrivialCmdDeletedProc(clientData)
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up.
+ * 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. */
+TrivialEventProc(
+ ClientData clientData, /* Information about window. */
+ XEvent *eventPtr) /* Information about event. */
{
TrivialCommandHeader *headerPtr = (TrivialCommandHeader *) clientData;
@@ -1519,8 +1412,8 @@ TrivialEventProc(clientData, eventPtr)
*
* TestfontObjCmd --
*
- * This procedure implements the "testfont" command, which is used
- * to test TkFont objects.
+ * This function implements the "testfont" command, which is used to test
+ * TkFont objects.
*
* Results:
* A standard Tcl result.
@@ -1533,18 +1426,18 @@ TrivialEventProc(clientData, eventPtr)
/* 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. */
+TestfontObjCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- static CONST char *options[] = {"counts", "subfonts", (char *) NULL};
+ static const char *options[] = {"counts", "subfonts", NULL};
enum option {COUNTS, SUBFONTS};
int index;
Tk_Window tkwin;
Tk_Font tkfont;
-
+
tkwin = (Tk_Window) clientData;
if (objc < 3) {
@@ -1558,20 +1451,18 @@ TestfontObjCmd(clientData, interp, objc, objv)
}
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;
+ 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;
@@ -1582,8 +1473,7 @@ TestfontObjCmd(clientData, interp, objc, objv)
*
* ImageCreate --
*
- * This procedure is called by the Tk image code to create "test"
- * images.
+ * This function is called by the Tk image code to create "test" images.
*
* Results:
* A standard Tcl result.
@@ -1595,54 +1485,19 @@ TestfontObjCmd(clientData, interp, objc, objv)
*/
/* ARGSUSED */
-#ifdef USE_OLD_IMAGE
static int
-ImageCreate(interp, name, argc, argv, typePtr, master, clientDataPtr)
- Tcl_Interp *interp; /* Interpreter for application containing
+ImageCreate(
+ Tcl_Interp *interp, /* Interpreter for application containing
* image. */
- char *name; /* Name to use for image. */
- int argc; /* Number of arguments. */
- char **argv; /* Argument strings for options (doesn't
+ char *name, /* Name to use for image. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[], /* Argument strings for options (doesn't
* include image name or type). */
- Tk_ImageType *typePtr; /* Pointer to our type record (not used). */
- Tk_ImageMaster master; /* Token for image, to be used by us in
- * later callbacks. */
- ClientData *clientDataPtr; /* Store manager's token for image here;
- * it will be returned in later callbacks. */
-{
- TImageMaster *timPtr;
- char *varName;
- int i;
-
- Tk_InitImageArgs(interp, argc, &argv);
- varName = "log";
- for (i = 0; i < argc; i += 2) {
- if (strcmp(argv[i], "-variable") != 0) {
- Tcl_AppendResult(interp, "bad option name \"",
- argv[i], "\"", (char *) NULL);
- return TCL_ERROR;
- }
- if ((i+1) == argc) {
- Tcl_AppendResult(interp, "no value given for \"",
- argv[i], "\" option", (char *) NULL);
- return TCL_ERROR;
- }
- varName = argv[i+1];
- }
-#else
-static int
-ImageCreate(interp, name, objc, objv, typePtr, master, clientDataPtr)
- Tcl_Interp *interp; /* Interpreter for application containing
- * image. */
- char *name; /* Name to use for image. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument strings for options (doesn't
- * include image name or type). */
- Tk_ImageType *typePtr; /* Pointer to our type record (not used). */
- Tk_ImageMaster master; /* Token for image, to be used by us in
- * later callbacks. */
- ClientData *clientDataPtr; /* Store manager's token for image here;
- * it will be returned in later callbacks. */
+ Tk_ImageType *typePtr, /* Pointer to our type record (not used). */
+ Tk_ImageMaster master, /* Token for image, to be used by us in later
+ * callbacks. */
+ ClientData *clientDataPtr) /* Store manager's token for image here; it
+ * will be returned in later callbacks. */
{
TImageMaster *timPtr;
char *varName;
@@ -1652,17 +1507,17 @@ ImageCreate(interp, name, objc, objv, typePtr, master, clientDataPtr)
for (i = 0; i < objc; i += 2) {
if (strcmp(Tcl_GetString(objv[i]), "-variable") != 0) {
Tcl_AppendResult(interp, "bad option name \"",
- Tcl_GetString(objv[i]), "\"", (char *) NULL);
+ Tcl_GetString(objv[i]), "\"", NULL);
return TCL_ERROR;
}
if ((i+1) == objc) {
Tcl_AppendResult(interp, "no value given for \"",
- Tcl_GetString(objv[i]), "\" option", (char *) NULL);
+ Tcl_GetString(objv[i]), "\" option", NULL);
return TCL_ERROR;
}
varName = Tcl_GetString(objv[i+1]);
}
-#endif
+
timPtr = (TImageMaster *) ckalloc(sizeof(TImageMaster));
timPtr->master = master;
timPtr->interp = interp;
@@ -1672,8 +1527,7 @@ ImageCreate(interp, name, objc, objv, typePtr, master, clientDataPtr)
strcpy(timPtr->imageName, name);
timPtr->varName = (char *) ckalloc((unsigned) (strlen(varName) + 1));
strcpy(timPtr->varName, varName);
- Tcl_CreateCommand(interp, name, ImageCmd, (ClientData) timPtr,
- (Tcl_CmdDeleteProc *) NULL);
+ Tcl_CreateCommand(interp, name, ImageCmd, (ClientData) timPtr, NULL);
*clientDataPtr = (ClientData) timPtr;
Tk_ImageChanged(master, 0, 0, 30, 15, 30, 15);
return TCL_OK;
@@ -1684,8 +1538,8 @@ ImageCreate(interp, name, objc, objv, typePtr, master, clientDataPtr)
*
* ImageCmd --
*
- * This procedure implements the commands corresponding to individual
- * images.
+ * This function implements the commands corresponding to individual
+ * images.
*
* Results:
* A standard Tcl result.
@@ -1698,26 +1552,24 @@ ImageCreate(interp, name, objc, objv, typePtr, master, clientDataPtr)
/* ARGSUSED */
static int
-ImageCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Main window for application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+ImageCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ const char **argv) /* Argument strings. */
{
TImageMaster *timPtr = (TImageMaster *) clientData;
int x, y, width, height;
if (argc < 2) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], "option ?arg arg ...?", (char *) NULL);
+ argv[0], "option ?arg arg ...?", NULL);
return TCL_ERROR;
}
if (strcmp(argv[1], "changed") == 0) {
if (argc != 8) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0],
- " changed x y width height imageWidth imageHeight",
- (char *) NULL);
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+ " changed x y width height imageWidth imageHeight", NULL);
return TCL_ERROR;
}
if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK)
@@ -1732,7 +1584,7 @@ ImageCmd(clientData, interp, argc, argv)
timPtr->height);
} else {
Tcl_AppendResult(interp, "bad option \"", argv[1],
- "\": must be changed", (char *) NULL);
+ "\": must be changed", NULL);
return TCL_ERROR;
}
return TCL_OK;
@@ -1743,12 +1595,12 @@ ImageCmd(clientData, interp, argc, argv)
*
* ImageGet --
*
- * This procedure is called by Tk to set things up for using a
- * test image in a particular widget.
+ * This function is called by Tk to set things up for using a test image
+ * in a particular widget.
*
* Results:
- * The return value is a token for the image instance, which is
- * used in future callbacks to ImageDisplay and ImageFree.
+ * The return value is a token for the image instance, which is used in
+ * future callbacks to ImageDisplay and ImageFree.
*
* Side effects:
* None.
@@ -1757,10 +1609,10 @@ ImageCmd(clientData, interp, argc, argv)
*/
static ClientData
-ImageGet(tkwin, clientData)
- Tk_Window tkwin; /* Token for window in which image will
- * be used. */
- ClientData clientData; /* Pointer to TImageMaster for image. */
+ImageGet(
+ Tk_Window tkwin, /* Token for window in which image will be
+ * used. */
+ ClientData clientData) /* Pointer to TImageMaster for image. */
{
TImageMaster *timPtr = (TImageMaster *) clientData;
TImageInstance *instPtr;
@@ -1784,29 +1636,29 @@ ImageGet(tkwin, clientData)
*
* ImageDisplay --
*
- * This procedure is invoked to redisplay part or all of an
- * image in a given drawable.
+ * This function is invoked to redisplay part or all of an image in a
+ * given drawable.
*
* Results:
* None.
*
* Side effects:
- * The image gets partially redrawn, as an "X" that shows the
- * exact redraw area.
+ * The image gets partially redrawn, as an "X" that shows the exact
+ * redraw area.
*
*----------------------------------------------------------------------
*/
static void
-ImageDisplay(clientData, display, drawable, imageX, imageY, width, height,
- drawableX, drawableY)
- ClientData clientData; /* Pointer to TImageInstance for image. */
- Display *display; /* Display to use for drawing. */
- Drawable drawable; /* Where to redraw image. */
- int imageX, imageY; /* Origin of area to redraw, relative to
+ImageDisplay(
+ ClientData clientData, /* Pointer to TImageInstance for image. */
+ Display *display, /* Display to use for drawing. */
+ Drawable drawable, /* Where to redraw image. */
+ int imageX, int imageY, /* Origin of area to redraw, relative to
* origin of image. */
- int width, height; /* Dimensions of area to redraw. */
- int drawableX, drawableY; /* Coordinates in drawable corresponding to
+ int width, int height, /* Dimensions of area to redraw. */
+ int drawableX, int drawableY)
+ /* Coordinates in drawable corresponding to
* imageX and imageY. */
{
TImageInstance *instPtr = (TImageInstance *) clientData;
@@ -1837,8 +1689,8 @@ ImageDisplay(clientData, display, drawable, imageX, imageY, width, height,
*
* ImageFree --
*
- * This procedure is called when an instance of an image is
- * no longer used.
+ * This function is called when an instance of an image is no longer
+ * used.
*
* Results:
* None.
@@ -1850,9 +1702,9 @@ ImageDisplay(clientData, display, drawable, imageX, imageY, width, height,
*/
static void
-ImageFree(clientData, display)
- ClientData clientData; /* Pointer to TImageInstance for instance. */
- Display *display; /* Display where image was to be drawn. */
+ImageFree(
+ ClientData clientData, /* Pointer to TImageInstance for instance. */
+ Display *display) /* Display where image was to be drawn. */
{
TImageInstance *instPtr = (TImageInstance *) clientData;
char buffer[200];
@@ -1870,8 +1722,8 @@ ImageFree(clientData, display)
*
* ImageDelete --
*
- * This procedure is called to clean up a test image when
- * an application goes away.
+ * This function is called to clean up a test image when an application
+ * goes away.
*
* Results:
* None.
@@ -1883,10 +1735,10 @@ ImageFree(clientData, display)
*/
static void
-ImageDelete(clientData)
- ClientData clientData; /* Pointer to TImageMaster for image. When
- * this procedure is called, no more
- * instances exist. */
+ImageDelete(
+ ClientData clientData) /* Pointer to TImageMaster for image. When
+ * this function is called, no more instances
+ * exist. */
{
TImageMaster *timPtr = (TImageMaster *) clientData;
char buffer[100];
@@ -1906,9 +1758,9 @@ ImageDelete(clientData)
*
* TestmakeexistCmd --
*
- * This procedure implements the "testmakeexist" command. It calls
- * Tk_MakeWindowExist on each of its arguments to force the windows
- * to be created.
+ * This function implements the "testmakeexist" command. It calls
+ * Tk_MakeWindowExist on each of its arguments to force the windows to be
+ * created.
*
* Results:
* A standard Tcl result.
@@ -1921,11 +1773,11 @@ ImageDelete(clientData)
/* ARGSUSED */
static int
-TestmakeexistCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Main window for application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+TestmakeexistCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ const char **argv) /* Argument strings. */
{
Tk_Window mainWin = (Tk_Window) clientData;
int i;
@@ -1947,9 +1799,9 @@ TestmakeexistCmd(clientData, interp, argc, argv)
*
* TestmenubarCmd --
*
- * This procedure implements the "testmenubar" command. It is used
- * to test the Unix facilities for creating space above a toplevel
- * window for a menubar.
+ * This function implements the "testmenubar" command. It is used to test
+ * the Unix facilities for creating space above a toplevel window for a
+ * menubar.
*
* Results:
* A standard Tcl result.
@@ -1963,11 +1815,11 @@ TestmakeexistCmd(clientData, interp, argc, argv)
/* ARGSUSED */
#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
static int
-TestmenubarCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Main window for application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+TestmenubarCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ const char **argv) /* Argument strings. */
{
#ifdef __UNIX__
Tk_Window mainWin = (Tk_Window) clientData;
@@ -1975,14 +1827,14 @@ TestmenubarCmd(clientData, interp, argc, argv)
if (argc < 2) {
Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
- " option ?arg ...?\"", (char *) NULL);
+ " option ?arg ...?\"", NULL);
return TCL_ERROR;
}
if (strcmp(argv[1], "window") == 0) {
if (argc != 4) {
Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
- "window toplevel menubar\"", (char *) NULL);
+ "window toplevel menubar\"", NULL);
return TCL_ERROR;
}
tkwin = Tk_NameToWindow(interp, argv[2], mainWin);
@@ -2000,7 +1852,7 @@ TestmenubarCmd(clientData, interp, argc, argv)
}
} else {
Tcl_AppendResult(interp, "bad option \"", argv[1],
- "\": must be window", (char *) NULL);
+ "\": must be window", NULL);
return TCL_ERROR;
}
@@ -2018,8 +1870,8 @@ TestmenubarCmd(clientData, interp, argc, argv)
*
* TestmetricsCmd --
*
- * This procedure implements the testmetrics command. It provides
- * a way to determine the size of various widget components.
+ * This function implements the testmetrics command. It provides a way to
+ * determine the size of various widget components.
*
* Results:
* A standard Tcl result.
@@ -2032,11 +1884,11 @@ TestmenubarCmd(clientData, interp, argc, argv)
#if defined(__WIN32__) || defined(MAC_OSX_TK)
static int
-TestmetricsCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Main window for application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+TestmetricsCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ const char **argv) /* Argument strings. */
{
char buf[TCL_INTEGER_SPACE];
int val;
@@ -2044,7 +1896,7 @@ TestmetricsCmd(clientData, interp, argc, argv)
#ifdef __WIN32__
if (argc < 2) {
Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
- " option ?arg ...?\"", (char *) NULL);
+ " option ?arg ...?\"", NULL);
return TCL_ERROR;
}
#else
@@ -2053,7 +1905,7 @@ TestmetricsCmd(clientData, interp, argc, argv)
if (argc != 3) {
Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
- " option window\"", (char *) NULL);
+ " option window\"", NULL);
return TCL_ERROR;
}
@@ -2077,11 +1929,11 @@ TestmetricsCmd(clientData, interp, argc, argv)
#endif
} else {
Tcl_AppendResult(interp, "bad option \"", argv[1],
- "\": must be cxhscroll or cyvscroll", (char *) NULL);
+ "\": must be cxhscroll or cyvscroll", NULL);
return TCL_ERROR;
}
sprintf(buf, "%d", val);
- Tcl_AppendResult(interp, buf, (char *) NULL);
+ Tcl_AppendResult(interp, buf, NULL);
return TCL_OK;
}
#endif
@@ -2091,8 +1943,8 @@ TestmetricsCmd(clientData, interp, argc, argv)
*
* TestpropCmd --
*
- * This procedure implements the "testprop" command. It fetches
- * and prints the value of a property on a window.
+ * This function implements the "testprop" command. It fetches and prints
+ * the value of a property on a window.
*
* Results:
* A standard Tcl result.
@@ -2105,23 +1957,24 @@ TestmetricsCmd(clientData, interp, argc, argv)
/* ARGSUSED */
static int
-TestpropCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Main window for application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+TestpropCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ const char **argv) /* Argument strings. */
{
Tk_Window mainWin = (Tk_Window) clientData;
int result, actualFormat;
unsigned long bytesAfter, length, value;
Atom actualType, propName;
- char *property, *p, *end;
+ unsigned char *property, *p;
+ char *end;
Window w;
char buffer[30];
if (argc != 3) {
Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
- " window property\"", (char *) NULL);
+ " window property\"", NULL);
return TCL_ERROR;
}
@@ -2131,7 +1984,7 @@ TestpropCmd(clientData, interp, argc, argv)
result = XGetWindowProperty(Tk_Display(mainWin),
w, propName, 0, 100000, False, AnyPropertyType,
&actualType, &actualFormat, &length,
- &bytesAfter, (unsigned char **) &property);
+ &bytesAfter, &property);
if ((result == Success) && (actualType != None)) {
if ((actualFormat == 8) && (actualType == XA_STRING)) {
for (p = property; ((unsigned long)(p-property)) < length; p++) {
@@ -2139,7 +1992,7 @@ TestpropCmd(clientData, interp, argc, argv)
*p = '\n';
}
}
- Tcl_SetResult(interp, property, TCL_VOLATILE);
+ Tcl_SetResult(interp, (/*!unsigned*/char*)property, TCL_VOLATILE);
} else {
for (p = property; length > 0; length--) {
if (actualFormat == 32) {
@@ -2163,209 +2016,15 @@ TestpropCmd(clientData, interp, argc, argv)
return TCL_OK;
}
-/*
- *----------------------------------------------------------------------
- *
- * TestsendCmd --
- *
- * This procedure implements the "testsend" command. It provides
- * a set of functions for testing the "send" command and support
- * procedure in tkSend.c.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * Depends on option; see below.
- *
- *----------------------------------------------------------------------
- */
-
- /* ARGSUSED */
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
-static int
-TestsendCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Main window for application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
-{
- TkWindow *winPtr = (TkWindow *) clientData;
-
- if (argc < 2) {
- Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
- " option ?arg ...?\"", (char *) NULL);
- return TCL_ERROR;
- }
-
- if (strcmp(argv[1], "bogus") == 0) {
- XChangeProperty(winPtr->dispPtr->display,
- RootWindow(winPtr->dispPtr->display, 0),
- winPtr->dispPtr->registryProperty, XA_INTEGER, 32,
- PropModeReplace,
- (unsigned char *) "This is bogus information", 6);
- } else if (strcmp(argv[1], "prop") == 0) {
- int result, actualFormat;
- unsigned long length, bytesAfter;
- Atom actualType, propName;
- char *property, *p, *end;
- Window w;
-
- if ((argc != 4) && (argc != 5)) {
- Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
- " prop window name ?value ?\"", (char *) NULL);
- return TCL_ERROR;
- }
- if (strcmp(argv[2], "root") == 0) {
- w = RootWindow(winPtr->dispPtr->display, 0);
- } else if (strcmp(argv[2], "comm") == 0) {
- w = Tk_WindowId(winPtr->dispPtr->commTkwin);
- } else {
- w = strtoul(argv[2], &end, 0);
- }
- propName = Tk_InternAtom((Tk_Window) winPtr, argv[3]);
- if (argc == 4) {
- property = NULL;
- result = XGetWindowProperty(winPtr->dispPtr->display,
- w, propName, 0, 100000, False, XA_STRING,
- &actualType, &actualFormat, &length,
- &bytesAfter, (unsigned char **) &property);
- if ((result == Success) && (actualType != None)
- && (actualFormat == 8) && (actualType == XA_STRING)) {
- for (p = property; (p-property) < length; p++) {
- if (*p == 0) {
- *p = '\n';
- }
- }
- Tcl_SetResult(interp, property, TCL_VOLATILE);
- }
- if (property != NULL) {
- XFree(property);
- }
- } else {
- if (argv[4][0] == 0) {
- XDeleteProperty(winPtr->dispPtr->display, w, propName);
- } else {
- Tcl_DString tmp;
-
- Tcl_DStringInit(&tmp);
- for (p = Tcl_DStringAppend(&tmp, argv[4],
- (int) strlen(argv[4]));
- *p != 0; p++) {
- if (*p == '\n') {
- *p = 0;
- }
- }
-
- XChangeProperty(winPtr->dispPtr->display,
- w, propName, XA_STRING, 8, PropModeReplace,
- (unsigned char *) Tcl_DStringValue(&tmp),
- p-Tcl_DStringValue(&tmp));
- Tcl_DStringFree(&tmp);
- }
- }
- } else if (strcmp(argv[1], "serial") == 0) {
- 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);
- return TCL_ERROR;
- }
- return TCL_OK;
-}
-#endif
-
-/*
- *----------------------------------------------------------------------
- *
- * 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. */
- CONST 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_OSX_TK))
/*
*----------------------------------------------------------------------
*
* TestwrapperCmd --
*
- * This procedure implements the "testwrapper" command. It
- * provides a way from Tcl to determine the extra window Tk adds
- * in between the toplevel window and the window decorations.
+ * This function implements the "testwrapper" command. It provides a way
+ * from Tcl to determine the extra window Tk adds in between the toplevel
+ * window and the window decorations.
*
* Results:
* A standard Tcl result.
@@ -2378,21 +2037,21 @@ TesttextCmd(clientData, interp, argc, argv)
/* ARGSUSED */
static int
-TestwrapperCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Main window for application. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+TestwrapperCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ const char **argv) /* Argument strings. */
{
TkWindow *winPtr, *wrapperPtr;
Tk_Window tkwin;
if (argc != 2) {
Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
- " window\"", (char *) NULL);
+ " window\"", NULL);
return TCL_ERROR;
}
-
+
tkwin = (Tk_Window) clientData;
winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[1], tkwin);
if (winPtr == NULL) {
@@ -2415,7 +2074,7 @@ TestwrapperCmd(clientData, interp, argc, argv)
*
* CustomOptionSet, CustomOptionGet, CustomOptionRestore, CustomOptionFree --
*
- * Handlers for object-based custom configuration options. See
+ * Handlers for object-based custom configuration options. See
* Testobjconfigcommand.
*
* Results:
@@ -2437,20 +2096,19 @@ TestwrapperCmd(clientData, interp, argc, argv)
*/
static int
-CustomOptionSet(clientData,interp, tkwin, value, recordPtr, internalOffset,
- saveInternalPtr, flags)
- ClientData clientData;
- Tcl_Interp *interp;
- Tk_Window tkwin;
- Tcl_Obj **value;
- char *recordPtr;
- int internalOffset;
- char *saveInternalPtr;
- int flags;
+CustomOptionSet(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ Tk_Window tkwin,
+ Tcl_Obj **value,
+ char *recordPtr,
+ int internalOffset,
+ char *saveInternalPtr,
+ int flags)
{
int objEmpty, length;
- char *new, *string, *internalPtr;
-
+ char *newStr, *string, *internalPtr;
+
objEmpty = 0;
if (internalOffset >= 0) {
@@ -2458,21 +2116,20 @@ CustomOptionSet(clientData,interp, tkwin, value, recordPtr, internalOffset,
} else {
internalPtr = NULL;
}
-
+
/*
* See if the object is empty.
*/
+
if (value == NULL) {
objEmpty = 1;
+ } else if ((*value)->bytes != NULL) {
+ objEmpty = ((*value)->length == 0);
} else {
- if ((*value)->bytes != NULL) {
- objEmpty = ((*value)->length == 0);
- } else {
- Tcl_GetStringFromObj((*value), &length);
- objEmpty = (length == 0);
- }
+ Tcl_GetStringFromObj((*value), &length);
+ objEmpty = (length == 0);
}
-
+
if ((flags & TK_OPTION_NULL_OK) && objEmpty) {
*value = NULL;
} else {
@@ -2487,47 +2144,54 @@ CustomOptionSet(clientData,interp, tkwin, value, recordPtr, internalOffset,
if (internalPtr != NULL) {
if ((*value) != NULL) {
string = Tcl_GetStringFromObj((*value), &length);
- new = ckalloc((size_t) (length + 1));
- strcpy(new, string);
+ newStr = ckalloc((size_t) (length + 1));
+ strcpy(newStr, string);
} else {
- new = NULL;
+ newStr = NULL;
}
*((char **) saveInternalPtr) = *((char **) internalPtr);
- *((char **) internalPtr) = new;
+ *((char **) internalPtr) = newStr;
}
return TCL_OK;
}
static Tcl_Obj *
-CustomOptionGet(clientData, tkwin, recordPtr, internalOffset)
- ClientData clientData;
- Tk_Window tkwin;
- char *recordPtr;
- int internalOffset;
+CustomOptionGet(
+ ClientData clientData,
+ Tk_Window tkwin,
+ char *recordPtr,
+ int internalOffset)
{
return (Tcl_NewStringObj(*(char **)(recordPtr + internalOffset), -1));
}
static void
-CustomOptionRestore(clientData, tkwin, internalPtr, saveInternalPtr)
- ClientData clientData;
- Tk_Window tkwin;
- char *internalPtr;
- char *saveInternalPtr;
+CustomOptionRestore(
+ ClientData clientData,
+ Tk_Window tkwin,
+ char *internalPtr,
+ char *saveInternalPtr)
{
*(char **)internalPtr = *(char **)saveInternalPtr;
return;
}
static void
-CustomOptionFree(clientData, tkwin, internalPtr)
- ClientData clientData;
- Tk_Window tkwin;
- char *internalPtr;
+CustomOptionFree(
+ ClientData clientData,
+ Tk_Window tkwin,
+ char *internalPtr)
{
if (*(char **)internalPtr != NULL) {
ckfree(*(char **)internalPtr);
}
}
-
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkText.c b/generic/tkText.c
index fb15468..f3e1c26 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -1,22 +1,20 @@
-/*
+/*
* tkText.c --
*
- * This module provides a big chunk of the implementation of
- * multi-line editable text widgets for Tk. Among other things,
- * it provides the Tcl command interfaces to text widgets and
- * the display code. The B-tree representation of text is
- * implemented elsewhere.
+ * This module provides a big chunk of the implementation of multi-line
+ * editable text widgets for Tk. Among other things, it provides the Tcl
+ * command interfaces to text widgets. The B-tree representation of text
+ * and its actual display are implemented elsewhere.
*
* Copyright (c) 1992-1994 The Regents of the University of California.
* Copyright (c) 1994-1996 Sun Microsystems, Inc.
* Copyright (c) 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "default.h"
-#include "tkPort.h"
#include "tkInt.h"
#include "tkUndo.h"
@@ -25,323 +23,409 @@
#define DInfo TkDInfo
#endif
+/*
+ * For compatibility with Tk 4.0 through 8.4.x, we allow tabs to be
+ * mis-specified with non-increasing values. These are converted into tabs
+ * which are the equivalent of at least a character width apart.
+ */
+
+#if (TK_MAJOR_VERSION < 9)
+#define _TK_ALLOW_DECREASING_TABS
+#endif
+
#include "tkText.h"
/*
- * Custom options for handling "-state"
+ * Used to avoid having to allocate and deallocate arrays on the fly for
+ * commonly used functions. Must be > 0.
+ */
+
+#define PIXEL_CLIENTS 5
+
+/*
+ * The 'TkTextState' enum in tkText.h is used to define a type for the -state
+ * option of the Text widget. These values are used as indices into the string
+ * table below.
*/
-static Tk_CustomOption stateOption = {
- (Tk_OptionParseProc *) TkStateParseProc,
- TkStatePrintProc, (ClientData) NULL /* only "normal" and "disabled" */
+static const char *const stateStrings[] = {
+ "disabled", "normal", NULL
};
/*
- * Information used to parse text configuration options:
+ * The 'TkWrapMode' enum in tkText.h is used to define a type for the -wrap
+ * option of the Text widget. These values are used as indices into the string
+ * table below.
*/
-static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_BOOLEAN, "-autoseparators", "autoSeparators",
- "AutoSeparators", DEF_TEXT_AUTO_SEPARATORS,
- Tk_Offset(TkText, autoSeparators), 0},
- {TK_CONFIG_BORDER, "-background", "background", "Background",
- DEF_TEXT_BG_COLOR, Tk_Offset(TkText, border), TK_CONFIG_COLOR_ONLY},
- {TK_CONFIG_BORDER, "-background", "background", "Background",
- DEF_TEXT_BG_MONO, Tk_Offset(TkText, 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_TEXT_BORDER_WIDTH, Tk_Offset(TkText, borderWidth), 0},
- {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
- DEF_TEXT_CURSOR, Tk_Offset(TkText, cursor), TK_CONFIG_NULL_OK},
- {TK_CONFIG_BOOLEAN, "-exportselection", "exportSelection",
- "ExportSelection", DEF_TEXT_EXPORT_SELECTION,
- Tk_Offset(TkText, exportSelection), 0},
- {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL,
- (char *) NULL, 0, 0},
- {TK_CONFIG_FONT, "-font", "font", "Font",
- DEF_TEXT_FONT, Tk_Offset(TkText, tkfont), 0},
- {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
- DEF_TEXT_FG, Tk_Offset(TkText, fgColor), 0},
- {TK_CONFIG_PIXELS, "-height", "height", "Height",
- DEF_TEXT_HEIGHT, Tk_Offset(TkText, height), 0},
- {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
- "HighlightBackground", DEF_TEXT_HIGHLIGHT_BG,
- Tk_Offset(TkText, highlightBgColorPtr), 0},
- {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
- DEF_TEXT_HIGHLIGHT, Tk_Offset(TkText, highlightColorPtr), 0},
- {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
- "HighlightThickness",
- DEF_TEXT_HIGHLIGHT_WIDTH, Tk_Offset(TkText, highlightWidth), 0},
- {TK_CONFIG_BORDER, "-insertbackground", "insertBackground", "Foreground",
- DEF_TEXT_INSERT_BG, Tk_Offset(TkText, insertBorder), 0},
- {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth",
- DEF_TEXT_INSERT_BD_COLOR, Tk_Offset(TkText, insertBorderWidth),
- TK_CONFIG_COLOR_ONLY},
- {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth",
- DEF_TEXT_INSERT_BD_MONO, Tk_Offset(TkText, insertBorderWidth),
- TK_CONFIG_MONO_ONLY},
- {TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime",
- DEF_TEXT_INSERT_OFF_TIME, Tk_Offset(TkText, insertOffTime), 0},
- {TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime",
- DEF_TEXT_INSERT_ON_TIME, Tk_Offset(TkText, insertOnTime), 0},
- {TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
- DEF_TEXT_INSERT_WIDTH, Tk_Offset(TkText, insertWidth), 0},
- {TK_CONFIG_INT, "-maxundo", "maxUndo", "MaxUndo",
- DEF_TEXT_MAX_UNDO, Tk_Offset(TkText, maxUndo), 0},
- {TK_CONFIG_PIXELS, "-padx", "padX", "Pad",
- DEF_TEXT_PADX, Tk_Offset(TkText, padX), 0},
- {TK_CONFIG_PIXELS, "-pady", "padY", "Pad",
- DEF_TEXT_PADY, Tk_Offset(TkText, padY), 0},
- {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
- DEF_TEXT_RELIEF, Tk_Offset(TkText, relief), 0},
- {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
- DEF_TEXT_SELECT_COLOR, Tk_Offset(TkText, selBorder),
- TK_CONFIG_COLOR_ONLY},
- {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
- DEF_TEXT_SELECT_MONO, Tk_Offset(TkText, selBorder),
- TK_CONFIG_MONO_ONLY},
- {TK_CONFIG_STRING, "-selectborderwidth", "selectBorderWidth", "BorderWidth",
- DEF_TEXT_SELECT_BD_COLOR, Tk_Offset(TkText, selBdString),
- TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-selectborderwidth", "selectBorderWidth", "BorderWidth",
- DEF_TEXT_SELECT_BD_MONO, Tk_Offset(TkText, selBdString),
- TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK},
- {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
- DEF_TEXT_SELECT_FG_COLOR, Tk_Offset(TkText, selFgColorPtr),
- TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK},
- {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
- DEF_TEXT_SELECT_FG_MONO, Tk_Offset(TkText, selFgColorPtr),
- TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK},
- {TK_CONFIG_BOOLEAN, "-setgrid", "setGrid", "SetGrid",
- DEF_TEXT_SET_GRID, Tk_Offset(TkText, setGrid), 0},
- {TK_CONFIG_PIXELS, "-spacing1", "spacing1", "Spacing",
- DEF_TEXT_SPACING1, Tk_Offset(TkText, spacing1),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_PIXELS, "-spacing2", "spacing2", "Spacing",
- DEF_TEXT_SPACING2, Tk_Offset(TkText, spacing2),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_PIXELS, "-spacing3", "spacing3", "Spacing",
- DEF_TEXT_SPACING3, Tk_Offset(TkText, spacing3),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_CUSTOM, "-state", "state", "State",
- DEF_TEXT_STATE, Tk_Offset(TkText, state), 0, &stateOption},
- {TK_CONFIG_STRING, "-tabs", "tabs", "Tabs",
- DEF_TEXT_TABS, Tk_Offset(TkText, tabOptionString), TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
- DEF_TEXT_TAKE_FOCUS, Tk_Offset(TkText, takeFocus),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_BOOLEAN, "-undo", "undo", "Undo",
- DEF_TEXT_UNDO, Tk_Offset(TkText, undo), 0},
- {TK_CONFIG_INT, "-width", "width", "Width",
- DEF_TEXT_WIDTH, Tk_Offset(TkText, width), 0},
- {TK_CONFIG_CUSTOM, "-wrap", "wrap", "Wrap",
- DEF_TEXT_WRAP, Tk_Offset(TkText, wrapMode), 0, &TkTextWrapModeOption},
- {TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
- DEF_TEXT_XSCROLL_COMMAND, Tk_Offset(TkText, xScrollCmd),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
- DEF_TEXT_YSCROLL_COMMAND, Tk_Offset(TkText, yScrollCmd),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+static const char *const wrapStrings[] = {
+ "char", "none", "word", NULL
};
/*
- * Boolean variable indicating whether or not special debugging code
- * should be executed.
+ * The 'TkTextTabStyle' enum in tkText.h is used to define a type for the
+ * -tabstyle option of the Text widget. These values are used as indices into
+ * the string table below.
*/
-int tkTextDebug = 0;
+static const char *const tabStyleStrings[] = {
+ "tabular", "wordprocessor", NULL
+};
/*
- * Custom options for handling "-wrap":
+ * The following functions and custom option type are used to define the
+ * "line" option type, and thereby handle the text widget '-startline',
+ * '-endline' configuration options which are of that type.
+ *
+ * We do not need a 'freeProc' because all changes to these two options are
+ * handled through the TK_TEXT_LINE_RANGE flag in the optionSpecs list, and
+ * the internal storage is just a pointer, which therefore doesn't need
+ * freeing.
*/
-static int WrapModeParseProc _ANSI_ARGS_((ClientData clientData,
+static int SetLineStartEnd(ClientData clientData,
Tcl_Interp *interp, Tk_Window tkwin,
- CONST char *value, char *widgRec, int offset));
-static char * WrapModePrintProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin, char *widgRec, int offset,
- Tcl_FreeProc **freeProcPtr));
-
-Tk_CustomOption TkTextWrapModeOption = {
- WrapModeParseProc,
- WrapModePrintProc,
- (ClientData) NULL
+ Tcl_Obj **value, char *recordPtr,
+ int internalOffset, char *oldInternalPtr,
+ int flags);
+static Tcl_Obj * GetLineStartEnd(ClientData clientData,
+ Tk_Window tkwin, char *recordPtr,
+ int internalOffset);
+static void RestoreLineStartEnd(ClientData clientData,
+ Tk_Window tkwin, char *internalPtr,
+ char *oldInternalPtr);
+static int ObjectIsEmpty(Tcl_Obj *objPtr);
+
+static const Tk_ObjCustomOption lineOption = {
+ "line", /* name */
+ SetLineStartEnd, /* setProc */
+ GetLineStartEnd, /* getProc */
+ RestoreLineStartEnd, /* restoreProc */
+ NULL, /* freeProc */
+ 0
};
/*
- *--------------------------------------------------------------
- *
- * WrapModeParseProc --
- *
- * This procedure is invoked during option processing to handle
- * "-wrap" options for text widgets.
- *
- * Results:
- * A standard Tcl return value.
- *
- * Side effects:
- * The wrap mode for a given item gets replaced by the wrap mode
- * indicated in the value argument.
- *
- *--------------------------------------------------------------
+ * Information used to parse text configuration options:
*/
-static int
-WrapModeParseProc(clientData, interp, tkwin, value, widgRec, offset)
- ClientData clientData; /* some flags.*/
- Tcl_Interp *interp; /* Used for reporting errors. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- CONST char *value; /* Value of option (list of tag
- * names). */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Offset into item. */
-{
- int c;
- size_t length;
+static const Tk_OptionSpec optionSpecs[] = {
+ {TK_OPTION_BOOLEAN, "-autoseparators", "autoSeparators",
+ "AutoSeparators", DEF_TEXT_AUTO_SEPARATORS, -1,
+ Tk_Offset(TkText, autoSeparators), 0, 0, 0},
+ {TK_OPTION_BORDER, "-background", "background", "Background",
+ DEF_TEXT_BG_COLOR, -1, Tk_Offset(TkText, border),
+ 0, (ClientData) DEF_TEXT_BG_MONO, 0},
+ {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-borderwidth",
+ TK_TEXT_LINE_GEOMETRY},
+ {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
+ NULL, 0, -1, 0, (ClientData) "-background", 0},
+ {TK_OPTION_BOOLEAN, "-blockcursor", "blockCursor",
+ "BlockCursor", DEF_TEXT_BLOCK_CURSOR, -1,
+ Tk_Offset(TkText, insertCursorType), 0, 0, 0},
+ {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
+ DEF_TEXT_BORDER_WIDTH, -1, Tk_Offset(TkText, borderWidth),
+ 0, 0, TK_TEXT_LINE_GEOMETRY},
+ {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
+ DEF_TEXT_CURSOR, -1, Tk_Offset(TkText, cursor),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_CUSTOM, "-endline", NULL, NULL,
+ NULL, -1, Tk_Offset(TkText, end), TK_OPTION_NULL_OK,
+ (ClientData) &lineOption, TK_TEXT_LINE_RANGE},
+ {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
+ "ExportSelection", DEF_TEXT_EXPORT_SELECTION, -1,
+ Tk_Offset(TkText, exportSelection), 0, 0, 0},
+ {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
+ NULL, 0, -1, 0, (ClientData) "-foreground", 0},
+ {TK_OPTION_FONT, "-font", "font", "Font",
+ DEF_TEXT_FONT, -1, Tk_Offset(TkText, tkfont), 0, 0,
+ TK_TEXT_LINE_GEOMETRY},
+ {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
+ DEF_TEXT_FG, -1, Tk_Offset(TkText, fgColor), 0,
+ 0, 0},
+ {TK_OPTION_PIXELS, "-height", "height", "Height",
+ DEF_TEXT_HEIGHT, -1, Tk_Offset(TkText, height), 0, 0, 0},
+ {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
+ "HighlightBackground", DEF_TEXT_HIGHLIGHT_BG,
+ -1, Tk_Offset(TkText, highlightBgColorPtr),
+ 0, 0, 0},
+ {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
+ DEF_TEXT_HIGHLIGHT, -1, Tk_Offset(TkText, highlightColorPtr),
+ 0, 0, 0},
+ {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
+ "HighlightThickness", DEF_TEXT_HIGHLIGHT_WIDTH, -1,
+ Tk_Offset(TkText, highlightWidth), 0, 0, TK_TEXT_LINE_GEOMETRY},
+ {TK_OPTION_BORDER, "-inactiveselectbackground","inactiveSelectBackground",
+ "Foreground",
+ DEF_TEXT_INACTIVE_SELECT_COLOR,
+ -1, Tk_Offset(TkText, inactiveSelBorder),
+ TK_OPTION_NULL_OK, (ClientData) DEF_TEXT_SELECT_MONO, 0},
+ {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
+ DEF_TEXT_INSERT_BG,
+ -1, Tk_Offset(TkText, insertBorder),
+ 0, 0, 0},
+ {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
+ "BorderWidth", DEF_TEXT_INSERT_BD_COLOR, -1,
+ Tk_Offset(TkText, insertBorderWidth), 0,
+ (ClientData) DEF_TEXT_INSERT_BD_MONO, 0},
+ {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
+ DEF_TEXT_INSERT_OFF_TIME, -1, Tk_Offset(TkText, insertOffTime),
+ 0, 0, 0},
+ {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
+ DEF_TEXT_INSERT_ON_TIME, -1, Tk_Offset(TkText, insertOnTime),
+ 0, 0, 0},
+ {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
+ DEF_TEXT_INSERT_WIDTH, -1, Tk_Offset(TkText, insertWidth),
+ 0, 0, 0},
+ {TK_OPTION_INT, "-maxundo", "maxUndo", "MaxUndo",
+ DEF_TEXT_MAX_UNDO, -1, Tk_Offset(TkText, maxUndo), 0, 0, 0},
+ {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
+ DEF_TEXT_PADX, -1, Tk_Offset(TkText, padX), 0, 0,
+ TK_TEXT_LINE_GEOMETRY},
+ {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
+ DEF_TEXT_PADY, -1, Tk_Offset(TkText, padY), 0, 0, 0},
+ {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
+ DEF_TEXT_RELIEF, -1, Tk_Offset(TkText, relief), 0, 0, 0},
+ {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
+ DEF_TEXT_SELECT_COLOR, -1, Tk_Offset(TkText, selBorder),
+ 0, (ClientData) DEF_TEXT_SELECT_MONO, 0},
+ {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
+ "BorderWidth", DEF_TEXT_SELECT_BD_COLOR,
+ Tk_Offset(TkText, selBorderWidthPtr),
+ Tk_Offset(TkText, selBorderWidth),
+ TK_OPTION_NULL_OK, (ClientData) DEF_TEXT_SELECT_BD_MONO, 0},
+ {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
+ DEF_TEXT_SELECT_FG_COLOR, -1, Tk_Offset(TkText, selFgColorPtr),
+ TK_CONFIG_NULL_OK, (ClientData) DEF_TEXT_SELECT_FG_MONO, 0},
+ {TK_OPTION_BOOLEAN, "-setgrid", "setGrid", "SetGrid",
+ DEF_TEXT_SET_GRID, -1, Tk_Offset(TkText, setGrid), 0, 0, 0},
+ {TK_OPTION_PIXELS, "-spacing1", "spacing1", "Spacing",
+ DEF_TEXT_SPACING1, -1, Tk_Offset(TkText, spacing1),
+ TK_OPTION_DONT_SET_DEFAULT, 0 , TK_TEXT_LINE_GEOMETRY },
+ {TK_OPTION_PIXELS, "-spacing2", "spacing2", "Spacing",
+ DEF_TEXT_SPACING2, -1, Tk_Offset(TkText, spacing2),
+ TK_OPTION_DONT_SET_DEFAULT, 0 , TK_TEXT_LINE_GEOMETRY },
+ {TK_OPTION_PIXELS, "-spacing3", "spacing3", "Spacing",
+ DEF_TEXT_SPACING3, -1, Tk_Offset(TkText, spacing3),
+ TK_OPTION_DONT_SET_DEFAULT, 0 , TK_TEXT_LINE_GEOMETRY },
+ {TK_OPTION_CUSTOM, "-startline", NULL, NULL,
+ NULL, -1, Tk_Offset(TkText, start), TK_OPTION_NULL_OK,
+ (ClientData) &lineOption, TK_TEXT_LINE_RANGE},
+ {TK_OPTION_STRING_TABLE, "-state", "state", "State",
+ DEF_TEXT_STATE, -1, Tk_Offset(TkText, state),
+ 0, (ClientData) stateStrings, 0},
+ {TK_OPTION_STRING, "-tabs", "tabs", "Tabs",
+ DEF_TEXT_TABS, Tk_Offset(TkText, tabOptionPtr), -1,
+ TK_OPTION_NULL_OK, 0, TK_TEXT_LINE_GEOMETRY},
+ {TK_OPTION_STRING_TABLE, "-tabstyle", "tabStyle", "TabStyle",
+ DEF_TEXT_TABSTYLE, -1, Tk_Offset(TkText, tabStyle),
+ 0, (ClientData) tabStyleStrings, TK_TEXT_LINE_GEOMETRY},
+ {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
+ DEF_TEXT_TAKE_FOCUS, -1, Tk_Offset(TkText, takeFocus),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_BOOLEAN, "-undo", "undo", "Undo",
+ DEF_TEXT_UNDO, -1, Tk_Offset(TkText, undo), 0, 0 , 0},
+ {TK_OPTION_INT, "-width", "width", "Width",
+ DEF_TEXT_WIDTH, -1, Tk_Offset(TkText, width), 0, 0,
+ TK_TEXT_LINE_GEOMETRY},
+ {TK_OPTION_STRING_TABLE, "-wrap", "wrap", "Wrap",
+ DEF_TEXT_WRAP, -1, Tk_Offset(TkText, wrapMode),
+ 0, (ClientData) wrapStrings, TK_TEXT_LINE_GEOMETRY},
+ {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
+ DEF_TEXT_XSCROLL_COMMAND, -1, Tk_Offset(TkText, xScrollCmd),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
+ DEF_TEXT_YSCROLL_COMMAND, -1, Tk_Offset(TkText, yScrollCmd),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0}
+};
- register TkWrapMode *wrapPtr = (TkWrapMode *) (widgRec + offset);
+/*
+ * These three typedefs, the structure and the SearchPerform, SearchCore
+ * functions below are used for line-based searches of the text widget, and,
+ * in particular, to handle multi-line matching even though the text widget is
+ * a single-line based data structure. They are completely abstracted away
+ * from the Text widget internals, however, so could easily be re-used with
+ * any line-based entity to provide multi-line matching.
+ *
+ * We have abstracted this code away from the text widget to try to keep Tk as
+ * modular as possible.
+ */
- if(value == NULL || *value == 0) {
- *wrapPtr = TEXT_WRAPMODE_NULL;
- return TCL_OK;
- }
+struct SearchSpec; /* Forward declaration. */
+
+typedef ClientData SearchAddLineProc(int lineNum,
+ struct SearchSpec *searchSpecPtr,
+ Tcl_Obj *theLine, int *lenPtr,
+ int *extraLinesPtr);
+typedef int SearchMatchProc(int lineNum,
+ struct SearchSpec *searchSpecPtr,
+ ClientData clientData, Tcl_Obj *theLine,
+ int matchOffset, int matchLength);
+typedef int SearchLineIndexProc(Tcl_Interp *interp,
+ Tcl_Obj *objPtr, struct SearchSpec *searchSpecPtr,
+ int *linePosPtr, int *offsetPosPtr);
+
+typedef struct SearchSpec {
+ int exact; /* Whether search is exact or regexp. */
+ int noCase; /* Case-insenstivive? */
+ int noLineStop; /* If not set, a regexp search will use the
+ * TCL_REG_NLSTOP flag. */
+ int overlap; /* If set, results from multiple searches
+ * (-all) are allowed to overlap each
+ * other. */
+ int strictLimits; /* If set, matches must be completely inside
+ * the from,to range. Otherwise the limits
+ * only apply to the start of each match. */
+ int all; /* Whether all or the first match should be
+ * reported. */
+ int startLine; /* First line to examine. */
+ int startOffset; /* Index in first line to start at. */
+ int stopLine; /* Last line to examine, or -1 when we search
+ * all available text. */
+ int stopOffset; /* Index to stop at, provided stopLine is not
+ * -1. */
+ int numLines; /* Total lines which are available. */
+ int backwards; /* Searching forwards or backwards. */
+ Tcl_Obj *varPtr; /* If non-NULL, store length(s) of match(es)
+ * in this variable. */
+ Tcl_Obj *countPtr; /* Keeps track of currently found lengths. */
+ Tcl_Obj *resPtr; /* Keeps track of currently found locations */
+ int searchElide; /* Search in hidden text as well. */
+ SearchAddLineProc *addLineProc;
+ /* Function to call when we need to add
+ * another line to the search string so far */
+ SearchMatchProc *foundMatchProc;
+ /* Function to call when we have found a
+ * match. */
+ SearchLineIndexProc *lineIndexProc;
+ /* Function to call when we have found a
+ * match. */
+ ClientData clientData; /* Information about structure being searched,
+ * in this case a text widget. */
+} SearchSpec;
- c = value[0];
- length = strlen(value);
+/*
+ * The text-widget-independent functions which actually perform the search,
+ * handling both regexp and exact searches.
+ */
- if ((c == 'c') && (strncmp(value, "char", length) == 0)) {
- *wrapPtr = TEXT_WRAPMODE_CHAR;
- return TCL_OK;
- }
- if ((c == 'n') && (strncmp(value, "none", length) == 0)) {
- *wrapPtr = TEXT_WRAPMODE_NONE;
- return TCL_OK;
- }
- if ((c == 'w') && (strncmp(value, "word", length) == 0)) {
- *wrapPtr = TEXT_WRAPMODE_WORD;
- return TCL_OK;
- }
- Tcl_AppendResult(interp, "bad wrap mode \"", value,
- "\": must be char, none, or word",
- (char *) NULL);
- *wrapPtr = TEXT_WRAPMODE_CHAR;
- return TCL_ERROR;
-}
+static int SearchCore(Tcl_Interp *interp,
+ SearchSpec *searchSpecPtr, Tcl_Obj *patObj);
+static int SearchPerform(Tcl_Interp *interp,
+ SearchSpec *searchSpecPtr, Tcl_Obj *patObj,
+ Tcl_Obj *fromPtr, Tcl_Obj *toPtr);
/*
- *--------------------------------------------------------------
- *
- * WrapModePrintProc --
- *
- * This procedure is invoked by the Tk configuration code
- * to produce a printable string for the "-wrap" configuration
- * option for canvas items.
- *
- * Results:
- * The return value is a string describing the state for
- * the item referred to by "widgRec". In addition, *freeProcPtr
- * is filled in with the address of a procedure to call to free
- * the result string when it's no longer needed (or NULL to
- * indicate that the string doesn't need to be freed).
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
+ * Boolean variable indicating whether or not special debugging code should be
+ * executed.
*/
-static char *
-WrapModePrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
- ClientData clientData; /* Ignored. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Ignored. */
- Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
- * information about how to reclaim
- * storage for return string. */
-{
- register TkWrapMode *wrapPtr = (TkWrapMode *) (widgRec + offset);
-
- if (*wrapPtr==TEXT_WRAPMODE_CHAR) {
- return "char";
- } else if (*wrapPtr==TEXT_WRAPMODE_NONE) {
- return "none";
- } else if (*wrapPtr==TEXT_WRAPMODE_WORD) {
- return "word";
- } else {
- return "";
- }
-}
+int tkTextDebug = 0;
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static int ConfigureText _ANSI_ARGS_((Tcl_Interp *interp,
- TkText *textPtr, int argc, CONST char **argv,
- int flags));
-static int DeleteChars _ANSI_ARGS_((TkText *textPtr,
- CONST char *index1String, CONST char *index2String,
- TkTextIndex *indexPtr1, TkTextIndex *indexPtr2));
-static void DestroyText _ANSI_ARGS_((char *memPtr));
-static void InsertChars _ANSI_ARGS_((TkText *textPtr,
- TkTextIndex *indexPtr, CONST char *string));
-static void TextBlinkProc _ANSI_ARGS_((ClientData clientData));
-static void TextCmdDeletedProc _ANSI_ARGS_((
- ClientData clientData));
-static void TextEventProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static int TextFetchSelection _ANSI_ARGS_((ClientData clientData,
- int offset, char *buffer, int maxBytes));
-static int TextIndexSortProc _ANSI_ARGS_((CONST VOID *first,
- CONST VOID *second));
-static int TextSearchCmd _ANSI_ARGS_((TkText *textPtr,
- Tcl_Interp *interp, int argc, CONST char **argv));
-static int TextEditCmd _ANSI_ARGS_((TkText *textPtr,
- Tcl_Interp *interp, int argc, CONST char **argv));
-static int TextWidgetCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int argc, CONST char **argv));
-static void TextWorldChanged _ANSI_ARGS_((
- ClientData instanceData));
-static int TextDumpCmd _ANSI_ARGS_((TkText *textPtr,
- Tcl_Interp *interp, int argc, CONST char **argv));
-static void DumpLine _ANSI_ARGS_((Tcl_Interp *interp,
- TkText *textPtr, int what, TkTextLine *linePtr,
- int start, int end, int lineno,
- CONST char *command));
-static int DumpSegment _ANSI_ARGS_((Tcl_Interp *interp, char *key,
- char *value, CONST char * command,
- TkTextIndex *index, int what));
-static int TextEditUndo _ANSI_ARGS_((TkText *textPtr));
-static int TextEditRedo _ANSI_ARGS_((TkText *textPtr));
-static void TextGetText _ANSI_ARGS_((TkTextIndex * index1,
- TkTextIndex * index2, Tcl_DString *dsPtr));
+static int ConfigureText(Tcl_Interp *interp,
+ TkText *textPtr, int objc, Tcl_Obj *const objv[]);
+static int DeleteIndexRange(TkSharedText *sharedPtr,
+ TkText *textPtr, const TkTextIndex *indexPtr1,
+ const TkTextIndex *indexPtr2, int viewUpdate);
+static int CountIndices(const TkText *textPtr,
+ const TkTextIndex *indexPtr1,
+ const TkTextIndex *indexPtr2,
+ TkTextCountType type);
+static void DestroyText(TkText *textPtr);
+static int InsertChars(TkSharedText *sharedTextPtr,
+ TkText *textPtr, TkTextIndex *indexPtr,
+ Tcl_Obj *stringPtr, int viewUpdate);
+static void TextBlinkProc(ClientData clientData);
+static void TextCmdDeletedProc(ClientData clientData);
+static int CreateWidget(TkSharedText *sharedPtr, Tk_Window tkwin,
+ Tcl_Interp *interp, const TkText *parent,
+ int objc, Tcl_Obj *const objv[]);
+static void TextEventProc(ClientData clientData,
+ XEvent *eventPtr);
+static int TextFetchSelection(ClientData clientData, int offset,
+ char *buffer, int maxBytes);
+static int TextIndexSortProc(const void *first,
+ const void *second);
+static int TextInsertCmd(TkSharedText *sharedTextPtr,
+ TkText *textPtr, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[],
+ const TkTextIndex *indexPtr, int viewUpdate);
+static int TextReplaceCmd(TkText *textPtr, Tcl_Interp *interp,
+ const TkTextIndex *indexFromPtr,
+ const TkTextIndex *indexToPtr,
+ int objc, Tcl_Obj *const objv[], int viewUpdate);
+static int TextSearchCmd(TkText *textPtr, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int TextEditCmd(TkText *textPtr, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int TextWidgetObjCmd(ClientData clientData,
+ Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int SharedTextObjCmd(ClientData clientData,
+ Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static void TextWorldChangedCallback(ClientData instanceData);
+static void TextWorldChanged(TkText *textPtr, int mask);
+static int TextDumpCmd(TkText *textPtr, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int DumpLine(Tcl_Interp *interp, TkText *textPtr,
+ int what, TkTextLine *linePtr, int start, int end,
+ int lineno, Tcl_Obj *command);
+static int DumpSegment(TkText *textPtr, Tcl_Interp *interp,
+ const char *key, const char *value,
+ Tcl_Obj *command, const TkTextIndex *index,
+ int what);
+static int TextEditUndo(TkText *textPtr);
+static int TextEditRedo(TkText *textPtr);
+static Tcl_Obj * TextGetText(const TkText *textPtr,
+ const TkTextIndex *index1,
+ const TkTextIndex *index2, int visibleOnly);
static void GenerateModifiedEvent(TkText *textPtr);
-static void updateDirtyFlag _ANSI_ARGS_((TkText *textPtr));
+static void UpdateDirtyFlag(TkSharedText *sharedPtr);
+static void TextPushUndoAction(TkText *textPtr,
+ Tcl_Obj *undoString, int insert,
+ const TkTextIndex *index1Ptr,
+ const TkTextIndex *index2Ptr);
+static int TextSearchIndexInLine(const SearchSpec *searchSpecPtr,
+ TkTextLine *linePtr, int byteIndex);
+static int TextPeerCmd(TkText *textPtr, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static TkUndoProc TextUndoRedoCallback;
+
+/*
+ * Declarations of the three search procs required by the multi-line search
+ * routines.
+ */
+
+static SearchMatchProc TextSearchFoundMatch;
+static SearchAddLineProc TextSearchAddNextLine;
+static SearchLineIndexProc TextSearchGetLineIndex;
/*
- * The structure below defines text class behavior by means of procedures
- * that can be invoked from generic window code.
+ * The structure below defines text class behavior by means of functions that
+ * can be invoked from generic window code.
*/
static Tk_ClassProcs textClass = {
sizeof(Tk_ClassProcs), /* size */
- TextWorldChanged, /* worldChangedProc */
+ TextWorldChangedCallback, /* worldChangedProc */
+ NULL, /* createProc */
+ NULL /* modalProc */
};
-
/*
*--------------------------------------------------------------
*
- * Tk_TextCmd --
+ * Tk_TextObjCmd --
*
- * This procedure is invoked to process the "text" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is invoked to process the "text" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -353,85 +437,201 @@ static Tk_ClassProcs textClass = {
*/
int
-Tk_TextCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Main window associated with
- * interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+Tk_TextObjCmd(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
Tk_Window tkwin = (Tk_Window) clientData;
- Tk_Window new;
- register TkText *textPtr;
- TkTextIndex startIndex;
- 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;
}
+ return CreateWidget(NULL, tkwin, interp, NULL, objc, objv);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * CreateWidget --
+ *
+ * This function is invoked to process the "text" Tcl command, (when
+ * called by Tk_TextObjCmd) and the "$text peer create" text widget
+ * sub-command (called from TextPeerCmd).
+ *
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result, places the name of the widget created into the
+ * interp's result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+CreateWidget(
+ TkSharedText *sharedPtr, /* Shared widget info, or NULL. */
+ Tk_Window tkwin, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ const TkText *parent, /* If non-NULL then take default start, end
+ * from this parent. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ register TkText *textPtr;
+ Tk_OptionTable optionTable;
+ TkTextIndex startIndex;
+ Tk_Window newWin;
+
/*
* Create the window.
*/
- new = Tk_CreateWindowFromPath(interp, tkwin, argv[1], (char *) NULL);
- if (new == NULL) {
+ newWin = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]),
+ NULL);
+ if (newWin == NULL) {
return TCL_ERROR;
}
/*
- * Create the text widget and initialize everything to zero,
- * then set the necessary initial (non-NULL) values.
+ * Create the text widget and initialize everything to zero, then set the
+ * necessary initial (non-NULL) values. It is important that the 'set' tag
+ * and 'insert', 'current' mark pointers are all NULL to start.
*/
textPtr = (TkText *) ckalloc(sizeof(TkText));
- memset((VOID *) textPtr, 0, sizeof(TkText));
+ memset(textPtr, 0, sizeof(TkText));
- textPtr->tkwin = new;
- textPtr->display = Tk_Display(new);
+ textPtr->tkwin = newWin;
+ textPtr->display = Tk_Display(newWin);
textPtr->interp = interp;
- textPtr->widgetCmd = Tcl_CreateCommand(interp,
- Tk_PathName(textPtr->tkwin), TextWidgetCmd,
+ textPtr->widgetCmd = Tcl_CreateObjCommand(interp,
+ Tk_PathName(textPtr->tkwin), TextWidgetObjCmd,
(ClientData) textPtr, TextCmdDeletedProc);
- textPtr->tree = TkBTreeCreate(textPtr);
- Tcl_InitHashTable(&textPtr->tagTable, TCL_STRING_KEYS);
- Tcl_InitHashTable(&textPtr->markTable, TCL_STRING_KEYS);
- Tcl_InitHashTable(&textPtr->windowTable, TCL_STRING_KEYS);
- Tcl_InitHashTable(&textPtr->imageTable, TCL_STRING_KEYS);
- textPtr->state = TK_STATE_NORMAL;
+
+ if (sharedPtr == NULL) {
+ sharedPtr = (TkSharedText *) ckalloc(sizeof(TkSharedText));
+ memset(sharedPtr, 0, sizeof(TkSharedText));
+
+ sharedPtr->refCount = 0;
+ sharedPtr->peers = NULL;
+ sharedPtr->tree = TkBTreeCreate(sharedPtr);
+
+ Tcl_InitHashTable(&sharedPtr->tagTable, TCL_STRING_KEYS);
+ Tcl_InitHashTable(&sharedPtr->markTable, TCL_STRING_KEYS);
+ Tcl_InitHashTable(&sharedPtr->windowTable, TCL_STRING_KEYS);
+ Tcl_InitHashTable(&sharedPtr->imageTable, TCL_STRING_KEYS);
+ sharedPtr->undoStack = TkUndoInitStack(interp,0);
+ sharedPtr->undo = 1;
+ sharedPtr->isDirty = 0;
+ sharedPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
+ sharedPtr->autoSeparators = 1;
+ sharedPtr->lastEditMode = TK_TEXT_EDIT_OTHER;
+ sharedPtr->stateEpoch = 0;
+ }
+
+ /*
+ * Add the new widget to the shared list.
+ */
+
+ textPtr->sharedTextPtr = sharedPtr;
+ sharedPtr->refCount++;
+ textPtr->next = sharedPtr->peers;
+ sharedPtr->peers = textPtr;
+
+ /*
+ * This refCount will be held until DestroyText is called. Note also that
+ * the later call to 'TkTextCreateDInfo' will add more refCounts.
+ */
+
+ textPtr->refCount = 1;
+
+ /*
+ * Specify start and end lines in the B-tree. The default is the same as
+ * the parent, but this can be adjusted to display more or less if the
+ * start, end where given as configuration options.
+ */
+
+ if (parent != NULL) {
+ textPtr->start = parent->start;
+ textPtr->end = parent->end;
+ } else {
+ textPtr->start = NULL;
+ textPtr->end = NULL;
+ }
+
+ /*
+ * Register with the B-tree. In some sense it would be best if we could do
+ * this later (after configuration options), so that any changes to
+ * start,end do not require a total recalculation.
+ */
+
+ TkBTreeAddClient(sharedPtr->tree, textPtr, textPtr->charHeight);
+
+ textPtr->state = TK_TEXT_STATE_NORMAL;
textPtr->relief = TK_RELIEF_FLAT;
textPtr->cursor = None;
textPtr->charWidth = 1;
+ textPtr->charHeight = 10;
textPtr->wrapMode = TEXT_WRAPMODE_CHAR;
- textPtr->prevWidth = Tk_Width(new);
- textPtr->prevHeight = Tk_Height(new);
+ textPtr->prevWidth = Tk_Width(newWin);
+ textPtr->prevHeight = Tk_Height(newWin);
+
+ /*
+ * This will add refCounts to textPtr.
+ */
+
TkTextCreateDInfo(textPtr);
- TkTextMakeByteIndex(textPtr->tree, 0, 0, &startIndex);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0,
+ &startIndex);
TkTextSetYView(textPtr, &startIndex, 0);
textPtr->exportSelection = 1;
textPtr->pickEvent.type = LeaveNotify;
- textPtr->undoStack = TkUndoInitStack(interp,0);
- textPtr->undo = 1;
- textPtr->isDirty = 0;
- textPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
- textPtr->autoSeparators = 1;
- textPtr->lastEditMode = TK_TEXT_EDIT_OTHER;
+ textPtr->undo = textPtr->sharedTextPtr->undo;
+ textPtr->maxUndo = textPtr->sharedTextPtr->maxUndo;
+ textPtr->autoSeparators = textPtr->sharedTextPtr->autoSeparators;
+ textPtr->tabOptionPtr = NULL;
/*
* Create the "sel" tag and the "current" and "insert" marks.
*/
- textPtr->selTagPtr = TkTextCreateTag(textPtr, "sel");
- textPtr->selTagPtr->reliefString =
- (char *) ckalloc(sizeof(DEF_TEXT_SELECT_RELIEF));
+ textPtr->selBorder = NULL;
+ textPtr->inactiveSelBorder = NULL;
+ textPtr->selBorderWidth = 0;
+ textPtr->selBorderWidthPtr = NULL;
+ textPtr->selFgColorPtr = NULL;
+
+ /*
+ * Note: it is important that textPtr->selTagPtr is NULL before this
+ * initial call.
+ */
+
+ textPtr->selTagPtr = TkTextCreateTag(textPtr, "sel", NULL);
+ textPtr->selTagPtr->reliefString = (char *)
+ ckalloc(sizeof(DEF_TEXT_SELECT_RELIEF));
strcpy(textPtr->selTagPtr->reliefString, DEF_TEXT_SELECT_RELIEF);
- Tk_GetRelief(interp, DEF_TEXT_SELECT_RELIEF, &(textPtr->selTagPtr->relief));
+ Tk_GetRelief(interp, DEF_TEXT_SELECT_RELIEF, &textPtr->selTagPtr->relief);
textPtr->currentMarkPtr = TkTextSetMark(textPtr, "current", &startIndex);
textPtr->insertMarkPtr = TkTextSetMark(textPtr, "insert", &startIndex);
+ /*
+ * Create the option table for this widget class. If it has already been
+ * created, the cached pointer will be returned.
+ */
+
+ optionTable = Tk_CreateOptionTable(interp, optionSpecs);
+
Tk_SetClass(textPtr->tkwin, "Text");
Tk_SetClassProcs(textPtr->tkwin, &textClass, (ClientData) textPtr);
+ textPtr->optionTable = optionTable;
+
Tk_CreateEventHandler(textPtr->tkwin,
ExposureMask|StructureNotifyMask|FocusChangeMask,
TextEventProc, (ClientData) textPtr);
@@ -441,23 +641,30 @@ Tk_TextCmd(clientData, interp, argc, argv)
TkTextBindProc, (ClientData) textPtr);
Tk_CreateSelHandler(textPtr->tkwin, XA_PRIMARY, XA_STRING,
TextFetchSelection, (ClientData) textPtr, XA_STRING);
- if (ConfigureText(interp, textPtr, argc-2, argv+2, 0) != TCL_OK) {
+
+ if (Tk_InitOptions(interp, (char *) textPtr, optionTable, textPtr->tkwin)
+ != TCL_OK) {
+ Tk_DestroyWindow(textPtr->tkwin);
+ return TCL_ERROR;
+ }
+ if (ConfigureText(interp, textPtr, objc-2, objv+2) != TCL_OK) {
Tk_DestroyWindow(textPtr->tkwin);
return TCL_ERROR;
}
- Tcl_SetResult(interp, Tk_PathName(textPtr->tkwin), TCL_STATIC);
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj(Tk_PathName(textPtr->tkwin),-1));
return TCL_OK;
}
/*
*--------------------------------------------------------------
*
- * TextWidgetCmd --
+ * TextWidgetObjCmd --
*
- * This procedure is invoked to process the Tcl command
- * that corresponds to a text widget. See the user
- * documentation for details on what it does.
+ * This function is invoked to process the Tcl command that corresponds
+ * to a text widget. See the user documentation for details on what it
+ * does.
*
* Results:
* A standard Tcl result.
@@ -469,88 +676,118 @@ Tk_TextCmd(clientData, interp, argc, argv)
*/
static int
-TextWidgetCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Information about text widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+TextWidgetObjCmd(
+ ClientData clientData, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
register TkText *textPtr = (TkText *) clientData;
- int c, result = TCL_OK;
- size_t length;
- TkTextIndex index1, index2;
+ int result = TCL_OK;
+ int index;
+
+ static const char *optionStrings[] = {
+ "bbox", "cget", "compare", "configure", "count", "debug", "delete",
+ "dlineinfo", "dump", "edit", "get", "image", "index", "insert",
+ "mark", "peer", "replace", "scan", "search", "see", "tag", "window",
+ "xview", "yview", NULL
+ };
+ enum options {
+ TEXT_BBOX, TEXT_CGET, TEXT_COMPARE, TEXT_CONFIGURE, TEXT_COUNT,
+ TEXT_DEBUG, TEXT_DELETE, TEXT_DLINEINFO, TEXT_DUMP, TEXT_EDIT,
+ TEXT_GET, TEXT_IMAGE, TEXT_INDEX, TEXT_INSERT, TEXT_MARK,
+ TEXT_PEER, TEXT_REPLACE, TEXT_SCAN, TEXT_SEARCH, TEXT_SEE,
+ TEXT_TAG, TEXT_WINDOW, TEXT_XVIEW, TEXT_YVIEW
+ };
+
+ 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], optionStrings, "option", 0,
+ &index) != TCL_OK) {
return TCL_ERROR;
}
- Tcl_Preserve((ClientData) textPtr);
- c = argv[1][0];
- length = strlen(argv[1]);
- if ((c == 'b') && (strncmp(argv[1], "bbox", length) == 0)) {
+ textPtr->refCount++;
+
+ switch ((enum options) index) {
+ case TEXT_BBOX: {
int x, y, width, height;
+ const TkTextIndex *indexPtr;
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " bbox index\"", (char *) NULL);
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
result = TCL_ERROR;
goto done;
}
- if (TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK) {
+ indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]);
+ if (indexPtr == NULL) {
result = TCL_ERROR;
goto done;
}
- if (TkTextCharBbox(textPtr, &index1, &x, &y, &width, &height) == 0) {
- 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)) {
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " cget option\"",
- (char *) NULL);
+ if (TkTextIndexBbox(textPtr, indexPtr, &x, &y, &width, &height,
+ NULL) == 0) {
+ Tcl_Obj *listObj = Tcl_NewListObj(0, NULL);
+
+ Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(x));
+ Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(y));
+ Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(width));
+ Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(height));
+
+ Tcl_SetObjResult(interp, listObj);
+ }
+ break;
+ }
+ case TEXT_CGET:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option");
result = TCL_ERROR;
goto done;
+ } else {
+ Tcl_Obj *objPtr = Tk_GetOptionValue(interp, (char *) textPtr,
+ textPtr->optionTable, objv[2], textPtr->tkwin);
+ if (objPtr == NULL) {
+ result = TCL_ERROR;
+ goto done;
+ } else {
+ Tcl_SetObjResult(interp, objPtr);
+ result = TCL_OK;
+ }
}
- result = Tk_ConfigureValue(interp, textPtr->tkwin, configSpecs,
- (char *) textPtr, argv[2], 0);
- } else if ((c == 'c') && (strncmp(argv[1], "compare", length) == 0)
- && (length >= 3)) {
+ break;
+ case TEXT_COMPARE: {
int relation, value;
- CONST char *p;
+ const char *p;
+ const TkTextIndex *index1Ptr, *index2Ptr;
- if (argc != 5) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " compare index1 op index2\"", (char *) NULL);
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index1 op index2");
result = TCL_ERROR;
goto done;
}
- if ((TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK)
- || (TkTextGetIndex(interp, textPtr, argv[4], &index2)
- != TCL_OK)) {
+ index1Ptr = TkTextGetIndexFromObj(interp, textPtr, objv[2]);
+ index2Ptr = TkTextGetIndexFromObj(interp, textPtr, objv[4]);
+ if (index1Ptr == NULL || index2Ptr == NULL) {
result = TCL_ERROR;
goto done;
}
- relation = TkTextIndexCmp(&index1, &index2);
- p = argv[3];
+ relation = TkTextIndexCmp(index1Ptr, index2Ptr);
+ p = Tcl_GetString(objv[3]);
if (p[0] == '<') {
- value = (relation < 0);
+ value = (relation < 0);
if ((p[1] == '=') && (p[2] == 0)) {
value = (relation <= 0);
} else if (p[1] != 0) {
- compareError:
+ compareError:
Tcl_AppendResult(interp, "bad comparison operator \"",
- argv[3], "\": must be <, <=, ==, >=, >, or !=",
- (char *) NULL);
+ Tcl_GetString(objv[3]),
+ "\": must be <, <=, ==, >=, >, or !=", NULL);
result = TCL_ERROR;
goto done;
}
} else if (p[0] == '>') {
- value = (relation > 0);
+ value = (relation > 0);
if ((p[1] == '=') && (p[2] == 0)) {
value = (relation >= 0);
} else if (p[1] != 0) {
@@ -563,104 +800,347 @@ TextWidgetCmd(clientData, interp, argc, argv)
} else {
goto compareError;
}
- Tcl_SetResult(interp, ((value) ? "1" : "0"), TCL_STATIC);
- } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)
- && (length >= 3)) {
- if (argc == 2) {
- result = Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs,
- (char *) textPtr, (char *) NULL, 0);
- } else if (argc == 3) {
- result = Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs,
- (char *) textPtr, argv[2], 0);
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
+ break;
+ }
+ case TEXT_CONFIGURE:
+ if (objc <= 3) {
+ Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, (char *) textPtr,
+ textPtr->optionTable, ((objc == 3) ? objv[2] : NULL),
+ textPtr->tkwin);
+ if (objPtr == NULL) {
+ result = TCL_ERROR;
+ goto done;
+ } else {
+ Tcl_SetObjResult(interp, objPtr);
+ }
} else {
- result = ConfigureText(interp, textPtr, argc-2, argv+2,
- TK_CONFIG_ARGV_ONLY);
- }
- } else if ((c == 'd') && (strncmp(argv[1], "debug", length) == 0)
- && (length >= 3)) {
- if (argc > 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " debug boolean\"", (char *) NULL);
+ result = ConfigureText(interp, textPtr, objc-2, objv+2);
+ }
+ break;
+ case TEXT_COUNT: {
+ const TkTextIndex *indexFromPtr, *indexToPtr;
+ int i, found = 0, update = 0;
+ Tcl_Obj *objPtr = NULL;
+
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?options? index1 index2");
+ result = TCL_ERROR;
+ goto done;
+ }
+
+ indexFromPtr = TkTextGetIndexFromObj(interp, textPtr, objv[objc-2]);
+ if (indexFromPtr == NULL) {
+ result = TCL_ERROR;
+ goto done;
+ }
+ indexToPtr = TkTextGetIndexFromObj(interp, textPtr, objv[objc-1]);
+ if (indexToPtr == NULL) {
result = TCL_ERROR;
goto done;
}
- if (argc == 2) {
- Tcl_SetResult(interp, ((tkBTreeDebug) ? "1" : "0"), TCL_STATIC);
+
+ for (i = 2; i < objc-2; i++) {
+ int value, length;
+ const char *option = Tcl_GetStringFromObj(objv[i], &length);
+ char c;
+
+ if (length < 2 || option[0] != '-') {
+ badOption:
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "bad option \"",
+ Tcl_GetString(objv[i]),
+ "\" must be -chars, -displaychars, -displayindices, ",
+ "-displaylines, -indices, -lines, -update, ",
+ "-xpixels, or -ypixels", NULL);
+ result = TCL_ERROR;
+ goto done;
+ }
+ c = option[1];
+ if (c == 'c' && !strncmp("-chars", option, (unsigned) length)) {
+ value = CountIndices(textPtr, indexFromPtr, indexToPtr,
+ COUNT_CHARS);
+ } else if (c == 'd' && (length > 8)
+ && !strncmp("-displaychars", option, (unsigned) length)) {
+ value = CountIndices(textPtr, indexFromPtr, indexToPtr,
+ COUNT_DISPLAY_CHARS);
+ } else if (c == 'd' && (length > 8)
+ && !strncmp("-displayindices", option,(unsigned)length)) {
+ value = CountIndices(textPtr, indexFromPtr, indexToPtr,
+ COUNT_DISPLAY_INDICES);
+ } else if (c == 'd' && (length > 8)
+ && !strncmp("-displaylines", option, (unsigned) length)) {
+ TkTextLine *fromPtr, *lastPtr;
+ TkTextIndex index;
+
+ int compare = TkTextIndexCmp(indexFromPtr, indexToPtr);
+ value = 0;
+
+ if (compare == 0) {
+ goto countDone;
+ }
+
+ if (compare > 0) {
+ const TkTextIndex *tmpPtr = indexFromPtr;
+
+ indexFromPtr = indexToPtr;
+ indexToPtr = tmpPtr;
+ }
+
+ lastPtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree,
+ textPtr,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree,textPtr));
+ fromPtr = indexFromPtr->linePtr;
+ if (fromPtr == lastPtr) {
+ goto countDone;
+ }
+
+ /*
+ * Caution: we must NEVER call TkTextUpdateOneLine with the
+ * last artificial line in the widget.
+ */
+
+ index = *indexFromPtr;
+ index.byteIndex = 0;
+
+ /*
+ * We're going to count up all display lines in the logical
+ * line of 'indexFromPtr' up to, but not including the logical
+ * line of 'indexToPtr', and then subtract off what we didn't
+ * want from 'from' and add on what we didn't count from 'to.
+ */
+
+ while (index.linePtr != indexToPtr->linePtr) {
+ value += TkTextUpdateOneLine(textPtr, fromPtr,0,&index,0);
+
+ /*
+ * We might have skipped past indexToPtr, if we have
+ * multiple logical lines in a single display line.
+ */
+ if (TkTextIndexCmp(&index,indexToPtr) > 0) {
+ break;
+ }
+ }
+
+ /*
+ * Now we need to adjust the count to add on the number of
+ * display lines in the last logical line, and subtract off
+ * the number of display lines overcounted in the first
+ * logical line. This logic is still ok if both indices are in
+ * the same logical line.
+ */
+
+ index.linePtr = indexFromPtr->linePtr;
+ index.byteIndex = 0;
+ while (1) {
+ TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL);
+ if (index.byteIndex >= indexFromPtr->byteIndex) {
+ break;
+ }
+ TkTextIndexForwBytes(textPtr, &index, 1, &index);
+ value--;
+
+ }
+ if (indexToPtr->linePtr != lastPtr) {
+ index.linePtr = indexToPtr->linePtr;
+ index.byteIndex = 0;
+ while (1) {
+ TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL);
+ if (index.byteIndex >= indexToPtr->byteIndex) {
+ break;
+ }
+ TkTextIndexForwBytes(textPtr, &index, 1, &index);
+ value++;
+ }
+ }
+
+ if (compare > 0) {
+ value = -value;
+ }
+ } else if (c == 'i'
+ && !strncmp("-indices", option, (unsigned) length)) {
+ value = CountIndices(textPtr, indexFromPtr, indexToPtr,
+ COUNT_INDICES);
+ } else if (c == 'l'
+ && !strncmp("-lines", option, (unsigned) length)) {
+ value = TkBTreeLinesTo(textPtr, indexToPtr->linePtr)
+ - TkBTreeLinesTo(textPtr, indexFromPtr->linePtr);
+ } else if (c == 'u'
+ && !strncmp("-update", option, (unsigned) length)) {
+ update = 1;
+ continue;
+ } else if (c == 'x'
+ && !strncmp("-xpixels", option, (unsigned) length)) {
+ int x1, x2;
+ TkTextIndex index;
+
+ index = *indexFromPtr;
+ TkTextFindDisplayLineEnd(textPtr, &index, 0, &x1);
+ index = *indexToPtr;
+ TkTextFindDisplayLineEnd(textPtr, &index, 0, &x2);
+ value = x2 - x1;
+ } else if (c == 'y'
+ && !strncmp("-ypixels", option, (unsigned) length)) {
+ if (update) {
+ TkTextUpdateLineMetrics(textPtr,
+ TkBTreeLinesTo(textPtr, indexFromPtr->linePtr),
+ TkBTreeLinesTo(textPtr, indexToPtr->linePtr), -1);
+ }
+ value = TkTextIndexYPixels(textPtr, indexToPtr)
+ - TkTextIndexYPixels(textPtr, indexFromPtr);
+ } else {
+ goto badOption;
+ }
+
+ countDone:
+ found++;
+ if (found == 1) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(value));
+ } else {
+ if (found == 2) {
+ /*
+ * Move the first item we put into the result into the
+ * first element of the list object.
+ */
+
+ objPtr = Tcl_NewObj();
+ Tcl_ListObjAppendElement(NULL, objPtr,
+ Tcl_GetObjResult(interp));
+ }
+ Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewIntObj(value));
+ }
+ }
+
+ if (found == 0) {
+ /*
+ * Use the default '-indices'.
+ */
+
+ int value = CountIndices(textPtr, indexFromPtr, indexToPtr,
+ COUNT_INDICES);
+
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(value));
+ } else if (found > 1) {
+ Tcl_SetObjResult(interp, objPtr);
+ }
+ break;
+ }
+ case TEXT_DEBUG:
+ if (objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "boolean");
+ result = TCL_ERROR;
+ goto done;
+ }
+ if (objc == 2) {
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(tkBTreeDebug));
} else {
- if (Tcl_GetBoolean(interp, argv[2], &tkBTreeDebug) != TCL_OK) {
+ if (Tcl_GetBooleanFromObj(interp, objv[2],
+ &tkBTreeDebug) != TCL_OK) {
result = TCL_ERROR;
goto done;
}
tkTextDebug = tkBTreeDebug;
}
- } else if ((c == 'd') && (strncmp(argv[1], "delete", length) == 0)
- && (length >= 3)) {
- int i;
-
- if (argc < 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " delete index1 ?index2 ...?\"", (char *) NULL);
+ break;
+ case TEXT_DELETE:
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index1 ?index2 ...?");
result = TCL_ERROR;
goto done;
}
- if (textPtr->state == TK_STATE_NORMAL) {
- if (argc < 5) {
+ if (textPtr->state == TK_TEXT_STATE_NORMAL) {
+ if (objc < 5) {
/*
* Simple case requires no predetermination of indices.
*/
- result = DeleteChars(textPtr, argv[2],
- (argc == 4) ? argv[3] : NULL, NULL, NULL);
+
+ const TkTextIndex *indexPtr1, *indexPtr2;
+
+ /*
+ * Parse the starting and stopping indices.
+ */
+
+ indexPtr1 = TkTextGetIndexFromObj(textPtr->interp, textPtr,
+ objv[2]);
+ if (indexPtr1 == NULL) {
+ result = TCL_ERROR;
+ goto done;
+ }
+ if (objc == 4) {
+ indexPtr2 = TkTextGetIndexFromObj(textPtr->interp,
+ textPtr, objv[3]);
+ if (indexPtr2 == NULL) {
+ result = TCL_ERROR;
+ goto done;
+ }
+ } else {
+ indexPtr2 = NULL;
+ }
+ DeleteIndexRange(NULL, textPtr, indexPtr1, indexPtr2, 1);
} else {
/*
* Multi-index pair case requires that we prevalidate the
- * indices and sort from last to first so that deletes
- * occur in the exact (unshifted) text. It also needs to
- * handle partial and fully overlapping ranges. We have to
- * do this with multiple passes.
+ * indices and sort from last to first so that deletes occur
+ * in the exact (unshifted) text. It also needs to handle
+ * partial and fully overlapping ranges. We have to do this
+ * with multiple passes.
*/
+
TkTextIndex *indices, *ixStart, *ixEnd, *lastStart;
char *useIdx;
+ int i;
- argc -= 2;
- argv += 2;
+ objc -= 2;
+ objv += 2;
indices = (TkTextIndex *)
- ckalloc((argc + 1) * sizeof(TkTextIndex));
+ ckalloc((objc + 1) * sizeof(TkTextIndex));
/*
* First pass verifies that all indices are valid.
*/
- for (i = 0; i < argc; i++) {
- if (TkTextGetIndex(interp, textPtr, argv[i],
- &indices[i]) != TCL_OK) {
+
+ for (i = 0; i < objc; i++) {
+ const TkTextIndex *indexPtr =
+ TkTextGetIndexFromObj(interp, textPtr, objv[i]);
+
+ if (indexPtr == NULL) {
result = TCL_ERROR;
ckfree((char *) indices);
goto done;
}
+ indices[i] = *indexPtr;
}
+
/*
* Pad out the pairs evenly to make later code easier.
*/
- if (argc & 1) {
+
+ if (objc & 1) {
indices[i] = indices[i-1];
- TkTextIndexForwChars(&indices[i], 1, &indices[i]);
- argc++;
+ TkTextIndexForwChars(NULL, &indices[i], 1, &indices[i],
+ COUNT_INDICES);
+ objc++;
}
- useIdx = (char *) ckalloc((unsigned) argc);
- memset(useIdx, 0, (unsigned) argc);
+ useIdx = (char *) ckalloc((unsigned) objc);
+ memset(useIdx, 0, (unsigned) objc);
+
/*
- * Do a decreasing order sort so that we delete the end
- * ranges first to maintain index consistency.
+ * Do a decreasing order sort so that we delete the end ranges
+ * first to maintain index consistency.
*/
- qsort((VOID *) indices, (unsigned) (argc / 2),
+
+ qsort(indices, (unsigned) objc / 2,
2 * sizeof(TkTextIndex), TextIndexSortProc);
lastStart = NULL;
+
/*
* Second pass will handle bogus ranges (end < start) and
* overlapping ranges.
*/
- for (i = 0; i < argc; i += 2) {
+
+ for (i = 0; i < objc; i += 2) {
ixStart = &indices[i];
- ixEnd = &indices[i+1];
+ ixEnd = &indices[i+1];
if (TkTextIndexCmp(ixEnd, ixStart) <= 0) {
continue;
}
@@ -670,13 +1150,15 @@ TextWidgetCmd(clientData, interp, argc, argv)
* Start indices were equal, and the sort placed
* the longest range first, so skip this one.
*/
+
continue;
} else if (TkTextIndexCmp(lastStart, ixEnd) < 0) {
/*
* The next pair has a start range before the end
- * point of the last range. Constrain the delete
+ * point of the last range. Constrain the delete
* range, but use the pointer values.
*/
+
*ixEnd = *lastStart;
if (TkTextIndexCmp(ixEnd, ixStart) <= 0) {
continue;
@@ -684,200 +1166,589 @@ TextWidgetCmd(clientData, interp, argc, argv)
}
}
lastStart = ixStart;
- useIdx[i] = 1;
+ useIdx[i] = 1;
}
+
/*
- * Final pass take the input from the previous and deletes
- * the ranges which are flagged to be deleted.
+ * Final pass take the input from the previous and deletes the
+ * ranges which are flagged to be deleted.
*/
- for (i = 0; i < argc; i += 2) {
+
+ for (i = 0; i < objc; i += 2) {
if (useIdx[i]) {
/*
* We don't need to check the return value because all
* indices are preparsed above.
*/
- DeleteChars(textPtr, NULL, NULL,
- &indices[i], &indices[i+1]);
+
+ DeleteIndexRange(NULL, textPtr, &indices[i],
+ &indices[i+1], 1);
}
}
ckfree((char *) indices);
}
}
- } else if ((c == 'd') && (strncmp(argv[1], "dlineinfo", length) == 0)
- && (length >= 2)) {
+ break;
+ case TEXT_DLINEINFO: {
int x, y, width, height, base;
+ const TkTextIndex *indexPtr;
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " dlineinfo index\"", (char *) NULL);
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
result = TCL_ERROR;
goto done;
}
- if (TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK) {
+ indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]);
+ if (indexPtr == NULL) {
result = TCL_ERROR;
goto done;
}
- if (TkTextDLineInfo(textPtr, &index1, &x, &y, &width, &height, &base)
- == 0) {
- char buf[TCL_INTEGER_SPACE * 5];
-
- sprintf(buf, "%d %d %d %d %d", x, y, width, height, base);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ if (TkTextDLineInfo(textPtr, indexPtr, &x, &y, &width, &height,
+ &base) == 0) {
+ Tcl_Obj *listObj = Tcl_NewListObj(0, NULL);
+
+ Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(x));
+ Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(y));
+ Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(width));
+ Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(height));
+ Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(base));
+
+ Tcl_SetObjResult(interp, listObj);
}
- } else if ((c == 'e') && (strncmp(argv[1], "edit", length) == 0)) {
- result = TextEditCmd(textPtr, interp, argc, argv);
- } else if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) {
+ break;
+ }
+ case TEXT_DUMP:
+ result = TextDumpCmd(textPtr, interp, objc, objv);
+ break;
+ case TEXT_EDIT:
+ result = TextEditCmd(textPtr, interp, objc, objv);
+ break;
+ case TEXT_GET: {
Tcl_Obj *objPtr = NULL;
- Tcl_DString ds;
- int i, found = 0;
+ int i, found = 0, visible = 0;
+ const char *name;
+ int length;
- if (argc < 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " get index1 ?index2 ...?\"", (char *) NULL);
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-displaychars? ?--? index1 ?index2 ...?");
result = TCL_ERROR;
goto done;
}
- for (i = 2; i < argc; i += 2) {
- if (TkTextGetIndex(interp, textPtr, argv[i], &index1) != TCL_OK) {
- result = TCL_ERROR;
- goto done;
+
+ /*
+ * Simple, restrictive argument parsing. The only options are -- and
+ * -displaychars (or any unique prefix).
+ */
+
+ i = 2;
+ if (objc > 3) {
+ name = Tcl_GetStringFromObj(objv[i], &length);
+ if (length > 1 && name[0] == '-') {
+ if (strncmp("-displaychars", name, (unsigned)length)==0) {
+ i++;
+ visible = 1;
+ name = Tcl_GetStringFromObj(objv[i], &length);
+ }
+ if ((i < objc-1) && (length == 2) && !strcmp("--", name)) {
+ i++;
+ }
}
- if (i+1 == argc) {
- index2 = index1;
- TkTextIndexForwChars(&index2, 1, &index2);
- } else if (TkTextGetIndex(interp, textPtr, argv[i+1], &index2)
- != TCL_OK) {
+ }
+
+ for (; i < objc; i += 2) {
+ const TkTextIndex *index1Ptr, *index2Ptr;
+ TkTextIndex index2;
+
+ index1Ptr = TkTextGetIndexFromObj(interp, textPtr, objv[i]);
+ if (index1Ptr == NULL) {
if (objPtr) {
Tcl_DecrRefCount(objPtr);
}
result = TCL_ERROR;
goto done;
}
- if (TkTextIndexCmp(&index1, &index2) < 0) {
- /*
- * Place the text in a DString and move it to the result.
- * Since this could in principle be a megabyte or more, we
- * want to do it efficiently!
+
+ if (i+1 == objc) {
+ TkTextIndexForwChars(NULL, index1Ptr, 1, &index2,
+ COUNT_INDICES);
+ index2Ptr = &index2;
+ } else {
+ index2Ptr = TkTextGetIndexFromObj(interp, textPtr, objv[i+1]);
+ if (index2Ptr == NULL) {
+ if (objPtr) {
+ Tcl_DecrRefCount(objPtr);
+ }
+ result = TCL_ERROR;
+ goto done;
+ }
+ }
+
+ if (TkTextIndexCmp(index1Ptr, index2Ptr) < 0) {
+ /*
+ * We want to move the text we get from the window into the
+ * result, but since this could in principle be a megabyte or
+ * more, we want to do it efficiently!
*/
- TextGetText(&index1, &index2, &ds);
+
+ Tcl_Obj *get = TextGetText(textPtr, index1Ptr, index2Ptr,
+ visible);
+
found++;
if (found == 1) {
- Tcl_DStringResult(interp, &ds);
+ Tcl_SetObjResult(interp, get);
} else {
if (found == 2) {
/*
- * Move the first item we put into the result into
- * the first element of the list object.
+ * Move the first item we put into the result into the
+ * first element of the list object.
*/
+
objPtr = Tcl_NewObj();
Tcl_ListObjAppendElement(NULL, objPtr,
Tcl_GetObjResult(interp));
}
- Tcl_ListObjAppendElement(NULL, objPtr,
- Tcl_NewStringObj(Tcl_DStringValue(&ds),
- Tcl_DStringLength(&ds)));
+ Tcl_ListObjAppendElement(NULL, objPtr, get);
}
- Tcl_DStringFree(&ds);
}
}
if (found > 1) {
Tcl_SetObjResult(interp, objPtr);
}
- } else if ((c == 'i') && (strncmp(argv[1], "index", length) == 0)
- && (length >= 3)) {
- char buf[200];
+ break;
+ }
+ case TEXT_IMAGE:
+ result = TkTextImageCmd(textPtr, interp, objc, objv);
+ break;
+ case TEXT_INDEX: {
+ const TkTextIndex *indexPtr;
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " index index\"",
- (char *) NULL);
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
result = TCL_ERROR;
goto done;
}
- if (TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK) {
+
+ indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]);
+ if (indexPtr == NULL) {
result = TCL_ERROR;
goto done;
}
- 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;
- CONST char **tagNames;
- TkTextTag **oldTagArrayPtr;
-
- if (argc < 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0],
- " insert index chars ?tagList chars tagList ...?\"",
- (char *) NULL);
+ Tcl_SetObjResult(interp, TkTextNewIndexObj(textPtr, indexPtr));
+ break;
+ }
+ case TEXT_INSERT: {
+ const TkTextIndex *indexPtr;
+
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "index chars ?tagList chars tagList ...?");
result = TCL_ERROR;
goto done;
}
- if (TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK) {
+ indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]);
+ if (indexPtr == NULL) {
result = TCL_ERROR;
goto done;
}
- if (textPtr->state == TK_STATE_NORMAL) {
- for (j = 3; j < argc; j += 2) {
- InsertChars(textPtr, &index1, argv[j]);
- if (argc > (j+1)) {
- TkTextIndexForwBytes(&index1, (int) strlen(argv[j]),
- &index2);
- oldTagArrayPtr = TkBTreeGetTags(&index1, &numTags);
- if (oldTagArrayPtr != NULL) {
- for (i = 0; i < numTags; i++) {
- TkBTreeTag(&index1, &index2, oldTagArrayPtr[i], 0);
- }
- ckfree((char *) oldTagArrayPtr);
- }
- if (Tcl_SplitList(interp, argv[j+1], &numTags, &tagNames)
- != TCL_OK) {
- result = TCL_ERROR;
- goto done;
- }
- for (i = 0; i < numTags; i++) {
- TkBTreeTag(&index1, &index2,
- TkTextCreateTag(textPtr, tagNames[i]), 1);
- }
- ckfree((char *) tagNames);
- index1 = index2;
+ if (textPtr->state == TK_TEXT_STATE_NORMAL) {
+ result = TextInsertCmd(NULL, textPtr, interp, objc-3, objv+3,
+ indexPtr, 1);
+ }
+ break;
+ }
+ case TEXT_MARK:
+ result = TkTextMarkCmd(textPtr, interp, objc, objv);
+ break;
+ case TEXT_PEER:
+ result = TextPeerCmd(textPtr, interp, objc, objv);
+ break;
+ case TEXT_REPLACE: {
+ const TkTextIndex *indexFromPtr, *indexToPtr;
+
+ if (objc < 5) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "index1 index2 chars ?tagList chars tagList ...?");
+ result = TCL_ERROR;
+ goto done;
+ }
+ indexFromPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]);
+ if (indexFromPtr == NULL) {
+ result = TCL_ERROR;
+ goto done;
+ }
+ indexToPtr = TkTextGetIndexFromObj(interp, textPtr, objv[3]);
+ if (indexToPtr == NULL) {
+ result = TCL_ERROR;
+ goto done;
+ }
+ if (TkTextIndexCmp(indexFromPtr, indexToPtr) > 0) {
+ Tcl_AppendResult(interp, "Index \"", Tcl_GetString(objv[3]),
+ "\" before \"", Tcl_GetString(objv[2]),
+ "\" in the text", NULL);
+ result = TCL_ERROR;
+ goto done;
+ }
+ if (textPtr->state == TK_TEXT_STATE_NORMAL) {
+ int lineNum, byteIndex;
+ TkTextIndex index;
+
+ /*
+ * The 'replace' operation is quite complex to do correctly,
+ * because we want a number of criteria to hold:
+ *
+ * 1. The insertion point shouldn't move, unless it is within the
+ * deleted range. In this case it should end up after the new
+ * text.
+ *
+ * 2. The window should not change the text it shows - should not
+ * scroll vertically - unless the result of the replace is
+ * that the insertion position which used to be on-screen is
+ * now off-screen.
+ */
+
+ byteIndex = textPtr->topIndex.byteIndex;
+ lineNum = TkBTreeLinesTo(textPtr, textPtr->topIndex.linePtr);
+
+ TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
+ if ((TkTextIndexCmp(indexFromPtr, &index) < 0)
+ && (TkTextIndexCmp(indexToPtr, &index) > 0)) {
+ /*
+ * The insertion point is inside the range to be replaced, so
+ * we have to do some calculations to ensure it doesn't move
+ * unnecessarily.
+ */
+
+ int deleteInsertOffset, insertLength, j;
+
+ insertLength = 0;
+ for (j = 4; j < objc; j += 2) {
+ insertLength += Tcl_GetCharLength(objv[j]);
}
+
+ /*
+ * Calculate 'deleteInsertOffset' as an offset we will apply
+ * to the insertion point after this operation.
+ */
+
+ deleteInsertOffset = CountIndices(textPtr, indexFromPtr,
+ &index, COUNT_CHARS);
+ if (deleteInsertOffset > insertLength) {
+ deleteInsertOffset = insertLength;
+ }
+
+ result = TextReplaceCmd(textPtr, interp, indexFromPtr,
+ indexToPtr, objc, objv, 0);
+
+ if (result == TCL_OK) {
+ /*
+ * Move the insertion position to the correct place.
+ */
+
+ TkTextIndexForwChars(NULL, indexFromPtr,
+ deleteInsertOffset, &index, COUNT_INDICES);
+ TkBTreeUnlinkSegment(textPtr->insertMarkPtr,
+ textPtr->insertMarkPtr->body.mark.linePtr);
+ TkBTreeLinkSegment(textPtr->insertMarkPtr, &index);
+ }
+ } else {
+ result = TextReplaceCmd(textPtr, interp, indexFromPtr,
+ indexToPtr, objc, objv, 1);
+ }
+ if (result == TCL_OK) {
+ /*
+ * Now ensure the top-line is in the right place.
+ */
+
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ lineNum, byteIndex, &index);
+ TkTextSetYView(textPtr, &index, TK_TEXT_NOPIXELADJUST);
}
}
- } else if ((c == 'd') && (strncmp(argv[1], "dump", length) == 0)) {
- result = TextDumpCmd(textPtr, interp, argc, argv);
- } else if ((c == 'i') && (strncmp(argv[1], "image", length) == 0)) {
- result = TkTextImageCmd(textPtr, interp, argc, argv);
- } else if ((c == 'm') && (strncmp(argv[1], "mark", length) == 0)) {
- result = TkTextMarkCmd(textPtr, interp, argc, argv);
- } else if ((c == 's') && (strcmp(argv[1], "scan") == 0) && (length >= 2)) {
- result = TkTextScanCmd(textPtr, interp, argc, argv);
- } else if ((c == 's') && (strcmp(argv[1], "search") == 0)
- && (length >= 3)) {
- result = TextSearchCmd(textPtr, interp, argc, argv);
- } else if ((c == 's') && (strcmp(argv[1], "see") == 0) && (length >= 3)) {
- result = TkTextSeeCmd(textPtr, interp, argc, argv);
- } else if ((c == 't') && (strcmp(argv[1], "tag") == 0)) {
- result = TkTextTagCmd(textPtr, interp, argc, argv);
- } else if ((c == 'w') && (strncmp(argv[1], "window", length) == 0)) {
- result = TkTextWindowCmd(textPtr, interp, argc, argv);
- } else if ((c == 'x') && (strncmp(argv[1], "xview", length) == 0)) {
- result = TkTextXviewCmd(textPtr, interp, argc, argv);
- } else if ((c == 'y') && (strncmp(argv[1], "yview", length) == 0)
- && (length >= 2)) {
- result = TkTextYviewCmd(textPtr, interp, argc, argv);
- } else {
- Tcl_AppendResult(interp, "bad option \"", argv[1],
- "\": must be bbox, cget, compare, configure, debug, delete, ",
- "dlineinfo, dump, edit, get, image, index, insert, mark, ",
- "scan, search, see, tag, window, xview, or yview",
- (char *) NULL);
- result = TCL_ERROR;
+ break;
+ }
+ case TEXT_SCAN:
+ result = TkTextScanCmd(textPtr, interp, objc, objv);
+ break;
+ case TEXT_SEARCH:
+ result = TextSearchCmd(textPtr, interp, objc, objv);
+ break;
+ case TEXT_SEE:
+ result = TkTextSeeCmd(textPtr, interp, objc, objv);
+ break;
+ case TEXT_TAG:
+ result = TkTextTagCmd(textPtr, interp, objc, objv);
+ break;
+ case TEXT_WINDOW:
+ result = TkTextWindowCmd(textPtr, interp, objc, objv);
+ break;
+ case TEXT_XVIEW:
+ result = TkTextXviewCmd(textPtr, interp, objc, objv);
+ break;
+ case TEXT_YVIEW:
+ result = TkTextYviewCmd(textPtr, interp, objc, objv);
+ break;
+ }
+
+ done:
+ textPtr->refCount--;
+ if (textPtr->refCount == 0) {
+ ckfree((char *) textPtr);
+ }
+ return result;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * SharedTextObjCmd --
+ *
+ * This function is invoked to process commands on the shared portion of
+ * a text widget. Currently it is not actually exported as a Tcl command,
+ * and is only used internally to process parts of undo/redo scripts.
+ * See the user documentation for 'text' for details on what it does -
+ * the only subcommands it currently supports are 'insert' and 'delete'.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation for "text".
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+SharedTextObjCmd(
+ ClientData clientData, /* Information about shared test B-tree. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ register TkSharedText *sharedPtr = (TkSharedText *) clientData;
+ int result = TCL_OK;
+ int index;
+
+ static const char *optionStrings[] = {
+ "delete", "insert", NULL
+ };
+ enum options {
+ TEXT_DELETE, TEXT_INSERT
+ };
+
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ switch ((enum options) index) {
+ case TEXT_DELETE:
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index1 ?index2 ...?");
+ return TCL_ERROR;
+ }
+ if (objc < 5) {
+ /*
+ * Simple case requires no predetermination of indices.
+ */
+
+ TkTextIndex index1;
+
+ /*
+ * Parse the starting and stopping indices.
+ */
+
+ result = TkTextSharedGetObjIndex(interp, sharedPtr, objv[2],
+ &index1);
+ if (result != TCL_OK) {
+ return result;
+ }
+ if (objc == 4) {
+ TkTextIndex index2;
+
+ result = TkTextSharedGetObjIndex(interp, sharedPtr, objv[3],
+ &index2);
+ if (result != TCL_OK) {
+ return result;
+ }
+ DeleteIndexRange(sharedPtr, NULL, &index1, &index2, 1);
+ } else {
+ DeleteIndexRange(sharedPtr, NULL, &index1, NULL, 1);
+ }
+ return TCL_OK;
+ } else {
+ /* Too many arguments */
+ return TCL_ERROR;
+ }
+ break;
+ case TEXT_INSERT: {
+ TkTextIndex index1;
+
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "index chars ?tagList chars tagList ...?");
+ return TCL_ERROR;
+ }
+ result = TkTextSharedGetObjIndex(interp, sharedPtr, objv[2],
+ &index1);
+ if (result != TCL_OK) {
+ return result;
+ }
+ return TextInsertCmd(sharedPtr, NULL, interp, objc-3, objv+3, &index1,
+ 1);
+ }
+ default:
+ return TCL_OK;
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TextPeerCmd --
+ *
+ * This function is invoked to process the "text peer" Tcl command. See
+ * the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+TextPeerCmd(
+ TkText *textPtr, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ Tk_Window tkwin = textPtr->tkwin;
+ int index;
+
+ static const char *peerOptionStrings[] = {
+ "create", "names", NULL
+ };
+ enum peerOptions {
+ PEER_CREATE, PEER_NAMES
+ };
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetIndexFromObj(interp, objv[2], peerOptionStrings,
+ "peer option", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ switch ((enum peerOptions)index) {
+ case PEER_CREATE:
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "pathName ?options?");
+ return TCL_ERROR;
+ }
+ return CreateWidget(textPtr->sharedTextPtr, tkwin, interp, textPtr,
+ objc-2, objv+2);
+ case PEER_NAMES: {
+ TkText *tPtr = textPtr->sharedTextPtr->peers;
+
+ if (objc > 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
+ return TCL_ERROR;
+ }
+ while (tPtr != NULL) {
+ if (tPtr != textPtr) {
+ Tcl_AppendElement(interp, Tk_PathName(tPtr->tkwin));
+ }
+ tPtr = tPtr->next;
+ }
+ }
+ }
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TextReplaceCmd --
+ *
+ * This function is invoked to process part of the "replace" widget
+ * command for text widgets.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ * If 'viewUpdate' is false, then textPtr->topIndex may no longer be a
+ * valid index after this function returns. The caller is responsible for
+ * ensuring a correct index is in place.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TextReplaceCmd(
+ TkText *textPtr, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ const TkTextIndex *indexFromPtr,
+ /* Index from which to replace. */
+ const TkTextIndex *indexToPtr,
+ /* Index to which to replace. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[], /* Argument objects. */
+ int viewUpdate) /* Update vertical view if set. */
+{
+ /*
+ * Perform the deletion and insertion, but ensure no undo-separator is
+ * placed between the two operations. Since we are using the helper
+ * functions 'DeleteIndexRange' and 'TextInsertCmd' we have to pretend
+ * that the autoSeparators setting is off, so that we don't get an
+ * undo-separator between the delete and insert.
+ */
+
+ int origAutoSep = textPtr->sharedTextPtr->autoSeparators;
+ int result, lineNumber;
+ TkTextIndex indexTmp;
+
+ if (textPtr->sharedTextPtr->undo) {
+ textPtr->sharedTextPtr->autoSeparators = 0;
+ if (origAutoSep &&
+ textPtr->sharedTextPtr->lastEditMode!=TK_TEXT_EDIT_REPLACE) {
+ TkUndoInsertUndoSeparator(textPtr->sharedTextPtr->undoStack);
+ }
+ }
+
+ /*
+ * Must save and restore line in indexFromPtr based on line number; can't
+ * keep the line itself as that might be eliminated/invalidated when
+ * deleting the range. [Bug 1602537]
+ */
+
+ indexTmp = *indexFromPtr;
+ lineNumber = TkBTreeLinesTo(textPtr, indexFromPtr->linePtr);
+ DeleteIndexRange(NULL, textPtr, indexFromPtr, indexToPtr, viewUpdate);
+ indexTmp.linePtr = TkBTreeFindLine(indexTmp.tree, textPtr, lineNumber);
+ result = TextInsertCmd(NULL, textPtr, interp, objc-4, objv+4,
+ &indexTmp, viewUpdate);
+
+ if (textPtr->sharedTextPtr->undo) {
+ textPtr->sharedTextPtr->lastEditMode = TK_TEXT_EDIT_REPLACE;
+ textPtr->sharedTextPtr->autoSeparators = origAutoSep;
}
- done:
- Tcl_Release((ClientData) textPtr);
return result;
}
@@ -886,13 +1757,13 @@ TextWidgetCmd(clientData, interp, argc, argv)
*
* TextIndexSortProc --
*
- * This procedure is called by qsort when sorting an array of
- * indices in *decreasing* order (last to first).
+ * This function is called by qsort when sorting an array of indices in
+ * *decreasing* order (last to first).
*
* Results:
- * The return value is -1 if the first argument should be before
- * the second element, 0 if it's equivalent, and 1 if it should be
- * after the second element.
+ * The return value is -1 if the first argument should be before the
+ * second element, 0 if it's equivalent, and 1 if it should be after the
+ * second element.
*
* Side effects:
* None.
@@ -901,8 +1772,9 @@ TextWidgetCmd(clientData, interp, argc, argv)
*/
static int
-TextIndexSortProc(first, second)
- CONST VOID *first, *second; /* Elements to be compared. */
+TextIndexSortProc(
+ const void *first, /* Elements to be compared. */
+ const void *second)
{
TkTextIndex *pair1 = (TkTextIndex *) first;
TkTextIndex *pair2 = (TkTextIndex *) second;
@@ -911,9 +1783,10 @@ TextIndexSortProc(first, second)
if (cmp == 0) {
/*
* If the first indices were equal, we want the second index of the
- * pair also to be the greater. Use pointer magic to access the
- * second index pair.
+ * pair also to be the greater. Use pointer magic to access the second
+ * index pair.
*/
+
cmp = TkTextIndexCmp(&pair1[0], &pair2[0]);
}
if (cmp > 0) {
@@ -929,71 +1802,168 @@ TextIndexSortProc(first, second)
*
* DestroyText --
*
- * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release
- * to clean up the internal structure of a text at a safe time
- * (when no-one is using it anymore).
+ * This function is invoked when we receive a destroy event to clean up
+ * the internal structure of a text widget. We will free up most of the
+ * internal structure and delete the associated Tcl command. If there are
+ * no outstanding references to the widget, we also free up the textPtr
+ * itself.
+ *
+ * The widget has already been flagged as deleted.
*
* Results:
* None.
*
* Side effects:
- * Everything associated with the text is freed up.
+ * Either everything or almost everything associated with the text is
+ * freed up.
*
*----------------------------------------------------------------------
*/
static void
-DestroyText(memPtr)
- char *memPtr; /* Info about text widget. */
+DestroyText(
+ TkText *textPtr) /* Info about text widget. */
{
- register TkText *textPtr = (TkText *) memPtr;
Tcl_HashSearch search;
Tcl_HashEntry *hPtr;
TkTextTag *tagPtr;
+ TkSharedText *sharedTextPtr = textPtr->sharedTextPtr;
/*
- * Free up all the stuff that requires special handling, then
- * let Tk_FreeOptions handle all the standard option-related
- * stuff. Special note: free up display-related information
- * before deleting the B-tree, since display-related stuff
- * may refer to stuff in the B-tree.
+ * Free up all the stuff that requires special handling. We have already
+ * called let Tk_FreeConfigOptions to handle all the standard
+ * option-related stuff (and so none of that exists when we are called).
+ * Special note: free up display-related information before deleting the
+ * B-tree, since display-related stuff may refer to stuff in the B-tree.
*/
TkTextFreeDInfo(textPtr);
- TkBTreeDestroy(textPtr->tree);
- for (hPtr = Tcl_FirstHashEntry(&textPtr->tagTable, &search);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr);
- TkTextFreeTag(textPtr, tagPtr);
- }
- Tcl_DeleteHashTable(&textPtr->tagTable);
- for (hPtr = Tcl_FirstHashEntry(&textPtr->markTable, &search);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- ckfree((char *) Tcl_GetHashValue(hPtr));
- }
- Tcl_DeleteHashTable(&textPtr->markTable);
+ textPtr->dInfoPtr = NULL;
+
+ /*
+ * Remove ourselves from the peer list.
+ */
+
+ if (sharedTextPtr->peers == textPtr) {
+ sharedTextPtr->peers = textPtr->next;
+ } else {
+ TkText *nextPtr = sharedTextPtr->peers;
+ while (nextPtr != NULL) {
+ if (nextPtr->next == textPtr) {
+ nextPtr->next = textPtr->next;
+ break;
+ }
+ nextPtr = nextPtr->next;
+ }
+ }
+
+ /*
+ * Always clean up the widget-specific tags first. Common tags (i.e. most)
+ * will only be cleaned up when the shared structure is cleaned up.
+ *
+ * We also need to clean up widget-specific marks ('insert', 'current'),
+ * since otherwise marks will never disappear from the B-tree.
+ */
+
+ TkTextDeleteTag(textPtr, textPtr->selTagPtr);
+ TkBTreeUnlinkSegment(textPtr->insertMarkPtr,
+ textPtr->insertMarkPtr->body.mark.linePtr);
+ ckfree((char *) textPtr->insertMarkPtr);
+ TkBTreeUnlinkSegment(textPtr->currentMarkPtr,
+ textPtr->currentMarkPtr->body.mark.linePtr);
+ ckfree((char *) textPtr->currentMarkPtr);
+
+ /*
+ * Now we've cleaned up everything of relevance to us in the B-tree, so we
+ * disassociate outselves from it.
+ *
+ * When the refCount reaches zero, it's time to clean up the shared
+ * portion of the text widget.
+ */
+
+ sharedTextPtr->refCount--;
+
+ if (sharedTextPtr->refCount > 0) {
+ TkBTreeRemoveClient(sharedTextPtr->tree, textPtr);
+
+ /*
+ * Free up any embedded windows which belong to this widget.
+ */
+
+ for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->windowTable, &search);
+ hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+ TkTextEmbWindowClient *loop;
+ TkTextSegment *ewPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+
+ loop = ewPtr->body.ew.clients;
+ if (loop->textPtr == textPtr) {
+ ewPtr->body.ew.clients = loop->next;
+ TkTextWinFreeClient(hPtr, loop);
+ } else {
+ TkTextEmbWindowClient *client = ewPtr->body.ew.clients;
+
+ client = loop->next;
+ while (client != NULL) {
+ if (client->textPtr == textPtr) {
+ loop->next = client->next;
+ TkTextWinFreeClient(hPtr, client);
+ break;
+ } else {
+ loop = loop->next;
+ }
+ client = loop->next;
+ }
+ }
+ }
+ } else {
+ /*
+ * No need to call 'TkBTreeRemoveClient' first, since this will do
+ * everything in one go, more quickly.
+ */
+
+ TkBTreeDestroy(sharedTextPtr->tree);
+
+ for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search);
+ hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+ tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr);
+
+ /*
+ * No need to use 'TkTextDeleteTag' since we've already removed
+ * the B-tree completely.
+ */
+
+ TkTextFreeTag(textPtr, tagPtr);
+ }
+ Tcl_DeleteHashTable(&sharedTextPtr->tagTable);
+ for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->markTable, &search);
+ hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+ ckfree((char *) Tcl_GetHashValue(hPtr));
+ }
+ Tcl_DeleteHashTable(&sharedTextPtr->markTable);
+ TkUndoFreeStack(sharedTextPtr->undoStack);
+
+ Tcl_DeleteHashTable(&sharedTextPtr->windowTable);
+ Tcl_DeleteHashTable(&sharedTextPtr->imageTable);
+
+ if (sharedTextPtr->bindingTable != NULL) {
+ Tk_DeleteBindingTable(sharedTextPtr->bindingTable);
+ }
+ ckfree((char *) sharedTextPtr);
+ }
+
if (textPtr->tabArrayPtr != NULL) {
ckfree((char *) textPtr->tabArrayPtr);
}
if (textPtr->insertBlinkHandler != NULL) {
Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler);
}
- if (textPtr->bindingTable != NULL) {
- Tk_DeleteBindingTable(textPtr->bindingTable);
- }
- TkUndoFreeStack(textPtr->undoStack);
- /*
- * NOTE: do NOT free up selBorder, selBdString, or selFgColorPtr:
- * they are duplicates of information in the "sel" tag, which was
- * freed up as part of deleting the tags above.
- */
-
- textPtr->selBorder = NULL;
- textPtr->selBdString = NULL;
- textPtr->selFgColorPtr = NULL;
- Tk_FreeOptions(configSpecs, (char *) textPtr, textPtr->display, 0);
- ckfree((char *) textPtr);
+ textPtr->tkwin = NULL;
+ textPtr->refCount--;
+ Tcl_DeleteCommandFromToken(textPtr->interp, textPtr->widgetCmd);
+ if (textPtr->refCount == 0) {
+ ckfree((char *) textPtr);
+ }
}
/*
@@ -1001,47 +1971,165 @@ DestroyText(memPtr)
*
* ConfigureText --
*
- * This procedure is called to process an argv/argc list, plus
- * the Tk option database, in order to configure (or
- * reconfigure) a text widget.
+ * This function is called to process an objv/objc list, plus the Tk
+ * option database, in order to configure (or reconfigure) a text widget.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message.
+ * 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 text string, colors, font,
- * etc. get set for textPtr; old resources get freed, if there
- * were any.
+ * Configuration information, such as text string, colors, font, etc. get
+ * set for textPtr; old resources get freed, if there were any.
*
*----------------------------------------------------------------------
*/
static int
-ConfigureText(interp, textPtr, argc, argv, flags)
- Tcl_Interp *interp; /* Used for error reporting. */
- register TkText *textPtr; /* Information about widget; may or may
- * not already have values for some fields. */
- int argc; /* Number of valid entries in argv. */
- CONST char **argv; /* Arguments. */
- int flags; /* Flags to pass to Tk_ConfigureWidget. */
+ConfigureText(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ register TkText *textPtr, /* Information about widget; may or may not
+ * already have values for some fields. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
+ Tk_SavedOptions savedOptions;
int oldExport = textPtr->exportSelection;
+ int mask = 0;
- if (Tk_ConfigureWidget(interp, textPtr->tkwin, configSpecs,
- argc, argv, (char *) textPtr, flags) != TCL_OK) {
+ if (Tk_SetOptions(interp, (char *) textPtr, textPtr->optionTable,
+ objc, objv, textPtr->tkwin, &savedOptions, &mask) != TCL_OK) {
return TCL_ERROR;
}
- TkUndoSetDepth(textPtr->undoStack, textPtr->maxUndo);
+ /*
+ * Copy down shared flags.
+ */
+
+ textPtr->sharedTextPtr->undo = textPtr->undo;
+ textPtr->sharedTextPtr->maxUndo = textPtr->maxUndo;
+ textPtr->sharedTextPtr->autoSeparators = textPtr->autoSeparators;
+
+ TkUndoSetDepth(textPtr->sharedTextPtr->undoStack,
+ textPtr->sharedTextPtr->maxUndo);
/*
- * A few other options also need special processing, such as parsing
- * the geometry and setting the background from a 3-D border.
+ * A few other options also need special processing, such as parsing the
+ * geometry and setting the background from a 3-D border.
*/
Tk_SetBackgroundFromBorder(textPtr->tkwin, textPtr->border);
+ if (mask & TK_TEXT_LINE_RANGE) {
+ int start, end, current;
+ TkTextIndex index1, index2, index3;
+
+ /*
+ * Line start and/or end have been adjusted. We need to validate the
+ * first displayed line and arrange for re-layout.
+ */
+
+ TkBTreeClientRangeChanged(textPtr, textPtr->charHeight);
+
+ if (textPtr->start != NULL) {
+ start = TkBTreeLinesTo(NULL, textPtr->start);
+ } else {
+ start = 0;
+ }
+ if (textPtr->end != NULL) {
+ end = TkBTreeLinesTo(NULL, textPtr->end);
+ } else {
+ end = TkBTreeNumLines(textPtr->sharedTextPtr->tree, NULL);
+ }
+ if (start > end) {
+ Tcl_AppendResult(interp,
+ "-startline must be less than or equal to -endline",
+ NULL);
+ Tk_RestoreSavedOptions(&savedOptions);
+ return TCL_ERROR;
+ }
+ current = TkBTreeLinesTo(NULL, textPtr->topIndex.linePtr);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, start, 0,
+ &index1);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, end, 0,
+ &index2);
+ if (current < start || current > end) {
+ TkTextSearch search;
+ TkTextIndex first, last;
+ int selChanged = 0;
+
+ TkTextSetYView(textPtr, &index1, 0);
+
+ /*
+ * We may need to adjust the selection. So we have to check
+ * whether the "sel" tag was applied to anything outside the
+ * current start,end.
+ */
+
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, 0, 0,
+ &first);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, NULL),
+ 0, &last);
+ TkBTreeStartSearch(&first, &last, textPtr->selTagPtr, &search);
+ if (!TkBTreeCharTagged(&first, textPtr->selTagPtr)
+ && !TkBTreeNextTag(&search)) {
+ /* Nothing tagged with "sel" */
+ } else {
+ int line = TkBTreeLinesTo(NULL, search.curIndex.linePtr);
+ if (line < start) {
+ selChanged = 1;
+ } else {
+ TkTextLine *linePtr = search.curIndex.linePtr;
+
+ while (TkBTreeNextTag(&search)) {
+ linePtr = search.curIndex.linePtr;
+ }
+ line = TkBTreeLinesTo(NULL, linePtr);
+ if (line >= end) {
+ selChanged = 1;
+ }
+ }
+ }
+ if (selChanged) {
+ /*
+ * Send an event that the selection has changed, and abort any
+ * partial-selections in progress.
+ */
+
+ TkTextSelectionEvent(textPtr);
+ textPtr->abortSelections = 1;
+ }
+ }
+
+ /* Indices are potentially obsolete after changing -startline and/or
+ * -endline, therefore increase the epoch.
+ * Also, clamp the insert and current (unshared) marks to the new
+ * -startline/-endline range limits of the widget. All other (shared)
+ * marks are unchanged.
+ * The return value of TkTextMarkNameToIndex does not need to be
+ * checked: "insert" and "current" marks always exist, and the
+ * purpose of the code below precisely is to move them inside the
+ * -startline/-endline range.
+ */
+
+ textPtr->sharedTextPtr->stateEpoch++;
+ TkTextMarkNameToIndex(textPtr, "insert", &index3);
+ if (TkTextIndexCmp(&index3, &index1) < 0) {
+ textPtr->insertMarkPtr = TkTextSetMark(textPtr, "insert", &index1);
+ }
+ if (TkTextIndexCmp(&index3, &index2) > 0) {
+ textPtr->insertMarkPtr = TkTextSetMark(textPtr, "insert", &index2);
+ }
+ TkTextMarkNameToIndex(textPtr, "current", &index3);
+ if (TkTextIndexCmp(&index3, &index1) < 0) {
+ textPtr->currentMarkPtr = TkTextSetMark(textPtr, "current", &index1);
+ }
+ if (TkTextIndexCmp(&index3, &index2) > 0) {
+ textPtr->currentMarkPtr = TkTextSetMark(textPtr, "current", &index2);
+ }
+ }
+
/*
* Don't allow negative spacings.
*/
@@ -1064,62 +2152,56 @@ ConfigureText(interp, textPtr, argc, argv, flags)
ckfree((char *) textPtr->tabArrayPtr);
textPtr->tabArrayPtr = NULL;
}
- if (textPtr->tabOptionString != NULL) {
- textPtr->tabArrayPtr = TkTextGetTabs(interp, textPtr->tkwin,
- textPtr->tabOptionString);
+ if (textPtr->tabOptionPtr != NULL) {
+ textPtr->tabArrayPtr = TkTextGetTabs(interp, textPtr,
+ textPtr->tabOptionPtr);
if (textPtr->tabArrayPtr == NULL) {
Tcl_AddErrorInfo(interp,"\n (while processing -tabs option)");
+ Tk_RestoreSavedOptions(&savedOptions);
return TCL_ERROR;
}
}
/*
- * Make sure that configuration options are properly mirrored
- * between the widget record and the "sel" tags. NOTE: we don't
- * have to free up information during the mirroring; old
- * information was freed when it was replaced in the widget
- * record.
+ * Make sure that configuration options are properly mirrored between the
+ * widget record and the "sel" tags. NOTE: we don't have to free up
+ * information during the mirroring; old information was freed when it was
+ * replaced in the widget record.
*/
textPtr->selTagPtr->border = textPtr->selBorder;
- if (textPtr->selTagPtr->bdString != textPtr->selBdString) {
- textPtr->selTagPtr->bdString = textPtr->selBdString;
- if (textPtr->selBdString != NULL) {
- if (Tk_GetPixels(interp, textPtr->tkwin, textPtr->selBdString,
- &textPtr->selTagPtr->borderWidth) != TCL_OK) {
- return TCL_ERROR;
- }
- if (textPtr->selTagPtr->borderWidth < 0) {
- textPtr->selTagPtr->borderWidth = 0;
- }
- }
+ if (textPtr->selTagPtr->borderWidthPtr != textPtr->selBorderWidthPtr) {
+ textPtr->selTagPtr->borderWidthPtr = textPtr->selBorderWidthPtr;
+ textPtr->selTagPtr->borderWidth = textPtr->selBorderWidth;
}
textPtr->selTagPtr->fgColor = textPtr->selFgColorPtr;
textPtr->selTagPtr->affectsDisplay = 0;
- if ((textPtr->selTagPtr->border != NULL)
- || (textPtr->selTagPtr->bdString != NULL)
- || (textPtr->selTagPtr->reliefString != NULL)
- || (textPtr->selTagPtr->bgStipple != None)
- || (textPtr->selTagPtr->fgColor != NULL)
+ textPtr->selTagPtr->affectsDisplayGeometry = 0;
+ if ((textPtr->selTagPtr->elideString != NULL)
|| (textPtr->selTagPtr->tkfont != None)
- || (textPtr->selTagPtr->fgStipple != None)
|| (textPtr->selTagPtr->justifyString != NULL)
|| (textPtr->selTagPtr->lMargin1String != NULL)
|| (textPtr->selTagPtr->lMargin2String != NULL)
|| (textPtr->selTagPtr->offsetString != NULL)
- || (textPtr->selTagPtr->overstrikeString != NULL)
|| (textPtr->selTagPtr->rMarginString != NULL)
|| (textPtr->selTagPtr->spacing1String != NULL)
|| (textPtr->selTagPtr->spacing2String != NULL)
|| (textPtr->selTagPtr->spacing3String != NULL)
- || (textPtr->selTagPtr->tabString != NULL)
- || (textPtr->selTagPtr->underlineString != NULL)
- || (textPtr->selTagPtr->elideString != NULL)
+ || (textPtr->selTagPtr->tabStringPtr != NULL)
|| (textPtr->selTagPtr->wrapMode != TEXT_WRAPMODE_NULL)) {
textPtr->selTagPtr->affectsDisplay = 1;
+ textPtr->selTagPtr->affectsDisplayGeometry = 1;
}
- TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, (TkTextIndex *) NULL,
- textPtr->selTagPtr, 1);
+ if ((textPtr->selTagPtr->border != NULL)
+ || (textPtr->selTagPtr->reliefString != NULL)
+ || (textPtr->selTagPtr->bgStipple != None)
+ || (textPtr->selTagPtr->fgColor != NULL)
+ || (textPtr->selTagPtr->fgStipple != None)
+ || (textPtr->selTagPtr->overstrikeString != NULL)
+ || (textPtr->selTagPtr->underlineString != NULL)) {
+ textPtr->selTagPtr->affectsDisplay = 1;
+ }
+ TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr, 1);
/*
* Claim the selection if we've suddenly started exporting it and there
@@ -1130,9 +2212,11 @@ ConfigureText(interp, textPtr, argc, argv, flags)
TkTextSearch search;
TkTextIndex first, last;
- TkTextMakeByteIndex(textPtr->tree, 0, 0, &first);
- TkTextMakeByteIndex(textPtr->tree,
- TkBTreeNumLines(textPtr->tree), 0, &last);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0,
+ &first);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr),
+ 0, &last);
TkBTreeStartSearch(&first, &last, textPtr->selTagPtr, &search);
if (TkBTreeCharTagged(&first, textPtr->selTagPtr)
|| TkBTreeNextTag(&search)) {
@@ -1153,8 +2237,8 @@ ConfigureText(interp, textPtr, argc, argv, flags)
}
/*
- * Register the desired geometry for the window, and arrange for
- * the window to be redisplayed.
+ * Register the desired geometry for the window, and arrange for the
+ * window to be redisplayed.
*/
if (textPtr->width <= 0) {
@@ -1163,60 +2247,97 @@ ConfigureText(interp, textPtr, argc, argv, flags)
if (textPtr->height <= 0) {
textPtr->height = 1;
}
- TextWorldChanged((ClientData) textPtr);
+ Tk_FreeSavedOptions(&savedOptions);
+ TextWorldChanged(textPtr, mask);
return TCL_OK;
}
/*
*---------------------------------------------------------------------------
*
- * TextWorldChanged --
+ * TextWorldChangedCallback --
*
- * This procedure is called when the world has changed in some
- * way and the widget needs to recompute all its graphics contexts
- * and determine its new geometry.
+ * This function is called when the world has changed in some way and the
+ * widget needs to recompute all its graphics contexts and determine its
+ * new geometry.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Configures all tags in the Text with a empty argc/argv, for
- * the side effect of causing all the items to recompute their
- * geometry and to be redisplayed.
+ * Configures all tags in the Text with a empty objc/objv, for the side
+ * effect of causing all the items to recompute their geometry and to be
+ * redisplayed.
*
*---------------------------------------------------------------------------
*/
-
+
static void
-TextWorldChanged(instanceData)
- ClientData instanceData; /* Information about widget. */
+TextWorldChangedCallback(
+ ClientData instanceData) /* Information about widget. */
{
TkText *textPtr;
- Tk_FontMetrics fm;
textPtr = (TkText *) instanceData;
+ TextWorldChanged(textPtr, TK_TEXT_LINE_GEOMETRY);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TextWorldChanged --
+ *
+ * This function is called when the world has changed in some way and the
+ * widget needs to recompute all its graphics contexts and determine its
+ * new geometry.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Configures all tags in the Text with a empty objc/objv, for the side
+ * effect of causing all the items to recompute their geometry and to be
+ * redisplayed.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+TextWorldChanged(
+ TkText *textPtr, /* Information about widget. */
+ int mask) /* OR'd collection of bits showing what has
+ * changed. */
+{
+ Tk_FontMetrics fm;
+ int border;
textPtr->charWidth = Tk_TextWidth(textPtr->tkfont, "0", 1);
if (textPtr->charWidth <= 0) {
textPtr->charWidth = 1;
}
Tk_GetFontMetrics(textPtr->tkfont, &fm);
+
+ textPtr->charHeight = fm.linespace;
+ if (textPtr->charHeight <= 0) {
+ textPtr->charHeight = 1;
+ }
+ border = textPtr->borderWidth + textPtr->highlightWidth;
Tk_GeometryRequest(textPtr->tkwin,
- textPtr->width * textPtr->charWidth + 2*textPtr->borderWidth
- + 2*textPtr->padX + 2*textPtr->highlightWidth,
- textPtr->height * (fm.linespace + textPtr->spacing1
- + textPtr->spacing3) + 2*textPtr->borderWidth
- + 2*textPtr->padY + 2*textPtr->highlightWidth);
- Tk_SetInternalBorder(textPtr->tkwin,
- textPtr->borderWidth + textPtr->highlightWidth);
+ textPtr->width * textPtr->charWidth + 2*textPtr->padX + 2*border,
+ textPtr->height*(fm.linespace+textPtr->spacing1+textPtr->spacing3)
+ + 2*textPtr->padY + 2*border);
+
+ Tk_SetInternalBorderEx(textPtr->tkwin,
+ border + textPtr->padX, border + textPtr->padX,
+ border + textPtr->padY, border + textPtr->padY);
if (textPtr->setGrid) {
Tk_SetGrid(textPtr->tkwin, textPtr->width, textPtr->height,
- textPtr->charWidth, fm.linespace);
+ textPtr->charWidth, textPtr->charHeight);
} else {
Tk_UnsetGrid(textPtr->tkwin);
}
- TkTextRelayoutWindow(textPtr);
+ TkTextRelayoutWindow(textPtr, mask);
}
/*
@@ -1224,24 +2345,24 @@ TextWorldChanged(instanceData)
*
* TextEventProc --
*
- * This procedure is invoked by the Tk dispatcher on
- * structure changes to a text. For texts with 3D
- * borders, this procedure is also invoked for exposures.
+ * This function is invoked by the Tk dispatcher on structure changes to
+ * a text. For texts with 3D borders, this function is also invoked for
+ * exposures.
*
* Results:
* None.
*
* Side effects:
- * When the window gets deleted, internal structures get
- * cleaned up. When it gets exposed, it is redisplayed.
+ * When the window gets deleted, internal structures get cleaned up.
+ * When it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-TextEventProc(clientData, eventPtr)
- ClientData clientData; /* Information about window. */
- register XEvent *eventPtr; /* Information about event. */
+TextEventProc(
+ ClientData clientData, /* Information about window. */
+ register XEvent *eventPtr) /* Information about event. */
{
register TkText *textPtr = (TkText *) clientData;
TkTextIndex index, index2;
@@ -1253,22 +2374,51 @@ TextEventProc(clientData, eventPtr)
} else if (eventPtr->type == ConfigureNotify) {
if ((textPtr->prevWidth != Tk_Width(textPtr->tkwin))
|| (textPtr->prevHeight != Tk_Height(textPtr->tkwin))) {
- TkTextRelayoutWindow(textPtr);
+ int mask = 0;
+
+ if (textPtr->prevWidth != Tk_Width(textPtr->tkwin)) {
+ mask = TK_TEXT_LINE_GEOMETRY;
+ }
+ TkTextRelayoutWindow(textPtr, mask);
textPtr->prevWidth = Tk_Width(textPtr->tkwin);
textPtr->prevHeight = Tk_Height(textPtr->tkwin);
}
} else if (eventPtr->type == DestroyNotify) {
- if (textPtr->tkwin != NULL) {
- if (textPtr->setGrid) {
- Tk_UnsetGrid(textPtr->tkwin);
- }
- textPtr->tkwin = NULL;
- Tcl_DeleteCommandFromToken(textPtr->interp,
- textPtr->widgetCmd);
+ /*
+ * NOTE: we must zero out selBorder, selBorderWidthPtr and
+ * selFgColorPtr: they are duplicates of information in the "sel" tag,
+ * which will be freed up when we delete all tags. Hence we don't want
+ * the automatic config options freeing process to delete them as
+ * well.
+ */
+
+ textPtr->selBorder = NULL;
+ textPtr->selBorderWidthPtr = NULL;
+ textPtr->selBorderWidth = 0;
+ textPtr->selFgColorPtr = NULL;
+ if (textPtr->setGrid) {
+ Tk_UnsetGrid(textPtr->tkwin);
+ textPtr->setGrid = 0;
}
- Tcl_EventuallyFree((ClientData) textPtr, DestroyText);
+ if (!(textPtr->flags & OPTIONS_FREED)) {
+ Tk_FreeConfigOptions((char *) textPtr, textPtr->optionTable,
+ textPtr->tkwin);
+ textPtr->flags |= OPTIONS_FREED;
+ }
+ textPtr->flags |= DESTROYED;
+
+ /*
+ * Call 'DestroyTest' to handle the deletion for us. The actual
+ * textPtr may still exist after this, if there are some outstanding
+ * references. But we have flagged it as DESTROYED just above, so
+ * nothing will try to make use of it very extensively.
+ */
+
+ DestroyText(textPtr);
} else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) {
- if (eventPtr->xfocus.detail != NotifyInferior) {
+ if (eventPtr->xfocus.detail == NotifyInferior
+ || eventPtr->xfocus.detail == NotifyAncestor
+ || eventPtr->xfocus.detail == NotifyNonlinear) {
Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler);
if (eventPtr->type == FocusIn) {
textPtr->flags |= GOT_FOCUS | INSERT_ON;
@@ -1281,19 +2431,19 @@ TextEventProc(clientData, eventPtr)
textPtr->flags &= ~(GOT_FOCUS | INSERT_ON);
textPtr->insertBlinkHandler = (Tcl_TimerToken) NULL;
}
- if (
-#ifndef MAC_OSX_TK
- !TkpAlwaysShowSelection(textPtr->tkwin)
-#else
- /* Don't show inactive selection in disabled widgets. */
- textPtr->state != TK_STATE_DISABLED
-#endif
- ) {
- TkTextRedrawTag(textPtr, NULL, NULL, textPtr->selTagPtr, 1);
+ if (textPtr->inactiveSelBorder != textPtr->selBorder) {
+ TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr,
+ 1);
}
TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
- TkTextIndexForwChars(&index, 1, &index2);
- TkTextChanged(textPtr, &index, &index2);
+ TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES);
+
+ /*
+ * While we wish to redisplay, no heights have changed, so no need
+ * to call TkTextInvalidateLineMetrics.
+ */
+
+ TkTextChanged(NULL, textPtr, &index, &index2);
if (textPtr->highlightWidth > 0) {
TkTextRedrawRegion(textPtr, 0, 0, textPtr->highlightWidth,
textPtr->highlightWidth);
@@ -1307,9 +2457,9 @@ TextEventProc(clientData, eventPtr)
*
* TextCmdDeletedProc --
*
- * 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.
+ * This function 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.
@@ -1321,24 +2471,25 @@ TextEventProc(clientData, eventPtr)
*/
static void
-TextCmdDeletedProc(clientData)
- ClientData clientData; /* Pointer to widget record for widget. */
+TextCmdDeletedProc(
+ ClientData clientData) /* Pointer to widget record for widget. */
{
TkText *textPtr = (TkText *) clientData;
Tk_Window tkwin = textPtr->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.
+ * This function could be invoked either because the window was destroyed
+ * and the command was then deleted (in which this flag is already set) or
+ * because the command was deleted, and then this function destroys the
+ * widget.
*/
- if (tkwin != NULL) {
+ if (!(textPtr->flags & DESTROYED)) {
if (textPtr->setGrid) {
Tk_UnsetGrid(textPtr->tkwin);
+ textPtr->setGrid = 0;
}
- textPtr->tkwin = NULL;
+ textPtr->flags |= DESTROYED;
Tk_DestroyWindow(tkwin);
}
}
@@ -1348,205 +2499,483 @@ TextCmdDeletedProc(clientData)
*
* InsertChars --
*
- * This procedure implements most of the functionality of the
- * "insert" widget command.
+ * This function implements most of the functionality of the "insert"
+ * widget command.
*
* Results:
- * None.
+ * The length of the inserted string.
*
* Side effects:
- * The characters in "string" get added to the text just before
- * the character indicated by "indexPtr".
+ * The characters in "stringPtr" get added to the text just before the
+ * character indicated by "indexPtr".
+ *
+ * If 'viewUpdate' is true, we may adjust the window contents'
+ * y-position, and scrollbar setting.
*
*----------------------------------------------------------------------
*/
-static void
-InsertChars(textPtr, indexPtr, string)
- TkText *textPtr; /* Overall information about text widget. */
- TkTextIndex *indexPtr; /* Where to insert new characters. May be
- * modified and/or invalidated. */
- CONST char *string; /* Null-terminated string containing new
+static int
+InsertChars(
+ TkSharedText *sharedTextPtr,
+ TkText *textPtr, /* Overall information about text widget. */
+ TkTextIndex *indexPtr, /* Where to insert new characters. May be
+ * modified if the index is not valid for
+ * insertion (e.g. if at "end"). */
+ Tcl_Obj *stringPtr, /* Null-terminated string containing new
* information to add to text. */
+ int viewUpdate) /* Update the view if set. */
{
- int lineIndex, resetView, offset;
- TkTextIndex newTop;
- char indexBuffer[TK_POS_CHARS];
+ int lineIndex, length;
+ TkText *tPtr;
+ int *lineAndByteIndex;
+ int resetViewCount;
+ int pixels[2*PIXEL_CLIENTS];
- /*
- * Don't do anything for an empty string [Bug 1275237]
- */
+ const char *string = Tcl_GetStringFromObj(stringPtr, &length);
- if (*string == '\0') {
- return;
+ if (sharedTextPtr == NULL) {
+ sharedTextPtr = textPtr->sharedTextPtr;
}
/*
- * Don't allow insertions on the last (dummy) line of the text.
+ * Don't allow insertions on the last (dummy) line of the text. This is
+ * the only place in this function where the indexPtr is modified.
*/
- lineIndex = TkBTreeLineIndex(indexPtr->linePtr);
- if (lineIndex == TkBTreeNumLines(textPtr->tree)) {
+ lineIndex = TkBTreeLinesTo(textPtr, indexPtr->linePtr);
+ if (lineIndex == TkBTreeNumLines(sharedTextPtr->tree, textPtr)) {
lineIndex--;
- TkTextMakeByteIndex(textPtr->tree, lineIndex, 1000000, indexPtr);
+ TkTextMakeByteIndex(sharedTextPtr->tree, textPtr, lineIndex, 1000000,
+ indexPtr);
}
/*
- * Notify the display module that lines are about to change, then do
- * the insertion. If the insertion occurs on the top line of the
- * widget (textPtr->topIndex), then we have to recompute topIndex
- * after the insertion, since the insertion could invalidate it.
+ * Notify the display module that lines are about to change, then do the
+ * insertion. If the insertion occurs on the top line of the widget
+ * (textPtr->topIndex), then we have to recompute topIndex after the
+ * insertion, since the insertion could invalidate it.
*/
- resetView = offset = 0;
- if (indexPtr->linePtr == textPtr->topIndex.linePtr) {
- resetView = 1;
- offset = textPtr->topIndex.byteIndex;
- if (offset > indexPtr->byteIndex) {
- offset += strlen(string);
+ resetViewCount = 0;
+ if (sharedTextPtr->refCount > PIXEL_CLIENTS) {
+ lineAndByteIndex = (int *)
+ ckalloc(sizeof(int) * 2 * sharedTextPtr->refCount);
+ } else {
+ lineAndByteIndex = pixels;
+ }
+ for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) {
+ lineAndByteIndex[resetViewCount] = -1;
+ if (indexPtr->linePtr == tPtr->topIndex.linePtr) {
+ lineAndByteIndex[resetViewCount] =
+ TkBTreeLinesTo(tPtr, indexPtr->linePtr);
+ lineAndByteIndex[resetViewCount+1] = tPtr->topIndex.byteIndex;
+ if (lineAndByteIndex[resetViewCount+1] > indexPtr->byteIndex) {
+ lineAndByteIndex[resetViewCount+1] += length;
+ }
}
+ resetViewCount += 2;
}
- TkTextChanged(textPtr, indexPtr, indexPtr);
- TkBTreeInsertChars(indexPtr, string);
+
+ TkTextChanged(sharedTextPtr, NULL, indexPtr, indexPtr);
+
+ sharedTextPtr->stateEpoch++;
+
+ TkBTreeInsertChars(sharedTextPtr->tree, indexPtr, string);
/*
- * Push the insertion on the undo stack
+ * Push the insertion on the undo stack, and update the modified status of
+ * the widget.
*/
- if (textPtr->undo) {
- CONST char *cmdName;
- TkTextIndex toIndex;
+ if (length > 0) {
+ if (sharedTextPtr->undo) {
+ TkTextIndex toIndex;
+
+ if (sharedTextPtr->autoSeparators &&
+ sharedTextPtr->lastEditMode != TK_TEXT_EDIT_INSERT) {
+ TkUndoInsertUndoSeparator(sharedTextPtr->undoStack);
+ }
- Tcl_DString actionCommand;
- Tcl_DString revertCommand;
+ sharedTextPtr->lastEditMode = TK_TEXT_EDIT_INSERT;
- if (textPtr->autoSeparators &&
- textPtr->lastEditMode != TK_TEXT_EDIT_INSERT) {
- TkUndoInsertUndoSeparator(textPtr->undoStack);
+ TkTextIndexForwBytes(textPtr, indexPtr, length, &toIndex);
+ TextPushUndoAction(textPtr, stringPtr, 1, indexPtr, &toIndex);
}
- textPtr->lastEditMode = TK_TEXT_EDIT_INSERT;
- cmdName = Tcl_GetCommandName(textPtr->interp, textPtr->widgetCmd);
+ UpdateDirtyFlag(sharedTextPtr);
+ }
+
+ resetViewCount = 0;
+ for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) {
+ if (lineAndByteIndex[resetViewCount] != -1) {
+ if ((tPtr != textPtr) || viewUpdate) {
+ TkTextIndex newTop;
+
+ TkTextMakeByteIndex(sharedTextPtr->tree, tPtr,
+ lineAndByteIndex[resetViewCount], 0, &newTop);
+ TkTextIndexForwBytes(tPtr, &newTop,
+ lineAndByteIndex[resetViewCount+1], &newTop);
+ TkTextSetYView(tPtr, &newTop, 0);
+ }
+ }
+ resetViewCount += 2;
+ }
+ if (sharedTextPtr->refCount > PIXEL_CLIENTS) {
+ ckfree((char *) lineAndByteIndex);
+ }
+
+ /*
+ * Invalidate any selection retrievals in progress.
+ */
+
+ for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) {
+ tPtr->abortSelections = 1;
+ }
- Tcl_DStringInit(&actionCommand);
- Tcl_DStringInit(&revertCommand);
+ /*
+ * For convenience, return the length of the string.
+ */
- Tcl_DStringAppendElement(&actionCommand, cmdName);
- Tcl_DStringAppend(&actionCommand, " insert ", -1);
- TkTextPrintIndex(indexPtr,indexBuffer);
- Tcl_DStringAppend(&actionCommand, indexBuffer, -1);
- Tcl_DStringAppend(&actionCommand, " ", -1);
- Tcl_DStringAppendElement(&actionCommand, string);
- Tcl_DStringAppend(&actionCommand, ";", -1);
- Tcl_DStringAppendElement(&actionCommand, cmdName);
- Tcl_DStringAppend(&actionCommand, " mark set insert ", -1);
- TkTextIndexForwBytes(indexPtr, (int) strlen(string), &toIndex);
- TkTextPrintIndex(&toIndex, indexBuffer);
- Tcl_DStringAppend(&actionCommand, indexBuffer,-1);
- Tcl_DStringAppend(&actionCommand, "; ", -1);
- Tcl_DStringAppendElement(&actionCommand, cmdName);
- Tcl_DStringAppend(&actionCommand, " see insert", -1);
+ return length;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TextPushUndoAction --
+ *
+ * Shared by insert and delete actions. Stores the appropriate scripts
+ * into our undo stack. We will add a single refCount to the 'undoString'
+ * object, so, if it previously had a refCount of zero, the caller should
+ * not free it.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Items pushed onto stack.
+ *
+ *----------------------------------------------------------------------
+ */
- Tcl_DStringAppendElement(&revertCommand, cmdName);
- Tcl_DStringAppend(&revertCommand, " delete ", -1);
- TkTextPrintIndex(indexPtr, indexBuffer);
- Tcl_DStringAppend(&revertCommand, indexBuffer, -1);
- Tcl_DStringAppend(&revertCommand, " ", -1);
- TkTextPrintIndex(&toIndex, indexBuffer);
- Tcl_DStringAppend(&revertCommand, indexBuffer, -1);
- Tcl_DStringAppend(&revertCommand, " ;", -1);
- Tcl_DStringAppendElement(&revertCommand, cmdName);
- Tcl_DStringAppend(&revertCommand, " mark set insert ", -1);
- TkTextPrintIndex(indexPtr,indexBuffer);
- Tcl_DStringAppend(&revertCommand, indexBuffer, -1);
- Tcl_DStringAppend(&revertCommand, "; ", -1);
- Tcl_DStringAppendElement(&revertCommand, cmdName);
- Tcl_DStringAppend(&revertCommand," see insert", -1);
+static void
+TextPushUndoAction(
+ TkText *textPtr, /* Overall information about text widget. */
+ Tcl_Obj *undoString, /* New text. */
+ int insert, /* 1 if insert, else delete. */
+ const TkTextIndex *index1Ptr,
+ /* Index describing first location. */
+ const TkTextIndex *index2Ptr)
+ /* Index describing second location. */
+{
+ TkUndoSubAtom *iAtom, *dAtom;
- TkUndoPushAction(textPtr->undoStack, &actionCommand, &revertCommand);
+ /*
+ * Create the helpers.
+ */
- Tcl_DStringFree(&actionCommand);
- Tcl_DStringFree(&revertCommand);
+ Tcl_Obj *seeInsertObj = Tcl_NewObj();
+ Tcl_Obj *markSet1InsertObj = Tcl_NewObj();
+ Tcl_Obj *markSet2InsertObj = NULL;
+ Tcl_Obj *insertCmdObj = Tcl_NewObj();
+ Tcl_Obj *deleteCmdObj = Tcl_NewObj();
+
+ /*
+ * Get the index positions.
+ */
+
+ Tcl_Obj *index1Obj = TkTextNewIndexObj(NULL, index1Ptr);
+ Tcl_Obj *index2Obj = TkTextNewIndexObj(NULL, index2Ptr);
+
+ /*
+ * These need refCounts, because they are used more than once below.
+ */
+
+ Tcl_IncrRefCount(seeInsertObj);
+ Tcl_IncrRefCount(index1Obj);
+ Tcl_IncrRefCount(index2Obj);
+
+ Tcl_ListObjAppendElement(NULL, seeInsertObj,
+ Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1));
+ Tcl_ListObjAppendElement(NULL, seeInsertObj, Tcl_NewStringObj("see", 3));
+ Tcl_ListObjAppendElement(NULL, seeInsertObj,
+ Tcl_NewStringObj("insert", 6));
+
+ Tcl_ListObjAppendElement(NULL, markSet1InsertObj,
+ Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1));
+ Tcl_ListObjAppendElement(NULL, markSet1InsertObj,
+ Tcl_NewStringObj("mark", 4));
+ Tcl_ListObjAppendElement(NULL, markSet1InsertObj,
+ Tcl_NewStringObj("set", 3));
+ Tcl_ListObjAppendElement(NULL, markSet1InsertObj,
+ Tcl_NewStringObj("insert", 6));
+ markSet2InsertObj = Tcl_DuplicateObj(markSet1InsertObj);
+ Tcl_ListObjAppendElement(NULL, markSet1InsertObj, index1Obj);
+ Tcl_ListObjAppendElement(NULL, markSet2InsertObj, index2Obj);
+
+ Tcl_ListObjAppendElement(NULL, insertCmdObj,
+ Tcl_NewStringObj("insert", 6));
+ Tcl_ListObjAppendElement(NULL, insertCmdObj, index1Obj);
+
+ /*
+ * Only use of 'undoString' is here.
+ */
+
+ Tcl_ListObjAppendElement(NULL, insertCmdObj, undoString);
+
+ Tcl_ListObjAppendElement(NULL, deleteCmdObj,
+ Tcl_NewStringObj("delete", 6));
+ Tcl_ListObjAppendElement(NULL, deleteCmdObj, index1Obj);
+ Tcl_ListObjAppendElement(NULL, deleteCmdObj, index2Obj);
+
+ /*
+ * Note: we don't wish to use textPtr->widgetCmd in these callbacks
+ * because if we delete the textPtr, but peers still exist, we will then
+ * have references to a non-existent Tcl_Command in the undo stack, which
+ * will lead to crashes later. Also, the behaviour of the widget w.r.t.
+ * bindings (%W substitutions) always uses the widget path name, so there
+ * is no good reason the undo stack should do otherwise.
+ *
+ * For the 'insert' and 'delete' actions, we have to register a functional
+ * callback, because these actions are defined to operate on the
+ * underlying data shared by all peers.
+ */
+
+ iAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback,
+ (ClientData)textPtr->sharedTextPtr, insertCmdObj, NULL);
+ TkUndoMakeCmdSubAtom(NULL, markSet2InsertObj, iAtom);
+ TkUndoMakeCmdSubAtom(NULL, seeInsertObj, iAtom);
+
+ dAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback,
+ (ClientData)textPtr->sharedTextPtr, deleteCmdObj, NULL);
+ TkUndoMakeCmdSubAtom(NULL, markSet1InsertObj, dAtom);
+ TkUndoMakeCmdSubAtom(NULL, seeInsertObj, dAtom);
+
+ Tcl_DecrRefCount(seeInsertObj);
+ Tcl_DecrRefCount(index1Obj);
+ Tcl_DecrRefCount(index2Obj);
+
+ /*
+ * Depending whether the action is to insert or delete, we provide the
+ * appropriate second and third arguments to TkUndoPushAction. (The first
+ * is the 'actionCommand', and the second the 'revertCommand').
+ */
+
+ if (insert) {
+ TkUndoPushAction(textPtr->sharedTextPtr->undoStack, iAtom, dAtom);
+ } else {
+ TkUndoPushAction(textPtr->sharedTextPtr->undoStack, dAtom, iAtom);
}
- updateDirtyFlag(textPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TextUndoRedoCallback --
+ *
+ * This function is registered with the generic undo/redo code to handle
+ * 'insert' and 'delete' actions on all text widgets. We cannot perform
+ * those actions on any particular text widget, because that text widget
+ * might have been deleted by the time we get here.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * Will insert or delete text, depending on the first word contained in
+ * objPtr.
+ *
+ *----------------------------------------------------------------------
+ */
- if (resetView) {
- TkTextMakeByteIndex(textPtr->tree, lineIndex, 0, &newTop);
- TkTextIndexForwBytes(&newTop, offset, &newTop);
- TkTextSetYView(textPtr, &newTop, 0);
+int
+TextUndoRedoCallback(
+ Tcl_Interp *interp, /* Current interpreter. */
+ ClientData clientData, /* Passed from undo code, but contains our
+ * shared text data structure. */
+ Tcl_Obj *objPtr) /* Arguments of a command to be handled by the
+ * shared text data structure. */
+{
+ TkSharedText *sharedPtr = (TkSharedText *) clientData;
+ int res, objc;
+ Tcl_Obj **objv;
+ TkText *textPtr;
+
+ res = Tcl_ListObjGetElements(interp, objPtr, &objc, &objv);
+ if (res != TCL_OK) {
+ return res;
}
/*
- * Invalidate any selection retrievals in progress.
+ * If possible, use a real text widget to perform the undo/redo action
+ * (i.e. insertion or deletion of text). This provides maximum
+ * compatibility with older versions of Tk, in which the user may rename
+ * the text widget to allow capture of undo or redo actions.
+ *
+ * In particular, this sorting of capture is useful in text editors based
+ * on the Tk text widget, which need to know which new text needs
+ * re-coloring.
+ *
+ * It would be better if the text widget provided some other mechanism to
+ * allow capture of this information ("What has just changed in the text
+ * widget?"). What we have here is not entirely satisfactory under all
+ * circumstances.
+ */
+
+ textPtr = sharedPtr->peers;
+ while (textPtr != NULL) {
+ if (textPtr->start == NULL && textPtr->end == NULL) {
+ Tcl_Obj *cmdNameObj, *evalObj;
+
+ evalObj = Tcl_NewObj();
+ Tcl_IncrRefCount(evalObj);
+
+ /*
+ * We might wish to use the real, current command-name for the
+ * widget, but this will break any code that has over-ridden the
+ * widget, and is expecting to observe the insert/delete actions
+ * which are caused by undo/redo operations.
+ *
+ * cmdNameObj = Tcl_NewObj();
+ * Tcl_GetCommandFullName(interp, textPtr->widgetCmd, cmdNameObj);
+ *
+ * While such interception is not explicitly documented as
+ * supported, it does occur, and so until we can provide some
+ * alternative mechanism for such code to do what it needs, we
+ * allow it to take place here.
+ */
+
+ cmdNameObj = Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1);
+ Tcl_ListObjAppendElement(NULL, evalObj, cmdNameObj);
+ Tcl_ListObjAppendList(NULL, evalObj, objPtr);
+ res = Tcl_EvalObjEx(interp, evalObj, TCL_EVAL_GLOBAL);
+ Tcl_DecrRefCount(evalObj);
+ return res;
+ }
+ textPtr = textPtr->next;
+ }
+
+ /*
+ * If there's no current text widget which shows everything, then we fall
+ * back on acting directly. This means there is no way to intercept from
+ * the Tcl level.
*/
- textPtr->abortSelections = 1;
+ return SharedTextObjCmd((ClientData)sharedPtr, interp, objc+1, objv-1);
}
/*
*----------------------------------------------------------------------
*
- * DeleteChars --
+ * CountIndices --
+ *
+ * This function implements most of the functionality of the "count"
+ * widget command.
*
- * This procedure implements most of the functionality of the
- * "delete" widget command.
+ * Note that 'textPtr' is only used if we need to check for elided
+ * attributes, i.e. if type is COUNT_DISPLAY_INDICES or
+ * COUNT_DISPLAY_CHARS
*
* Results:
- * Returns a standard Tcl result, and leaves an error message
- * in textPtr->interp if there is an error.
+ * Returns the number of characters in the range.
*
* Side effects:
- * Characters get deleted from the text.
+ * None.
*
*----------------------------------------------------------------------
*/
static int
-DeleteChars(textPtr, index1String, index2String, indexPtr1, indexPtr2)
- TkText *textPtr; /* Overall information about text widget. */
- CONST char *index1String; /* String describing location of first
- * character to delete. */
- CONST char *index2String; /* String describing location of last
- * character to delete. NULL means just
- * delete the one character given by
- * index1String. */
- TkTextIndex *indexPtr1; /* index describing location of first
+CountIndices(
+ const TkText *textPtr, /* Overall information about text widget. */
+ const TkTextIndex *indexPtr1,
+ /* Index describing location of first
* character to delete. */
- TkTextIndex *indexPtr2; /* index describing location of last
- * character to delete. NULL means just
- * delete the one character given by
- * indexPtr1. */
+ const TkTextIndex *indexPtr2,
+ /* Index describing location of last character
+ * to delete. NULL means just delete the one
+ * character given by indexPtr1. */
+ TkTextCountType type) /* The kind of indices to count. */
+{
+ /*
+ * Order the starting and stopping indices.
+ */
+
+ int compare = TkTextIndexCmp(indexPtr1, indexPtr2);
+
+ if (compare == 0) {
+ return 0;
+ } else if (compare > 0) {
+ return -TkTextIndexCount(textPtr, indexPtr2, indexPtr1, type);
+ } else {
+ return TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteIndexRange --
+ *
+ * This function implements most of the functionality of the "delete"
+ * widget command.
+ *
+ * Results:
+ * Returns a standard Tcl result, currently always TCL_OK.
+ *
+ * Side effects:
+ * Characters and other entities (windows, images) get deleted from the
+ * text.
+ *
+ * If 'viewUpdate' is true, we may adjust the window contents'
+ * y-position, and scrollbar setting.
+ *
+ * If 'viewUpdate' is false, true we can guarantee that textPtr->topIndex
+ * points to a valid TkTextLine after this function returns. However, if
+ * 'viewUpdate' is false, then there is no such guarantee (since
+ * topIndex.linePtr can be garbage). The caller is expected to take
+ * actions to ensure the topIndex is validated before laying out the
+ * window again.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DeleteIndexRange(
+ TkSharedText *sharedTextPtr,/* Shared portion of peer widgets. */
+ TkText *textPtr, /* Overall information about text widget. */
+ const TkTextIndex *indexPtr1,
+ /* Index describing location of first
+ * character (or other entity) to delete. */
+ const TkTextIndex *indexPtr2,
+ /* Index describing location of last
+ * character (or other entity) to delete.
+ * NULL means just delete the one character
+ * given by indexPtr1. */
+ int viewUpdate) /* Update vertical view if set. */
{
- int line1, line2, line, byteIndex, resetView;
+ int line1, line2;
TkTextIndex index1, index2;
- char indexBuffer[TK_POS_CHARS];
+ TkText *tPtr;
+ int *lineAndByteIndex;
+ int resetViewCount;
+ int pixels[2*PIXEL_CLIENTS];
+
+ if (sharedTextPtr == NULL) {
+ sharedTextPtr = textPtr->sharedTextPtr;
+ }
/*
- * Parse the starting and stopping indices.
+ * Prepare the starting and stopping indices.
*/
- if (index1String != NULL) {
- if (TkTextGetIndex(textPtr->interp, textPtr, index1String, &index1)
- != TCL_OK) {
- return TCL_ERROR;
- }
- if (index2String != NULL) {
- if (TkTextGetIndex(textPtr->interp, textPtr, index2String, &index2)
- != TCL_OK) {
- return TCL_ERROR;
- }
- } else {
- index2 = index1;
- TkTextIndexForwChars(&index2, 1, &index2);
- }
+ index1 = *indexPtr1;
+ if (indexPtr2 != NULL) {
+ index2 = *indexPtr2;
} else {
- index1 = *indexPtr1;
- if (indexPtr2 != NULL) {
- index2 = *indexPtr2;
- } else {
- index2 = index1;
- TkTextIndexForwChars(&index2, 1, &index2);
- }
+ index2 = index1;
+ TkTextIndexForwChars(NULL, &index2, 1, &index2, COUNT_INDICES);
}
/*
@@ -1558,32 +2987,33 @@ DeleteChars(textPtr, index1String, index2String, indexPtr1, indexPtr2)
}
/*
- * The code below is ugly, but it's needed to make sure there
- * is always a dummy empty line at the end of the text. If the
- * final newline of the file (just before the dummy line) is being
- * deleted, then back up index to just before the newline. If
- * there is a newline just before the first character being deleted,
- * then back up the first index too, so that an even number of lines
- * gets deleted. Furthermore, remove any tags that are present on
- * the newline that isn't going to be deleted after all (this simulates
- * deleting the newline and then adding a "clean" one back again).
+ * The code below is ugly, but it's needed to make sure there is always a
+ * dummy empty line at the end of the text. If the final newline of the
+ * file (just before the dummy line) is being deleted, then back up index
+ * to just before the newline. If there is a newline just before the first
+ * character being deleted, then back up the first index too, so that an
+ * even number of lines gets deleted. Furthermore, remove any tags that
+ * are present on the newline that isn't going to be deleted after all
+ * (this simulates deleting the newline and then adding a "clean" one back
+ * again). Note that index1 and index2 might now be equal again which
+ * means that no text will be deleted but tags might be removed.
*/
- line1 = TkBTreeLineIndex(index1.linePtr);
- line2 = TkBTreeLineIndex(index2.linePtr);
- if (line2 == TkBTreeNumLines(textPtr->tree)) {
+ line1 = TkBTreeLinesTo(textPtr, index1.linePtr);
+ line2 = TkBTreeLinesTo(textPtr, index2.linePtr);
+ if (line2 == TkBTreeNumLines(sharedTextPtr->tree, textPtr)) {
TkTextTag **arrayPtr;
int arraySize, i;
TkTextIndex oldIndex2;
oldIndex2 = index2;
- TkTextIndexBackChars(&oldIndex2, 1, &index2);
+ TkTextIndexBackChars(NULL, &oldIndex2, 1, &index2, COUNT_INDICES);
line2--;
if ((index1.byteIndex == 0) && (line1 != 0)) {
- TkTextIndexBackChars(&index1, 1, &index1);
+ TkTextIndexBackChars(NULL, &index1, 1, &index1, COUNT_INDICES);
line1--;
}
- arrayPtr = TkBTreeGetTags(&index2, &arraySize);
+ arrayPtr = TkBTreeGetTags(&index2, NULL, &arraySize);
if (arrayPtr != NULL) {
for (i = 0; i < arraySize; i++) {
TkBTreeTag(&index2, &oldIndex2, arrayPtr[i], 0);
@@ -1597,144 +3027,206 @@ DeleteChars(textPtr, index1String, index2String, indexPtr1, indexPtr2)
* We are deleting more than one line. For speed, we remove all tags
* from the range first. If we don't do this, the code below can (when
* there are many tags) grow non-linearly in execution time.
- * [Bug 1456342]
*/
Tcl_HashSearch search;
Tcl_HashEntry *hPtr;
+ int i;
- for (hPtr=Tcl_FirstHashEntry(&textPtr->tagTable, &search);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+ for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search);
+ hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) {
TkTextTag *tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr);
TkBTreeTag(&index1, &index2, tagPtr, 0);
}
+
+ /*
+ * Special case for the sel tag which is not in the hash table. We
+ * need to do this once for each peer text widget.
+ */
+
+ for (tPtr = sharedTextPtr->peers; tPtr != NULL ;
+ tPtr = tPtr->next) {
+ if (TkBTreeTag(&index1, &index2, tPtr->selTagPtr, 0)) {
+ /*
+ * Send an event that the selection changed. This is
+ * equivalent to:
+ * event generate $textWidget <<Selection>>
+ */
+
+ TkTextSelectionEvent(textPtr);
+ tPtr->abortSelections = 1;
+ }
+ }
}
/*
- * Tell the display what's about to happen so it can discard
- * obsolete display information, then do the deletion. Also,
- * if the deletion involves the top line on the screen, then
- * we have to reset the view (the deletion will invalidate
- * textPtr->topIndex). Compute what the new first character
- * will be, then do the deletion, then reset the view.
+ * Tell the display what's about to happen so it can discard obsolete
+ * display information, then do the deletion. Also, if the deletion
+ * involves the top line on the screen, then we have to reset the view
+ * (the deletion will invalidate textPtr->topIndex). Compute what the new
+ * first character will be, then do the deletion, then reset the view.
*/
- TkTextChanged(textPtr, &index1, &index2);
- resetView = 0;
- line = 0;
- byteIndex = 0;
- if (TkTextIndexCmp(&index2, &textPtr->topIndex) >= 0) {
- if (TkTextIndexCmp(&index1, &textPtr->topIndex) <= 0) {
- /*
- * Deletion range straddles topIndex: use the beginning
- * of the range as the new topIndex.
- */
+ TkTextChanged(sharedTextPtr, NULL, &index1, &index2);
- resetView = 1;
- line = line1;
- byteIndex = index1.byteIndex;
- } else if (index1.linePtr == textPtr->topIndex.linePtr) {
+ resetViewCount = 0;
+ if (sharedTextPtr->refCount > PIXEL_CLIENTS) {
+ lineAndByteIndex = (int *)
+ ckalloc(sizeof(int) * 2 * sharedTextPtr->refCount);
+ } else {
+ lineAndByteIndex = pixels;
+ }
+ for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) {
+ int line = 0;
+ int byteIndex = 0;
+ int resetView = 0;
+
+ if (TkTextIndexCmp(&index2, &tPtr->topIndex) >= 0) {
+ if (TkTextIndexCmp(&index1, &tPtr->topIndex) <= 0) {
+ /*
+ * Deletion range straddles topIndex: use the beginning of the
+ * range as the new topIndex.
+ */
+
+ resetView = 1;
+ line = line1;
+ byteIndex = index1.byteIndex;
+ } else if (index1.linePtr == tPtr->topIndex.linePtr) {
+ /*
+ * Deletion range starts on top line but after topIndex. Use
+ * the current topIndex as the new one.
+ */
+
+ resetView = 1;
+ line = line1;
+ byteIndex = tPtr->topIndex.byteIndex;
+ } else {
+ /*
+ * Deletion range starts after the top line. This peers's view
+ * will not need to be reset. Nothing to do.
+ */
+ }
+ } else if (index2.linePtr == tPtr->topIndex.linePtr) {
/*
- * Deletion range starts on top line but after topIndex.
- * Use the current topIndex as the new one.
+ * Deletion range ends on top line but before topIndex. Figure out
+ * what will be the new character index for the character
+ * currently pointed to by topIndex.
*/
resetView = 1;
- line = line1;
- byteIndex = textPtr->topIndex.byteIndex;
+ line = line2;
+ byteIndex = tPtr->topIndex.byteIndex;
+ if (index1.linePtr != index2.linePtr) {
+ byteIndex -= index2.byteIndex;
+ } else {
+ byteIndex -= (index2.byteIndex - index1.byteIndex);
+ }
+ } else {
+ /*
+ * Deletion range ends before the top line. This peers's view
+ * will not need to be reset. Nothing to do.
+ */
}
- } else if (index2.linePtr == textPtr->topIndex.linePtr) {
- /*
- * Deletion range ends on top line but before topIndex.
- * Figure out what will be the new character index for
- * the character currently pointed to by topIndex.
- */
-
- resetView = 1;
- line = line2;
- byteIndex = textPtr->topIndex.byteIndex;
- if (index1.linePtr != index2.linePtr) {
- byteIndex -= index2.byteIndex;
+ if (resetView) {
+ lineAndByteIndex[resetViewCount] = line;
+ lineAndByteIndex[resetViewCount+1] = byteIndex;
} else {
- byteIndex -= (index2.byteIndex - index1.byteIndex);
+ lineAndByteIndex[resetViewCount] = -1;
}
+ resetViewCount+=2;
}
/*
- * Push the deletion on the undo stack
+ * Push the deletion on the undo stack if something was actually deleted.
*/
- if (textPtr->undo) {
- CONST char *cmdName;
- Tcl_DString ds;
- Tcl_DString actionCommand;
- Tcl_DString revertCommand;
-
- if (textPtr->autoSeparators
- && (textPtr->lastEditMode != TK_TEXT_EDIT_DELETE)) {
- TkUndoInsertUndoSeparator(textPtr->undoStack);
- }
-
- textPtr->lastEditMode = TK_TEXT_EDIT_DELETE;
- cmdName = Tcl_GetCommandName(textPtr->interp, textPtr->widgetCmd);
+ if (TkTextIndexCmp(&index1, &index2) < 0) {
+ if (sharedTextPtr->undo) {
+ Tcl_Obj *get;
- Tcl_DStringInit(&actionCommand);
- Tcl_DStringInit(&revertCommand);
-
- Tcl_DStringAppendElement(&actionCommand, cmdName);
- Tcl_DStringAppend(&actionCommand, " delete ", -1);
- TkTextPrintIndex(&index1, indexBuffer);
- Tcl_DStringAppend(&actionCommand, indexBuffer, -1);
- Tcl_DStringAppend(&actionCommand, " ", -1);
- TkTextPrintIndex(&index2, indexBuffer);
- Tcl_DStringAppend(&actionCommand, indexBuffer, -1);
- Tcl_DStringAppend(&actionCommand, "; ", -1);
- Tcl_DStringAppendElement(&actionCommand, cmdName);
- Tcl_DStringAppend(&actionCommand, " mark set insert ", -1);
- TkTextPrintIndex(&index1, indexBuffer);
- Tcl_DStringAppend(&actionCommand,indexBuffer, -1);
-
- Tcl_DStringAppend(&actionCommand, "; ", -1);
- Tcl_DStringAppendElement(&actionCommand, cmdName);
- Tcl_DStringAppend(&actionCommand, " see insert", -1);
+ if (sharedTextPtr->autoSeparators
+ && (sharedTextPtr->lastEditMode != TK_TEXT_EDIT_DELETE)) {
+ TkUndoInsertUndoSeparator(sharedTextPtr->undoStack);
+ }
- TextGetText(&index1, &index2, &ds);
+ sharedTextPtr->lastEditMode = TK_TEXT_EDIT_DELETE;
- Tcl_DStringAppendElement(&revertCommand, cmdName);
- Tcl_DStringAppend(&revertCommand, " insert ", -1);
- TkTextPrintIndex(&index1, indexBuffer);
- Tcl_DStringAppend(&revertCommand, indexBuffer, -1);
- Tcl_DStringAppend(&revertCommand, " ", -1);
- Tcl_DStringAppendElement(&revertCommand, Tcl_DStringValue(&ds));
- Tcl_DStringAppend(&revertCommand, "; ", -1);
- Tcl_DStringAppendElement(&revertCommand, cmdName);
- Tcl_DStringAppend(&revertCommand, " mark set insert ", -1);
- TkTextPrintIndex(&index2, indexBuffer);
- Tcl_DStringAppend(&revertCommand, indexBuffer, -1);
- Tcl_DStringAppend(&revertCommand, "; ", -1);
- Tcl_DStringAppendElement(&revertCommand, cmdName);
- Tcl_DStringAppend(&revertCommand, " see insert", -1);
+ get = TextGetText(textPtr, &index1, &index2, 0);
+ TextPushUndoAction(textPtr, get, 0, &index1, &index2);
+ }
+ sharedTextPtr->stateEpoch++;
- TkUndoPushAction(textPtr->undoStack, &actionCommand, &revertCommand);
+ TkBTreeDeleteIndexRange(sharedTextPtr->tree, &index1, &index2);
- Tcl_DStringFree(&actionCommand);
- Tcl_DStringFree(&revertCommand);
+ UpdateDirtyFlag(sharedTextPtr);
}
- TkBTreeDeleteChars(&index1, &index2);
-
- updateDirtyFlag(textPtr);
- if (resetView) {
- TkTextMakeByteIndex(textPtr->tree, line, byteIndex, &index1);
- TkTextSetYView(textPtr, &index1, 0);
+ resetViewCount = 0;
+ for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) {
+ int line = lineAndByteIndex[resetViewCount];
+
+ if (line != -1) {
+ int byteIndex = lineAndByteIndex[resetViewCount+1];
+ TkTextIndex indexTmp;
+
+ if (tPtr == textPtr) {
+ if (viewUpdate) {
+ /*
+ * line cannot be before -startline of textPtr because
+ * this line corresponds to an index which is necessarily
+ * between "1.0" and "end" relative to textPtr.
+ * Therefore no need to clamp line to the -start/-end
+ * range.
+ */
+
+ TkTextMakeByteIndex(sharedTextPtr->tree, textPtr, line,
+ byteIndex, &indexTmp);
+ TkTextSetYView(tPtr, &indexTmp, 0);
+ }
+ } else {
+ TkTextMakeByteIndex(sharedTextPtr->tree, tPtr, line,
+ byteIndex, &indexTmp);
+ /*
+ * line may be before -startline of tPtr and must be
+ * clamped to -startline before providing it to
+ * TkTextSetYView otherwise lines before -startline
+ * would be displayed.
+ * There is no need to worry about -endline however,
+ * because the view will only be reset if the deletion
+ * involves the TOP line of the screen
+ */
+
+ if (tPtr->start != NULL) {
+ int start;
+ TkTextIndex indexStart;
+
+ start = TkBTreeLinesTo(NULL, tPtr->start);
+ TkTextMakeByteIndex(sharedTextPtr->tree, NULL, start,
+ 0, &indexStart);
+ if (TkTextIndexCmp(&indexTmp, &indexStart) < 0) {
+ indexTmp = indexStart;
+ }
+ }
+ TkTextSetYView(tPtr, &indexTmp, 0);
+ }
+ }
+ resetViewCount += 2;
+ }
+ if (sharedTextPtr->refCount > PIXEL_CLIENTS) {
+ ckfree((char *) lineAndByteIndex);
}
- /*
- * Invalidate any selection retrievals in progress.
- */
+ if (line1 >= line2) {
+ /*
+ * Invalidate any selection retrievals in progress, assuming we didn't
+ * check for this case above.
+ */
- textPtr->abortSelections = 1;
+ for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) {
+ tPtr->abortSelections = 1;
+ }
+ }
return TCL_OK;
}
@@ -1744,15 +3236,15 @@ DeleteChars(textPtr, index1String, index2String, indexPtr1, indexPtr2)
*
* TextFetchSelection --
*
- * This procedure is called back by Tk when the selection is
- * requested by someone. It returns part or all of the selection
- * in a buffer provided by the caller.
+ * This function is called back by Tk when the selection is requested by
+ * someone. It returns part or all of the selection in a buffer provided
+ * by the caller.
*
* Results:
- * The return value is the number of non-NULL bytes stored
- * at buffer. Buffer is filled (or partially filled) with a
- * NULL-terminated string containing part or all of the selection,
- * as given by offset and maxBytes.
+ * The return value is the number of non-NULL bytes stored at buffer.
+ * Buffer is filled (or partially filled) with a NULL-terminated string
+ * containing part or all of the selection, as given by offset and
+ * maxBytes.
*
* Side effects:
* None.
@@ -1761,15 +3253,14 @@ DeleteChars(textPtr, index1String, index2String, indexPtr1, indexPtr2)
*/
static int
-TextFetchSelection(clientData, offset, buffer, maxBytes)
- ClientData clientData; /* Information about text 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. */
+TextFetchSelection(
+ ClientData clientData, /* Information about text 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. */
{
register TkText *textPtr = (TkText *) clientData;
TkTextIndex eof;
@@ -1782,20 +3273,21 @@ TextFetchSelection(clientData, offset, buffer, maxBytes)
}
/*
- * Find the beginning of the next range of selected text. Note: if
- * the selection is being retrieved in multiple pieces (offset != 0)
- * and some modification has been made to the text that affects the
- * selection then reject the selection request (make 'em start over
- * again).
+ * Find the beginning of the next range of selected text. Note: if the
+ * selection is being retrieved in multiple pieces (offset != 0) and some
+ * modification has been made to the text that affects the selection then
+ * reject the selection request (make 'em start over again).
*/
if (offset == 0) {
- TkTextMakeByteIndex(textPtr->tree, 0, 0, &textPtr->selIndex);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0,
+ &textPtr->selIndex);
textPtr->abortSelections = 0;
} else if (textPtr->abortSelections) {
return 0;
}
- TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, &eof);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), 0, &eof);
TkBTreeStartSearch(&textPtr->selIndex, &eof, textPtr->selTagPtr, &search);
if (!TkBTreeCharTagged(&textPtr->selIndex, textPtr->selTagPtr)) {
if (!TkBTreeNextTag(&search)) {
@@ -1810,8 +3302,8 @@ TextFetchSelection(clientData, offset, buffer, maxBytes)
/*
* Each iteration through the outer loop below scans one selected range.
- * Each iteration through the inner loop scans one segment in the
- * selected range.
+ * Each iteration through the inner loop scans one segment in the selected
+ * range.
*/
count = 0;
@@ -1821,18 +3313,18 @@ TextFetchSelection(clientData, offset, buffer, maxBytes)
*/
if (!TkBTreeNextTag(&search)) {
- panic("TextFetchSelection couldn't find end of range");
+ Tcl_Panic("TextFetchSelection couldn't find end of range");
}
/*
- * Copy information from character segments into the buffer
- * until either we run out of space in the buffer or we get
- * to the end of this range of text.
+ * Copy information from character segments into the buffer until
+ * either we run out of space in the buffer or we get to the end of
+ * this range of text.
*/
while (1) {
if (maxBytes == 0) {
- goto done;
+ goto fetchDone;
}
segPtr = TkTextIndexToSeg(&textPtr->selIndex, &offsetInSeg);
chunkSize = segPtr->size - offsetInSeg;
@@ -1852,14 +3344,14 @@ TextFetchSelection(clientData, offset, buffer, maxBytes)
}
}
if ((segPtr->typePtr == &tkTextCharType)
- && !TkTextIsElided(textPtr, &textPtr->selIndex)) {
- memcpy((VOID *) buffer, (VOID *) (segPtr->body.chars
- + offsetInSeg), (size_t) chunkSize);
+ && !TkTextIsElided(textPtr, &textPtr->selIndex, NULL)) {
+ memcpy(buffer, segPtr->body.chars + offsetInSeg,
+ (size_t) chunkSize);
buffer += chunkSize;
maxBytes -= chunkSize;
count += chunkSize;
}
- TkTextIndexForwBytes(&textPtr->selIndex, chunkSize,
+ TkTextIndexForwBytes(textPtr, &textPtr->selIndex, chunkSize,
&textPtr->selIndex);
}
@@ -1873,7 +3365,7 @@ TextFetchSelection(clientData, offset, buffer, maxBytes)
textPtr->selIndex = search.curIndex;
}
- done:
+ fetchDone:
*buffer = 0;
return count;
}
@@ -1883,11 +3375,10 @@ TextFetchSelection(clientData, offset, buffer, maxBytes)
*
* TkTextLostSelection --
*
- * This procedure is called back by Tk when the selection is
- * grabbed away from a text widget. On Windows and Mac systems, we
- * want to remember the selection for the next time the focus
- * enters the window. On Unix, just remove the "sel" tag from
- * everything in the widget.
+ * This function is called back by Tk when the selection is grabbed away
+ * from a text widget. On Windows and Mac systems, we want to remember
+ * the selection for the next time the focus enters the window. On Unix,
+ * just remove the "sel" tag from everything in the widget.
*
* Results:
* None.
@@ -1899,11 +3390,10 @@ TextFetchSelection(clientData, offset, buffer, maxBytes)
*/
void
-TkTextLostSelection(clientData)
- ClientData clientData; /* Information about text widget. */
+TkTextLostSelection(
+ ClientData clientData) /* Information about text widget. */
{
register TkText *textPtr = (TkText *) clientData;
- XEvent event;
if (TkpAlwaysShowSelection(textPtr->tkwin)) {
TkTextIndex start, end;
@@ -1913,30 +3403,26 @@ TkTextLostSelection(clientData)
}
/*
- * On Windows and Mac systems, we want to remember the selection
- * for the next time the focus enters the window. On Unix,
- * just remove the "sel" tag from everything in the widget.
+ * On Windows and Mac systems, we want to remember the selection for
+ * the next time the focus enters the window. On Unix, just remove the
+ * "sel" tag from everything in the widget.
*/
- TkTextMakeByteIndex(textPtr->tree, 0, 0, &start);
- TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, &end);
- TkTextRedrawTag(textPtr, &start, &end, textPtr->selTagPtr, 1);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ 0, 0, &start);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr),
+ 0, &end);
+ TkTextRedrawTag(NULL, textPtr, &start, &end, textPtr->selTagPtr, 1);
TkBTreeTag(&start, &end, textPtr->selTagPtr, 0);
}
/*
- * Send an event that the selection changed. This is equivalent to
- * "event generate $textWidget <<Selection>>"
+ * Send an event that the selection changed. This is equivalent to:
+ * event generate $textWidget <<Selection>>
*/
- memset((VOID *) &event, 0, sizeof(event));
- event.xany.type = VirtualEvent;
- event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin));
- event.xany.send_event = False;
- event.xany.window = Tk_WindowId(textPtr->tkwin);
- event.xany.display = Tk_Display(textPtr->tkwin);
- ((XVirtualEvent *) &event)->name = Tk_GetUid("Selection");
- Tk_HandleEvent(&event);
+ TkTextSelectionEvent(textPtr);
textPtr->flags &= ~GOT_SELECTION;
}
@@ -1944,31 +3430,78 @@ TkTextLostSelection(clientData)
/*
*----------------------------------------------------------------------
*
+ * TkTextSelectionEvent --
+ *
+ * When anything relevant to the "sel" tag has been changed, call this
+ * function to generate a <<Selection>> event.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * If <<Selection>> bindings are present, they will trigger.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkTextSelectionEvent(
+ TkText *textPtr)
+{
+ /*
+ * Send an event that the selection changed. This is equivalent to:
+ * event generate $textWidget <<Selection>>
+ */
+
+ union {XEvent general; XVirtualEvent virtual;} event;
+
+ memset(&event, 0, sizeof(event));
+ event.general.xany.type = VirtualEvent;
+ event.general.xany.serial = NextRequest(Tk_Display(textPtr->tkwin));
+ event.general.xany.send_event = False;
+ event.general.xany.window = Tk_WindowId(textPtr->tkwin);
+ event.general.xany.display = Tk_Display(textPtr->tkwin);
+ event.virtual.name = Tk_GetUid("Selection");
+ Tk_HandleEvent(&event.general);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TextBlinkProc --
*
- * This procedure is called as a timer handler to blink the
- * insertion cursor off and on.
+ * This function is called as a timer handler to blink the insertion
+ * cursor off and on.
*
* Results:
* None.
*
* Side effects:
- * The cursor gets turned on or off, redisplay gets invoked,
- * and this procedure reschedules itself.
+ * The cursor gets turned on or off, redisplay gets invoked, and this
+ * function reschedules itself.
*
*----------------------------------------------------------------------
*/
static void
-TextBlinkProc(clientData)
- ClientData clientData; /* Pointer to record describing text. */
+TextBlinkProc(
+ ClientData clientData) /* Pointer to record describing text. */
{
register TkText *textPtr = (TkText *) clientData;
TkTextIndex index;
- int x, y, w, h;
+ int x, y, w, h, charWidth;
- if ((textPtr->state == TK_STATE_DISABLED) ||
+ if ((textPtr->state == TK_TEXT_STATE_DISABLED) ||
!(textPtr->flags & GOT_FOCUS) || (textPtr->insertOffTime == 0)) {
+ if ((textPtr->insertOffTime == 0) && !(textPtr->flags & INSERT_ON)) {
+ /*
+ * The widget was configured to have zero offtime while the
+ * insertion point was not displayed. We have to display it once.
+ */
+
+ textPtr->flags |= INSERT_ON;
+ goto redrawInsert;
+ }
return;
}
if (textPtr->flags & INSERT_ON) {
@@ -1980,21 +3513,111 @@ TextBlinkProc(clientData)
textPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
textPtr->insertOnTime, TextBlinkProc, (ClientData) textPtr);
}
+ redrawInsert:
TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
- if (TkTextCharBbox(textPtr, &index, &x, &y, &w, &h) == 0) {
- TkTextRedrawRegion(textPtr, x - textPtr->insertWidth / 2, y,
- textPtr->insertWidth, h);
+ if (TkTextIndexBbox(textPtr, &index, &x, &y, &w, &h, &charWidth) == 0) {
+ if (textPtr->insertCursorType) {
+ /* Block cursor */
+ TkTextRedrawRegion(textPtr, x - textPtr->width / 2, y,
+ charWidth + textPtr->insertWidth / 2, h);
+ } else {
+ /* I-beam cursor */
+ TkTextRedrawRegion(textPtr, x - textPtr->insertWidth / 2, y,
+ textPtr->insertWidth, h);
+ }
}
}
/*
*----------------------------------------------------------------------
*
+ * TextInsertCmd --
+ *
+ * This function is invoked to process the "insert" and "replace" widget
+ * commands for text widgets.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ * If 'viewUpdate' is true, we may adjust the window contents'
+ * y-position, and scrollbar setting.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TextInsertCmd(
+ TkSharedText *sharedTextPtr,/* Shared portion of peer widgets. */
+ TkText *textPtr, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[], /* Argument objects. */
+ const TkTextIndex *indexPtr,/* Index at which to insert. */
+ int viewUpdate) /* Update the view if set. */
+{
+ TkTextIndex index1, index2;
+ int j;
+
+ if (sharedTextPtr == NULL) {
+ sharedTextPtr = textPtr->sharedTextPtr;
+ }
+
+ index1 = *indexPtr;
+ for (j = 0; j < objc; j += 2) {
+ /*
+ * Here we rely on this call to modify index1 if it is outside the
+ * acceptable range. In particular, if index1 is "end", it must be set
+ * to the last allowable index for insertion, otherwise subsequent tag
+ * insertions will fail.
+ */
+
+ int length = InsertChars(sharedTextPtr, textPtr, &index1, objv[j],
+ viewUpdate);
+
+ if (objc > (j+1)) {
+ Tcl_Obj **tagNamePtrs;
+ TkTextTag **oldTagArrayPtr;
+ int numTags;
+
+ TkTextIndexForwBytes(textPtr, &index1, length, &index2);
+ oldTagArrayPtr = TkBTreeGetTags(&index1, NULL, &numTags);
+ if (oldTagArrayPtr != NULL) {
+ int i;
+
+ for (i = 0; i < numTags; i++) {
+ TkBTreeTag(&index1, &index2, oldTagArrayPtr[i], 0);
+ }
+ ckfree((char *) oldTagArrayPtr);
+ }
+ if (Tcl_ListObjGetElements(interp, objv[j+1], &numTags,
+ &tagNamePtrs) != TCL_OK) {
+ return TCL_ERROR;
+ } else {
+ int i;
+
+ for (i = 0; i < numTags; i++) {
+ const char *strTag = Tcl_GetString(tagNamePtrs[i]);
+
+ TkBTreeTag(&index1, &index2,
+ TkTextCreateTag(textPtr, strTag, NULL), 1);
+ }
+ index1 = index2;
+ }
+ }
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TextSearchCmd --
*
- * This procedure is invoked to process the "search" widget command
- * for text widgets. See the user documentation for details on what
- * it does.
+ * This function is invoked to process the "search" widget command for
+ * text widgets. See the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -2006,393 +3629,680 @@ TextBlinkProc(clientData)
*/
static int
-TextSearchCmd(textPtr, interp, argc, argv)
- TkText *textPtr; /* Information about text widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+TextSearchCmd(
+ TkText *textPtr, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- int backwards, exact, searchElide, c, i, argsLeft, noCase, leftToScan;
- size_t length;
- int numLines, startingLine, startingByte, lineNum, firstByte, lastByte;
- int code, matchLength, matchByte, passes, stopLine, searchWholeText;
- int patLength;
- CONST char *arg, *pattern, *varName, *p, *startOfLine;
- char buffer[20];
- TkTextIndex index, stopIndex;
- Tcl_DString line, patDString;
- TkTextSegment *segPtr;
- TkTextLine *linePtr;
- TkTextIndex curIndex;
- Tcl_Obj *patObj = NULL;
- Tcl_RegExp regexp = NULL; /* Initialization needed only to
- * prevent compiler warning. */
+ int i, argsLeft, code;
+ SearchSpec searchSpec;
+
+ static const char *switchStrings[] = {
+ "--", "-all", "-backwards", "-count", "-elide", "-exact", "-forwards",
+ "-hidden", "-nocase", "-nolinestop", "-overlap", "-regexp",
+ "-strictlimits", NULL
+ };
+ enum SearchSwitches {
+ SEARCH_END, SEARCH_ALL, SEARCH_BACK, SEARCH_COUNT, SEARCH_ELIDE,
+ SEARCH_EXACT, SEARCH_FWD, SEARCH_HIDDEN, SEARCH_NOCASE,
+ SEARCH_NOLINESTOP, SEARCH_OVERLAP, SEARCH_REGEXP, SEARCH_STRICTLIMITS
+ };
+
+ /*
+ * Set up the search specification, including the last 4 fields which are
+ * text widget specific.
+ */
+
+ searchSpec.exact = 1;
+ searchSpec.noCase = 0;
+ searchSpec.all = 0;
+ searchSpec.backwards = 0;
+ searchSpec.varPtr = NULL;
+ searchSpec.countPtr = NULL;
+ searchSpec.resPtr = NULL;
+ searchSpec.searchElide = 0;
+ searchSpec.noLineStop = 0;
+ searchSpec.overlap = 0;
+ searchSpec.strictLimits = 0;
+ searchSpec.numLines =
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr);
+ searchSpec.clientData = (ClientData)textPtr;
+ searchSpec.addLineProc = &TextSearchAddNextLine;
+ searchSpec.foundMatchProc = &TextSearchFoundMatch;
+ searchSpec.lineIndexProc = &TextSearchGetLineIndex;
/*
* Parse switches and other arguments.
*/
- exact = 1;
- searchElide = 0;
- curIndex.tree = textPtr->tree;
- backwards = 0;
- noCase = 0;
- varName = NULL;
- for (i = 2; i < argc; i++) {
- arg = argv[i];
- if (arg[0] != '-') {
+ for (i=2 ; i<objc ; i++) {
+ int index;
+ if (Tcl_GetString(objv[i])[0] != '-') {
break;
}
- length = strlen(arg);
- if (length < 2) {
- badSwitch:
- Tcl_AppendResult(interp, "bad switch \"", arg,
- "\": must be --, -backward, -count, -elide, -exact, ",
- "-forward, -nocase, or -regexp", (char *) NULL);
+
+ if (Tcl_GetIndexFromObj(interp, objv[i], switchStrings, "switch", 0,
+ &index) != TCL_OK) {
+ /*
+ * Hide the -hidden option.
+ */
+
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "bad switch \"", Tcl_GetString(objv[i]),
+ "\": must be --, -all, -backward, -count, -elide, ",
+ "-exact, -forward, -nocase, -nolinestop, -overlap, ",
+ "-regexp, or -strictlimits", NULL);
return TCL_ERROR;
}
- c = arg[1];
- if ((c == 'b') && (strncmp(argv[i], "-backwards", length) == 0)) {
- backwards = 1;
- } else if ((c == 'c') && (strncmp(argv[i], "-count", length) == 0)) {
- if (i >= (argc-1)) {
+
+ switch ((enum SearchSwitches) index) {
+ case SEARCH_END:
+ i++;
+ goto endOfSwitchProcessing;
+ case SEARCH_ALL:
+ searchSpec.all = 1;
+ break;
+ case SEARCH_BACK:
+ searchSpec.backwards = 1;
+ break;
+ case SEARCH_COUNT:
+ if (i >= objc-1) {
Tcl_SetResult(interp, "no value given for \"-count\" option",
TCL_STATIC);
return TCL_ERROR;
}
i++;
- varName = argv[i];
- } else if ((c == 'e') && (length > 2)
- && (strncmp(argv[i], "-exact", length) == 0)) {
- exact = 1;
- } else if ((c == 'e') && (length > 2)
- && (strncmp(argv[i], "-elide", length) == 0)) {
- searchElide = 1;
- } else if ((c == 'h') && (strncmp(argv[i], "-hidden", length) == 0)) {
+
/*
- * -hidden is kept around for backwards compatibility with
- * the dash patch, but -elide is the official option
+ * Assumption objv[i] isn't going to disappear on us during this
+ * function, which is fair.
*/
- searchElide = 1;
- } else if ((c == 'f') && (strncmp(argv[i], "-forwards", length) == 0)) {
- backwards = 0;
- } else if ((c == 'n') && (strncmp(argv[i], "-nocase", length) == 0)) {
- noCase = 1;
- } else if ((c == 'r') && (strncmp(argv[i], "-regexp", length) == 0)) {
- exact = 0;
- } else if ((c == '-') && (strncmp(argv[i], "--", length) == 0)) {
- i++;
+
+ searchSpec.varPtr = objv[i];
break;
- } else {
- goto badSwitch;
+ case SEARCH_ELIDE:
+ case SEARCH_HIDDEN:
+ searchSpec.searchElide = 1;
+ break;
+ case SEARCH_EXACT:
+ searchSpec.exact = 1;
+ break;
+ case SEARCH_FWD:
+ searchSpec.backwards = 0;
+ break;
+ case SEARCH_NOCASE:
+ searchSpec.noCase = 1;
+ break;
+ case SEARCH_NOLINESTOP:
+ searchSpec.noLineStop = 1;
+ break;
+ case SEARCH_OVERLAP:
+ searchSpec.overlap = 1;
+ break;
+ case SEARCH_STRICTLIMITS:
+ searchSpec.strictLimits = 1;
+ break;
+ case SEARCH_REGEXP:
+ searchSpec.exact = 0;
+ break;
+ default:
+ Tcl_Panic("unexpected switch fallthrough");
}
}
- argsLeft = argc - (i+2);
+ endOfSwitchProcessing:
+
+ argsLeft = objc - (i+2);
if ((argsLeft != 0) && (argsLeft != 1)) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " search ?switches? pattern index ?stopIndex?\"",
- (char *) NULL);
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?switches? pattern index ?stopIndex?");
+ return TCL_ERROR;
+ }
+
+ if (searchSpec.noLineStop && searchSpec.exact) {
+ Tcl_SetResult(interp, "the \"-nolinestop\" option requires the "
+ "\"-regexp\" option to be present", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+ if (searchSpec.overlap && !searchSpec.all) {
+ Tcl_SetResult(interp, "the \"-overlap\" option requires the "
+ "\"-all\" option to be present", TCL_STATIC);
return TCL_ERROR;
}
- pattern = argv[i];
/*
- * Convert the pattern to lower-case if we're supposed to ignore case.
+ * Scan through all of the lines of the text circularly, starting at the
+ * given index. 'objv[i]' is the pattern which may be an exact string or a
+ * regexp pattern depending on the flags set above.
*/
- if (noCase && exact) {
- Tcl_DStringInit(&patDString);
- Tcl_DStringAppend(&patDString, pattern, -1);
- Tcl_UtfToLower(Tcl_DStringValue(&patDString));
- pattern = Tcl_DStringValue(&patDString);
+ code = SearchPerform(interp, &searchSpec, objv[i], objv[i+1],
+ (argsLeft == 1 ? objv[i+2] : NULL));
+ if (code != TCL_OK) {
+ goto cleanup;
}
- Tcl_DStringInit(&line);
- if (TkTextGetIndex(interp, textPtr, argv[i+1], &index) != TCL_OK) {
- code = TCL_ERROR;
- goto done;
- }
- numLines = TkBTreeNumLines(textPtr->tree);
- startingLine = TkBTreeLineIndex(index.linePtr);
- startingByte = index.byteIndex;
- if (startingLine >= numLines) {
- if (backwards) {
- startingLine = TkBTreeNumLines(textPtr->tree) - 1;
- startingByte = TkBTreeBytesInLine(TkBTreeFindLine(textPtr->tree,
- startingLine));
- } else {
- startingLine = 0;
- startingByte = 0;
- }
- }
- if (argsLeft == 1) {
- if (TkTextGetIndex(interp, textPtr, argv[i+2], &stopIndex) != TCL_OK) {
+ /*
+ * Set the '-count' variable, if given.
+ */
+
+ if (searchSpec.varPtr != NULL && searchSpec.countPtr != NULL) {
+ Tcl_IncrRefCount(searchSpec.countPtr);
+ if (Tcl_ObjSetVar2(interp, searchSpec.varPtr, NULL,
+ searchSpec.countPtr, TCL_LEAVE_ERR_MSG) == NULL) {
code = TCL_ERROR;
- goto done;
- }
- stopLine = TkBTreeLineIndex(stopIndex.linePtr);
- if (!backwards && (stopLine == numLines)) {
- stopLine = numLines-1;
+ goto cleanup;
}
- searchWholeText = 0;
- } else {
- stopLine = 0;
- searchWholeText = 1;
}
/*
- * Scan through all of the lines of the text circularly, starting
- * at the given index.
+ * Set the result.
*/
- matchLength = patLength = 0; /* Only needed to prevent compiler
- * warnings. */
- if (exact) {
- patLength = strlen(pattern);
- } else {
- patObj = Tcl_NewStringObj(pattern, -1);
- Tcl_IncrRefCount(patObj);
- regexp = Tcl_GetRegExpFromObj(interp, patObj,
- (noCase ? TCL_REG_NOCASE : 0) | TCL_REG_ADVANCED);
- if (regexp == NULL) {
- code = TCL_ERROR;
- goto done;
- }
+ if (searchSpec.resPtr != NULL) {
+ Tcl_SetObjResult(interp, searchSpec.resPtr);
+ searchSpec.resPtr = NULL;
}
- lineNum = startingLine;
- code = TCL_OK;
- for (passes = 0; passes < 2; ) {
- if (lineNum >= numLines) {
- /*
- * Don't search the dummy last line of the text.
- */
- goto nextLine;
- }
+ cleanup:
+ if (searchSpec.countPtr != NULL) {
+ Tcl_DecrRefCount(searchSpec.countPtr);
+ }
+ if (searchSpec.resPtr != NULL) {
+ Tcl_DecrRefCount(searchSpec.resPtr);
+ }
+ return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TextSearchGetLineIndex --
+ *
+ * Extract a row, text offset index position from an objPtr
+ *
+ * This means we ignore any embedded windows/images and elidden text
+ * (unless we are searching that).
+ *
+ * Results:
+ * Standard Tcl error code (with a message in the interpreter on error
+ * conditions).
+ *
+ * The offset placed in offsetPosPtr is a utf-8 char* byte index for
+ * exact searches, and a Unicode character index for regexp searches.
+ *
+ * The line number should start at zero (searches which wrap around
+ * assume the first line is numbered 0).
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TextSearchGetLineIndex(
+ Tcl_Interp *interp, /* For error messages. */
+ Tcl_Obj *objPtr, /* Contains a textual index like "1.2" */
+ SearchSpec *searchSpecPtr, /* Contains other search parameters. */
+ int *linePosPtr, /* For returning the line number. */
+ int *offsetPosPtr) /* For returning the text offset in the
+ * line. */
+{
+ const TkTextIndex *indexPtr;
+ int line;
+ TkText *textPtr = (TkText *) searchSpecPtr->clientData;
+
+ indexPtr = TkTextGetIndexFromObj(interp, textPtr, objPtr);
+ if (indexPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ line = TkBTreeLinesTo(textPtr, indexPtr->linePtr);
+ if (line >= searchSpecPtr->numLines) {
+ TkTextLine *linePtr;
+ int count = 0;
+ TkTextSegment *segPtr;
+
+ line = searchSpecPtr->numLines-1;
+ linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr, line);
/*
- * Extract the text from the line. If we're doing regular
- * expression matching, drop the newline from the line, so
- * that "$" can be used to match the end of the line.
+ * Count the number of bytes in this line.
*/
- linePtr = TkBTreeFindLine(textPtr->tree, lineNum);
- curIndex.linePtr = linePtr; curIndex.byteIndex = 0;
- for (segPtr = linePtr->segPtr; segPtr != NULL;
+ for (segPtr=linePtr->segPtr ; segPtr!=NULL ; segPtr=segPtr->nextPtr) {
+ count += segPtr->size;
+ }
+ *offsetPosPtr = TextSearchIndexInLine(searchSpecPtr, linePtr, count);
+ } else {
+ *offsetPosPtr = TextSearchIndexInLine(searchSpecPtr,
+ indexPtr->linePtr, indexPtr->byteIndex);
+ }
+
+ *linePosPtr = line;
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TextSearchIndexInLine --
+ *
+ * Find textual index of 'byteIndex' in the searchable characters of
+ * 'linePtr'.
+ *
+ * This means we ignore any embedded windows/images and elidden text
+ * (unless we are searching that).
+ *
+ * Results:
+ * The returned index is a utf-8 char* byte index for exact searches, and
+ * a Unicode character index for regexp searches.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TextSearchIndexInLine(
+ const SearchSpec *searchSpecPtr,
+ /* Search parameters. */
+ TkTextLine *linePtr, /* The line we're looking at. */
+ int byteIndex) /* Index into the line. */
+{
+ TkTextSegment *segPtr;
+ TkTextIndex curIndex;
+ int index, leftToScan;
+ TkText *textPtr = (TkText *) searchSpecPtr->clientData;
+
+ index = 0;
+ curIndex.tree = textPtr->sharedTextPtr->tree;
+ curIndex.linePtr = linePtr; curIndex.byteIndex = 0;
+ for (segPtr = linePtr->segPtr, leftToScan = byteIndex;
+ leftToScan > 0;
+ curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) {
+ if ((segPtr->typePtr == &tkTextCharType) &&
+ (searchSpecPtr->searchElide
+ || !TkTextIsElided(textPtr, &curIndex, NULL))) {
+ if (leftToScan < segPtr->size) {
+ if (searchSpecPtr->exact) {
+ index += leftToScan;
+ } else {
+ index += Tcl_NumUtfChars(segPtr->body.chars, leftToScan);
+ }
+ } else if (searchSpecPtr->exact) {
+ index += segPtr->size;
+ } else {
+ index += Tcl_NumUtfChars(segPtr->body.chars, -1);
+ }
+ }
+ leftToScan -= segPtr->size;
+ }
+ return index;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TextSearchAddNextLine --
+ *
+ * Adds a line from the text widget to the object 'theLine'.
+ *
+ * Results:
+ * A pointer to the TkTextLine corresponding to the given line, or NULL
+ * if there was no available line.
+ *
+ * Also 'lenPtr' (if non-NULL) is filled in with the total length of
+ * 'theLine' (not just what we added to it, but the length including what
+ * was already in there). This is in bytes for an exact search and in
+ * chars for a regexp search.
+ *
+ * Also 'extraLinesPtr' (if non-NULL) will have its value incremented by
+ * 1 for each additional logical line we have added because a newline is
+ * elided (this will only ever happen if we have chosen not to search
+ * elided text, of course).
+ *
+ * Side effects:
+ * Memory may be allocated or re-allocated for theLine's string
+ * representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ClientData
+TextSearchAddNextLine(
+ int lineNum, /* Line we must add. */
+ SearchSpec *searchSpecPtr, /* Search parameters. */
+ Tcl_Obj *theLine, /* Object to append to. */
+ int *lenPtr, /* For returning the total length. */
+ int *extraLinesPtr) /* If non-NULL, will have its value
+ * incremented by the number of additional
+ * logical lines which are merged into this
+ * one by newlines being elided. */
+{
+ TkTextLine *linePtr, *thisLinePtr;
+ TkTextIndex curIndex;
+ TkTextSegment *segPtr;
+ TkText *textPtr = (TkText *) searchSpecPtr->clientData;
+ int nothingYet = 1;
+
+ /*
+ * Extract the text from the line.
+ */
+
+ linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr, lineNum);
+ if (linePtr == NULL) {
+ return NULL;
+ }
+ curIndex.tree = textPtr->sharedTextPtr->tree;
+ thisLinePtr = linePtr;
+
+ while (thisLinePtr != NULL) {
+ int elideWraps = 0;
+
+ curIndex.linePtr = thisLinePtr;
+ curIndex.byteIndex = 0;
+ for (segPtr = thisLinePtr->segPtr; segPtr != NULL;
curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) {
- if ((segPtr->typePtr != &tkTextCharType)
- || (!searchElide && TkTextIsElided(textPtr, &curIndex))) {
+ if (!searchSpecPtr->searchElide
+ && TkTextIsElided(textPtr, &curIndex, NULL)) {
+ /*
+ * If we reach the end of the logical line, and if we have at
+ * least one character in the string, then we continue
+ * wrapping to the next logical line. If there are no
+ * characters yet, then the entire line of characters is
+ * elided and there's no need to complicate matters by
+ * wrapping - we'll look at the next line in due course.
+ */
+
+ if (segPtr->nextPtr == NULL && !nothingYet) {
+ elideWraps = 1;
+ }
+ continue;
+ }
+ if (segPtr->typePtr != &tkTextCharType) {
continue;
}
- Tcl_DStringAppend(&line, segPtr->body.chars, segPtr->size);
+ Tcl_AppendToObj(theLine, segPtr->body.chars, segPtr->size);
+ nothingYet = 0;
}
- if (!exact) {
- Tcl_DStringSetLength(&line, Tcl_DStringLength(&line)-1);
+ if (!elideWraps) {
+ break;
+ }
+ lineNum++;
+ if (lineNum >= searchSpecPtr->numLines) {
+ break;
}
- startOfLine = Tcl_DStringValue(&line);
+ thisLinePtr = TkBTreeNextLine(textPtr, thisLinePtr);
+ if (thisLinePtr != NULL && extraLinesPtr != NULL) {
+ /*
+ * Tell our caller we have an extra line merged in.
+ */
- /*
- * If we're ignoring case, convert the line to lower case.
- */
+ *extraLinesPtr = (*extraLinesPtr) + 1;
+ }
+ }
+
+ /*
+ * If we're ignoring case, convert the line to lower case. There is no
+ * need to do this for regexp searches, since they handle a flag for this
+ * purpose.
+ */
- if (noCase) {
- Tcl_DStringSetLength(&line,
- Tcl_UtfToLower(Tcl_DStringValue(&line)));
+ if (searchSpecPtr->exact && searchSpecPtr->noCase) {
+ Tcl_SetObjLength(theLine, Tcl_UtfToLower(Tcl_GetString(theLine)));
+ }
+
+ if (lenPtr != NULL) {
+ if (searchSpecPtr->exact) {
+ Tcl_GetStringFromObj(theLine, lenPtr);
+ } else {
+ *lenPtr = Tcl_GetCharLength(theLine);
}
+ }
+ return (ClientData)linePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TextSearchFoundMatch --
+ *
+ * Stores information from a successful search.
+ *
+ * Results:
+ * 1 if the information was stored, 0 if the position at which the match
+ * was found actually falls outside the allowable search region (and
+ * therefore the search is actually complete).
+ *
+ * Side effects:
+ * Memory may be allocated in the 'countPtr' and 'resPtr' fields of
+ * 'searchSpecPtr'. Each of those objects will have refCount zero and
+ * must eventually be freed or stored elsewhere as appropriate.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+TextSearchFoundMatch(
+ int lineNum, /* Line on which match was found. */
+ SearchSpec *searchSpecPtr, /* Search parameters. */
+ ClientData clientData, /* Token returned by the 'addNextLineProc',
+ * TextSearchAddNextLine. May be NULL, in
+ * which we case we must generate it (from
+ * lineNum). */
+ Tcl_Obj *theLine, /* Text from current line, only accessed for
+ * exact searches, and is allowed to be NULL
+ * for regexp searches. */
+ int matchOffset, /* Offset of found item in utf-8 bytes for
+ * exact search, Unicode chars for regexp. */
+ int matchLength) /* Length also in bytes/chars as per search
+ * type. */
+{
+ int numChars;
+ int leftToScan;
+ TkTextIndex curIndex, foundIndex;
+ TkTextSegment *segPtr;
+ TkTextLine *linePtr;
+ TkText *textPtr = (TkText *) searchSpecPtr->clientData;
+
+ if (lineNum == searchSpecPtr->stopLine) {
/*
- * Check for matches within the current line. If so, and if we're
- * searching backwards, repeat the search to find the last match
- * in the line. (Note: The lastByte should include the NULL char
- * so we can handle searching for end of line easier.)
+ * If the current index is on the wrong side of the stopIndex, then
+ * the item we just found is actually outside the acceptable range,
+ * and the search is over.
*/
- matchByte = -1;
- firstByte = 0;
- lastByte = Tcl_DStringLength(&line) + 1;
- if (lineNum == startingLine) {
- int indexInDString;
+ if (searchSpecPtr->backwards ^
+ (matchOffset >= searchSpecPtr->stopOffset)) {
+ return 0;
+ }
+ }
- /*
- * The starting line is tricky: the first time we see it
- * we check one part of the line, and the second pass through
- * we check the other part of the line. We have to be very
- * careful here because there could be embedded windows or
- * other things that are not in the extracted line. Rescan
- * the original line to compute the index in it of the first
- * character.
- */
+ /*
+ * Calculate the character count, which may need augmenting if there are
+ * embedded windows or elidden text.
+ */
+
+ if (searchSpecPtr->exact) {
+ const char *startOfLine = Tcl_GetString(theLine);
+
+ numChars = Tcl_NumUtfChars(startOfLine + matchOffset, matchLength);
+ } else {
+ numChars = matchLength;
+ }
+
+ /*
+ * If we're using strict limits checking, ensure that the match with its
+ * full length fits inside the given range.
+ */
+
+ if (searchSpecPtr->strictLimits && lineNum == searchSpecPtr->stopLine) {
+ if (searchSpecPtr->backwards ^
+ ((matchOffset + numChars) > searchSpecPtr->stopOffset)) {
+ return 0;
+ }
+ }
+
+ /*
+ * The index information returned by the regular expression parser only
+ * considers textual information: it doesn't account for embedded windows,
+ * elided text (when we are not searching elided text) or any other
+ * non-textual info. Scan through the line's segments again to adjust both
+ * matchChar and matchCount.
+ *
+ * We will walk through the segments of this line until we have either
+ * reached the end of the match or we have reached the end of the line.
+ */
+
+ linePtr = (TkTextLine *)clientData;
+ if (linePtr == NULL) {
+ linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr,
+ lineNum);
+ }
+
+ curIndex.tree = textPtr->sharedTextPtr->tree;
+
+ /*
+ * Find the starting point.
+ */
+
+ leftToScan = matchOffset;
+ while (1) {
+ curIndex.linePtr = linePtr;
+ curIndex.byteIndex = 0;
- indexInDString = startingByte;
- for (segPtr = linePtr->segPtr, leftToScan = startingByte;
- leftToScan > 0; segPtr = segPtr->nextPtr) {
- if (segPtr->typePtr != &tkTextCharType) {
- indexInDString -= segPtr->size;
+ /*
+ * Note that we allow leftToScan to be zero because we want to skip
+ * over any preceding non-textual items.
+ */
+
+ for (segPtr = linePtr->segPtr; leftToScan >= 0 && segPtr;
+ segPtr = segPtr->nextPtr) {
+ if (segPtr->typePtr != &tkTextCharType) {
+ matchOffset += segPtr->size;
+ } else if (!searchSpecPtr->searchElide
+ && TkTextIsElided(textPtr, &curIndex, NULL)) {
+ if (searchSpecPtr->exact) {
+ matchOffset += segPtr->size;
+ } else {
+ matchOffset += Tcl_NumUtfChars(segPtr->body.chars, -1);
}
+ } else {
leftToScan -= segPtr->size;
}
+ curIndex.byteIndex += segPtr->size;
+ }
+ if (segPtr == NULL && leftToScan >= 0) {
+ /*
+ * This will only happen if we are eliding newlines.
+ */
- passes++;
- if ((passes == 1) ^ backwards) {
+ linePtr = TkBTreeNextLine(textPtr, linePtr);
+ if (linePtr == NULL) {
/*
- * Only use the last part of the line.
+ * If we reach the end of the text, we have a serious problem,
+ * unless there's actually nothing left to look for.
*/
- firstByte = indexInDString;
- if ((firstByte >= Tcl_DStringLength(&line))
- && !((Tcl_DStringLength(&line) == 0) && !exact)) {
- goto nextLine;
+ if (leftToScan == 0) {
+ break;
+ } else {
+ Tcl_Panic("Reached end of text in a match");
}
- } else {
- /*
- * Use only the first part of the line.
- */
-
- lastByte = indexInDString;
}
+
+ /*
+ * We've wrapped to the beginning of the next logical line, which
+ * has been merged with the previous one whose newline was elided.
+ */
+
+ lineNum++;
+ matchOffset = 0;
+ } else {
+ break;
}
- do {
- int thisLength;
- Tcl_UniChar ch;
+ }
- if (exact) {
- p = strstr(startOfLine + firstByte, /* INTL: Native. */
- pattern);
- if (p == NULL) {
- break;
- }
- i = p - startOfLine;
- thisLength = patLength;
- } else {
- CONST char *start, *end;
- int match;
+ /*
+ * Calculate and store the found index in the result.
+ */
- match = Tcl_RegExpExec(interp, regexp,
- startOfLine + firstByte, startOfLine);
- if (match < 0) {
- code = TCL_ERROR;
- goto done;
- }
- if (!match) {
- break;
- }
- Tcl_RegExpRange(regexp, 0, &start, &end);
- i = start - startOfLine;
- thisLength = end - start;
- }
- if (i >= lastByte) {
- break;
- }
- matchByte = i;
- matchLength = thisLength;
- firstByte = i + Tcl_UtfToUniChar(startOfLine + matchByte, &ch);
- } while (backwards);
+ if (searchSpecPtr->exact) {
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, lineNum,
+ matchOffset, &foundIndex);
+ } else {
+ TkTextMakeCharIndex(textPtr->sharedTextPtr->tree, textPtr, lineNum,
+ matchOffset, &foundIndex);
+ }
- /*
- * If we found a match then we're done. Make sure that
- * the match occurred before the stopping index, if one was
- * specified.
- */
+ if (searchSpecPtr->all) {
+ if (searchSpecPtr->resPtr == NULL) {
+ searchSpecPtr->resPtr = Tcl_NewObj();
+ }
+ Tcl_ListObjAppendElement(NULL, searchSpecPtr->resPtr,
+ TkTextNewIndexObj(textPtr, &foundIndex));
+ } else {
+ searchSpecPtr->resPtr = TkTextNewIndexObj(textPtr, &foundIndex);
+ }
- if (matchByte >= 0) {
- int numChars;
+ /*
+ * Find the end point. Here 'leftToScan' could be negative already as a
+ * result of the above loop if the segment we reached spanned the start of
+ * the string. When we add matchLength it will become non-negative.
+ */
+ for (leftToScan += matchLength; leftToScan > 0;
+ curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) {
+ if (segPtr == NULL) {
/*
- * Convert the byte length to a character count.
+ * We are on the next line - this of course should only ever
+ * happen with searches which have matched across multiple lines.
*/
- numChars = Tcl_NumUtfChars(startOfLine + matchByte,
- matchLength);
-
+ linePtr = TkBTreeNextLine(textPtr, linePtr);
+ segPtr = linePtr->segPtr;
+ curIndex.linePtr = linePtr; curIndex.byteIndex = 0;
+ }
+ if (segPtr->typePtr != &tkTextCharType) {
/*
- * The index information returned by the regular expression
- * parser only considers textual information: it doesn't
- * account for embedded windows, elided text (when we are not
- * searching elided text) or any other non-textual info.
- * Scan through the line's segments again to adjust both
- * matchChar and matchCount.
- *
- * We will walk through the segments of this line until we have
- * either reached the end of the match or we have reached the end
- * of the line.
+ * Anything we didn't count in the search needs adding.
*/
- curIndex.linePtr = linePtr; curIndex.byteIndex = 0;
- for (segPtr = linePtr->segPtr, leftToScan = matchByte;
- leftToScan >= 0 && segPtr; segPtr = segPtr->nextPtr) {
- if (segPtr->typePtr != &tkTextCharType || \
- (!searchElide && TkTextIsElided(textPtr, &curIndex))) {
- matchByte += segPtr->size;
- } else {
- leftToScan -= segPtr->size;
- }
- curIndex.byteIndex += segPtr->size;
- }
- for (leftToScan += matchLength; leftToScan > 0;
- segPtr = segPtr->nextPtr) {
- if (segPtr->typePtr != &tkTextCharType) {
- numChars += segPtr->size;
- continue;
- }
- leftToScan -= segPtr->size;
- }
- TkTextMakeByteIndex(textPtr->tree, lineNum, matchByte, &index);
- if (!searchWholeText) {
- if (!backwards && (TkTextIndexCmp(&index, &stopIndex) >= 0)) {
- goto done;
- }
- if (backwards && (TkTextIndexCmp(&index, &stopIndex) < 0)) {
- goto done;
- }
- }
- if (varName != NULL) {
- sprintf(buffer, "%d", numChars);
- if (Tcl_SetVar(interp, varName, buffer, TCL_LEAVE_ERR_MSG)
- == NULL) {
- code = TCL_ERROR;
- goto done;
- }
- }
- TkTextPrintIndex(&index, buffer);
- Tcl_SetResult(interp, buffer, TCL_VOLATILE);
- goto done;
+ numChars += segPtr->size;
+ continue;
+ } else if (!searchSpecPtr->searchElide
+ && TkTextIsElided(textPtr, &curIndex, NULL)) {
+ numChars += Tcl_NumUtfChars(segPtr->body.chars, -1);
+ continue;
+ }
+ if (searchSpecPtr->exact) {
+ leftToScan -= segPtr->size;
+ } else {
+ leftToScan -= Tcl_NumUtfChars(segPtr->body.chars, -1);
}
+ }
- /*
- * Go to the next (or previous) line;
- */
+ /*
+ * Now store the count result, if it is wanted.
+ */
- nextLine:
- if (backwards) {
- lineNum--;
- if (!searchWholeText) {
- if (lineNum < stopLine) {
- break;
- }
- } else if (lineNum < 0) {
- lineNum = numLines-1;
+ if (searchSpecPtr->varPtr != NULL) {
+ Tcl_Obj *tmpPtr = Tcl_NewIntObj(numChars);
+ if (searchSpecPtr->all) {
+ if (searchSpecPtr->countPtr == NULL) {
+ searchSpecPtr->countPtr = Tcl_NewObj();
}
+ Tcl_ListObjAppendElement(NULL, searchSpecPtr->countPtr, tmpPtr);
} else {
- lineNum++;
- if (!searchWholeText) {
- if (lineNum > stopLine) {
- break;
- }
- } else if (lineNum >= numLines) {
- lineNum = 0;
- }
+ searchSpecPtr->countPtr = tmpPtr;
}
- Tcl_DStringSetLength(&line, 0);
- }
- done:
- Tcl_DStringFree(&line);
- if (noCase && exact) {
- Tcl_DStringFree(&patDString);
}
- if (patObj != NULL) {
- Tcl_DecrRefCount(patObj);
- }
- return code;
+ return 1;
}
/*
@@ -2403,105 +4313,158 @@ TextSearchCmd(textPtr, interp, argc, argv)
* Parses a string description of a set of tab stops.
*
* Results:
- * 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
- * the interp's result.
+ * 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 the interp's result.
*
* Side effects:
- * Memory is allocated for the structure that is returned. It is
- * up to the caller to free this structure when it is no longer
- * needed.
+ * Memory is allocated for the structure that is returned. It is up to
+ * the caller to free this structure when it is no longer needed.
*
*----------------------------------------------------------------------
*/
TkTextTabArray *
-TkTextGetTabs(interp, tkwin, string)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tk_Window tkwin; /* Window in which the tabs will be
- * used. */
- char *string; /* Description of the tab stops. See
- * the text manual entry for details. */
+TkTextGetTabs(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ TkText *textPtr, /* Information about the text widget. */
+ Tcl_Obj *stringPtr) /* Description of the tab stops. See the text
+ * manual entry for details. */
{
- int argc, i, count, c;
- CONST char **argv;
+ int objc, i, count;
+ Tcl_Obj **objv;
TkTextTabArray *tabArrayPtr;
TkTextTab *tabPtr;
Tcl_UniChar ch;
+ double prevStop, lastStop;
+ /*
+ * Map these strings to TkTextTabAlign values.
+ */
+ static const char *tabOptionStrings[] = {
+ "left", "right", "center", "numeric", NULL
+ };
- if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) {
+ if (Tcl_ListObjGetElements(interp, stringPtr, &objc, &objv) != TCL_OK) {
return NULL;
}
/*
- * First find out how many entries we need to allocate in the
- * tab array.
+ * First find out how many entries we need to allocate in the tab array.
*/
count = 0;
- for (i = 0; i < argc; i++) {
- c = argv[i][0];
+ for (i = 0; i < objc; i++) {
+ char c = Tcl_GetString(objv[i])[0];
if ((c != 'l') && (c != 'r') && (c != 'c') && (c != 'n')) {
count++;
}
}
/*
- * Parse the elements of the list one at a time to fill in the
- * array.
+ * Parse the elements of the list one at a time to fill in the array.
*/
tabArrayPtr = (TkTextTabArray *) ckalloc((unsigned)
(sizeof(TkTextTabArray) + (count-1)*sizeof(TkTextTab)));
tabArrayPtr->numTabs = 0;
- for (i = 0, tabPtr = &tabArrayPtr->tabs[0]; i < argc; i++, tabPtr++) {
- if (Tk_GetPixels(interp, tkwin, argv[i], &tabPtr->location)
- != TCL_OK) {
+ prevStop = 0.0;
+ lastStop = 0.0;
+ for (i = 0, tabPtr = &tabArrayPtr->tabs[0]; i < objc; i++, tabPtr++) {
+ int index;
+
+ /*
+ * This will round fractional pixels above 0.5 upwards, and otherwise
+ * downwards, to find the right integer pixel position.
+ */
+
+ if (Tk_GetPixelsFromObj(interp, textPtr->tkwin, objv[i],
+ &tabPtr->location) != TCL_OK) {
+ goto error;
+ }
+
+ if (tabPtr->location <= 0) {
+ Tcl_AppendResult(interp, "tab stop \"", Tcl_GetString(objv[i]),
+ "\" is not at a positive distance", NULL);
+ goto error;
+ }
+
+ prevStop = lastStop;
+ if (Tk_GetDoublePixelsFromObj (interp, textPtr->tkwin, objv[i],
+ &lastStop) != TCL_OK) {
goto error;
}
+
+ if (i > 0 && (tabPtr->location <= (tabPtr-1)->location)) {
+ /*
+ * This tab is actually to the left of the previous one, which is
+ * illegal.
+ */
+
+#ifdef _TK_ALLOW_DECREASING_TABS
+ /*
+ * Force the tab to be a typical character width to the right of
+ * the previous one, and update the 'lastStop' with the changed
+ * position.
+ */
+
+ if (textPtr->charWidth > 0) {
+ tabPtr->location = (tabPtr-1)->location + textPtr->charWidth;
+ } else {
+ tabPtr->location = (tabPtr-1)->location + 8;
+ }
+ lastStop = tabPtr->location;
+#else
+ Tcl_AppendResult(interp,
+ "tabs must be monotonically increasing, but \"",
+ Tcl_GetString(objv[i]),
+ "\" is smaller than or equal to the previous tab",
+ NULL);
+ goto error;
+#endif /* _TK_ALLOW_DECREASING_TABS */
+ }
+
tabArrayPtr->numTabs++;
/*
- * See if there is an explicit alignment in the next list
- * element. Otherwise just use "left".
+ * See if there is an explicit alignment in the next list element.
+ * Otherwise just use "left".
*/
tabPtr->alignment = LEFT;
- if ((i+1) == argc) {
+ if ((i+1) == objc) {
continue;
}
- Tcl_UtfToUniChar(argv[i+1], &ch);
+
+ /*
+ * There may be a more efficient way of getting this.
+ */
+
+ Tcl_UtfToUniChar(Tcl_GetString(objv[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;
- } else if ((c == 'r') && (strncmp(argv[i], "right",
- strlen(argv[i])) == 0)) {
- tabPtr->alignment = RIGHT;
- } else if ((c == 'c') && (strncmp(argv[i], "center",
- strlen(argv[i])) == 0)) {
- tabPtr->alignment = CENTER;
- } else if ((c == 'n') && (strncmp(argv[i],
- "numeric", strlen(argv[i])) == 0)) {
- tabPtr->alignment = NUMERIC;
- } else {
- Tcl_AppendResult(interp, "bad tab alignment \"",
- argv[i], "\": must be left, right, center, or numeric",
- (char *) NULL);
+
+ if (Tcl_GetIndexFromObj(interp, objv[i], tabOptionStrings,
+ "tab alignment", 0, &index) != TCL_OK) {
goto error;
}
+ tabPtr->alignment = ((TkTextTabAlign)index);
}
- ckfree((char *) argv);
+
+ /*
+ * For when we need to interpolate tab stops, store these two so we know
+ * the tab stop size to very high precision. With the above checks, we can
+ * guarantee that tabIncrement is strictly positive here.
+ */
+
+ tabArrayPtr->lastTab = lastStop;
+ tabArrayPtr->tabIncrement = lastStop - prevStop;
+
return tabArrayPtr;
- error:
+ error:
ckfree((char *) tabArrayPtr);
- ckfree((char *) argv);
return NULL;
}
@@ -2511,8 +4474,8 @@ TkTextGetTabs(interp, tkwin, string)
* TextDumpCmd --
*
* Return information about the text, tags, marks, and embedded windows
- * and images in a text widget. See the man page for the description
- * of the text dump operation for all the details.
+ * and images in a text widget. See the man page for the description of
+ * the text dump operation for all the details.
*
* Results:
* A standard Tcl result.
@@ -2525,21 +4488,21 @@ TkTextGetTabs(interp, tkwin, string)
*/
static int
-TextDumpCmd(textPtr, interp, argc, argv)
- register TkText *textPtr; /* Information about text widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. Someone else has already
+TextDumpCmd(
+ register TkText *textPtr, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. Someone else has already
* parsed this command enough to know that
- * argv[1] is "dump". */
+ * objv[1] is "dump". */
{
TkTextIndex index1, index2;
int arg;
- int lineno; /* Current line number */
- int what = 0; /* bitfield to select segment types */
- int atEnd; /* True if dumping up to logical end */
+ int lineno; /* Current line number. */
+ int what = 0; /* bitfield to select segment types. */
+ int atEnd; /* True if dumping up to logical end. */
TkTextLine *linePtr;
- CONST char *command = NULL; /* Script callback to apply to segments */
+ Tcl_Obj *command = NULL; /* Script callback to apply to segments. */
#define TK_DUMP_TEXT 0x1
#define TK_DUMP_MARK 0x2
#define TK_DUMP_TAG 0x4
@@ -2547,116 +4510,189 @@ TextDumpCmd(textPtr, interp, argc, argv)
#define TK_DUMP_IMG 0x10
#define TK_DUMP_ALL (TK_DUMP_TEXT|TK_DUMP_MARK|TK_DUMP_TAG| \
TK_DUMP_WIN|TK_DUMP_IMG)
-
- for (arg=2 ; argv[arg] != (char *) NULL ; arg++) {
- size_t len;
- if (argv[arg][0] != '-') {
+ static const char *optStrings[] = {
+ "-all", "-command", "-image", "-mark", "-tag", "-text", "-window",
+ NULL
+ };
+ enum opts {
+ DUMP_ALL, DUMP_CMD, DUMP_IMG, DUMP_MARK, DUMP_TAG, DUMP_TXT, DUMP_WIN
+ };
+
+ for (arg=2 ; arg < objc ; arg++) {
+ int index;
+ if (Tcl_GetString(objv[arg])[0] != '-') {
break;
}
- len = strlen(argv[arg]);
- if (strncmp("-all", argv[arg], len) == 0) {
+ if (Tcl_GetIndexFromObj(interp, objv[arg], optStrings, "option", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch ((enum opts) index) {
+ case DUMP_ALL:
what = TK_DUMP_ALL;
- } else if (strncmp("-text", argv[arg], len) == 0) {
+ break;
+ case DUMP_TXT:
what |= TK_DUMP_TEXT;
- } else if (strncmp("-tag", argv[arg], len) == 0) {
+ break;
+ case DUMP_TAG:
what |= TK_DUMP_TAG;
- } else if (strncmp("-mark", argv[arg], len) == 0) {
+ break;
+ case DUMP_MARK:
what |= TK_DUMP_MARK;
- } else if (strncmp("-image", argv[arg], len) == 0) {
+ break;
+ case DUMP_IMG:
what |= TK_DUMP_IMG;
- } else if (strncmp("-window", argv[arg], len) == 0) {
+ break;
+ case DUMP_WIN:
what |= TK_DUMP_WIN;
- } else if (strncmp("-command", argv[arg], len) == 0) {
+ break;
+ case DUMP_CMD:
arg++;
- if (arg >= argc) {
- Tcl_AppendResult(interp, "Usage: ", argv[0], " dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?", NULL);
+ if (arg >= objc) {
+ Tcl_AppendResult(interp, "Usage: ", Tcl_GetString(objv[0]),
+ " dump ?-all -image -text -mark -tag -window? ",
+ "?-command script? index ?index2?", NULL);
return TCL_ERROR;
}
- command = argv[arg];
- } else {
- Tcl_AppendResult(interp, "Usage: ", argv[0], " dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?", NULL);
- return TCL_ERROR;
+ command = objv[arg];
+ break;
+ default:
+ Tcl_Panic("unexpected switch fallthrough");
}
}
- if (arg >= argc) {
- Tcl_AppendResult(interp, "Usage: ", argv[0], " dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?", NULL);
+ if (arg >= objc || arg+2 < objc) {
+ Tcl_AppendResult(interp, "Usage: ", Tcl_GetString(objv[0]),
+ " dump ?-all -image -text -mark -tag -window? ",
+ "?-command script? index ?index2?", NULL);
return TCL_ERROR;
}
if (what == 0) {
what = TK_DUMP_ALL;
}
- if (TkTextGetIndex(interp, textPtr, argv[arg], &index1) != TCL_OK) {
+ if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index1) != TCL_OK) {
return TCL_ERROR;
}
- lineno = TkBTreeLineIndex(index1.linePtr);
arg++;
atEnd = 0;
- if (argc == arg) {
- TkTextIndexForwChars(&index1, 1, &index2);
+ if (objc == arg) {
+ TkTextIndexForwChars(NULL, &index1, 1, &index2, COUNT_INDICES);
} else {
- if (TkTextGetIndex(interp, textPtr, argv[arg], &index2) != TCL_OK) {
+ int length;
+ char *str;
+
+ if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) {
return TCL_ERROR;
}
- if (strncmp(argv[arg], "end", strlen(argv[arg])) == 0) {
+ str = Tcl_GetStringFromObj(objv[arg], &length);
+ if (strncmp(str, "end", (unsigned)length) == 0) {
atEnd = 1;
}
}
if (TkTextIndexCmp(&index1, &index2) >= 0) {
return TCL_OK;
}
+ lineno = TkBTreeLinesTo(textPtr, index1.linePtr);
if (index1.linePtr == index2.linePtr) {
DumpLine(interp, textPtr, what, index1.linePtr,
- index1.byteIndex, index2.byteIndex, lineno, command);
+ index1.byteIndex, index2.byteIndex, lineno, command);
} else {
- DumpLine(interp, textPtr, what, index1.linePtr,
+ int textChanged;
+ int lineend = TkBTreeLinesTo(textPtr, index2.linePtr);
+ int endByteIndex = index2.byteIndex;
+
+ textChanged = DumpLine(interp, textPtr, what, index1.linePtr,
index1.byteIndex, 32000000, lineno, command);
- linePtr = index1.linePtr;
- while ((linePtr = TkBTreeNextLine(linePtr)) != (TkTextLine *)NULL) {
+ if (textChanged) {
+ if (textPtr->flags & DESTROYED) {
+ return TCL_OK;
+ }
+ linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree,
+ textPtr, lineno);
+ textChanged = 0;
+ } else {
+ linePtr = index1.linePtr;
+ }
+ while ((linePtr = TkBTreeNextLine(textPtr, linePtr)) != NULL) {
lineno++;
- if (linePtr == index2.linePtr) {
+ if (lineno == lineend) {
break;
}
- DumpLine(interp, textPtr, what, linePtr, 0, 32000000,
+ textChanged = DumpLine(interp, textPtr, what, linePtr, 0, 32000000,
lineno, command);
+ if (textChanged) {
+ if (textPtr->flags & DESTROYED) {
+ return TCL_OK;
+ }
+ linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree,
+ textPtr, lineno);
+ textChanged = 0;
+ }
+ }
+ if (linePtr != NULL) {
+ DumpLine(interp, textPtr, what, linePtr, 0, endByteIndex, lineno,
+ command);
+ if (textPtr->flags & DESTROYED) {
+ return TCL_OK;
+ }
}
- DumpLine(interp, textPtr, what, index2.linePtr, 0,
- 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);
+ if (textPtr->flags & DESTROYED) {
+ return TCL_OK;
+ }
+
+ /*
+ * Re-get the end index, in case it has changed.
+ */
+ if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ DumpLine(interp, textPtr, what & ~TK_DUMP_TEXT, index2.linePtr,
+ 0, 1, lineno, command);
}
return TCL_OK;
}
/*
+ *----------------------------------------------------------------------
+ *
* DumpLine
- * Return information about a given text line from character
- * position "start" up to, but not including, "end".
+ *
+ * Return information about a given text line from character position
+ * "start" up to, but not including, "end".
*
* Results:
- * A standard Tcl result.
+ * Returns 1 if the command callback made any changes to the text widget
+ * which will have invalidated internal structures such as TkTextSegment,
+ * TkTextIndex, pointers. Our caller can then take action to recompute
+ * such entities. Returns 0 otherwise.
*
* Side effects:
- * None, but see DumpSegment.
+ * None, but see DumpSegment which can have arbitrary side-effects
+ *
+ *----------------------------------------------------------------------
*/
-static void
-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 startByte, endByte; /* Byte range to dump */
- int lineno; /* Line number for indices dump */
- CONST char *command; /* Script to apply to the segment */
+
+static int
+DumpLine(
+ Tcl_Interp *interp,
+ TkText *textPtr,
+ int what, /* Bit flags to select segment types. */
+ TkTextLine *linePtr, /* The current line. */
+ int startByte, int endByte, /* Byte range to dump. */
+ int lineno, /* Line number for indices dump. */
+ Tcl_Obj *command) /* Script to apply to the segment. */
{
- int offset;
- TkTextSegment *segPtr, *nextPtr;
+ TkTextSegment *segPtr;
TkTextIndex index;
+ int offset = 0, textChanged = 0;
+
/*
* Must loop through line looking at its segments.
* character
@@ -2666,335 +4702,485 @@ DumpLine(interp, textPtr, what, linePtr, startByte, endByte, lineno, command)
* window
*/
- for (offset = 0, segPtr = linePtr->segPtr ;
- (offset < endByte) && (segPtr != (TkTextSegment *)NULL) ;
- offset += segPtr->size, segPtr = nextPtr) {
- nextPtr = segPtr->nextPtr;
+ segPtr = linePtr->segPtr;
+ while ((offset < endByte) && (segPtr != NULL)) {
+ int lineChanged = 0;
+ int currentSize = segPtr->size;
+
if ((what & TK_DUMP_TEXT) && (segPtr->typePtr == &tkTextCharType) &&
- (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 > endByte) {
+ (offset + currentSize > startByte)) {
+ int last = currentSize; /* Index of last char in seg. */
+ int first = 0; /* Index of first char in seg. */
+
+ if (offset + currentSize > endByte) {
last = endByte - offset;
}
if (startByte > offset) {
first = startByte - offset;
}
- savedChar = segPtr->body.chars[last];
- segPtr->body.chars[last] = '\0';
-
- TkTextMakeByteIndex(textPtr->tree, lineno, offset + first, &index);
- DumpSegment(interp, "text", segPtr->body.chars + first,
- command, &index, what);
- segPtr->body.chars[last] = savedChar;
+ if (last != currentSize) {
+ /*
+ * To avoid modifying the string in place we copy over just
+ * the segment that we want. Since DumpSegment can modify the
+ * text, we could not confidently revert the modification
+ * here.
+ */
+
+ int length = last - first;
+ char *range = ckalloc((length + 1) * sizeof(char));
+
+ memcpy(range, segPtr->body.chars + first,
+ length * sizeof(char));
+ range[length] = '\0';
+
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ lineno, offset + first, &index);
+ lineChanged = DumpSegment(textPtr, interp, "text", range,
+ command, &index, what);
+ ckfree(range);
+ } else {
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ lineno, offset + first, &index);
+ lineChanged = DumpSegment(textPtr, interp, "text",
+ segPtr->body.chars + first, command, &index, what);
+ }
} 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);
-
- TkTextMakeByteIndex(textPtr->tree, lineno, offset, &index);
- DumpSegment(interp, "mark", name, command, &index, what);
+ char *name;
+ TkTextMark *markPtr = (TkTextMark *) &segPtr->body;
+
+ if (segPtr == textPtr->insertMarkPtr) {
+ name = "insert";
+ } else if (segPtr == textPtr->currentMarkPtr) {
+ name = "current";
+ } else if (markPtr->hPtr == NULL) {
+ name = NULL;
+ lineChanged = 0;
+ } else {
+ name = Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable,
+ markPtr->hPtr);
+ }
+ if (name != NULL) {
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ lineno, offset, &index);
+ lineChanged = DumpSegment(textPtr, interp, "mark", name,
+ command, &index, what);
+ }
} else if ((what & TK_DUMP_TAG) &&
- (segPtr->typePtr == &tkTextToggleOnType)) {
- TkTextMakeByteIndex(textPtr->tree, lineno, offset, &index);
- DumpSegment(interp, "tagon",
- segPtr->body.toggle.tagPtr->name,
- command, &index, what);
- } else if ((what & TK_DUMP_TAG) &&
- (segPtr->typePtr == &tkTextToggleOffType)) {
- TkTextMakeByteIndex(textPtr->tree, lineno, offset, &index);
- DumpSegment(interp, "tagoff",
- segPtr->body.toggle.tagPtr->name,
- command, &index, what);
- } else if ((what & TK_DUMP_IMG) &&
- (segPtr->typePtr->name[0] == 'i')) {
+ (segPtr->typePtr == &tkTextToggleOnType)) {
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ lineno, offset, &index);
+ lineChanged = DumpSegment(textPtr, interp, "tagon",
+ segPtr->body.toggle.tagPtr->name, command, &index,
+ what);
+ } else if ((what & TK_DUMP_TAG) &&
+ (segPtr->typePtr == &tkTextToggleOffType)) {
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ lineno, offset, &index);
+ lineChanged = DumpSegment(textPtr, interp, "tagoff",
+ segPtr->body.toggle.tagPtr->name, command, &index,
+ what);
+ } else if ((what & TK_DUMP_IMG) &&
+ (segPtr->typePtr->name[0] == 'i')) {
TkTextEmbImage *eiPtr = (TkTextEmbImage *)&segPtr->body;
- char *name = (eiPtr->name == NULL) ? "" : eiPtr->name;
- TkTextMakeByteIndex(textPtr->tree, lineno, offset, &index);
- DumpSegment(interp, "image", name,
+ char *name = (eiPtr->name == NULL) ? "" : eiPtr->name;
+
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ lineno, offset, &index);
+ lineChanged = DumpSegment(textPtr, interp, "image", name,
command, &index, what);
- } else if ((what & TK_DUMP_WIN) &&
- (segPtr->typePtr->name[0] == 'w')) {
+ } else if ((what & TK_DUMP_WIN) &&
+ (segPtr->typePtr->name[0] == 'w')) {
TkTextEmbWindow *ewPtr = (TkTextEmbWindow *)&segPtr->body;
char *pathname;
+
if (ewPtr->tkwin == (Tk_Window) NULL) {
pathname = "";
} else {
pathname = Tk_PathName(ewPtr->tkwin);
}
- TkTextMakeByteIndex(textPtr->tree, lineno, offset, &index);
- DumpSegment(interp, "window", pathname,
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ lineno, offset, &index);
+ lineChanged = DumpSegment(textPtr, interp, "window", pathname,
command, &index, what);
}
}
- if (nextPtr != segPtr->nextPtr) {
+ offset += currentSize;
+ if (lineChanged) {
+ TkTextSegment *newSegPtr;
+ int newOffset = 0;
+
+ textChanged = 1;
+
/*
- * Someone modified the text widget while we were dumping.
- * Just stop dumping. [Bug 1414171]
+ * Our indices are no longer valid.
*/
- break;
+
+ if (textPtr->flags & DESTROYED) {
+ return textChanged;
+ }
+ linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree,
+ textPtr, lineno);
+ newSegPtr = linePtr->segPtr;
+ if (segPtr == newSegPtr) {
+ segPtr = segPtr->nextPtr;
+ } else {
+ while ((newOffset < endByte) && (newOffset < offset)
+ && (newSegPtr != NULL)) {
+ newOffset += currentSize;
+ newSegPtr = newSegPtr->nextPtr;
+ if (segPtr == newSegPtr) {
+ break;
+ }
+ }
+ if (segPtr != newSegPtr && newOffset == offset
+ && currentSize == 0) {
+ TkTextSegment *searchPtr = newSegPtr;
+
+ while (searchPtr != NULL && searchPtr->size == 0) {
+ if (searchPtr == segPtr) {
+ newSegPtr = searchPtr;
+ break;
+ }
+ searchPtr = searchPtr->nextPtr;
+ }
+ }
+ segPtr = newSegPtr;
+ if (segPtr != NULL) {
+ segPtr = segPtr->nextPtr;
+ }
+ }
+ } else {
+ segPtr = segPtr->nextPtr;
}
}
+ return textChanged;
}
/*
+ *----------------------------------------------------------------------
+ *
* DumpSegment
- * Either append information about the current segment to the result,
- * or make a script callback with that information as arguments.
+ *
+ * Either append information about the current segment to the result, or
+ * make a script callback with that information as arguments.
*
* Results:
- * None
+ * Returns 1 if the command callback made any changes to the text widget
+ * which will have invalidated internal structures such as TkTextSegment,
+ * TkTextIndex, pointers. Our caller can then take action to recompute
+ * such entities. Returns 0 otherwise.
*
* Side effects:
* Either evals the callback or appends elements to the result string.
+ * The callback can have arbitrary side-effects.
+ *
+ *----------------------------------------------------------------------
*/
+
static int
-DumpSegment(interp, key, value, command, index, what)
- Tcl_Interp *interp;
- char *key; /* Segment type key */
- char *value; /* Segment value */
- CONST char *command; /* Script callback */
- TkTextIndex *index; /* index with line/byte position info */
- int what; /* Look for TK_DUMP_INDEX bit */
+DumpSegment(
+ TkText *textPtr,
+ Tcl_Interp *interp,
+ const char *key, /* Segment type key. */
+ const char *value, /* Segment value. */
+ Tcl_Obj *command, /* Script callback. */
+ const TkTextIndex *index, /* index with line/byte position info. */
+ int what) /* Look for TK_DUMP_INDEX bit. */
{
- char buffer[TCL_INTEGER_SPACE*2];
- TkTextPrintIndex(index, buffer);
+ char buffer[TK_POS_CHARS];
+
+ TkTextPrintIndex(textPtr, index, buffer);
if (command == NULL) {
Tcl_AppendElement(interp, key);
Tcl_AppendElement(interp, value);
Tcl_AppendElement(interp, buffer);
- return TCL_OK;
+ return 0;
} else {
- CONST char *argv[4];
+ const char *argv[4];
char *list;
- int result;
+ int oldStateEpoch = TkBTreeEpoch(textPtr->sharedTextPtr->tree);
+
argv[0] = key;
argv[1] = value;
argv[2] = buffer;
argv[3] = NULL;
list = Tcl_Merge(3, argv);
- result = Tcl_VarEval(interp, command, " ", list, (char *) NULL);
+ Tcl_VarEval(interp, Tcl_GetString(command), " ", list, NULL);
ckfree(list);
- return result;
+ if ((textPtr->flags & DESTROYED) ||
+ TkBTreeEpoch(textPtr->sharedTextPtr->tree) != oldStateEpoch) {
+ return 1;
+ } else {
+ return 0;
+ }
}
}
/*
+ *----------------------------------------------------------------------
+ *
* TextEditUndo --
- * undo the last change.
+ *
+ * Undo the last change.
*
* Results:
- * None
+ * None.
*
* Side effects:
- * None.
+ * Apart from manipulating the undo and redo stacks, the state of the
+ * rest of the widget may also change (due to whatever is being undone).
+ *
+ *----------------------------------------------------------------------
*/
static int
-TextEditUndo(textPtr)
- TkText *textPtr; /* Overall information about text widget. */
+TextEditUndo(
+ TkText *textPtr) /* Overall information about text widget. */
{
int status;
- if (!textPtr->undo) {
+ if (!textPtr->sharedTextPtr->undo) {
return TCL_OK;
}
- /* Turn off the undo feature */
- textPtr->undo = 0;
+ /*
+ * Turn off the undo feature while we revert a compound action, setting
+ * the dirty handling mode to undo for the duration (unless it is
+ * 'fixed').
+ */
- /* Set dirty mode to undo, unless it is fixed */
- if (textPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
- textPtr->dirtyMode = TK_TEXT_DIRTY_UNDO;
+ textPtr->sharedTextPtr->undo = 0;
+ if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
+ textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_UNDO;
}
- /* revert one compound action */
- status = TkUndoRevert(textPtr->undoStack);
+ status = TkUndoRevert(textPtr->sharedTextPtr->undoStack);
- /* Restore dirty mode */
- if (textPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
- textPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
+ if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
+ textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
}
-
- /* Turn back on the undo feature */
- textPtr->undo = 1;
+ textPtr->sharedTextPtr->undo = 1;
return status;
}
/*
+ *----------------------------------------------------------------------
+ *
* TextEditRedo --
- * redo the last undone change.
+ *
+ * Redo the last undone change.
*
* Results:
- * None
+ * None.
*
* Side effects:
- * None.
+ * Apart from manipulating the undo and redo stacks, the state of the
+ * rest of the widget may also change (due to whatever is being redone).
+ *
+ *----------------------------------------------------------------------
*/
static int
-TextEditRedo(textPtr)
- TkText *textPtr; /* Overall information about text widget. */
+TextEditRedo(
+ TkText *textPtr) /* Overall information about text widget. */
{
int status;
- if (!textPtr->undo) {
+ if (!textPtr->sharedTextPtr->undo) {
return TCL_OK;
}
- /* Turn off the undo feature temporarily */
- textPtr->undo = 0;
+ /*
+ * Turn off the undo feature temporarily while we revert a previously
+ * undone compound action, setting the dirty handling mode to redo for the
+ * duration (unless it is 'fixed').
+ */
- /* Set dirty mode to redo, unless it is fixed */
- if (textPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
- textPtr->dirtyMode = TK_TEXT_DIRTY_REDO;
+ textPtr->sharedTextPtr->undo = 0;
+ if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
+ textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_REDO;
}
- /* reapply one compound action */
- status = TkUndoApply(textPtr->undoStack);
+ status = TkUndoApply(textPtr->sharedTextPtr->undoStack);
- /* Restore dirty mode */
- if (textPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
- textPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
+ if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
+ textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
}
-
- /* Turn back on the undo feature */
- textPtr->undo = 1;
-
+ textPtr->sharedTextPtr->undo = 1;
return status;
}
/*
+ *----------------------------------------------------------------------
+ *
* TextEditCmd --
*
- * Handle the subcommands to "$text edit ...".
- * See documentation for details.
+ * Handle the subcommands to "$text edit ...". See documentation for
+ * details.
*
* Results:
- * None
+ * None
*
* Side effects:
- * None.
+ * None.
+ *
+ *----------------------------------------------------------------------
*/
static int
-TextEditCmd(textPtr, interp, argc, argv)
- TkText *textPtr; /* Information about text widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. */
+TextEditCmd(
+ TkText *textPtr, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- int c;
- size_t length;
+ int index;
- if (argc < 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " edit option ?arg arg ...?\"", (char *) NULL);
+ static const char *editOptionStrings[] = {
+ "modified", "redo", "reset", "separator", "undo", NULL
+ };
+ enum editOptions {
+ EDIT_MODIFIED, EDIT_REDO, EDIT_RESET, EDIT_SEPARATOR, EDIT_UNDO
+ };
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?");
return TCL_ERROR;
}
- c = argv[2][0];
- length = strlen(argv[2]);
- if ((c == 'm') && (strncmp(argv[2], "modified", length) == 0)) {
- if (argc == 3) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(textPtr->isDirty));
- } else if (argc != 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " edit modified ?boolean?\"", (char *) NULL);
+
+ if (Tcl_GetIndexFromObj(interp, objv[2], editOptionStrings,
+ "edit option", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ switch ((enum editOptions) index) {
+ case EDIT_MODIFIED:
+ if (objc == 3) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewBooleanObj(textPtr->sharedTextPtr->isDirty));
+ } else if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "?boolean?");
return TCL_ERROR;
} else {
- int setModified, wasModified = textPtr->isDirty;
+ int setModified, oldModified;
- if (Tcl_GetBoolean(interp, argv[3], &setModified) != TCL_OK) {
+ if (Tcl_GetBooleanFromObj(interp, objv[3],
+ &setModified) != TCL_OK) {
return TCL_ERROR;
}
/*
- * Set or reset the dirty info, and trigger a Modified event (.
+ * Set or reset the dirty info, and trigger a Modified event.
*/
setModified = setModified ? 1 : 0;
- textPtr->isDirty = setModified;
+ oldModified = textPtr->sharedTextPtr->isDirty;
+ textPtr->sharedTextPtr->isDirty = setModified;
if (setModified) {
- textPtr->dirtyMode = TK_TEXT_DIRTY_FIXED;
+ textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_FIXED;
} else {
- textPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
+ textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
}
- if ((!wasModified) != (!setModified)) {
+
+ /*
+ * Only issue the <<Modified>> event if the flag actually changed.
+ * However, degree of modified-ness doesn't matter. [Bug 1799782]
+ */
+
+ if ((!oldModified) != (!setModified)) {
GenerateModifiedEvent(textPtr);
}
- }
- } else if ((c == 'r') && (strncmp(argv[2], "redo", length) == 0)
- && (length >= 3)) {
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " edit redo\"", (char *) NULL);
+ }
+ break;
+ case EDIT_REDO:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
- if ( TextEditRedo(textPtr) ) {
- Tcl_AppendResult(interp, "nothing to redo", (char *) NULL);
+ if (TextEditRedo(textPtr)) {
+ Tcl_AppendResult(interp, "nothing to redo", NULL);
return TCL_ERROR;
- }
- } else if ((c == 'r') && (strncmp(argv[2], "reset", length) == 0)
- && (length >= 3)) {
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " edit reset\"", (char *) NULL);
+ }
+ break;
+ case EDIT_RESET:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
- TkUndoClearStacks(textPtr->undoStack);
- } else if ((c == 's') && (strncmp(argv[2], "separator", length) == 0)) {
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " edit separator\"", (char *) NULL);
+ TkUndoClearStacks(textPtr->sharedTextPtr->undoStack);
+ break;
+ case EDIT_SEPARATOR:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
- TkUndoInsertUndoSeparator(textPtr->undoStack);
- } else if ((c == 'u') && (strncmp(argv[2], "undo", length) == 0)) {
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " edit undo\"", (char *) NULL);
+ TkUndoInsertUndoSeparator(textPtr->sharedTextPtr->undoStack);
+ break;
+ case EDIT_UNDO:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
- if ( TextEditUndo(textPtr) ) {
- Tcl_AppendResult(interp, "nothing to undo",
- (char *) NULL);
+ if (TextEditUndo(textPtr)) {
+ Tcl_AppendResult(interp, "nothing to undo", NULL);
return TCL_ERROR;
- }
- } else {
- Tcl_AppendResult(interp, "bad edit option \"", argv[2],
- "\": must be modified, redo, reset, separator or undo",
- (char *) NULL);
- return TCL_ERROR;
+ }
+ break;
}
-
return TCL_OK;
}
/*
+ *----------------------------------------------------------------------
+ *
* TextGetText --
- * Returns the text from indexPtr1 to indexPtr2, placing that text
- * in the Tcl_DString given. That DString should be free or uninitialized.
+ *
+ * Returns the text from indexPtr1 to indexPtr2, placing that text in a
+ * string object which is returned with a refCount of zero.
+ *
+ * Since the amount of text may potentially be several megabytes (e.g.
+ * in text editors built on the text widget), efficiency is very
+ * important. We may want to investigate the efficiency of the
+ * Tcl_AppendToObj more carefully (e.g. if we know we are going to be
+ * appending several thousand lines, we could attempt to pre-allocate a
+ * larger space).
+ *
+ * Also the result is built up as a utf-8 string, but, if we knew we
+ * wanted it as Unicode, we could potentially save a huge conversion by
+ * building it up as Unicode directly. This could be as simple as
+ * replacing Tcl_NewObj by Tcl_NewUnicodeObj.
*
* Results:
- * None.
+ * Tcl_Obj of string type containing the specified text. If the
+ * visibleOnly flag is set to 1, then only those characters which are not
+ * elided will be returned. Otherwise (flag is 0) all characters in the
+ * given range are returned.
*
* Side effects:
- * Memory will be allocated for the DString. Remember to free it.
+ * Memory will be allocated for the new object. Remember to free it if it
+ * isn't going to be stored appropriately.
+ *
+ *----------------------------------------------------------------------
*/
-static void
-TextGetText(indexPtr1,indexPtr2, dsPtr)
- TkTextIndex *indexPtr1;
- TkTextIndex *indexPtr2;
- Tcl_DString *dsPtr;
+static Tcl_Obj *
+TextGetText(
+ const TkText *textPtr, /* Information about text widget. */
+ const TkTextIndex *indexPtr1,
+ /* Get text from this index... */
+ const TkTextIndex *indexPtr2,
+ /* ...to this index. */
+ int visibleOnly) /* If non-zero, then only return non-elided
+ * characters. */
{
TkTextIndex tmpIndex;
- Tcl_DStringInit(dsPtr);
-
- TkTextMakeByteIndex(indexPtr1->tree, TkBTreeLineIndex(indexPtr1->linePtr),
+ Tcl_Obj *resultPtr = Tcl_NewObj();
+
+ TkTextMakeByteIndex(indexPtr1->tree, textPtr,
+ TkBTreeLinesTo(textPtr, indexPtr1->linePtr),
indexPtr1->byteIndex, &tmpIndex);
if (TkTextIndexCmp(indexPtr1, indexPtr2) < 0) {
@@ -3005,26 +5191,38 @@ TextGetText(indexPtr1,indexPtr2, dsPtr)
segPtr = TkTextIndexToSeg(&tmpIndex, &offset);
last = segPtr->size;
if (tmpIndex.linePtr == indexPtr2->linePtr) {
- int last2;
+ /*
+ * The last line that was requested must be handled carefully,
+ * because we may need to break out of this loop in the middle
+ * of the line.
+ */
if (indexPtr2->byteIndex == tmpIndex.byteIndex) {
break;
- }
- last2 = indexPtr2->byteIndex - tmpIndex.byteIndex + offset;
- if (last2 < last) {
- last = last2;
+ } else {
+ int last2 = indexPtr2->byteIndex - tmpIndex.byteIndex
+ + offset;
+
+ if (last2 < last) {
+ last = last2;
+ }
}
}
if (segPtr->typePtr == &tkTextCharType) {
- Tcl_DStringAppend(dsPtr, segPtr->body.chars + offset,
- last - offset);
+ if (!visibleOnly || !TkTextIsElided(textPtr,&tmpIndex,NULL)) {
+ Tcl_AppendToObj(resultPtr, segPtr->body.chars + offset,
+ last - offset);
+ }
}
- TkTextIndexForwBytes(&tmpIndex, last-offset, &tmpIndex);
+ TkTextIndexForwBytes(textPtr, &tmpIndex, last-offset, &tmpIndex);
}
}
+ return resultPtr;
}
/*
+ *----------------------------------------------------------------------
+ *
* GenerateModifiedEvent --
*
* Send an event that the text was modified. This is equivalent to
@@ -3035,68 +5233,1464 @@ TextGetText(indexPtr1,indexPtr2, dsPtr)
*
* Side effects:
* May force the text window into existence.
+ *
+ *----------------------------------------------------------------------
*/
static void
GenerateModifiedEvent(
TkText *textPtr) /* Information about text widget. */
{
- XEvent event;
+ union {XEvent general; XVirtualEvent virtual;} event;
Tk_MakeWindowExist(textPtr->tkwin);
memset(&event, 0, sizeof(event));
- event.xany.type = VirtualEvent;
- event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin));
- event.xany.send_event = False;
- event.xany.window = Tk_WindowId(textPtr->tkwin);
- event.xany.display = Tk_Display(textPtr->tkwin);
- ((XVirtualEvent *) &event)->name = Tk_GetUid("Modified");
- Tk_HandleEvent(&event);
+ event.general.xany.type = VirtualEvent;
+ event.general.xany.serial = NextRequest(Tk_Display(textPtr->tkwin));
+ event.general.xany.send_event = False;
+ event.general.xany.window = Tk_WindowId(textPtr->tkwin);
+ event.general.xany.display = Tk_Display(textPtr->tkwin);
+ event.virtual.name = Tk_GetUid("Modified");
+ Tk_HandleEvent(&event.general);
}
/*
- * updateDirtyFlag --
- * updates the dirtyness of the text widget
+ *----------------------------------------------------------------------
+ *
+ * UpdateDirtyFlag --
+ *
+ * Updates the dirtyness of the text widget
*
* Results:
- * None
+ * None
*
* Side effects:
- * None.
+ * None.
+ *
+ *----------------------------------------------------------------------
*/
static void
-updateDirtyFlag(textPtr)
- TkText *textPtr; /* Information about text widget. */
+UpdateDirtyFlag(
+ TkSharedText *sharedTextPtr)/* Information about text widget. */
{
int oldDirtyFlag;
+ TkText *textPtr;
+
+ /*
+ * If we've been forced to be dirty, we stay dirty (until explicitly
+ * reset, of course).
+ */
+
+ if (sharedTextPtr->dirtyMode == TK_TEXT_DIRTY_FIXED) {
+ return;
+ }
+
+ if (sharedTextPtr->isDirty < 0
+ && sharedTextPtr->dirtyMode == TK_TEXT_DIRTY_NORMAL) {
+ /*
+ * If dirty flag is negative, only redo operations can make it zero
+ * again. If we do a normal operation, it can never become zero any
+ * more (other than by explicit reset).
+ */
- if (textPtr->dirtyMode == TK_TEXT_DIRTY_FIXED) {
+ sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_FIXED;
return;
}
+ oldDirtyFlag = sharedTextPtr->isDirty;
+ if (sharedTextPtr->dirtyMode == TK_TEXT_DIRTY_UNDO) {
+ sharedTextPtr->isDirty--;
+ } else {
+ sharedTextPtr->isDirty++;
+ }
+
+ if (sharedTextPtr->isDirty == 0 || oldDirtyFlag == 0) {
+ for (textPtr = sharedTextPtr->peers; textPtr != NULL;
+ textPtr = textPtr->next) {
+ GenerateModifiedEvent(textPtr);
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SearchPerform --
+ *
+ * Overall control of search process. Is given a pattern, a starting
+ * index and an ending index, and attempts to perform a search. This
+ * function is actually completely independent of Tk, and could in the
+ * future be split off.
+ *
+ * Results:
+ * Standard Tcl result code. In particular, if fromPtr or toPtr are not
+ * considered valid by the 'lineIndexProc', an error will be thrown and
+ * no search performed.
+ *
+ * Side effects:
+ * See 'SearchCore'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SearchPerform(
+ Tcl_Interp *interp, /* For error messages. */
+ SearchSpec *searchSpecPtr, /* Search parameters. */
+ Tcl_Obj *patObj, /* Contains an exact string or a regexp
+ * pattern. Must have a refCount > 0. */
+ Tcl_Obj *fromPtr, /* Contains information describing the first
+ * index. */
+ Tcl_Obj *toPtr) /* NULL or information describing the last
+ * index. */
+{
/*
- * If dirty flag is negative, only redo operations can make it zero again.
- * If we do a normal operation, it can never become zero anymore.
+ * Find the starting line and starting offset (measured in Unicode chars
+ * for regexp search, utf-8 bytes for exact search).
*/
- if (textPtr->isDirty < 0 && textPtr->dirtyMode == TK_TEXT_DIRTY_NORMAL) {
- textPtr->dirtyMode = TK_TEXT_DIRTY_FIXED;
- return;
+
+ if ((*searchSpecPtr->lineIndexProc)(interp, fromPtr, searchSpecPtr,
+ &searchSpecPtr->startLine,
+ &searchSpecPtr->startOffset) != TCL_OK) {
+ return TCL_ERROR;
}
- oldDirtyFlag = textPtr->isDirty;
+ /*
+ * Find the optional end location, similarly.
+ */
- switch (textPtr->dirtyMode) {
- case TK_TEXT_DIRTY_UNDO:
- textPtr->isDirty--;
- break;
- default:
- textPtr->isDirty++;
- break;
+ if (toPtr != NULL) {
+ const TkTextIndex *indexToPtr, *indexFromPtr;
+ TkText *textPtr = (TkText *) searchSpecPtr->clientData;
+
+ indexToPtr = TkTextGetIndexFromObj(interp, textPtr, toPtr);
+ if (indexToPtr == NULL) {
+ return TCL_ERROR;
+ }
+ indexFromPtr = TkTextGetIndexFromObj(interp, textPtr, fromPtr);
+
+ /*
+ * Check for any empty search range here. It might be better in the
+ * future to embed that in SearchCore (whose default behaviour is to
+ * wrap when given a negative search range).
+ */
+
+ if (searchSpecPtr->backwards) {
+ if (TkTextIndexCmp(indexFromPtr, indexToPtr) == -1) {
+ return TCL_OK;
+ }
+ } else {
+ if (TkTextIndexCmp(indexFromPtr, indexToPtr) == 1) {
+ return TCL_OK;
+ }
+ }
+
+ if ((*searchSpecPtr->lineIndexProc)(interp, toPtr, searchSpecPtr,
+ &searchSpecPtr->stopLine,
+ &searchSpecPtr->stopOffset) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ } else {
+ searchSpecPtr->stopLine = -1;
+ }
+
+ /*
+ * Scan through all of the lines of the text circularly, starting at the
+ * given index. 'patObj' is the pattern which may be an exact string or a
+ * regexp pattern depending on the flags in searchSpecPtr.
+ */
+
+ return SearchCore(interp, searchSpecPtr, patObj);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SearchCore --
+ *
+ * The core of the search function. This function is actually completely
+ * independent of Tk, and could in the future be split off.
+ *
+ * The function assumes regexp-based searches operate on Unicode strings,
+ * and exact searches on utf-8 strings. Therefore the 'foundMatchProc'
+ * and 'addLineProc' need to be aware of this distinction.
+ *
+ * Results:
+ * Standard Tcl result code.
+ *
+ * Side effects:
+ * Only those of the 'searchSpecPtr->foundMatchProc' which is called
+ * whenever a match is found.
+ *
+ * Note that the way matching across multiple lines is implemented, we
+ * start afresh with each line we have available, even though we may
+ * already have examined the contents of that line (and further ones) if
+ * we were attempting a multi-line match using the previous line. This
+ * means there may be ways to speed this up a lot by not throwing away
+ * all the multi-line information one has accumulated. Profiling should
+ * be done to see where the bottlenecks lie before attempting this,
+ * however. We would also need to be very careful such optimisation keep
+ * within the specified search bounds.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SearchCore(
+ Tcl_Interp *interp, /* For error messages. */
+ SearchSpec *searchSpecPtr, /* Search parameters. */
+ Tcl_Obj *patObj) /* Contains an exact string or a regexp
+ * pattern. Must have a refCount > 0. */
+{
+ /*
+ * For exact searches these are utf-8 char* offsets, for regexp searches
+ * they are Unicode char offsets.
+ */
+
+ int firstOffset, lastOffset, matchOffset, matchLength;
+ int passes;
+ int lineNum = searchSpecPtr->startLine;
+ int code = TCL_OK;
+ Tcl_Obj *theLine;
+ int alreadySearchOffset = -1;
+
+ const char *pattern = NULL; /* For exact searches only. */
+ int firstNewLine = -1; /* For exact searches only. */
+ Tcl_RegExp regexp = NULL; /* For regexp searches only. */
+
+ /*
+ * These items are for backward regexp searches only. They are for two
+ * purposes: to allow us to report backwards matches in the correct order,
+ * even though the implementation uses repeated forward searches; and to
+ * provide for overlap checking between backwards matches on different
+ * text lines.
+ */
+
+#define LOTS_OF_MATCHES 20
+ int matchNum = LOTS_OF_MATCHES;
+ int smArray[2 * LOTS_OF_MATCHES];
+ int *storeMatch = smArray;
+ int *storeLength = smArray + LOTS_OF_MATCHES;
+ int lastBackwardsLineMatch = -1;
+ int lastBackwardsMatchOffset = -1;
+
+ if (searchSpecPtr->exact) {
+ /*
+ * Convert the pattern to lower-case if we're supposed to ignore case.
+ */
+
+ if (searchSpecPtr->noCase) {
+ patObj = Tcl_DuplicateObj(patObj);
+
+ /*
+ * This can change the length of the string behind the object's
+ * back, so ensure it is correctly synchronised.
+ */
+
+ Tcl_SetObjLength(patObj, Tcl_UtfToLower(Tcl_GetString(patObj)));
+ }
+ } else {
+ /*
+ * Compile the regular expression. We want '^$' to match after and
+ * before \n respectively, so use the TCL_REG_NLANCH flag.
+ */
+
+ regexp = Tcl_GetRegExpFromObj(interp, patObj,
+ (searchSpecPtr->noCase ? TCL_REG_NOCASE : 0)
+ | (searchSpecPtr->noLineStop ? 0 : TCL_REG_NLSTOP)
+ | TCL_REG_ADVANCED | TCL_REG_CANMATCH | TCL_REG_NLANCH);
+ if (regexp == NULL) {
+ return TCL_ERROR;
+ }
+ }
+
+ /*
+ * For exact strings, we want to know where the first newline is, and we
+ * will also use this as a flag to test whether it is even possible to
+ * match the pattern on a single line. If not we will have to search
+ * across multiple lines.
+ */
+
+ if (searchSpecPtr->exact) {
+ const char *nl;
+
+ /*
+ * We only need to set the matchLength once for exact searches, and we
+ * do it here. It is also used below as the actual pattern length, so
+ * it has dual purpose.
+ */
+
+ pattern = Tcl_GetStringFromObj(patObj, &matchLength);
+ nl = strchr(pattern, '\n');
+
+ /*
+ * If there is no newline, or it is the very end of the string, then
+ * we don't need any special treatment, since single-line matching
+ * will work fine.
+ */
+
+ if (nl != NULL && nl[1] != '\0') {
+ firstNewLine = (nl - pattern);
+ }
+ } else {
+ matchLength = 0; /* Only needed to prevent compiler warnings. */
+ }
+
+ /*
+ * Keep a reference here, so that we can be sure the object doesn't
+ * disappear behind our backs and invalidate its contents which we are
+ * using.
+ */
+
+ Tcl_IncrRefCount(patObj);
+
+ /*
+ * For building up the current line being checked.
+ */
+
+ theLine = Tcl_NewObj();
+ Tcl_IncrRefCount(theLine);
+
+ for (passes = 0; passes < 2; ) {
+ ClientData lineInfo;
+ int linesSearched = 1;
+ int extraLinesSearched = 0;
+
+ if (lineNum >= searchSpecPtr->numLines) {
+ /*
+ * Don't search the dummy last line of the text.
+ */
+
+ goto nextLine;
+ }
+
+ /*
+ * Extract the text from the line, storing its length in 'lastOffset'
+ * (in bytes if exact, chars if regexp), since obviously the length is
+ * the maximum offset at which it is possible to find something on
+ * this line, which is what 'lastOffset' represents.
+ */
+
+ lineInfo = (*searchSpecPtr->addLineProc)(lineNum, searchSpecPtr,
+ theLine, &lastOffset, &linesSearched);
+
+ if (lineInfo == NULL) {
+ /*
+ * This should not happen, since 'lineNum' should be valid in the
+ * call above. However, let's try to be flexible and not cause a
+ * crash below.
+ */
+
+ goto nextLine;
+ }
+
+ if (lineNum == searchSpecPtr->stopLine && searchSpecPtr->backwards) {
+ firstOffset = searchSpecPtr->stopOffset;
+ } else {
+ firstOffset = 0;
+ }
+
+ if (alreadySearchOffset != -1) {
+ if (searchSpecPtr->backwards) {
+ if (alreadySearchOffset < lastOffset) {
+ lastOffset = alreadySearchOffset;
+ }
+ } else {
+ if (alreadySearchOffset > firstOffset) {
+ firstOffset = alreadySearchOffset;
+ }
+ }
+ alreadySearchOffset = -1;
+ }
+
+ if (lineNum == searchSpecPtr->startLine) {
+ /*
+ * The starting line is tricky: the first time we see it we check
+ * one part of the line, and the second pass through we check the
+ * other part of the line.
+ */
+
+ passes++;
+ if ((passes == 1) ^ searchSpecPtr->backwards) {
+ /*
+ * Forward search and first pass, or backward search and
+ * second pass.
+ *
+ * Only use the last part of the line.
+ */
+
+ if (searchSpecPtr->startOffset > firstOffset) {
+ firstOffset = searchSpecPtr->startOffset;
+ }
+ if ((firstOffset >= lastOffset)
+ && ((lastOffset != 0) || searchSpecPtr->exact)) {
+ goto nextLine;
+ }
+ } else {
+ /*
+ * Use only the first part of the line.
+ */
+
+ if (searchSpecPtr->startOffset < lastOffset) {
+ lastOffset = searchSpecPtr->startOffset;
+ }
+ }
+ }
+
+ /*
+ * Check for matches within the current line 'lineNum'. If so, and if
+ * we're searching backwards or for all matches, repeat the search
+ * until we find the last match in the line. The 'lastOffset' is one
+ * beyond the last position in the line at which a match is allowed to
+ * begin.
+ */
+
+ matchOffset = -1;
+
+ if (searchSpecPtr->exact) {
+ int maxExtraLines = 0;
+ const char *startOfLine = Tcl_GetString(theLine);
+
+ do {
+ Tcl_UniChar ch;
+ const char *p;
+ int lastFullLine = lastOffset;
+
+ if (firstNewLine == -1) {
+ if (searchSpecPtr->strictLimits
+ && (firstOffset + matchLength > lastOffset)) {
+ /*
+ * Not enough characters to match.
+ */
+
+ break;
+ }
+
+ /*
+ * Single line matching. We want to scan forwards or
+ * backwards as appropriate.
+ */
+
+ if (searchSpecPtr->backwards) {
+ /*
+ * Search back either from the previous match or from
+ * 'startOfLine + lastOffset - 1' until we find a
+ * match.
+ */
+
+ const char c = pattern[0];
+
+ if (alreadySearchOffset != -1) {
+ p = startOfLine + alreadySearchOffset;
+ alreadySearchOffset = -1;
+ } else {
+ p = startOfLine + lastOffset -1;
+ }
+ while (p >= startOfLine + firstOffset) {
+ if (p[0] == c && !strncmp(p, pattern,
+ (unsigned)matchLength)) {
+ goto backwardsMatch;
+ }
+ p--;
+ }
+ break;
+ } else {
+ p = strstr(startOfLine + firstOffset, pattern);
+ }
+ if (p == NULL) {
+ /*
+ * Single line match failed.
+ */
+
+ break;
+ }
+ } else if (firstNewLine >= (lastOffset - firstOffset)) {
+ /*
+ * Multi-line match, but not enough characters to match.
+ */
+
+ break;
+ } else {
+ /*
+ * Multi-line match has only one possible match position,
+ * because we know where the '\n' is.
+ */
+
+ p = startOfLine + lastOffset - firstNewLine - 1;
+ if (strncmp(p, pattern, (unsigned)(firstNewLine + 1))) {
+ /*
+ * No match.
+ */
+
+ break;
+ } else {
+ int extraLines = 1;
+
+ /*
+ * If we find a match that overlaps more than one
+ * line, we will use this value to determine the first
+ * allowed starting offset for the following search
+ * (to avoid overlapping results).
+ */
+
+ int lastTotal = lastOffset;
+ int skipFirst = lastOffset - firstNewLine -1;
+
+ /*
+ * We may be able to match if given more text. The
+ * following 'while' block handles multi-line exact
+ * searches.
+ */
+
+ while (1) {
+ lastFullLine = lastTotal;
+
+ if (lineNum+extraLines>=searchSpecPtr->numLines) {
+ p = NULL;
+ break;
+ }
+
+ /*
+ * Only add the line if we haven't already done so
+ * already.
+ */
+
+ if (extraLines > maxExtraLines) {
+ if ((*searchSpecPtr->addLineProc)(lineNum
+ + extraLines, searchSpecPtr, theLine,
+ &lastTotal, &extraLines) == NULL) {
+ p = NULL;
+ if (!searchSpecPtr->backwards) {
+ extraLinesSearched = extraLines;
+ }
+ break;
+ }
+ maxExtraLines = extraLines;
+ }
+
+ startOfLine = Tcl_GetString(theLine);
+ p = startOfLine + skipFirst;
+
+ /*
+ * Use the fact that 'matchLength = patLength' for
+ * exact searches.
+ */
+
+ if ((lastTotal - skipFirst) >= matchLength) {
+ /*
+ * We now have enough text to match, so we
+ * make a final test and break whatever the
+ * result.
+ */
+
+ if (strncmp(p,pattern,(unsigned)matchLength)) {
+ p = NULL;
+ }
+ break;
+ } else {
+ /*
+ * Not enough text yet, but check the prefix.
+ */
+
+ if (strncmp(p, pattern,
+ (unsigned)(lastTotal - skipFirst))) {
+ p = NULL;
+ break;
+ }
+
+ /*
+ * The prefix matches, so keep looking.
+ */
+ }
+ extraLines++;
+ }
+ /*
+ * If we reach here, with p != NULL, we've found a
+ * multi-line match, else we started a multi-match but
+ * didn't finish it off, so we go to the next line.
+ */
+
+ if (p == NULL) {
+ break;
+ }
+
+ /*
+ * We've found a multi-line match.
+ */
+
+ if (extraLines > 0) {
+ extraLinesSearched = extraLines - 1;
+ }
+ }
+ }
+
+ backwardsMatch:
+ if ((p - startOfLine) >= lastOffset) {
+ break;
+ }
+
+ /*
+ * Remember the match.
+ */
+
+ matchOffset = p - startOfLine;
+
+ if (searchSpecPtr->all &&
+ !(*searchSpecPtr->foundMatchProc)(lineNum,
+ searchSpecPtr, lineInfo, theLine, matchOffset,
+ matchLength)) {
+ /*
+ * We reached the end of the search.
+ */
+
+ goto searchDone;
+ }
+
+ if (!searchSpecPtr->overlap) {
+ if (searchSpecPtr->backwards) {
+ alreadySearchOffset = p - startOfLine;
+ if (firstNewLine != -1) {
+ break;
+ } else {
+ alreadySearchOffset -= matchLength;
+ }
+ } else {
+ firstOffset = p - startOfLine + matchLength;
+ if (firstOffset >= lastOffset) {
+ /*
+ * Now, we have to be careful not to find
+ * overlapping matches either on the same or
+ * following lines. Assume that if we did find
+ * something, it goes until the last extra line we
+ * added.
+ *
+ * We can break out of the loop, since we know no
+ * more will be found.
+ */
+
+ if (!searchSpecPtr->backwards) {
+ alreadySearchOffset =
+ firstOffset - lastFullLine;
+ break;
+ }
+ }
+ }
+ } else {
+ if (searchSpecPtr->backwards) {
+ alreadySearchOffset = p - startOfLine - 1;
+ if (alreadySearchOffset < 0) {
+ break;
+ }
+ } else {
+ firstOffset = p - startOfLine +
+ Tcl_UtfToUniChar(startOfLine+matchOffset,&ch);
+ }
+ }
+ } while (searchSpecPtr->all);
+ } else {
+ int maxExtraLines = 0;
+ int matches = 0;
+ int lastNonOverlap = -1;
+
+ do {
+ Tcl_RegExpInfo info;
+ int match;
+ int lastFullLine = lastOffset;
+
+ match = Tcl_RegExpExecObj(interp, regexp, theLine,
+ firstOffset, 1, (firstOffset>0 ? TCL_REG_NOTBOL : 0));
+ if (match < 0) {
+ code = TCL_ERROR;
+ goto searchDone;
+ }
+ Tcl_RegExpGetInfo(regexp, &info);
+
+ /*
+ * If we don't have a match, or if we do, but it extends to
+ * the end of the line, we must try to add more lines to get a
+ * full greedy match.
+ */
+
+ if (!match ||
+ ((info.extendStart == info.matches[0].start)
+ && (info.matches[0].end == lastOffset-firstOffset))) {
+ int extraLines = 0;
+ int prevFullLine;
+
+ /*
+ * If we find a match that overlaps more than one line, we
+ * will use this value to determine the first allowed
+ * starting offset for the following search (to avoid
+ * overlapping results).
+ */
+
+ int lastTotal = lastOffset;
+
+ if ((lastBackwardsLineMatch != -1)
+ && (lastBackwardsLineMatch == (lineNum + 1))) {
+ lastNonOverlap = lastTotal;
+ }
+
+ if (info.extendStart < 0) {
+ /*
+ * No multi-line match is possible.
+ */
+
+ break;
+ }
+
+ /*
+ * We may be able to match if given more text. The
+ * following 'while' block handles multi-line regexp
+ * searches.
+ */
+
+ while (1) {
+ prevFullLine = lastTotal;
+
+ /*
+ * Move firstOffset to first possible start.
+ */
+
+ if (!match) {
+ firstOffset += info.extendStart;
+ }
+ if (firstOffset >= lastOffset) {
+ /*
+ * We're being told that the only possible new
+ * match is starting after the end of the line.
+ * But, that is the next line which we will handle
+ * when we look at that line.
+ */
+
+ if (!match && !searchSpecPtr->backwards
+ && (firstOffset == 0)) {
+ extraLinesSearched = extraLines;
+ }
+ break;
+ }
+
+ if (lineNum + extraLines >= searchSpecPtr->numLines) {
+ break;
+ }
+
+ /*
+ * Add next line, provided we haven't already done so.
+ */
+
+ if (extraLines > maxExtraLines) {
+ if ((*searchSpecPtr->addLineProc)(lineNum
+ + extraLines, searchSpecPtr, theLine,
+ &lastTotal, &extraLines) == NULL) {
+ /*
+ * There are no more acceptable lines, so we
+ * can say we have searched all of these.
+ */
+
+ if (!match && !searchSpecPtr->backwards) {
+ extraLinesSearched = extraLines;
+ }
+ break;
+ }
+
+ maxExtraLines = extraLines;
+ if ((lastBackwardsLineMatch != -1)
+ && (lastBackwardsLineMatch
+ == (lineNum + extraLines + 1))) {
+ lastNonOverlap = lastTotal;
+ }
+ }
+
+ match = Tcl_RegExpExecObj(interp, regexp, theLine,
+ firstOffset, 1,
+ ((firstOffset > 0) ? TCL_REG_NOTBOL : 0));
+ if (match < 0) {
+ code = TCL_ERROR;
+ goto searchDone;
+ }
+ Tcl_RegExpGetInfo(regexp, &info);
+
+ /*
+ * Unfortunately there are bugs in Tcl's regexp
+ * library, which tells us that info.extendStart is
+ * zero when it should not be (should be -1), which
+ * makes our task a bit more complicated here. We
+ * check if there was a match, and the end of the
+ * match leaves an entire extra line unmatched, then
+ * we stop searching. Clearly it still might sometimes
+ * be possible to add more text and match again, but
+ * Tcl's regexp library doesn't tell us that.
+ *
+ * This means we often add and search one more line
+ * than might be necessary if Tcl were able to give us
+ * a correct value of info.extendStart under all
+ * circumstances.
+ */
+
+ if ((match &&
+ firstOffset+info.matches[0].end != lastTotal &&
+ firstOffset+info.matches[0].end < prevFullLine)
+ || info.extendStart < 0) {
+ break;
+ }
+
+ /*
+ * If there is a match, but that match starts after
+ * the end of the first line, then we'll handle that
+ * next time around, when we're actually looking at
+ * that line.
+ */
+
+ if (match && (info.matches[0].start >= lastOffset)) {
+ break;
+ }
+ if (match && ((firstOffset + info.matches[0].end)
+ >= prevFullLine)) {
+ if (extraLines > 0) {
+ extraLinesSearched = extraLines - 1;
+ }
+ lastFullLine = prevFullLine;
+ }
+
+ /*
+ * The prefix matches, so keep looking.
+ */
+
+ extraLines++;
+ }
+
+ /*
+ * If we reach here with 'match == 1', we've found a
+ * multi-line match, which we will record in the code
+ * which follows directly else we started a multi-line
+ * match but didn't finish it off, so we go to the next
+ * line.
+ */
+
+ if (!match) {
+ /*
+ * Here is where we could perform an optimisation,
+ * since we have already retrieved the contents of the
+ * next line (perhaps many more), so we shouldn't
+ * really throw it all away and start again. This
+ * could be particularly important for complex regexp
+ * searches.
+ *
+ * This 'break' will take us to just before the
+ * 'nextLine:' below.
+ */
+
+ break;
+ }
+
+ if (lastBackwardsLineMatch != -1) {
+ if ((lineNum + linesSearched + extraLinesSearched)
+ == lastBackwardsLineMatch) {
+ /*
+ * Possible overlap or inclusion.
+ */
+
+ int thisOffset = firstOffset + info.matches[0].end
+ - info.matches[0].start;
+
+ if (lastNonOverlap != -1) {
+ /*
+ * Possible overlap or enclosure.
+ */
+
+ if (thisOffset-lastNonOverlap >=
+ lastBackwardsMatchOffset+matchLength){
+ /*
+ * Totally encloses previous match, so
+ * forget the previous match.
+ */
+
+ lastBackwardsLineMatch = -1;
+ } else if ((thisOffset - lastNonOverlap)
+ > lastBackwardsMatchOffset) {
+ /*
+ * Overlap. Previous match is ok, and the
+ * current match is only ok if we are
+ * searching with -overlap.
+ */
+
+ if (searchSpecPtr->overlap) {
+ goto recordBackwardsMatch;
+ } else {
+ match = 0;
+ break;
+ }
+ } else {
+ /*
+ * No overlap, although the same line was
+ * reached.
+ */
+
+ goto recordBackwardsMatch;
+ }
+ } else {
+ /*
+ * No overlap.
+ */
+
+ goto recordBackwardsMatch;
+ }
+ } else if (lineNum+linesSearched+extraLinesSearched
+ < lastBackwardsLineMatch) {
+ /*
+ * No overlap.
+ */
+
+ goto recordBackwardsMatch;
+ } else {
+ /*
+ * Totally enclosed.
+ */
+
+ lastBackwardsLineMatch = -1;
+ }
+ }
+
+ } else {
+ /*
+ * Matched in a single line.
+ */
+
+ if (lastBackwardsLineMatch != -1) {
+ recordBackwardsMatch:
+ (*searchSpecPtr->foundMatchProc)(
+ lastBackwardsLineMatch, searchSpecPtr, NULL,
+ NULL, lastBackwardsMatchOffset, matchLength);
+ lastBackwardsLineMatch = -1;
+ if (!searchSpecPtr->all) {
+ goto searchDone;
+ }
+ }
+ }
+
+ firstOffset += info.matches[0].start;
+ if (firstOffset >= lastOffset) {
+ break;
+ }
+
+ /*
+ * Update our local variables with the match, if we haven't
+ * yet found anything, or if we're doing '-all' or
+ * '-backwards' _and_ this match isn't fully enclosed in the
+ * previous match.
+ */
+
+ if (matchOffset == -1 ||
+ ((searchSpecPtr->all || searchSpecPtr->backwards)
+ && ((firstOffset < matchOffset)
+ || ((firstOffset + info.matches[0].end
+ - info.matches[0].start)
+ > (matchOffset + matchLength))))) {
+
+ matchOffset = firstOffset;
+ matchLength = info.matches[0].end - info.matches[0].start;
+
+ if (searchSpecPtr->backwards) {
+ /*
+ * To get backwards searches in the correct order, we
+ * must store them away here.
+ */
+
+ if (matches == matchNum) {
+ /*
+ * We've run out of space in our normal store, so
+ * we must allocate space for these backwards
+ * matches on the heap.
+ */
+
+ int *newArray = (int *)
+ ckalloc(4 * matchNum * sizeof(int));
+ memcpy(newArray, storeMatch, matchNum*sizeof(int));
+ memcpy(newArray + 2*matchNum, storeLength,
+ matchNum * sizeof(int));
+ if (storeMatch != smArray) {
+ ckfree((char *) storeMatch);
+ }
+ matchNum *= 2;
+ storeMatch = newArray;
+ storeLength = newArray + matchNum;
+ }
+ storeMatch[matches] = matchOffset;
+ storeLength[matches] = matchLength;
+ matches++;
+ } else {
+ /*
+ * Now actually record the match, but only if we are
+ * doing an '-all' search.
+ */
+
+ if (searchSpecPtr->all &&
+ !(*searchSpecPtr->foundMatchProc)(lineNum,
+ searchSpecPtr, lineInfo, theLine, matchOffset,
+ matchLength)) {
+ /*
+ * We reached the end of the search.
+ */
+
+ goto searchDone;
+ }
+ }
+
+ /*
+ * For forward matches, unless we allow overlaps, we move
+ * this on by the length of the current match so that we
+ * explicitly disallow overlapping matches.
+ */
+
+ if (matchLength > 0 && !searchSpecPtr->overlap
+ && !searchSpecPtr->backwards) {
+ firstOffset += matchLength;
+ if (firstOffset >= lastOffset) {
+ /*
+ * Now, we have to be careful not to find
+ * overlapping matches either on the same or
+ * following lines. Assume that if we did find
+ * something, it goes until the last extra line we
+ * added.
+ *
+ * We can break out of the loop, since we know no
+ * more will be found.
+ */
+
+ alreadySearchOffset = firstOffset - lastFullLine;
+ break;
+ }
+
+ /*
+ * We'll add this on again just below.
+ */
+
+ firstOffset --;
+ }
+ }
+
+ /*
+ * Move the starting point on, in case we are doing repeated
+ * or backwards searches (for the latter, we actually do
+ * repeated forward searches).
+ */
+
+ firstOffset++;
+ } while (searchSpecPtr->backwards || searchSpecPtr->all);
+
+ if (matches > 0) {
+ /*
+ * Now we have all the matches in our array, but not stored
+ * with 'foundMatchProc' yet.
+ */
+
+ matches--;
+ matchOffset = storeMatch[matches];
+ matchLength = storeLength[matches];
+ while (--matches >= 0) {
+ if (lineNum == searchSpecPtr->stopLine) {
+ /*
+ * It appears as if a condition like:
+ *
+ * if (storeMatch[matches]<searchSpecPtr->stopOffset)
+ * break;
+ *
+ * might be needed here, but no test case has been
+ * found which would exercise such a problem.
+ */
+ }
+ if (storeMatch[matches] + storeLength[matches]
+ >= matchOffset + matchLength) {
+ /*
+ * The new match totally encloses the previous one, so
+ * we overwrite the previous one.
+ */
+
+ matchOffset = storeMatch[matches];
+ matchLength = storeLength[matches];
+ continue;
+ }
+ if (!searchSpecPtr->overlap) {
+ if (storeMatch[matches] + storeLength[matches]
+ > matchOffset) {
+ continue;
+ }
+ }
+ (*searchSpecPtr->foundMatchProc)(lineNum, searchSpecPtr,
+ lineInfo, theLine, matchOffset, matchLength);
+ if (!searchSpecPtr->all) {
+ goto searchDone;
+ }
+ matchOffset = storeMatch[matches];
+ matchLength = storeLength[matches];
+ }
+ if (searchSpecPtr->all && matches > 0) {
+ /*
+ * We only need to do this for the '-all' case, because
+ * just below we will call the foundMatchProc for the
+ * non-all case.
+ */
+
+ (*searchSpecPtr->foundMatchProc)(lineNum, searchSpecPtr,
+ lineInfo, theLine, matchOffset, matchLength);
+ } else {
+ lastBackwardsLineMatch = lineNum;
+ lastBackwardsMatchOffset = matchOffset;
+ }
+ }
+ }
+
+ /*
+ * If the 'all' flag is set, we will already have stored all matches,
+ * so we just proceed to the next line.
+ *
+ * If not, and there is a match we need to store that information and
+ * we are done.
+ */
+
+ if ((lastBackwardsLineMatch == -1) && (matchOffset >= 0)
+ && !searchSpecPtr->all) {
+ (*searchSpecPtr->foundMatchProc)(lineNum, searchSpecPtr, lineInfo,
+ theLine, matchOffset, matchLength);
+ goto searchDone;
+ }
+
+ /*
+ * Go to the next (or previous) line;
+ */
+
+ nextLine:
+ linesSearched += extraLinesSearched;
+
+ while (linesSearched-- > 0) {
+ /*
+ * If we have just completed the 'stopLine', we are done.
+ */
+
+ if (lineNum == searchSpecPtr->stopLine) {
+ goto searchDone;
+ }
+
+ if (searchSpecPtr->backwards) {
+ lineNum--;
+
+ if (lastBackwardsLineMatch != -1
+ && ((lineNum < 0)
+ || (lineNum + 2 < lastBackwardsLineMatch))) {
+ (*searchSpecPtr->foundMatchProc)(lastBackwardsLineMatch,
+ searchSpecPtr, NULL, NULL,
+ lastBackwardsMatchOffset, matchLength);
+ lastBackwardsLineMatch = -1;
+ if (!searchSpecPtr->all) {
+ goto searchDone;
+ }
+ }
+
+ if (lineNum < 0) {
+ lineNum = searchSpecPtr->numLines-1;
+ }
+ if (!searchSpecPtr->exact) {
+ /*
+ * The 'exact' search loops above are designed to give us
+ * an accurate picture of the number of lines which we can
+ * skip here. For 'regexp' searches, on the other hand,
+ * which can match potentially variable lengths, we cannot
+ * skip multiple lines when searching backwards. Therefore
+ * we only allow one line to be skipped here.
+ */
+
+ break;
+ }
+ } else {
+ lineNum++;
+ if (lineNum >= searchSpecPtr->numLines) {
+ lineNum = 0;
+ }
+ }
+ if (lineNum == searchSpecPtr->startLine && linesSearched > 0) {
+ /*
+ * We've just searched all the way round and have gone right
+ * through the start line without finding anything in the last
+ * attempt.
+ */
+
+ break;
+ }
+ }
+
+ Tcl_SetObjLength(theLine, 0);
}
+ searchDone:
- if (textPtr->isDirty == 0 || oldDirtyFlag == 0) {
- GenerateModifiedEvent(textPtr);
+ if (lastBackwardsLineMatch != -1) {
+ (*searchSpecPtr->foundMatchProc)(lastBackwardsLineMatch, searchSpecPtr,
+ NULL, NULL, lastBackwardsMatchOffset, matchLength);
}
+
+ /*
+ * Free up the cached line and pattern.
+ */
+
+ Tcl_DecrRefCount(theLine);
+ Tcl_DecrRefCount(patObj);
+
+ /*
+ * Free up any extra space we allocated.
+ */
+
+ if (storeMatch != smArray) {
+ ckfree((char *) storeMatch);
+ }
+
+ return code;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetLineStartEnd -
+ *
+ * Converts an internal TkTextLine ptr into a Tcl string obj containing
+ * the line number. (Handler for the 'line' configuration option type.)
+ *
+ * Results:
+ * Tcl_Obj containing the string representation of the line value.
+ *
+ * Side effects:
+ * Creates a new Tcl_Obj.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+GetLineStartEnd(
+ ClientData clientData,
+ Tk_Window tkwin,
+ char *recordPtr, /* Pointer to widget record. */
+ int internalOffset) /* Offset within *recordPtr containing the
+ * line value. */
+{
+ TkTextLine *linePtr = *(TkTextLine **)(recordPtr + internalOffset);
+
+ if (linePtr == NULL) {
+ return Tcl_NewObj();
+ } else {
+ return Tcl_NewIntObj(1+TkBTreeLinesTo(NULL, linePtr));
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetLineStartEnd --
+ *
+ * Converts a Tcl_Obj representing a widget's (start or end) line into a
+ * TkTextLine* value. (Handler for the 'line' configuration option type.)
+ *
+ * Results:
+ * Standard Tcl result.
+ *
+ * Side effects:
+ * May store the TkTextLine* value into the internal representation
+ * pointer. May change the pointer to the Tcl_Obj to NULL to indicate
+ * that the specified string was empty and that is acceptable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetLineStartEnd(
+ ClientData clientData,
+ Tcl_Interp *interp, /* Current interp; may be used for errors. */
+ Tk_Window tkwin, /* Window for which option is being set. */
+ Tcl_Obj **value, /* Pointer to the pointer to the value object.
+ * We use a pointer to the pointer because we
+ * may need to return a value (NULL). */
+ char *recordPtr, /* Pointer to storage for the widget record. */
+ int internalOffset, /* Offset within *recordPtr at which the
+ * internal value is to be stored. */
+ char *oldInternalPtr, /* Pointer to storage for the old value. */
+ int flags) /* Flags for the option, set Tk_SetOptions. */
+{
+ TkTextLine *linePtr = NULL;
+ char *internalPtr;
+ TkText *textPtr = (TkText *) recordPtr;
+
+ if (internalOffset >= 0) {
+ internalPtr = recordPtr + internalOffset;
+ } else {
+ internalPtr = NULL;
+ }
+
+ if (flags & TK_OPTION_NULL_OK && ObjectIsEmpty(*value)) {
+ *value = NULL;
+ } else {
+ int line;
+
+ if (Tcl_GetIntFromObj(interp, *value, &line) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, NULL, line-1);
+ }
+
+ if (internalPtr != NULL) {
+ *((TkTextLine **) oldInternalPtr) = *((TkTextLine **) internalPtr);
+ *((TkTextLine **) internalPtr) = linePtr;
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RestoreLineStartEnd --
+ *
+ * Restore a line option value from a saved value. (Handler for the
+ * 'line' configuration option type.)
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Restores the old value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RestoreLineStartEnd(
+ ClientData clientData,
+ Tk_Window tkwin,
+ char *internalPtr, /* Pointer to storage for value. */
+ char *oldInternalPtr) /* Pointer to old value. */
+{
+ *(TkTextLine **)internalPtr = *(TkTextLine **)oldInternalPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ObjectIsEmpty --
+ *
+ * This function tests whether the string value of an object is empty.
+ *
+ * Results:
+ * The return value is 1 if the string value of objPtr has length zero,
+ * and 0 otherwise.
+ *
+ * Side effects:
+ * May cause object shimmering, since this function can force a
+ * conversion to a string object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ObjectIsEmpty(
+ Tcl_Obj *objPtr) /* Object to test. May be NULL. */
+{
+ int length;
+
+ if (objPtr == NULL) {
+ return 1;
+ }
+ if (objPtr->bytes != NULL) {
+ return (objPtr->length == 0);
+ }
+ Tcl_GetStringFromObj(objPtr, &length);
+ return (length == 0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpTesttextCmd --
+ *
+ * This function 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.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkpTesttextCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ const 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;
+ }
+ if (info.isNativeObjectProc) {
+ textPtr = (TkText *) info.objClientData;
+ } else {
+ textPtr = (TkText *) info.clientData;
+ }
+ len = strlen(argv[2]);
+ if (strncmp(argv[2], "byteindex", len) == 0) {
+ if (argc != 5) {
+ return TCL_ERROR;
+ }
+ lineIndex = atoi(argv[3]) - 1;
+ byteIndex = atoi(argv[4]);
+
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 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(textPtr, &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(textPtr, &index, byteOffset, &index);
+ } else {
+ return TCL_ERROR;
+ }
+
+ TkTextSetMark(textPtr, "insert", &index);
+ TkTextPrintIndex(textPtr, &index, buf);
+ sprintf(buf + strlen(buf), " %d", index.byteIndex);
+ Tcl_AppendResult(interp, buf, NULL);
+
+ return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkText.h b/generic/tkText.h
index 6331735..4ffdc8a 100644
--- a/generic/tkText.h
+++ b/generic/tkText.h
@@ -1,14 +1,13 @@
/*
* tkText.h --
*
- * Declarations shared among the files that implement text
- * widgets.
+ * Declarations shared among the files that implement text widgets.
*
* Copyright (c) 1992-1994 The Regents of the University of California.
* Copyright (c) 1994-1995 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKTEXT
@@ -28,122 +27,142 @@
#endif
/*
- * Opaque types for structures whose guts are only needed by a single
- * file:
+ * Opaque types for structures whose guts are only needed by a single file.
*/
typedef struct TkTextBTree_ *TkTextBTree;
/*
- * The data structure below defines a single line of text (from newline
- * to newline, not necessarily what appears on one line of the screen).
+ * The data structure below defines a single logical line of text (from
+ * newline to newline, not necessarily what appears on one display line of the
+ * screen).
*/
typedef struct TkTextLine {
- struct Node *parentPtr; /* Pointer to parent node containing
- * line. */
- struct TkTextLine *nextPtr; /* Next in linked list of lines with
- * same parent node in B-tree. NULL
- * means end of list. */
- struct TkTextSegment *segPtr; /* First in ordered list of segments
- * that make up the line. */
+ struct Node *parentPtr; /* Pointer to parent node containing line. */
+ struct TkTextLine *nextPtr; /* Next in linked list of lines with same
+ * parent node in B-tree. NULL means end of
+ * list. */
+ struct TkTextSegment *segPtr;
+ /* First in ordered list of segments that make
+ * up the line. */
+ int *pixels; /* Array containing two integers for each
+ * referring text widget. The first of these
+ * is the number of vertical pixels taken up
+ * by this line, whether currently displayed
+ * or not. This number is only updated
+ * asychronously. The second of these is the
+ * last epoch at which the pixel height was
+ * recalculated. */
} TkTextLine;
/*
* -----------------------------------------------------------------------
* Segments: each line is divided into one or more segments, where each
- * segment is one of several things, such as a group of characters, a
- * tag toggle, a mark, or an embedded widget. Each segment starts with
- * a standard header followed by a body that varies from type to type.
+ * segment is one of several things, such as a group of characters, a tag
+ * toggle, a mark, or an embedded widget. Each segment starts with a standard
+ * header followed by a body that varies from type to type.
* -----------------------------------------------------------------------
*/
/*
- * The data structure below defines the body of a segment that represents
- * a tag toggle. There is one of these structures at both the beginning
- * and end of each tagged range.
+ * The data structure below defines the body of a segment that represents a
+ * tag toggle. There is one of these structures at both the beginning and end
+ * of each tagged range.
*/
typedef struct TkTextToggle {
- struct TkTextTag *tagPtr; /* Tag that starts or ends here. */
- int inNodeCounts; /* 1 means this toggle has been
- * accounted for in node toggle
- * counts; 0 means it hasn't, yet. */
+ struct TkTextTag *tagPtr; /* Tag that starts or ends here. */
+ int inNodeCounts; /* 1 means this toggle has been accounted for
+ * in node toggle counts; 0 means it hasn't,
+ * yet. */
} TkTextToggle;
/*
- * The data structure below defines line segments that represent
- * marks. There is one of these for each mark in the text.
+ * The data structure below defines line segments that represent marks. There
+ * is one of these for each mark in the text.
*/
typedef struct TkTextMark {
- struct TkText *textPtr; /* Overall information about text
- * widget. */
- TkTextLine *linePtr; /* Line structure that contains the
- * segment. */
- Tcl_HashEntry *hPtr; /* Pointer to hash table entry for mark
- * (in textPtr->markTable). */
+ struct TkText *textPtr; /* Overall information about text widget. */
+ TkTextLine *linePtr; /* Line structure that contains the
+ * segment. */
+ Tcl_HashEntry *hPtr; /* Pointer to hash table entry for mark (in
+ * sharedTextPtr->markTable). */
} TkTextMark;
/*
* A structure of the following type holds information for each window
- * embedded in a text widget. This information is only used by the
- * file tkTextWind.c
+ * embedded in a text widget. This information is only used by the file
+ * tkTextWind.c
*/
+typedef struct TkTextEmbWindowClient {
+ struct TkText *textPtr; /* Information about the overall text
+ * widget. */
+ Tk_Window tkwin; /* Window for this segment. NULL means that
+ * the window hasn't been created yet. */
+ int chunkCount; /* Number of display chunks that refer to this
+ * window. */
+ int displayed; /* Non-zero means that the window has been
+ * displayed on the screen recently. */
+ struct TkTextSegment *parent;
+ struct TkTextEmbWindowClient *next;
+} TkTextEmbWindowClient;
+
typedef struct TkTextEmbWindow {
- struct TkText *textPtr; /* Information about the overall text
- * widget. */
- TkTextLine *linePtr; /* Line structure that contains this
- * window. */
- Tk_Window tkwin; /* Window for this segment. NULL
- * means that the window hasn't
- * been created yet. */
- char *create; /* Script to create window on-demand.
- * NULL means no such script.
- * Malloc-ed. */
- int align; /* How to align window in vertical
- * space. See definitions in
- * tkTextWind.c. */
- int padX, padY; /* Padding to leave around each side
- * of window, in pixels. */
- int stretch; /* Should window stretch to fill
- * vertical space of line (except for
- * pady)? 0 or 1. */
- int chunkCount; /* Number of display chunks that
- * refer to this window. */
- int displayed; /* Non-zero means that the window
- * has been displayed on the screen
- * recently. */
+ struct TkSharedText *sharedTextPtr;
+ /* Information about the shared portion of the
+ * text widget. */
+ Tk_Window tkwin; /* Window for this segment. This is just a
+ * temporary value, copied from 'clients', to
+ * make option table updating easier. NULL
+ * means that the window hasn't been created
+ * yet. */
+ TkTextLine *linePtr; /* Line structure that contains this
+ * window. */
+ char *create; /* Script to create window on-demand. NULL
+ * means no such script. Malloc-ed. */
+ int align; /* How to align window in vertical space. See
+ * definitions in tkTextWind.c. */
+ int padX, padY; /* Padding to leave around each side of
+ * window, in pixels. */
+ int stretch; /* Should window stretch to fill vertical
+ * space of line (except for pady)? 0 or 1. */
+ Tk_OptionTable optionTable; /* Token representing the configuration
+ * specifications. */
+ TkTextEmbWindowClient *clients;
+ /* Linked list of peer-widget specific
+ * information for this embedded window. */
} TkTextEmbWindow;
/*
- * A structure of the following type holds information for each image
- * embedded in a text widget. This information is only used by the
- * file tkTextImage.c
+ * A structure of the following type holds information for each image embedded
+ * in a text widget. This information is only used by the file tkTextImage.c
*/
typedef struct TkTextEmbImage {
- struct TkText *textPtr; /* Information about the overall text
- * widget. */
- TkTextLine *linePtr; /* Line structure that contains this
- * image. */
- char *imageString; /* Name of the image for this segment */
- char *imageName; /* Name used by text widget to identify
- * this image. May be unique-ified */
- char *name; /* Name used in the hash table.
- * used by "image names" to identify
- * this instance of the image */
- Tk_Image image; /* Image for this segment. NULL
- * means that the image hasn't
- * been created yet. */
- int align; /* How to align image in vertical
- * space. See definitions in
- * tkTextImage.c. */
- int padX, padY; /* Padding to leave around each side
- * of image, in pixels. */
- int chunkCount; /* Number of display chunks that
- * refer to this image. */
+ struct TkSharedText *sharedTextPtr;
+ /* Information about the shared portion of the
+ * text widget. This is used when the image
+ * changes or is deleted. */
+ TkTextLine *linePtr; /* Line structure that contains this image. */
+ char *imageString; /* Name of the image for this segment. */
+ char *imageName; /* Name used by text widget to identify this
+ * image. May be unique-ified. */
+ char *name; /* Name used in the hash table. Used by
+ * "image names" to identify this instance of
+ * the image. */
+ Tk_Image image; /* Image for this segment. NULL means that the
+ * image hasn't been created yet. */
+ int align; /* How to align image in vertical space. See
+ * definitions in tkTextImage.c. */
+ int padX, padY; /* Padding to leave around each side of image,
+ * in pixels. */
+ int chunkCount; /* Number of display chunks that refer to this
+ * image. */
+ Tk_OptionTable optionTable; /* Token representing the configuration
+ * specifications. */
} TkTextEmbImage;
/*
@@ -151,40 +170,43 @@ typedef struct TkTextEmbImage {
*/
typedef struct TkTextSegment {
- struct Tk_SegType *typePtr; /* Pointer to record describing
- * segment's type. */
- struct TkTextSegment *nextPtr; /* Next in list of segments for this
- * line, or NULL for end of list. */
- int size; /* Size of this segment (# of bytes
- * of index space it occupies). */
+ const struct Tk_SegType *typePtr;
+ /* Pointer to record describing segment's
+ * type. */
+ struct TkTextSegment *nextPtr;
+ /* Next in list of segments for this line, or
+ * NULL for end of list. */
+ int size; /* Size of this segment (# of bytes of index
+ * space it occupies). */
union {
- char chars[4]; /* Characters that make up character
- * info. Actual length varies to
- * hold as many characters as needed.*/
- TkTextToggle toggle; /* Information about tag toggle. */
- TkTextMark mark; /* Information about mark. */
- TkTextEmbWindow ew; /* Information about embedded
- * window. */
- TkTextEmbImage ei; /* Information about embedded
- * image. */
+ char chars[4]; /* Characters that make up character info.
+ * Actual length varies to hold as many
+ * characters as needed.*/
+ TkTextToggle toggle; /* Information about tag toggle. */
+ TkTextMark mark; /* Information about mark. */
+ TkTextEmbWindow ew; /* Information about embedded window. */
+ TkTextEmbImage ei; /* Information about embedded image. */
} body;
} TkTextSegment;
/*
- * Data structures of the type defined below are used during the
- * execution of Tcl commands to keep track of various interesting
- * places in a text. An index is only valid up until the next
- * modification to the character structure of the b-tree so they
- * can't be retained across Tcl commands. However, mods to marks
- * or tags don't invalidate indices.
+ * Data structures of the type defined below are used during the execution of
+ * Tcl commands to keep track of various interesting places in a text. An
+ * index is only valid up until the next modification to the character
+ * structure of the b-tree so they can't be retained across Tcl commands.
+ * However, mods to marks or tags don't invalidate indices.
*/
typedef struct TkTextIndex {
- TkTextBTree tree; /* Tree containing desired position. */
- TkTextLine *linePtr; /* Pointer to line containing position
- * of interest. */
- int byteIndex; /* Index within line of desired
- * character (0 means first one). */
+ TkTextBTree tree; /* Tree containing desired position. */
+ TkTextLine *linePtr; /* Pointer to line containing position of
+ * interest. */
+ int byteIndex; /* Index within line of desired character (0
+ * means first one). */
+ struct TkText *textPtr; /* May be NULL, but otherwise the text widget
+ * with which this index is associated. If not
+ * NULL, then we have a refCount on the
+ * widget. */
} TkTextIndex;
/*
@@ -193,204 +215,209 @@ typedef struct TkTextIndex {
typedef struct TkTextDispChunk TkTextDispChunk;
-typedef void Tk_ChunkDisplayProc _ANSI_ARGS_((
+typedef void Tk_ChunkDisplayProc(struct TkText *textPtr,
TkTextDispChunk *chunkPtr, int x, int y,
int height, int baseline, Display *display,
- Drawable dst, int screenY));
-typedef void Tk_ChunkUndisplayProc _ANSI_ARGS_((
- struct TkText *textPtr,
- TkTextDispChunk *chunkPtr));
-typedef int Tk_ChunkMeasureProc _ANSI_ARGS_((
- TkTextDispChunk *chunkPtr, int x));
-typedef void Tk_ChunkBboxProc _ANSI_ARGS_((
+ Drawable dst, int screenY);
+typedef void Tk_ChunkUndisplayProc(struct TkText *textPtr,
+ TkTextDispChunk *chunkPtr);
+typedef int Tk_ChunkMeasureProc(TkTextDispChunk *chunkPtr, int x);
+typedef void Tk_ChunkBboxProc(struct TkText *textPtr,
TkTextDispChunk *chunkPtr, int index, int y,
int lineHeight, int baseline, int *xPtr,
- int *yPtr, int *widthPtr, int *heightPtr));
+ int *yPtr, int *widthPtr, int *heightPtr);
/*
- * The structure below represents a chunk of stuff that is displayed
- * together on the screen. This structure is allocated and freed by
- * generic display code but most of its fields are filled in by
- * segment-type-specific code.
+ * The structure below represents a chunk of stuff that is displayed together
+ * on the screen. This structure is allocated and freed by generic display
+ * code but most of its fields are filled in by segment-type-specific code.
*/
struct TkTextDispChunk {
/*
- * The fields below are set by the type-independent code before
- * calling the segment-type-specific layoutProc. They should not
- * be modified by segment-type-specific code.
+ * The fields below are set by the type-independent code before calling
+ * the segment-type-specific layoutProc. They should not be modified by
+ * segment-type-specific code.
*/
- int x; /* X position of chunk, in pixels.
- * This position is measured from the
- * left edge of the logical line,
- * not from the left edge of the
- * window (i.e. it doesn't change
- * under horizontal scrolling). */
- struct TkTextDispChunk *nextPtr; /* Next chunk in the display line
- * or NULL for the end of the list. */
- struct TextStyle *stylePtr; /* Display information, known only
- * to tkTextDisp.c. */
+ int x; /* X position of chunk, in pixels. This
+ * position is measured from the left edge of
+ * the logical line, not from the left edge of
+ * the window (i.e. it doesn't change under
+ * horizontal scrolling). */
+ struct TkTextDispChunk *nextPtr;
+ /* Next chunk in the display line or NULL for
+ * the end of the list. */
+ struct TextStyle *stylePtr; /* Display information, known only to
+ * tkTextDisp.c. */
/*
- * The fields below are set by the layoutProc that creates the
- * chunk.
+ * The fields below are set by the layoutProc that creates the chunk.
*/
- Tk_ChunkDisplayProc *displayProc; /* Procedure to invoke to draw this
- * chunk on the display or an
- * off-screen pixmap. */
+ Tk_ChunkDisplayProc *displayProc;
+ /* Procedure to invoke to draw this chunk on
+ * the display or an off-screen pixmap. */
Tk_ChunkUndisplayProc *undisplayProc;
- /* Procedure to invoke when segment
- * ceases to be displayed on screen
- * anymore. */
- Tk_ChunkMeasureProc *measureProc; /* Procedure to find character under
- * a given x-location. */
- Tk_ChunkBboxProc *bboxProc; /* Procedure to find bounding box
- * of character in chunk. */
- int numBytes; /* Number of bytes that will be
- * displayed in the chunk. */
- int minAscent; /* Minimum space above the baseline
- * needed by this chunk. */
- int minDescent; /* Minimum space below the baseline
- * needed by this chunk. */
- int minHeight; /* Minimum total line height needed
- * by this chunk. */
- int width; /* Width of this chunk, in pixels.
- * Initially set by chunk-specific
- * code, but may be increased to
- * include tab or extra space at end
- * of line. */
- int breakIndex; /* Index within chunk of last
- * acceptable position for a line
- * (break just before this byte index).
- * <= 0 means don't break during or
- * immediately after this chunk. */
- ClientData clientData; /* Additional information for use
- * of displayProc and undisplayProc. */
+ /* Procedure to invoke when segment ceases to
+ * be displayed on screen anymore. */
+ Tk_ChunkMeasureProc *measureProc;
+ /* Procedure to find character under a given
+ * x-location. */
+ Tk_ChunkBboxProc *bboxProc; /* Procedure to find bounding box of character
+ * in chunk. */
+ int numBytes; /* Number of bytes that will be displayed in
+ * the chunk. */
+ int minAscent; /* Minimum space above the baseline needed by
+ * this chunk. */
+ int minDescent; /* Minimum space below the baseline needed by
+ * this chunk. */
+ int minHeight; /* Minimum total line height needed by this
+ * chunk. */
+ int width; /* Width of this chunk, in pixels. Initially
+ * set by chunk-specific code, but may be
+ * increased to include tab or extra space at
+ * end of line. */
+ int breakIndex; /* Index within chunk of last acceptable
+ * position for a line (break just before this
+ * byte index). <= 0 means don't break during
+ * or immediately after this chunk. */
+ ClientData clientData; /* Additional information for use of
+ * displayProc and undisplayProc. */
};
/*
- * One data structure of the following type is used for each tag in a
- * text widget. These structures are kept in textPtr->tagTable and
- * referred to in other structures.
+ * One data structure of the following type is used for each tag in a text
+ * widget. These structures are kept in sharedTextPtr->tagTable and referred
+ * to in other structures.
*/
-typedef enum { TEXT_WRAPMODE_NULL, TEXT_WRAPMODE_NONE,
- TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_WORD
+typedef enum {
+ TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, TEXT_WRAPMODE_WORD,
+ TEXT_WRAPMODE_NULL
} TkWrapMode;
-EXTERN Tk_CustomOption TkTextWrapModeOption;
-
typedef struct TkTextTag {
- char *name; /* Name of this tag. This field is actually
- * a pointer to the key from the entry in
- * textPtr->tagTable, so it needn't be freed
- * explicitly. */
- int priority; /* Priority of this tag within widget. 0
- * means lowest priority. Exactly one tag
- * has each integer value between 0 and
- * numTags-1. */
- struct Node *tagRootPtr; /* Pointer into the B-Tree at the lowest
- * node that completely dominates the ranges
- * of text occupied by the tag. At this
- * node there is no information about the
- * tag. One or more children of the node
- * do contain information about the tag. */
- int toggleCount; /* Total number of tag toggles */
+ const char *name; /* Name of this tag. This field is actually a
+ * pointer to the key from the entry in
+ * sharedTextPtr->tagTable, so it needn't be
+ * freed explicitly. For 'sel' tags this is
+ * just a static string, so again need not be
+ * freed. */
+ const struct TkText *textPtr;
+ /* If non-NULL, then this tag only applies to
+ * the given text widget (when there are peer
+ * widgets). */
+ int priority; /* Priority of this tag within widget. 0 means
+ * lowest priority. Exactly one tag has each
+ * integer value between 0 and numTags-1. */
+ struct Node *tagRootPtr; /* Pointer into the B-Tree at the lowest node
+ * that completely dominates the ranges of
+ * text occupied by the tag. At this node
+ * there is no information about the tag. One
+ * or more children of the node do contain
+ * information about the tag. */
+ int toggleCount; /* Total number of tag toggles. */
/*
- * Information for displaying text with this tag. The information
- * belows acts as an override on information specified by lower-priority
- * tags. If no value is specified, then the next-lower-priority tag
- * on the text determins the value. The text widget itself provides
- * defaults if no tag specifies an override.
+ * Information for displaying text with this tag. The information belows
+ * acts as an override on information specified by lower-priority tags.
+ * If no value is specified, then the next-lower-priority tag on the text
+ * determins the value. The text widget itself provides defaults if no tag
+ * specifies an override.
*/
- Tk_3DBorder border; /* Used for drawing background. NULL means
- * no value specified here. */
- char *bdString; /* -borderwidth option string (malloc-ed).
- * NULL means option not specified. */
+ Tk_3DBorder border; /* Used for drawing background. NULL means no
+ * value specified here. */
int borderWidth; /* Width of 3-D border for background. */
- char *reliefString; /* -relief option string (malloc-ed).
- * NULL means option not specified. */
+ Tcl_Obj *borderWidthPtr; /* Width of 3-D border for background. */
+ char *reliefString; /* -relief option string (malloc-ed). NULL
+ * means option not specified. */
int relief; /* 3-D relief for background. */
- Pixmap bgStipple; /* Stipple bitmap for background. None
- * means no value specified here. */
- XColor *fgColor; /* Foreground color for text. NULL means
- * no value specified here. */
- Tk_Font tkfont; /* Font for displaying text. NULL means
+ Pixmap bgStipple; /* Stipple bitmap for background. None means
* no value specified here. */
+ XColor *fgColor; /* Foreground color for text. NULL means no
+ * value specified here. */
+ Tk_Font tkfont; /* Font for displaying text. NULL means no
+ * value specified here. */
Pixmap fgStipple; /* Stipple bitmap for text and other
- * foreground stuff. None means no value
+ * foreground stuff. None means no value
* specified here.*/
- char *justifyString; /* -justify option string (malloc-ed).
- * NULL means option not specified. */
+ char *justifyString; /* -justify option string (malloc-ed). NULL
+ * means option not specified. */
Tk_Justify justify; /* How to justify text: TK_JUSTIFY_LEFT,
* TK_JUSTIFY_RIGHT, or TK_JUSTIFY_CENTER.
* Only valid if justifyString is non-NULL. */
- char *lMargin1String; /* -lmargin1 option string (malloc-ed).
- * NULL means option not specified. */
- int lMargin1; /* Left margin for first display line of
- * each text line, in pixels. Only valid
- * if lMargin1String is non-NULL. */
- char *lMargin2String; /* -lmargin2 option string (malloc-ed).
- * NULL means option not specified. */
+ char *lMargin1String; /* -lmargin1 option string (malloc-ed). NULL
+ * means option not specified. */
+ int lMargin1; /* Left margin for first display line of each
+ * text line, in pixels. Only valid if
+ * lMargin1String is non-NULL. */
+ char *lMargin2String; /* -lmargin2 option string (malloc-ed). NULL
+ * means option not specified. */
int lMargin2; /* Left margin for second and later display
- * lines of each text line, in pixels. Only
+ * lines of each text line, in pixels. Only
* valid if lMargin2String is non-NULL. */
- char *offsetString; /* -offset option string (malloc-ed).
- * NULL means option not specified. */
+ char *offsetString; /* -offset option string (malloc-ed). NULL
+ * means option not specified. */
int offset; /* Vertical offset of text's baseline from
- * baseline of line. Used for superscripts
- * and subscripts. Only valid if
- * offsetString is non-NULL. */
- char *overstrikeString; /* -overstrike option string (malloc-ed).
- * NULL means option not specified. */
+ * baseline of line. Used for superscripts and
+ * subscripts. Only valid if offsetString is
+ * non-NULL. */
+ char *overstrikeString; /* -overstrike option string (malloc-ed). NULL
+ * means option not specified. */
int overstrike; /* Non-zero means draw horizontal line through
- * middle of text. Only valid if
+ * middle of text. Only valid if
* overstrikeString is non-NULL. */
- char *rMarginString; /* -rmargin option string (malloc-ed).
- * NULL means option not specified. */
- int rMargin; /* Right margin for text, in pixels. Only
+ char *rMarginString; /* -rmargin option string (malloc-ed). NULL
+ * means option not specified. */
+ int rMargin; /* Right margin for text, in pixels. Only
* valid if rMarginString is non-NULL. */
- char *spacing1String; /* -spacing1 option string (malloc-ed).
- * NULL means option not specified. */
- int spacing1; /* Extra spacing above first display
- * line for text line. Only valid if
- * spacing1String is non-NULL. */
- char *spacing2String; /* -spacing2 option string (malloc-ed).
- * NULL means option not specified. */
- int spacing2; /* Extra spacing between display
- * lines for the same text line. Only valid
- * if spacing2String is non-NULL. */
- char *spacing3String; /* -spacing2 option string (malloc-ed).
- * NULL means option not specified. */
- int spacing3; /* Extra spacing below last display
- * line for text line. Only valid if
- * spacing3String is non-NULL. */
- char *tabString; /* -tabs option string (malloc-ed).
- * NULL means option not specified. */
+ char *spacing1String; /* -spacing1 option string (malloc-ed). NULL
+ * means option not specified. */
+ int spacing1; /* Extra spacing above first display line for
+ * text line. Only valid if spacing1String is
+ * non-NULL. */
+ char *spacing2String; /* -spacing2 option string (malloc-ed). NULL
+ * means option not specified. */
+ int spacing2; /* Extra spacing between display lines for the
+ * same text line. Only valid if
+ * spacing2String is non-NULL. */
+ char *spacing3String; /* -spacing2 option string (malloc-ed). NULL
+ * means option not specified. */
+ int spacing3; /* Extra spacing below last display line for
+ * text line. Only valid if spacing3String is
+ * non-NULL. */
+ Tcl_Obj *tabStringPtr; /* -tabs option string. NULL means option not
+ * specified. */
struct TkTextTabArray *tabArrayPtr;
- /* Info about tabs for tag (malloc-ed)
- * or NULL. Corresponds to tabString. */
- char *underlineString; /* -underline option string (malloc-ed).
- * NULL means option not specified. */
+ /* Info about tabs for tag (malloc-ed) or
+ * NULL. Corresponds to tabString. */
+ int tabStyle; /* One of TABULAR or WORDPROCESSOR or NONE (if
+ * not specified). */
+ char *underlineString; /* -underline option string (malloc-ed). NULL
+ * means option not specified. */
int underline; /* Non-zero means draw underline underneath
- * text. Only valid if underlineString is
+ * text. Only valid if underlineString is
* non-NULL. */
TkWrapMode wrapMode; /* How to handle wrap-around for this tag.
* Must be TEXT_WRAPMODE_CHAR,
- * TEXT_WRAPMODE_NONE, TEXT_WRAPMODE_WORD,
- * or TEXT_WRAPMODE_NULL to use wrapmode for
+ * TEXT_WRAPMODE_NONE, TEXT_WRAPMODE_WORD, or
+ * TEXT_WRAPMODE_NULL to use wrapmode for
* whole widget. */
- char *elideString; /* -elide option string (malloc-ed).
- * NULL means option not specified. */
+ char *elideString; /* -elide option string (malloc-ed). NULL
+ * means option not specified. */
int elide; /* Non-zero means that data under this tag
* should not be displayed. */
int affectsDisplay; /* Non-zero means that this tag affects the
* way information is displayed on the screen
* (so need to redisplay if tag changes). */
+ Tk_OptionTable optionTable; /* Token representing the configuration
+ * specifications. */
+ int affectsDisplayGeometry; /* Non-zero means that this tag affects the
+ * size with which information is displayed on
+ * the screen (so need to recalculate line
+ * dimensions if tag changes). */
} TkTextTag;
#define TK_TAG_AFFECTS_DISPLAY 0x1
@@ -399,66 +426,81 @@ typedef struct TkTextTag {
#define TK_TAG_OFFSET 0x10
/*
- * The data structure below is used for searching a B-tree for transitions
- * on a single tag (or for all tag transitions). No code outside of
- * tkTextBTree.c should ever modify any of the fields in these structures,
- * but it's OK to use them for read-only information.
+ * The data structure below is used for searching a B-tree for transitions on
+ * a single tag (or for all tag transitions). No code outside of tkTextBTree.c
+ * should ever modify any of the fields in these structures, but it's OK to
+ * use them for read-only information.
*/
typedef struct TkTextSearch {
- TkTextIndex curIndex; /* Position of last tag transition
- * returned by TkBTreeNextTag, or
- * index of start of segment
- * containing starting position for
- * search if TkBTreeNextTag hasn't
- * been called yet, or same as
- * stopIndex if search is over. */
- TkTextSegment *segPtr; /* Actual tag segment returned by last
- * call to TkBTreeNextTag, or NULL if
- * TkBTreeNextTag hasn't returned
- * anything yet. */
- TkTextSegment *nextPtr; /* Where to resume search in next
- * call to TkBTreeNextTag. */
- TkTextSegment *lastPtr; /* Stop search before just before
- * considering this segment. */
- TkTextTag *tagPtr; /* Tag to search for (or tag found, if
- * allTags is non-zero). */
- int linesLeft; /* Lines left to search (including
- * curIndex and stopIndex). When
- * this becomes <= 0 the search is
- * over. */
- int allTags; /* Non-zero means ignore tag check:
- * search for transitions on all
- * tags. */
+ TkTextIndex curIndex; /* Position of last tag transition returned by
+ * TkBTreeNextTag, or index of start of
+ * segment containing starting position for
+ * search if TkBTreeNextTag hasn't been called
+ * yet, or same as stopIndex if search is
+ * over. */
+ TkTextSegment *segPtr; /* Actual tag segment returned by last call to
+ * TkBTreeNextTag, or NULL if TkBTreeNextTag
+ * hasn't returned anything yet. */
+ TkTextSegment *nextPtr; /* Where to resume search in next call to
+ * TkBTreeNextTag. */
+ TkTextSegment *lastPtr; /* Stop search before just before considering
+ * this segment. */
+ TkTextTag *tagPtr; /* Tag to search for (or tag found, if allTags
+ * is non-zero). */
+ int linesLeft; /* Lines left to search (including curIndex
+ * and stopIndex). When this becomes <= 0 the
+ * search is over. */
+ int allTags; /* Non-zero means ignore tag check: search for
+ * transitions on all tags. */
} TkTextSearch;
/*
- * The following data structure describes a single tab stop.
+ * The following data structure describes a single tab stop. It must be kept
+ * in sync with the 'tabOptionStrings' array in the function 'TkTextGetTabs'
*/
typedef enum {LEFT, RIGHT, CENTER, NUMERIC} TkTextTabAlign;
+/*
+ * The following are the supported styles of tabbing, used for the -tabstyle
+ * option of the text widget. The last element is only used for tag options.
+ */
+
+typedef enum {
+ TK_TEXT_TABSTYLE_TABULAR,
+ TK_TEXT_TABSTYLE_WORDPROCESSOR,
+ TK_TEXT_TABSTYLE_NONE
+} TkTextTabStyle;
+
typedef struct TkTextTab {
- int location; /* Offset in pixels of this tab stop
- * from the left margin (lmargin2) of
- * the text. */
- TkTextTabAlign alignment; /* Where the tab stop appears relative
- * to the text. */
+ int location; /* Offset in pixels of this tab stop from the
+ * left margin (lmargin2) of the text. */
+ TkTextTabAlign alignment; /* Where the tab stop appears relative to the
+ * text. */
} TkTextTab;
typedef struct TkTextTabArray {
- int numTabs; /* Number of tab stops. */
- TkTextTab tabs[1]; /* Array of tabs. The actual size
- * will be numTabs. THIS FIELD MUST
- * BE THE LAST IN THE STRUCTURE. */
+ int numTabs; /* Number of tab stops. */
+ double lastTab; /* The accurate fractional pixel position of
+ * the last tab. */
+ double tabIncrement; /* The accurate fractional pixel increment
+ * between interpolated tabs we have to create
+ * when we exceed numTabs. */
+ TkTextTab tabs[1]; /* Array of tabs. The actual size will be
+ * numTabs. THIS FIELD MUST BE THE LAST IN THE
+ * STRUCTURE. */
} TkTextTabArray;
-/* enum definining the edit modes of */
+/*
+ * Enumeration definining the edit modes of the widget.
+ */
typedef enum {
- TK_TEXT_EDIT_INSERT, /* insert mode */
- TK_TEXT_EDIT_DELETE, /* delete mode */
- TK_TEXT_EDIT_OTHER /* none of the above */
+ TK_TEXT_EDIT_INSERT, /* insert mode */
+ TK_TEXT_EDIT_DELETE, /* delete mode */
+ TK_TEXT_EDIT_REPLACE, /* replace mode */
+ TK_TEXT_EDIT_OTHER /* none of the above */
} TkTextEditMode;
/*
@@ -475,46 +517,127 @@ typedef enum {
} TkTextDirtyMode;
/*
- * A data structure of the following type is kept for each text widget that
- * currently exists for this process:
+ * The following enum is used to define a type for the -state option of the
+ * Text widget.
*/
-typedef struct TkText {
- Tk_Window tkwin; /* Window that embodies the text. NULL
- * means that the window has been destroyed
- * but the data structures haven't yet been
- * cleaned up.*/
- Display *display; /* Display for widget. Needed, among other
- * things, to allow resources to be freed
- * even after tkwin has gone away. */
- Tcl_Interp *interp; /* Interpreter associated with widget. Used
- * to delete widget command. */
- Tcl_Command widgetCmd; /* Token for text's widget command. */
+typedef enum {
+ TK_TEXT_STATE_DISABLED, TK_TEXT_STATE_NORMAL
+} TkTextState;
+
+/*
+ * A data structure of the following type is shared between each text widget
+ * that are peers.
+ */
+
+typedef struct TkSharedText {
+ int refCount; /* Reference count this shared object. */
TkTextBTree tree; /* B-tree representation of text and tags for
* widget. */
Tcl_HashTable tagTable; /* Hash table that maps from tag names to
- * pointers to TkTextTag structures. */
+ * pointers to TkTextTag structures. The "sel"
+ * tag does not feature in this table, since
+ * there's one of those for each text peer. */
int numTags; /* Number of tags currently defined for
- * widget; needed to keep track of
+ * widget; needed to keep track of
* priorities. */
Tcl_HashTable markTable; /* Hash table that maps from mark names to
- * pointers to mark segments. */
- Tcl_HashTable windowTable; /* Hash table that maps from window names
- * to pointers to window segments. If a
- * window segment doesn't yet have an
- * associated window, there is no entry for
- * it here. */
- Tcl_HashTable imageTable; /* Hash table that maps from image names
- * to pointers to image segments. If an
- * image segment doesn't yet have an
- * associated image, there is no entry for
- * it here. */
+ * pointers to mark segments. The special
+ * "insert" and "current" marks are not stored
+ * in this table, but directly accessed as
+ * fields of textPtr. */
+ Tcl_HashTable windowTable; /* Hash table that maps from window names to
+ * pointers to window segments. If a window
+ * segment doesn't yet have an associated
+ * window, there is no entry for it here. */
+ Tcl_HashTable imageTable; /* Hash table that maps from image names to
+ * pointers to image segments. If an image
+ * segment doesn't yet have an associated
+ * image, there is no entry for it here. */
+ Tk_BindingTable bindingTable;
+ /* Table of all bindings currently defined for
+ * this widget. NULL means that no bindings
+ * exist, so the table hasn't been created.
+ * Each "object" used for this table is the
+ * name of a tag. */
+ int stateEpoch; /* This is incremented each time the B-tree's
+ * contents change structurally, or when the
+ * start/end limits change, and means that any
+ * cached TkTextIndex objects are no longer
+ * valid. */
+
+ /*
+ * Information related to the undo/redo functionality.
+ */
+
+ TkUndoRedoStack *undoStack; /* The undo/redo stack. */
+ int undo; /* Non-zero means the undo/redo behaviour is
+ * enabled. */
+ int maxUndo; /* The maximum depth of the undo stack
+ * expressed as the maximum number of compound
+ * statements. */
+ int autoSeparators; /* Non-zero means the separators will be
+ * inserted automatically. */
+ int isDirty; /* Flag indicating the 'dirtyness' of the
+ * text widget. If the flag is not zero,
+ * unsaved modifications have been applied to
+ * the text widget. */
+ TkTextDirtyMode dirtyMode; /* The nature of the dirtyness characterized
+ * by the isDirty flag. */
+ TkTextEditMode lastEditMode;/* Keeps track of what the last edit mode
+ * was. */
+
+ /*
+ * Keep track of all the peers
+ */
+
+ struct TkText *peers;
+} TkSharedText;
+
+/*
+ * A data structure of the following type is kept for each text widget that
+ * currently exists for this process:
+ */
+
+typedef struct TkText {
+ /*
+ * Information related to and accessed by widget peers and the
+ * TkSharedText handling routines.
+ */
+
+ TkSharedText *sharedTextPtr;/* Shared section of all peers. */
+ struct TkText *next; /* Next in list of linked peers. */
+ TkTextLine *start; /* First B-tree line to show, or NULL to start
+ * at the beginning. */
+ TkTextLine *end; /* Last B-tree line to show, or NULL for up to
+ * the end. */
+ int pixelReference; /* Counter into the current tree reference
+ * index corresponding to this widget. */
+ int abortSelections; /* Set to 1 whenever the text is modified in a
+ * way that interferes with selection
+ * retrieval: used to abort incremental
+ * selection retrievals. */
+
+ /*
+ * Standard Tk widget information and text-widget specific items
+ */
+
+ Tk_Window tkwin; /* Window that embodies the text. NULL means
+ * that the window has been destroyed but the
+ * data structures haven't yet been cleaned
+ * up.*/
+ Display *display; /* Display for widget. Needed, among other
+ * things, to allow resources to be freed even
+ * after tkwin has gone away. */
+ Tcl_Interp *interp; /* Interpreter associated with widget. Used to
+ * delete widget command. */
+ Tcl_Command widgetCmd; /* Token for text's widget command. */
int state; /* Either STATE_NORMAL or STATE_DISABLED. A
* text widget is read-only when disabled. */
/*
- * Default information for displaying (may be overridden by tags
- * applied to ranges of characters).
+ * Default information for displaying (may be overridden by tags applied
+ * to ranges of characters).
*/
Tk_3DBorder border; /* Structure used to draw 3-D border and
@@ -522,44 +645,47 @@ typedef struct TkText {
int borderWidth; /* Width of 3-D border to draw around entire
* widget. */
int padX, padY; /* Padding between text and window border. */
- int relief; /* 3-d effect for border around entire
- * widget: TK_RELIEF_RAISED etc. */
- int highlightWidth; /* Width in pixels of highlight to draw
- * around widget when it has the focus.
- * <= 0 means don't draw a highlight. */
+ int relief; /* 3-d effect for border around entire widget:
+ * TK_RELIEF_RAISED etc. */
+ 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. */
+ /* Color for drawing traversal highlight area
+ * when highlight is off. */
XColor *highlightColorPtr; /* Color for drawing traversal highlight. */
Tk_Cursor cursor; /* Current cursor for window, or None. */
XColor *fgColor; /* Default foreground color for text. */
Tk_Font tkfont; /* Default font for displaying text. */
int charWidth; /* Width of average character in default
* font. */
+ int charHeight; /* Height of average character in default
+ * font, including line spacing. */
int spacing1; /* Default extra spacing above first display
* line for each text line. */
int spacing2; /* Default extra spacing between display lines
* for the same text line. */
int spacing3; /* Default extra spacing below last display
* line for each text line. */
- char *tabOptionString; /* Value of -tabs option string (malloc'ed). */
+ Tcl_Obj *tabOptionPtr; /* Value of -tabs option string. */
TkTextTabArray *tabArrayPtr;
/* Information about tab stops (malloc'ed).
* NULL means perform default tabbing
* behavior. */
+ int tabStyle; /* One of TABULAR or WORDPROCESSOR. */
/*
* Additional information used for displaying:
*/
- TkWrapMode wrapMode; /* How to handle wrap-around. Must be
+ TkWrapMode wrapMode; /* How to handle wrap-around. Must be
* TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, or
* TEXT_WRAPMODE_WORD. */
- int width, height; /* Desired dimensions for window, measured
- * in characters. */
- int setGrid; /* Non-zero means pass gridding information
- * to window manager. */
- int prevWidth, prevHeight; /* Last known dimensions of window; used to
+ int width, height; /* Desired dimensions for window, measured in
+ * characters. */
+ int setGrid; /* Non-zero means pass gridding information to
+ * window manager. */
+ int prevWidth, prevHeight; /* Last known dimensions of window; used to
* detect changes in size. */
TkTextIndex topIndex; /* Identifies first character in top display
* line of window. */
@@ -569,31 +695,27 @@ typedef struct TkText {
* Information related to selection.
*/
- TkTextTag *selTagPtr; /* Pointer to "sel" tag. Used to tell when
- * a new selection has been made. */
+ TkTextTag *selTagPtr; /* Pointer to "sel" tag. Used to tell when a
+ * new selection has been made. */
Tk_3DBorder selBorder; /* Border and background for selected
- * characters. This is a copy of information
- * in *cursorTagPtr, so it shouldn't be
- * explicitly freed. */
- char *selBdString; /* Value of -selectborderwidth option, or NULL
- * if not specified (malloc'ed). */
- XColor *selFgColorPtr; /* Foreground color for selected text.
- * This is a copy of information in
- * *cursorTagPtr, so it shouldn't be
+ * characters. This is a copy of information
+ * in *selTagPtr, so it shouldn't be
* explicitly freed. */
+ Tk_3DBorder inactiveSelBorder;
+ /* Border and background for selected
+ * characters when they don't have the
+ * focus. */
+ int selBorderWidth; /* Width of border around selection. */
+ Tcl_Obj *selBorderWidthPtr; /* Width of border around selection. */
+ XColor *selFgColorPtr; /* Foreground color for selected text. This is
+ * a copy of information in *selTagPtr, so it
+ * shouldn't be explicitly freed. */
int exportSelection; /* Non-zero means tie "sel" tag to X
* selection. */
- TkTextIndex selIndex; /* Used during multi-pass selection retrievals.
- * This index identifies the next character
- * to be returned from the selection. */
- int abortSelections; /* Set to 1 whenever the text is modified
- * in a way that interferes with selection
- * retrieval: used to abort incremental
- * selection retrievals. */
- int selOffset; /* Offset in selection corresponding to
- * selLine and selCh. -1 means neither
- * this information nor selIndex is of any
- * use. */
+ TkTextIndex selIndex; /* Used during multi-pass selection
+ * retrievals. This index identifies the next
+ * character to be returned from the
+ * selection. */
/*
* Information related to insertion cursor:
@@ -617,58 +739,49 @@ typedef struct TkText {
* Information used for event bindings associated with tags:
*/
- Tk_BindingTable bindingTable;
- /* Table of all bindings currently defined
- * for this widget. NULL means that no
- * bindings exist, so the table hasn't been
- * created. Each "object" used for this
- * table is the address of a tag. */
TkTextSegment *currentMarkPtr;
- /* Pointer to segment for "current" mark,
- * or NULL if none. */
+ /* Pointer to segment for "current" mark, or
+ * NULL if none. */
XEvent pickEvent; /* The event from which the current character
- * was chosen. Must be saved so that we
- * can repick after modifications to the
- * text. */
- int numCurTags; /* Number of tags associated with character
- * at current mark. */
- TkTextTag **curTagArrayPtr; /* Pointer to array of tags for current
- * mark, or NULL if none. */
+ * was chosen. Must be saved so that we can
+ * repick after modifications to the text. */
+ int numCurTags; /* Number of tags associated with character at
+ * current mark. */
+ TkTextTag **curTagArrayPtr; /* Pointer to array of tags for current mark,
+ * or NULL if none. */
/*
* Miscellaneous additional information:
*/
- char *takeFocus; /* Value of -takeFocus option; not used in
- * the C code, but used by keyboard traversal
- * scripts. Malloc'ed, but may be NULL. */
+ char *takeFocus; /* Value of -takeFocus option; not used in the
+ * C code, but used by keyboard traversal
+ * scripts. Malloc'ed, but may be NULL. */
char *xScrollCmd; /* Prefix of command to issue to update
* horizontal scrollbar when view changes. */
char *yScrollCmd; /* Prefix of command to issue to update
* vertical scrollbar when view changes. */
- int flags; /* Miscellaneous flags; see below for
+ int flags; /* Miscellaneous flags; see below for
* definitions. */
+ Tk_OptionTable optionTable; /* Token representing the configuration
+ * specifications. */
+ int refCount; /* Number of cached TkTextIndex objects
+ * refering to us. */
+ int insertCursorType; /* 0 = standard insertion cursor, 1 = block
+ * cursor. */
/*
- * Information related to the undo/redo funcitonality
+ * Copies of information from the shared section relating to the undo/redo
+ * functonality
*/
-
- TkUndoRedoStack *undoStack; /* The undo/redo stack. */
- int undo; /* non zero means the undo/redo behaviour is
+
+ int undo; /* Non-zero means the undo/redo behaviour is
* enabled. */
int maxUndo; /* The maximum depth of the undo stack
* expressed as the maximum number of compound
* statements. */
- int autoSeparators; /* non zero means the separatorss will be
+ int autoSeparators; /* Non-zero means the separators will be
* inserted automatically. */
- int isDirty; /* Flag indicating the 'dirtynesss' of the
- * text widget. If the flag is not zero,
- * unsaved modifications have been applied to
- * the text widget. */
- TkTextDirtyMode dirtyMode; /* The nature of the dirtyness characterized
- * by the isDirty flag. */
- TkTextEditMode lastEditMode;/* Keeps track of what the last edit mode
- * was. */
} TkText;
/*
@@ -680,11 +793,15 @@ typedef struct TkText {
* displayed on screen.
* GOT_FOCUS: Non-zero means this window has the input
* focus.
- * BUTTON_DOWN: 1 means that a mouse button is currently
- * down; this is used to implement grabs
- * for the duration of button presses.
+ * BUTTON_DOWN: 1 means that a mouse button is currently down;
+ * this is used to implement grabs for the
+ * duration of button presses.
* UPDATE_SCROLLBARS: Non-zero means scrollbar(s) should be updated
* during next redisplay operation.
+ * NEED_REPICK This appears unused and should probably be
+ * ignored.
+ * OPTIONS_FREED The widget's options have been freed.
+ * DESTROYED The widget is going away.
*/
#define GOT_SELECTION 1
@@ -693,230 +810,367 @@ typedef struct TkText {
#define BUTTON_DOWN 8
#define UPDATE_SCROLLBARS 0x10
#define NEED_REPICK 0x20
+#define OPTIONS_FREED 0x40
+#define DESTROYED 0x80
/*
- * Records of the following type define segment types in terms of
- * a collection of procedures that may be called to manipulate
- * segments of that type.
- */
-
-typedef TkTextSegment * Tk_SegSplitProc _ANSI_ARGS_((
- struct TkTextSegment *segPtr, int index));
-typedef int Tk_SegDeleteProc _ANSI_ARGS_((
- struct TkTextSegment *segPtr,
- TkTextLine *linePtr, int treeGone));
-typedef TkTextSegment * Tk_SegCleanupProc _ANSI_ARGS_((
- struct TkTextSegment *segPtr, TkTextLine *linePtr));
-typedef void Tk_SegLineChangeProc _ANSI_ARGS_((
- struct TkTextSegment *segPtr, TkTextLine *linePtr));
-typedef int Tk_SegLayoutProc _ANSI_ARGS_((struct TkText *textPtr,
- struct TkTextIndex *indexPtr, TkTextSegment *segPtr,
- int offset, int maxX, int maxChars,
- int noCharsYet, TkWrapMode wrapMode,
- struct TkTextDispChunk *chunkPtr));
-typedef void Tk_SegCheckProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr));
+ * Records of the following type define segment types in terms of a collection
+ * of procedures that may be called to manipulate segments of that type.
+ */
+
+typedef TkTextSegment * Tk_SegSplitProc(struct TkTextSegment *segPtr,
+ int index);
+typedef int Tk_SegDeleteProc(struct TkTextSegment *segPtr,
+ TkTextLine *linePtr, int treeGone);
+typedef TkTextSegment * Tk_SegCleanupProc(struct TkTextSegment *segPtr,
+ TkTextLine *linePtr);
+typedef void Tk_SegLineChangeProc(struct TkTextSegment *segPtr,
+ TkTextLine *linePtr);
+typedef int Tk_SegLayoutProc(struct TkText *textPtr,
+ struct TkTextIndex *indexPtr,
+ TkTextSegment *segPtr, int offset, int maxX,
+ int maxChars, int noCharsYet, TkWrapMode wrapMode,
+ struct TkTextDispChunk *chunkPtr);
+typedef void Tk_SegCheckProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr);
typedef struct Tk_SegType {
- char *name; /* Name of this kind of segment. */
- int leftGravity; /* If a segment has zero size (e.g. a
- * mark or tag toggle), does it
- * attach to character to its left
- * or right? 1 means left, 0 means
- * right. */
- Tk_SegSplitProc *splitProc; /* Procedure to split large segment
- * into two smaller ones. */
- Tk_SegDeleteProc *deleteProc; /* Procedure to call to delete
- * segment. */
- Tk_SegCleanupProc *cleanupProc; /* After any change to a line, this
- * procedure is invoked for all
- * segments left in the line to
- * perform any cleanup they wish
- * (e.g. joining neighboring
- * segments). */
+ const char *name; /* Name of this kind of segment. */
+ int leftGravity; /* If a segment has zero size (e.g. a mark or
+ * tag toggle), does it attach to character to
+ * its left or right? 1 means left, 0 means
+ * right. */
+ Tk_SegSplitProc *splitProc; /* Procedure to split large segment into two
+ * smaller ones. */
+ Tk_SegDeleteProc *deleteProc;
+ /* Procedure to call to delete segment. */
+ Tk_SegCleanupProc *cleanupProc;
+ /* After any change to a line, this procedure
+ * is invoked for all segments left in the
+ * line to perform any cleanup they wish
+ * (e.g. joining neighboring segments). */
Tk_SegLineChangeProc *lineChangeProc;
- /* Invoked when a segment is about
- * to be moved from its current line
- * to an earlier line because of
- * a deletion. The linePtr is that
- * for the segment's old line.
- * CleanupProc will be invoked after
- * the deletion is finished. */
- Tk_SegLayoutProc *layoutProc; /* Returns size information when
- * figuring out what to display in
- * window. */
- Tk_SegCheckProc *checkProc; /* Called during consistency checks
- * to check internal consistency of
- * segment. */
+ /* Invoked when a segment is about to be moved
+ * from its current line to an earlier line
+ * because of a deletion. The linePtr is that
+ * for the segment's old line. CleanupProc
+ * will be invoked after the deletion is
+ * finished. */
+ Tk_SegLayoutProc *layoutProc;
+ /* Returns size information when figuring out
+ * what to display in window. */
+ Tk_SegCheckProc *checkProc; /* Called during consistency checks to check
+ * internal consistency of segment. */
} Tk_SegType;
/*
- * The constant below is used to specify a line when what is really
- * wanted is the entire text. For now, just use a very big number.
+ * The following type and items describe different flags for text widget items
+ * to count. They are used in both tkText.c and tkTextIndex.c, in
+ * 'CountIndices', 'TkTextIndexBackChars', 'TkTextIndexForwChars', and
+ * 'TkTextIndexCount'.
+ */
+
+typedef int TkTextCountType;
+
+#define COUNT_CHARS 0
+#define COUNT_INDICES 1
+#define COUNT_DISPLAY 2
+#define COUNT_DISPLAY_CHARS (COUNT_CHARS | COUNT_DISPLAY)
+#define COUNT_DISPLAY_INDICES (COUNT_INDICES | COUNT_DISPLAY)
+
+/*
+ * The following structure is used to keep track of elided text taking account
+ * of different tag priorities, it is need for quick calculations of whether a
+ * single index is elided, and to start at a given index and maintain a
+ * correct elide state as we move or count forwards or backwards.
+ */
+
+#define LOTSA_TAGS 1000
+typedef struct TkTextElideInfo {
+ int numTags; /* Total tags in widget. */
+ int elide; /* Is the state currently elided. */
+ int elidePriority; /* Tag priority controlling elide state. */
+ TkTextSegment *segPtr; /* Segment to look at next. */
+ int segOffset; /* Offset of segment within line. */
+ int deftagCnts[LOTSA_TAGS];
+ TkTextTag *deftagPtrs[LOTSA_TAGS];
+ int *tagCnts; /* 0 or 1 depending if the tag with that
+ * priority is on or off. */
+ TkTextTag **tagPtrs; /* Only filled with a tagPtr if the
+ * corresponding tagCnt is 1. */
+} TkTextElideInfo;
+
+/*
+ * The constant below is used to specify a line when what is really wanted is
+ * the entire text. For now, just use a very big number.
*/
-#define TK_END_OF_TEXT 1000000
+#define TK_END_OF_TEXT 1000000
/*
- * The following definition specifies the maximum number of characters
- * needed in a string to hold a position specifier.
+ * The following definition specifies the maximum number of characters needed
+ * in a string to hold a position specifier.
*/
-#define TK_POS_CHARS 30
+#define TK_POS_CHARS 30
+
+/*
+ * Mask used for those options which may impact the pixel height calculations
+ * of individual lines displayed in the widget.
+ */
+
+#define TK_TEXT_LINE_GEOMETRY 1
+
+/*
+ * Mask used for those options which may impact the start and end lines used
+ * in the widget.
+ */
+
+#define TK_TEXT_LINE_RANGE 2
+
+/*
+ * Used as 'action' values in calls to TkTextInvalidateLineMetrics
+ */
+
+#define TK_TEXT_INVALIDATE_ONLY 0
+#define TK_TEXT_INVALIDATE_INSERT 1
+#define TK_TEXT_INVALIDATE_DELETE 2
+
+/*
+ * Used as special 'pickPlace' values in calls to TkTextSetYView. Zero or
+ * positive values indicate a number of pixels.
+ */
+
+#define TK_TEXT_PICKPLACE -1
+#define TK_TEXT_NOPIXELADJUST -2
/*
* Declarations for variables shared among the text-related files:
*/
-EXTERN int tkBTreeDebug;
-EXTERN int tkTextDebug;
-EXTERN Tk_SegType tkTextCharType;
-EXTERN Tk_SegType tkTextLeftMarkType;
-EXTERN Tk_SegType tkTextRightMarkType;
-EXTERN Tk_SegType tkTextToggleOnType;
-EXTERN Tk_SegType tkTextToggleOffType;
-
-/*
- * Declarations for procedures that are used by the text-related files
- * but shouldn't be used anywhere else in Tk (or by Tk clients):
- */
-
-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,
- TkTextIndex *index2Ptr));
-EXTERN TkTextLine * TkBTreeFindLine _ANSI_ARGS_((TkTextBTree tree,
- int line));
-EXTERN TkTextTag ** TkBTreeGetTags _ANSI_ARGS_((TkTextIndex *indexPtr,
- int *numTagsPtr));
-EXTERN void TkBTreeInsertChars _ANSI_ARGS_((TkTextIndex *indexPtr,
- CONST char *string));
-EXTERN int TkBTreeLineIndex _ANSI_ARGS_((TkTextLine *linePtr));
-EXTERN void TkBTreeLinkSegment _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextIndex *indexPtr));
-EXTERN TkTextLine * TkBTreeNextLine _ANSI_ARGS_((TkTextLine *linePtr));
-EXTERN int TkBTreeNextTag _ANSI_ARGS_((TkTextSearch *searchPtr));
-EXTERN int TkBTreeNumLines _ANSI_ARGS_((TkTextBTree tree));
-EXTERN TkTextLine * TkBTreePreviousLine _ANSI_ARGS_((TkTextLine *linePtr));
-EXTERN int TkBTreePrevTag _ANSI_ARGS_((TkTextSearch *searchPtr));
-EXTERN void TkBTreeStartSearch _ANSI_ARGS_((TkTextIndex *index1Ptr,
+MODULE_SCOPE int tkBTreeDebug;
+MODULE_SCOPE int tkTextDebug;
+MODULE_SCOPE const Tk_SegType tkTextCharType;
+MODULE_SCOPE const Tk_SegType tkTextLeftMarkType;
+MODULE_SCOPE const Tk_SegType tkTextRightMarkType;
+MODULE_SCOPE const Tk_SegType tkTextToggleOnType;
+MODULE_SCOPE const Tk_SegType tkTextToggleOffType;
+
+/*
+ * Convenience macros for use by B-tree clients which want to access pixel
+ * information on each line. Currently only used by TkTextDisp.c
+ */
+
+#define TkBTreeLinePixelCount(text, line) \
+ (line)->pixels[2*(text)->pixelReference]
+#define TkBTreeLinePixelEpoch(text, line) \
+ (line)->pixels[1+2*(text)->pixelReference]
+
+/*
+ * Declarations for procedures that are used by the text-related files but
+ * shouldn't be used anywhere else in Tk (or by Tk clients):
+ */
+
+MODULE_SCOPE int TkBTreeAdjustPixelHeight(const TkText *textPtr,
+ TkTextLine *linePtr, int newPixelHeight,
+ int mergedLogicalLines);
+MODULE_SCOPE int TkBTreeCharTagged(const TkTextIndex *indexPtr,
+ TkTextTag *tagPtr);
+MODULE_SCOPE void TkBTreeCheck(TkTextBTree tree);
+MODULE_SCOPE TkTextBTree TkBTreeCreate(TkSharedText *sharedTextPtr);
+MODULE_SCOPE void TkBTreeAddClient(TkTextBTree tree, TkText *textPtr,
+ int defaultHeight);
+MODULE_SCOPE void TkBTreeClientRangeChanged(TkText *textPtr,
+ int defaultHeight);
+MODULE_SCOPE void TkBTreeRemoveClient(TkTextBTree tree,
+ TkText *textPtr);
+MODULE_SCOPE void TkBTreeDestroy(TkTextBTree tree);
+MODULE_SCOPE void TkBTreeDeleteIndexRange(TkTextBTree tree,
+ TkTextIndex *index1Ptr, TkTextIndex *index2Ptr);
+MODULE_SCOPE int TkBTreeEpoch(TkTextBTree tree);
+MODULE_SCOPE TkTextLine *TkBTreeFindLine(TkTextBTree tree,
+ const TkText *textPtr, int line);
+MODULE_SCOPE TkTextLine *TkBTreeFindPixelLine(TkTextBTree tree,
+ const TkText *textPtr, int pixels,
+ int *pixelOffset);
+MODULE_SCOPE TkTextTag **TkBTreeGetTags(const TkTextIndex *indexPtr,
+ const TkText *textPtr, int *numTagsPtr);
+MODULE_SCOPE void TkBTreeInsertChars(TkTextBTree tree,
+ TkTextIndex *indexPtr, const char *string);
+MODULE_SCOPE int TkBTreeLinesTo(const TkText *textPtr,
+ TkTextLine *linePtr);
+MODULE_SCOPE int TkBTreePixelsTo(const TkText *textPtr,
+ TkTextLine *linePtr);
+MODULE_SCOPE void TkBTreeLinkSegment(TkTextSegment *segPtr,
+ TkTextIndex *indexPtr);
+MODULE_SCOPE TkTextLine *TkBTreeNextLine(const TkText *textPtr,
+ TkTextLine *linePtr);
+MODULE_SCOPE int TkBTreeNextTag(TkTextSearch *searchPtr);
+MODULE_SCOPE int TkBTreeNumLines(TkTextBTree tree,
+ const TkText *textPtr);
+MODULE_SCOPE int TkBTreeNumPixels(TkTextBTree tree,
+ const TkText *textPtr);
+MODULE_SCOPE TkTextLine *TkBTreePreviousLine(TkText *textPtr,
+ TkTextLine *linePtr);
+MODULE_SCOPE int TkBTreePrevTag(TkTextSearch *searchPtr);
+MODULE_SCOPE void TkBTreeStartSearch(TkTextIndex *index1Ptr,
TkTextIndex *index2Ptr, TkTextTag *tagPtr,
- TkTextSearch *searchPtr));
-EXTERN void TkBTreeStartSearchBack _ANSI_ARGS_((TkTextIndex *index1Ptr,
+ TkTextSearch *searchPtr);
+MODULE_SCOPE void TkBTreeStartSearchBack(TkTextIndex *index1Ptr,
TkTextIndex *index2Ptr, TkTextTag *tagPtr,
- TkTextSearch *searchPtr));
-EXTERN void TkBTreeTag _ANSI_ARGS_((TkTextIndex *index1Ptr,
+ TkTextSearch *searchPtr);
+MODULE_SCOPE int TkBTreeTag(TkTextIndex *index1Ptr,
TkTextIndex *index2Ptr, TkTextTag *tagPtr,
- int add));
-EXTERN void TkBTreeUnlinkSegment _ANSI_ARGS_((TkTextBTree tree,
- TkTextSegment *segPtr, TkTextLine *linePtr));
-EXTERN void TkTextBindProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-EXTERN void TkTextChanged _ANSI_ARGS_((TkText *textPtr,
- TkTextIndex *index1Ptr, TkTextIndex *index2Ptr));
-EXTERN int TkTextCharBbox _ANSI_ARGS_((TkText *textPtr,
- TkTextIndex *indexPtr, int *xPtr, int *yPtr,
- int *widthPtr, int *heightPtr));
-EXTERN int TkTextCharLayoutProc _ANSI_ARGS_((TkText *textPtr,
+ int add);
+MODULE_SCOPE void TkBTreeUnlinkSegment(TkTextSegment *segPtr,
+ TkTextLine *linePtr);
+MODULE_SCOPE void TkTextBindProc(ClientData clientData,
+ XEvent *eventPtr);
+MODULE_SCOPE void TkTextSelectionEvent(TkText *textPtr);
+MODULE_SCOPE void TkTextChanged(TkSharedText *sharedTextPtr,
+ TkText *textPtr, const TkTextIndex *index1Ptr,
+ const TkTextIndex *index2Ptr);
+MODULE_SCOPE int TkTextIndexBbox(TkText *textPtr,
+ const TkTextIndex *indexPtr, int *xPtr, int *yPtr,
+ int *widthPtr, int *heightPtr, int *charWidthPtr);
+MODULE_SCOPE int TkTextCharLayoutProc(TkText *textPtr,
TkTextIndex *indexPtr, TkTextSegment *segPtr,
int offset, int maxX, int maxChars, int noBreakYet,
- TkWrapMode wrapMode, TkTextDispChunk *chunkPtr));
-EXTERN void TkTextCreateDInfo _ANSI_ARGS_((TkText *textPtr));
-EXTERN int TkTextDLineInfo _ANSI_ARGS_((TkText *textPtr,
- TkTextIndex *indexPtr, int *xPtr, int *yPtr,
- int *widthPtr, int *heightPtr, int *basePtr));
-EXTERN TkTextTag * TkTextCreateTag _ANSI_ARGS_((TkText *textPtr,
- CONST char *tagName));
-EXTERN void TkTextFreeDInfo _ANSI_ARGS_((TkText *textPtr));
-EXTERN void TkTextFreeTag _ANSI_ARGS_((TkText *textPtr,
- TkTextTag *tagPtr));
-EXTERN int TkTextGetIndex _ANSI_ARGS_((Tcl_Interp *interp,
- TkText *textPtr, CONST char *string,
- TkTextIndex *indexPtr));
-EXTERN TkTextTabArray * TkTextGetTabs _ANSI_ARGS_((Tcl_Interp *interp,
- Tk_Window tkwin, char *string));
-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 * TkTextMakeCharIndex _ANSI_ARGS_((TkTextBTree tree,
+ TkWrapMode wrapMode, TkTextDispChunk *chunkPtr);
+MODULE_SCOPE void TkTextCreateDInfo(TkText *textPtr);
+MODULE_SCOPE int TkTextDLineInfo(TkText *textPtr,
+ const TkTextIndex *indexPtr, int *xPtr, int *yPtr,
+ int *widthPtr, int *heightPtr, int *basePtr);
+MODULE_SCOPE void TkTextEmbWinDisplayProc(TkText *textPtr,
+ TkTextDispChunk *chunkPtr, int x, int y,
+ int lineHeight, int baseline, Display *display,
+ Drawable dst, int screenY);
+MODULE_SCOPE TkTextTag *TkTextCreateTag(TkText *textPtr,
+ const char *tagName, int *newTag);
+MODULE_SCOPE void TkTextFreeDInfo(TkText *textPtr);
+MODULE_SCOPE void TkTextDeleteTag(TkText *textPtr, TkTextTag *tagPtr);
+MODULE_SCOPE void TkTextFreeTag(TkText *textPtr, TkTextTag *tagPtr);
+MODULE_SCOPE int TkTextGetIndex(Tcl_Interp *interp, TkText *textPtr,
+ const char *string, TkTextIndex *indexPtr);
+MODULE_SCOPE int TkTextGetObjIndex(Tcl_Interp *interp, TkText *textPtr,
+ Tcl_Obj *idxPtr, TkTextIndex *indexPtr);
+MODULE_SCOPE int TkTextSharedGetObjIndex(Tcl_Interp *interp,
+ TkSharedText *sharedTextPtr, Tcl_Obj *idxPtr,
+ TkTextIndex *indexPtr);
+MODULE_SCOPE const TkTextIndex *TkTextGetIndexFromObj(Tcl_Interp *interp,
+ TkText *textPtr, Tcl_Obj *objPtr);
+MODULE_SCOPE TkTextTabArray *TkTextGetTabs(Tcl_Interp *interp,
+ TkText *textPtr, Tcl_Obj *stringPtr);
+MODULE_SCOPE void TkTextFindDisplayLineEnd(TkText *textPtr,
+ TkTextIndex *indexPtr, int end, int *xOffset);
+MODULE_SCOPE int TkTextIndexBackBytes(const TkText *textPtr,
+ const TkTextIndex *srcPtr, int count,
+ TkTextIndex *dstPtr);
+MODULE_SCOPE void TkTextIndexBackChars(const TkText *textPtr,
+ const TkTextIndex *srcPtr, int count,
+ TkTextIndex *dstPtr, TkTextCountType type);
+MODULE_SCOPE int TkTextIndexCmp(const TkTextIndex *index1Ptr,
+ const TkTextIndex *index2Ptr);
+MODULE_SCOPE int TkTextIndexCount(const TkText *textPtr,
+ const TkTextIndex *index1Ptr,
+ const TkTextIndex *index2Ptr,
+ TkTextCountType type);
+MODULE_SCOPE int TkTextIndexForwBytes(const TkText *textPtr,
+ const TkTextIndex *srcPtr, int count,
+ TkTextIndex *dstPtr);
+MODULE_SCOPE void TkTextIndexForwChars(const TkText *textPtr,
+ const TkTextIndex *srcPtr, int count,
+ TkTextIndex *dstPtr, TkTextCountType type);
+MODULE_SCOPE void TkTextIndexOfX(TkText *textPtr, int x,
+ TkTextIndex *indexPtr);
+MODULE_SCOPE int TkTextIndexYPixels(TkText *textPtr,
+ const TkTextIndex *indexPtr);
+MODULE_SCOPE TkTextSegment *TkTextIndexToSeg(const TkTextIndex *indexPtr,
+ int *offsetPtr);
+MODULE_SCOPE void TkTextInsertDisplayProc(TkText *textPtr,
+ TkTextDispChunk *chunkPtr, int x, int y,
+ int height, int baseline, Display *display,
+ Drawable dst, int screenY);
+MODULE_SCOPE void TkTextLostSelection(ClientData clientData);
+MODULE_SCOPE TkTextIndex *TkTextMakeCharIndex(TkTextBTree tree, TkText *textPtr,
int lineIndex, int charIndex,
- TkTextIndex *indexPtr));
-EXTERN int TkTextIsElided _ANSI_ARGS_((TkText *textPtr,
- 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, CONST char **argv));
-EXTERN int TkTextMarkNameToIndex _ANSI_ARGS_((TkText *textPtr,
- CONST char *name, TkTextIndex *indexPtr));
-EXTERN void TkTextMarkSegToIndex _ANSI_ARGS_((TkText *textPtr,
- TkTextSegment *markPtr, TkTextIndex *indexPtr));
-EXTERN void TkTextEventuallyRepick _ANSI_ARGS_((TkText *textPtr));
-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_((
- 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,
- TkTextIndex *index1Ptr, TkTextIndex *index2Ptr,
- TkTextTag *tagPtr, int withTag));
-EXTERN void TkTextRelayoutWindow _ANSI_ARGS_((TkText *textPtr));
-EXTERN int TkTextScanCmd _ANSI_ARGS_((TkText *textPtr,
- Tcl_Interp *interp, int argc, CONST char **argv));
-EXTERN int TkTextSeeCmd _ANSI_ARGS_((TkText *textPtr,
- Tcl_Interp *interp, int argc, CONST char **argv));
-EXTERN int TkTextSegToOffset _ANSI_ARGS_((
- CONST TkTextSegment *segPtr,
- CONST TkTextLine *linePtr));
-EXTERN TkTextSegment * TkTextSetMark _ANSI_ARGS_((TkText *textPtr,
- CONST char *name, TkTextIndex *indexPtr));
-EXTERN void TkTextSetYView _ANSI_ARGS_((TkText *textPtr,
- TkTextIndex *indexPtr, int pickPlace));
-EXTERN int TkTextTagCmd _ANSI_ARGS_((TkText *textPtr,
- Tcl_Interp *interp, int argc, CONST char **argv));
-EXTERN int TkTextImageCmd _ANSI_ARGS_((TkText *textPtr,
- Tcl_Interp *interp, int argc, CONST char **argv));
-EXTERN int TkTextImageIndex _ANSI_ARGS_((TkText *textPtr,
- CONST char *name, TkTextIndex *indexPtr));
-EXTERN int TkTextWindowCmd _ANSI_ARGS_((TkText *textPtr,
- Tcl_Interp *interp, int argc, CONST char **argv));
-EXTERN int TkTextWindowIndex _ANSI_ARGS_((TkText *textPtr,
- CONST char *name, TkTextIndex *indexPtr));
-EXTERN int TkTextXviewCmd _ANSI_ARGS_((TkText *textPtr,
- Tcl_Interp *interp, int argc, CONST char **argv));
-EXTERN int TkTextYviewCmd _ANSI_ARGS_((TkText *textPtr,
- Tcl_Interp *interp, int argc, CONST char **argv));
+ TkTextIndex *indexPtr);
+MODULE_SCOPE int TkTextMeasureDown(TkText *textPtr,
+ TkTextIndex *srcPtr, int distance);
+MODULE_SCOPE void TkTextFreeElideInfo(TkTextElideInfo *infoPtr);
+MODULE_SCOPE int TkTextIsElided(const TkText *textPtr,
+ const TkTextIndex *indexPtr,
+ TkTextElideInfo *infoPtr);
+MODULE_SCOPE TkTextIndex *TkTextMakeByteIndex(TkTextBTree tree,
+ const TkText *textPtr, int lineIndex,
+ int byteIndex, TkTextIndex *indexPtr);
+MODULE_SCOPE int TkTextMakePixelIndex(TkText *textPtr,
+ int pixelIndex, TkTextIndex *indexPtr);
+MODULE_SCOPE void TkTextInvalidateLineMetrics(
+ TkSharedText *sharedTextPtr, TkText *textPtr,
+ TkTextLine *linePtr, int lineCount, int action);
+MODULE_SCOPE int TkTextUpdateLineMetrics(TkText *textPtr, int lineNum,
+ int endLine, int doThisMuch);
+MODULE_SCOPE int TkTextUpdateOneLine(TkText *textPtr,
+ TkTextLine *linePtr, int pixelHeight,
+ TkTextIndex *indexPtr, int partialCalc);
+MODULE_SCOPE int TkTextMarkCmd(TkText *textPtr, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE int TkTextMarkNameToIndex(TkText *textPtr,
+ const char *name, TkTextIndex *indexPtr);
+MODULE_SCOPE void TkTextMarkSegToIndex(TkText *textPtr,
+ TkTextSegment *markPtr, TkTextIndex *indexPtr);
+MODULE_SCOPE void TkTextEventuallyRepick(TkText *textPtr);
+MODULE_SCOPE void TkTextPickCurrent(TkText *textPtr, XEvent *eventPtr);
+MODULE_SCOPE void TkTextPixelIndex(TkText *textPtr, int x, int y,
+ TkTextIndex *indexPtr, int *nearest);
+MODULE_SCOPE int TkTextPrintIndex(const TkText *textPtr,
+ const TkTextIndex *indexPtr, char *string);
+MODULE_SCOPE Tcl_Obj * TkTextNewIndexObj(TkText *textPtr,
+ const TkTextIndex *indexPtr);
+MODULE_SCOPE void TkTextRedrawRegion(TkText *textPtr, int x, int y,
+ int width, int height);
+MODULE_SCOPE void TkTextRedrawTag(TkSharedText *sharedTextPtr,
+ TkText *textPtr, TkTextIndex *index1Ptr,
+ TkTextIndex *index2Ptr, TkTextTag *tagPtr,
+ int withTag);
+MODULE_SCOPE void TkTextRelayoutWindow(TkText *textPtr, int mask);
+MODULE_SCOPE int TkTextScanCmd(TkText *textPtr, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE int TkTextSeeCmd(TkText *textPtr, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE int TkTextSegToOffset(const TkTextSegment *segPtr,
+ const TkTextLine *linePtr);
+MODULE_SCOPE TkTextSegment *TkTextSetMark(TkText *textPtr,
+ const char *name, TkTextIndex *indexPtr);
+MODULE_SCOPE void TkTextSetYView(TkText *textPtr,
+ TkTextIndex *indexPtr, int pickPlace);
+MODULE_SCOPE int TkTextTagCmd(TkText *textPtr, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE int TkTextImageCmd(TkText *textPtr, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE int TkTextImageIndex(TkText *textPtr,
+ const char *name, TkTextIndex *indexPtr);
+MODULE_SCOPE int TkTextWindowCmd(TkText *textPtr, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE int TkTextWindowIndex(TkText *textPtr, const char *name,
+ TkTextIndex *indexPtr);
+MODULE_SCOPE int TkTextXviewCmd(TkText *textPtr, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE int TkTextYviewCmd(TkText *textPtr, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE void TkTextWinFreeClient(Tcl_HashEntry *hPtr,
+ TkTextEmbWindowClient *client);
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLIMPORT
#endif /* _TKTEXT */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkTextBTree.c b/generic/tkTextBTree.c
index 5a5a9b5..67ff79d 100644
--- a/generic/tkTextBTree.c
+++ b/generic/tkTextBTree.c
@@ -1,33 +1,54 @@
-/*
+/*
* tkTextBTree.c --
*
- * This file contains code that manages the B-tree representation
- * of text for Tk's text widget and implements character and
- * toggle segment types.
+ * This file contains code that manages the B-tree representation of text
+ * for Tk's text widget and implements character and toggle segment
+ * types.
*
* Copyright (c) 1992-1994 The Regents of the University of California.
* Copyright (c) 1994-1995 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
-#include "tkPort.h"
#include "tkText.h"
/*
- * The data structure below keeps summary information about one tag as part
- * of the tag information in a node.
+ * Implementation notes:
+ *
+ * Most of this file is independent of the text widget implementation and
+ * representation now. Without much effort this could be developed further
+ * into a new Tcl object type of which the Tk text widget is one example of a
+ * client.
+ *
+ * The B-tree is set up with a dummy last line of text which must not be
+ * displayed, and must _never_ have a non-zero pixel count. This dummy line is
+ * a historical convenience to avoid other code having to deal with NULL
+ * TkTextLines. Since Tk 8.5, with pixel line height calculations and peer
+ * widgets, this dummy line is becoming somewhat of a liability, and special
+ * case code has been required to deal with it. It is probably a good idea to
+ * investigate removing the dummy line completely. This could result in an
+ * overall simplification (although it would require new special case code to
+ * deal with the fact that '.text index end' would then not really point to a
+ * valid line, rather it would point to the beginning of a non-existent line
+ * one beyond all current lines - we could perhaps define that as a
+ * TkTextIndex with a NULL TkTextLine ptr).
+ */
+
+/*
+ * The data structure below keeps summary information about one tag as part of
+ * the tag information in a node.
*/
typedef struct Summary {
- TkTextTag *tagPtr; /* Handle for tag. */
- int toggleCount; /* Number of transitions into or
- * out of this tag that occur in
- * the subtree rooted at this node. */
- struct Summary *nextPtr; /* Next in list of all tags for same
- * node, or NULL if at end of list. */
+ TkTextTag *tagPtr; /* Handle for tag. */
+ int toggleCount; /* Number of transitions into or out of this
+ * tag that occur in the subtree rooted at
+ * this node. */
+ struct Summary *nextPtr; /* Next in list of all tags for same node, or
+ * NULL if at end of list. */
} Summary;
/*
@@ -35,43 +56,63 @@ typedef struct Summary {
*/
typedef struct Node {
- struct Node *parentPtr; /* Pointer to parent node, or NULL if
- * this is the root. */
- struct Node *nextPtr; /* Next in list of siblings with the
- * same parent node, or NULL for end
- * of list. */
- Summary *summaryPtr; /* First in malloc-ed list of info
- * about tags in this subtree (NULL if
- * no tag info in the subtree). */
- int level; /* Level of this node in the B-tree.
- * 0 refers to the bottom of the tree
- * (children are lines, not nodes). */
- union { /* First in linked list of children. */
- struct Node *nodePtr; /* Used if level > 0. */
- TkTextLine *linePtr; /* Used if level == 0. */
+ struct Node *parentPtr; /* Pointer to parent node, or NULL if this is
+ * the root. */
+ struct Node *nextPtr; /* Next in list of siblings with the same
+ * parent node, or NULL for end of list. */
+ Summary *summaryPtr; /* First in malloc-ed list of info about tags
+ * in this subtree (NULL if no tag info in the
+ * subtree). */
+ int level; /* Level of this node in the B-tree. 0 refers
+ * to the bottom of the tree (children are
+ * lines, not nodes). */
+ union { /* First in linked list of children. */
+ struct Node *nodePtr; /* Used if level > 0. */
+ TkTextLine *linePtr; /* Used if level == 0. */
} children;
- int numChildren; /* Number of children of this node. */
- int numLines; /* Total number of lines (leaves) in
- * the subtree rooted here. */
+ int numChildren; /* Number of children of this node. */
+ int numLines; /* Total number of lines (leaves) in the
+ * subtree rooted here. */
+ int *numPixels; /* Array containing total number of vertical
+ * display pixels in the subtree rooted here,
+ * one entry for each peer widget. */
} Node;
/*
- * Upper and lower bounds on how many children a node may have:
- * rebalance when either of these limits is exceeded. MAX_CHILDREN
- * should be twice MIN_CHILDREN and MIN_CHILDREN must be >= 2.
+ * Used to avoid having to allocate and deallocate arrays on the fly for
+ * commonly used functions. Must be > 0.
+ */
+
+#define PIXEL_CLIENTS 5
+
+/*
+ * Upper and lower bounds on how many children a node may have: rebalance when
+ * either of these limits is exceeded. MAX_CHILDREN should be twice
+ * MIN_CHILDREN and MIN_CHILDREN must be >= 2.
*/
#define MAX_CHILDREN 12
#define MIN_CHILDREN 6
/*
- * The data structure below defines an entire B-tree.
+ * The data structure below defines an entire B-tree. Since text widgets are
+ * the only current B-tree clients, 'clients' and 'pixelReferences' are
+ * identical.
*/
typedef struct BTree {
- Node *rootPtr; /* Pointer to root of B-tree. */
- TkText *textPtr; /* Used to find tagTable in consistency
- * checking code */
+ Node *rootPtr; /* Pointer to root of B-tree. */
+ int clients; /* Number of clients of this B-tree. */
+ int pixelReferences; /* Number of clients of this B-tree which care
+ * about pixel heights. */
+ int stateEpoch; /* Updated each time any aspect of the B-tree
+ * changes. */
+ TkSharedText *sharedTextPtr;/* Used to find tagTable in consistency
+ * checking code, and to access list of all
+ * B-tree clients. */
+ int startEndCount;
+ TkTextLine **startEnd;
+ TkText **startEndRef;
} BTree;
/*
@@ -80,20 +121,17 @@ typedef struct BTree {
*/
typedef struct TagInfo {
- int numTags; /* Number of tags for which there
- * is currently information in
- * tags and counts. */
- int arraySize; /* Number of entries allocated for
- * tags and counts. */
- TkTextTag **tagPtrs; /* Array of tags seen so far.
- * Malloc-ed. */
- int *counts; /* Toggle count (so far) for each
- * entry in tags. Malloc-ed. */
+ int numTags; /* Number of tags for which there is currently
+ * information in tags and counts. */
+ int arraySize; /* Number of entries allocated for tags and
+ * counts. */
+ TkTextTag **tagPtrs; /* Array of tags seen so far. Malloc-ed. */
+ int *counts; /* Toggle count (so far) for each entry in
+ * tags. Malloc-ed. */
} TagInfo;
/*
- * Variable that indicates whether to enable consistency checks for
- * debugging.
+ * Variable that indicates whether to enable consistency checks for debugging.
*/
int tkBTreeDebug = 0;
@@ -108,86 +146,98 @@ int tkBTreeDebug = 0;
+ sizeof(TkTextToggle)))
/*
- * Forward declarations for procedures defined in this file:
- */
-
-static void ChangeNodeToggleCount _ANSI_ARGS_((Node *nodePtr,
- TkTextTag *tagPtr, int delta));
-static void CharCheckProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr));
-static int CharDeleteProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr, int treeGone));
-static TkTextSegment * CharCleanupProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr));
-static TkTextSegment * CharSplitProc _ANSI_ARGS_((TkTextSegment *segPtr,
- int index));
-static void CheckNodeConsistency _ANSI_ARGS_((Node *nodePtr));
-static void CleanupLine _ANSI_ARGS_((TkTextLine *linePtr));
-static void DeleteSummaries _ANSI_ARGS_((Summary *tagPtr));
-static void DestroyNode _ANSI_ARGS_((Node *nodePtr));
-static TkTextSegment * FindTagEnd _ANSI_ARGS_((TkTextBTree tree,
- TkTextTag *tagPtr, TkTextIndex *indexPtr));
-static void IncCount _ANSI_ARGS_((TkTextTag *tagPtr, int inc,
- TagInfo *tagInfoPtr));
-static void Rebalance _ANSI_ARGS_((BTree *treePtr, Node *nodePtr));
-static void RecomputeNodeCounts _ANSI_ARGS_((Node *nodePtr));
-static TkTextSegment * SplitSeg _ANSI_ARGS_((TkTextIndex *indexPtr));
-static void ToggleCheckProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr));
-static TkTextSegment * ToggleCleanupProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr));
-static int ToggleDeleteProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr, int treeGone));
-static void ToggleLineChangeProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr));
-static TkTextSegment * FindTagStart _ANSI_ARGS_((TkTextBTree tree,
- TkTextTag *tagPtr, TkTextIndex *indexPtr));
+ * Forward declarations for functions defined in this file:
+ */
+
+static int AdjustPixelClient(BTree *treePtr, int defaultHeight,
+ Node *nodePtr, TkTextLine *start, TkTextLine *end,
+ int useReference, int newPixelReferences,
+ int *counting);
+static void ChangeNodeToggleCount(Node *nodePtr,
+ TkTextTag *tagPtr, int delta);
+static void CharCheckProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr);
+static int CharDeleteProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr, int treeGone);
+static TkTextSegment * CharCleanupProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr);
+static TkTextSegment * CharSplitProc(TkTextSegment *segPtr, int index);
+static void CheckNodeConsistency(Node *nodePtr, int references);
+static void CleanupLine(TkTextLine *linePtr);
+static void DeleteSummaries(Summary *tagPtr);
+static void DestroyNode(Node *nodePtr);
+static TkTextSegment * FindTagEnd(TkTextBTree tree, TkTextTag *tagPtr,
+ TkTextIndex *indexPtr);
+static void IncCount(TkTextTag *tagPtr, int inc,
+ TagInfo *tagInfoPtr);
+static void Rebalance(BTree *treePtr, Node *nodePtr);
+static void RecomputeNodeCounts(BTree *treePtr, Node *nodePtr);
+static void RemovePixelClient(BTree *treePtr, Node *nodePtr,
+ int overwriteWithLast);
+static TkTextSegment * SplitSeg(TkTextIndex *indexPtr);
+static void ToggleCheckProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr);
+static TkTextSegment * ToggleCleanupProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr);
+static int ToggleDeleteProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr, int treeGone);
+static void ToggleLineChangeProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr);
+static TkTextSegment * FindTagStart(TkTextBTree tree, TkTextTag *tagPtr,
+ TkTextIndex *indexPtr);
+static void AdjustStartEndRefs(BTree *treePtr, TkText *textPtr,
+ int action);
+
+/*
+ * Actions for use by AdjustStartEndRefs
+ */
+
+#define TEXT_ADD_REFS 1
+#define TEXT_REMOVE_REFS 2
/*
* Type record for character segments:
*/
-Tk_SegType tkTextCharType = {
- "character", /* name */
- 0, /* leftGravity */
- CharSplitProc, /* splitProc */
- CharDeleteProc, /* deleteProc */
- CharCleanupProc, /* cleanupProc */
- (Tk_SegLineChangeProc *) NULL, /* lineChangeProc */
- TkTextCharLayoutProc, /* layoutProc */
- CharCheckProc /* checkProc */
+const Tk_SegType tkTextCharType = {
+ "character", /* name */
+ 0, /* leftGravity */
+ CharSplitProc, /* splitProc */
+ CharDeleteProc, /* deleteProc */
+ CharCleanupProc, /* cleanupProc */
+ NULL, /* lineChangeProc */
+ TkTextCharLayoutProc, /* layoutProc */
+ CharCheckProc /* checkProc */
};
/*
- * Type record for segments marking the beginning of a tagged
- * range:
+ * Type record for segments marking the beginning of a tagged range:
*/
-Tk_SegType tkTextToggleOnType = {
- "toggleOn", /* name */
- 0, /* leftGravity */
- (Tk_SegSplitProc *) NULL, /* splitProc */
- ToggleDeleteProc, /* deleteProc */
- ToggleCleanupProc, /* cleanupProc */
- ToggleLineChangeProc, /* lineChangeProc */
- (Tk_SegLayoutProc *) NULL, /* layoutProc */
- ToggleCheckProc /* checkProc */
+const Tk_SegType tkTextToggleOnType = {
+ "toggleOn", /* name */
+ 0, /* leftGravity */
+ NULL, /* splitProc */
+ ToggleDeleteProc, /* deleteProc */
+ ToggleCleanupProc, /* cleanupProc */
+ ToggleLineChangeProc, /* lineChangeProc */
+ NULL, /* layoutProc */
+ ToggleCheckProc /* checkProc */
};
/*
- * Type record for segments marking the end of a tagged
- * range:
+ * Type record for segments marking the end of a tagged range:
*/
-Tk_SegType tkTextToggleOffType = {
- "toggleOff", /* name */
- 1, /* leftGravity */
- (Tk_SegSplitProc *) NULL, /* splitProc */
- ToggleDeleteProc, /* deleteProc */
- ToggleCleanupProc, /* cleanupProc */
- ToggleLineChangeProc, /* lineChangeProc */
- (Tk_SegLayoutProc *) NULL, /* layoutProc */
- ToggleCheckProc /* checkProc */
+const Tk_SegType tkTextToggleOffType = {
+ "toggleOff", /* name */
+ 1, /* leftGravity */
+ NULL, /* splitProc */
+ ToggleDeleteProc, /* deleteProc */
+ ToggleCleanupProc, /* cleanupProc */
+ ToggleLineChangeProc, /* lineChangeProc */
+ NULL, /* layoutProc */
+ ToggleCheckProc /* checkProc */
};
/*
@@ -195,11 +245,11 @@ Tk_SegType tkTextToggleOffType = {
*
* TkBTreeCreate --
*
- * This procedure is called to create a new text B-tree.
+ * This function is called to create a new text B-tree.
*
* Results:
- * The return value is a pointer to a new B-tree containing
- * one line with nothing but a newline character.
+ * The return value is a pointer to a new B-tree containing one line with
+ * nothing but a newline character.
*
* Side effects:
* Memory is allocated and initialized.
@@ -208,8 +258,8 @@ Tk_SegType tkTextToggleOffType = {
*/
TkTextBTree
-TkBTreeCreate(textPtr)
- TkText *textPtr;
+TkBTreeCreate(
+ TkSharedText *sharedTextPtr)
{
register BTree *treePtr;
register Node *rootPtr;
@@ -217,15 +267,16 @@ TkBTreeCreate(textPtr)
register TkTextSegment *segPtr;
/*
- * The tree will initially have two empty lines. The second line
- * isn't actually part of the tree's contents, but its presence
- * makes several operations easier. The tree will have one node,
- * which is also the root of the tree.
+ * The tree will initially have two empty lines. The second line isn't
+ * actually part of the tree's contents, but its presence makes several
+ * operations easier. The tree will have one node, which is also the root
+ * of the tree.
*/
rootPtr = (Node *) ckalloc(sizeof(Node));
linePtr = (TkTextLine *) ckalloc(sizeof(TkTextLine));
linePtr2 = (TkTextLine *) ckalloc(sizeof(TkTextLine));
+
rootPtr->parentPtr = NULL;
rootPtr->nextPtr = NULL;
rootPtr->summaryPtr = NULL;
@@ -234,6 +285,15 @@ TkBTreeCreate(textPtr)
rootPtr->numChildren = 2;
rootPtr->numLines = 2;
+ /*
+ * The tree currently has no registered clients, so all pixel count
+ * pointers are simply NULL.
+ */
+
+ rootPtr->numPixels = NULL;
+ linePtr->pixels = NULL;
+ linePtr2->pixels = NULL;
+
linePtr->parentPtr = rootPtr;
linePtr->nextPtr = linePtr2;
segPtr = (TkTextSegment *) ckalloc(CSEG_SIZE(1));
@@ -255,8 +315,14 @@ TkBTreeCreate(textPtr)
segPtr->body.chars[1] = 0;
treePtr = (BTree *) ckalloc(sizeof(BTree));
+ treePtr->sharedTextPtr = sharedTextPtr;
treePtr->rootPtr = rootPtr;
- treePtr->textPtr = textPtr;
+ treePtr->clients = 0;
+ treePtr->stateEpoch = 0;
+ treePtr->pixelReferences = 0;
+ treePtr->startEndCount = 0;
+ treePtr->startEnd = NULL;
+ treePtr->startEndRef = NULL;
return (TkTextBTree) treePtr;
}
@@ -264,13 +330,133 @@ TkBTreeCreate(textPtr)
/*
*----------------------------------------------------------------------
*
+ * TkBTreeAddClient --
+ *
+ * This function is called to provide a client with access to a given
+ * B-tree. If the client wishes to make use of the B-tree's pixel height
+ * storage, caching and calculation mechanisms, then a non-negative
+ * 'defaultHeight' must be provided. In this case the return value is a
+ * pixel tree reference which must be provided in all of the B-tree API
+ * which refers to or modifies pixel heights:
+ *
+ * TkBTreeAdjustPixelHeight,
+ * TkBTreeFindPixelLine,
+ * TkBTreeNumPixels,
+ * TkBTreePixelsTo,
+ * (and two private functions AdjustPixelClient, RemovePixelClient).
+ *
+ * If this is not provided, then the above functions must never be called
+ * for this client.
+ *
+ * Results:
+ * The return value is the pixelReference used by the B-tree to refer to
+ * pixel counts for the new client. It should be stored by the caller. If
+ * defaultHeight was negative, then the return value will be -1.
+ *
+ * Side effects:
+ * Memory may be allocated and initialized.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkBTreeAddClient(
+ TkTextBTree tree, /* B-tree to add a client to. */
+ TkText *textPtr, /* Client to add. */
+ int defaultHeight) /* Default line height for the new client, or
+ * -1 if no pixel heights are to be kept. */
+{
+ register BTree *treePtr = (BTree *) tree;
+
+ if (treePtr == NULL) {
+ Tcl_Panic("NULL treePtr in TkBTreeAddClient");
+ }
+
+ if (textPtr->start != NULL || textPtr->end != NULL) {
+ AdjustStartEndRefs(treePtr, textPtr, TEXT_ADD_REFS);
+ }
+
+ if (defaultHeight >= 0) {
+ TkTextLine *end;
+ int counting = (textPtr->start == NULL ? 1 : 0);
+ int useReference = treePtr->pixelReferences;
+
+ /*
+ * We must set the 'end' value in AdjustPixelClient so that the last
+ * dummy line in the B-tree doesn't contain a pixel height.
+ */
+
+ end = textPtr->end;
+ if (end == NULL) {
+ end = TkBTreeFindLine(tree, NULL, TkBTreeNumLines(tree, NULL));
+ }
+ AdjustPixelClient(treePtr, defaultHeight, treePtr->rootPtr,
+ textPtr->start, end, useReference, useReference+1, &counting);
+
+ textPtr->pixelReference = useReference;
+ treePtr->pixelReferences++;
+ } else {
+ textPtr->pixelReference = -1;
+ }
+ treePtr->clients++;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkBTreeClientRangeChanged --
+ *
+ * Called when the -startline or -endline options of a text widget client
+ * of the B-tree have changed.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Lots of processing of the B-tree is done, with potential for memory to
+ * be allocated and initialized for the pixel heights of the widget.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkBTreeClientRangeChanged(
+ TkText *textPtr, /* Client whose start, end have changed. */
+ int defaultHeight) /* Default line height for the new client, or
+ * -1 if no pixel heights are to be kept. */
+{
+ TkTextLine *end;
+ BTree *treePtr = (BTree *) textPtr->sharedTextPtr->tree;
+
+ int counting = (textPtr->start == NULL ? 1 : 0);
+ int useReference = textPtr->pixelReference;
+
+ AdjustStartEndRefs(treePtr, textPtr, TEXT_ADD_REFS | TEXT_REMOVE_REFS);
+
+ /*
+ * We must set the 'end' value in AdjustPixelClient so that the last dummy
+ * line in the B-tree doesn't contain a pixel height.
+ */
+
+ end = textPtr->end;
+ if (end == NULL) {
+ end = TkBTreeFindLine(textPtr->sharedTextPtr->tree,
+ NULL, TkBTreeNumLines(textPtr->sharedTextPtr->tree, NULL));
+ }
+ AdjustPixelClient(treePtr, defaultHeight, treePtr->rootPtr,
+ textPtr->start, end, useReference, treePtr->pixelReferences,
+ &counting);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkBTreeDestroy --
*
* Delete a B-tree, recycling all of the storage it contains.
*
* Results:
- * The tree given by treePtr is deleted. TreePtr should never
- * again be used.
+ * The tree is deleted, so 'tree' should never again be used.
*
* Side effects:
* Memory is freed.
@@ -279,22 +465,382 @@ TkBTreeCreate(textPtr)
*/
void
-TkBTreeDestroy(tree)
- TkTextBTree tree; /* Pointer to tree to delete. */
+TkBTreeDestroy(
+ TkTextBTree tree) /* Tree to clean up. */
{
BTree *treePtr = (BTree *) tree;
+ /*
+ * There's no need to loop over each client of the tree, calling
+ * 'TkBTreeRemoveClient', since the 'DestroyNode' will clean everything up
+ * itself.
+ */
+
DestroyNode(treePtr->rootPtr);
+ if (treePtr->startEnd != NULL) {
+ ckfree((char *) treePtr->startEnd);
+ ckfree((char *) treePtr->startEndRef);
+ }
ckfree((char *) treePtr);
}
/*
*----------------------------------------------------------------------
*
+ * TkBTreeEpoch --
+ *
+ * Return the epoch for the B-tree. This number is incremented any time
+ * anything changes in the tree.
+ *
+ * Results:
+ * The epoch number.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkBTreeEpoch(
+ TkTextBTree tree) /* Tree to get epoch for. */
+{
+ BTree *treePtr = (BTree *) tree;
+ return treePtr->stateEpoch;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkBTreeRemoveClient --
+ *
+ * Remove a client widget from its B-tree, cleaning up the pixel arrays
+ * which it uses if necessary. If this is the last such widget, we also
+ * destroy the whole tree.
+ *
+ * Results:
+ * All tree-specific aspects of the given client are deleted. If no more
+ * references exist, then the given tree is also deleted (in which case
+ * 'tree' must not be used again).
+ *
+ * Side effects:
+ * Memory may be freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkBTreeRemoveClient(
+ TkTextBTree tree, /* Tree to remove client from. */
+ TkText *textPtr) /* Client to remove. */
+{
+ BTree *treePtr = (BTree *) tree;
+ int pixelReference = textPtr->pixelReference;
+
+ if (treePtr->clients == 1) {
+ /*
+ * The last reference to the tree.
+ */
+
+ DestroyNode(treePtr->rootPtr);
+ ckfree((char *) treePtr);
+ return;
+ } else if (pixelReference == -1) {
+ /*
+ * A client which doesn't care about pixels.
+ */
+
+ treePtr->clients--;
+ } else {
+ /*
+ * Clean up pixel data for the given reference.
+ */
+
+ if (pixelReference == (treePtr->pixelReferences-1)) {
+ /*
+ * The widget we're removing has the last index, so deletion is
+ * easier.
+ */
+
+ RemovePixelClient(treePtr, treePtr->rootPtr, -1);
+ } else {
+ TkText *adjustPtr;
+
+ RemovePixelClient(treePtr, treePtr->rootPtr, pixelReference);
+
+ /*
+ * Now we need to adjust the 'pixelReference' of the peer widget
+ * whose storage we've just moved.
+ */
+
+ adjustPtr = treePtr->sharedTextPtr->peers;
+ while (adjustPtr != NULL) {
+ if (adjustPtr->pixelReference == treePtr->pixelReferences-1) {
+ adjustPtr->pixelReference = pixelReference;
+ break;
+ }
+ adjustPtr = adjustPtr->next;
+ }
+ if (adjustPtr == NULL) {
+ Tcl_Panic("Couldn't find text widget with correct reference");
+ }
+ }
+ treePtr->pixelReferences--;
+ treePtr->clients--;
+ }
+
+ if (textPtr->start != NULL || textPtr->end != NULL) {
+ AdjustStartEndRefs(treePtr, textPtr, TEXT_REMOVE_REFS);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AdjustStartEndRefs --
+ *
+ * Modify B-tree's cache of start, end lines for the given text widget.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The number of cached items may change (treePtr->startEndCount).
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AdjustStartEndRefs(
+ BTree *treePtr, /* The entire B-tree. */
+ TkText *textPtr, /* The text widget for which we want to adjust
+ * it's start and end cache. */
+ int action) /* Action to perform. */
+{
+ if (action & TEXT_REMOVE_REFS) {
+ int i = 0;
+ int count = 0;
+
+ while (i < treePtr->startEndCount) {
+ if (i != count) {
+ treePtr->startEnd[count] = treePtr->startEnd[i];
+ treePtr->startEndRef[count] = treePtr->startEndRef[i];
+ }
+ if (treePtr->startEndRef[i] != textPtr) {
+ count++;
+ }
+ i++;
+ }
+ treePtr->startEndCount = count;
+ treePtr->startEnd = (TkTextLine **)
+ ckrealloc((char *) treePtr->startEnd,
+ sizeof(TkTextLine *) * count);
+ treePtr->startEndRef = (TkText **)
+ ckrealloc((char *) treePtr->startEndRef,
+ sizeof(TkText *) * count);
+ }
+ if ((action & TEXT_ADD_REFS)
+ && (textPtr->start != NULL || textPtr->end != NULL)) {
+ int count;
+
+ if (textPtr->start != NULL) {
+ treePtr->startEndCount++;
+ }
+ if (textPtr->end != NULL) {
+ treePtr->startEndCount++;
+ }
+
+ count = treePtr->startEndCount;
+
+ treePtr->startEnd = (TkTextLine **)
+ ckrealloc((char *) treePtr->startEnd,
+ sizeof(TkTextLine *) * count);
+ treePtr->startEndRef = (TkText **)
+ ckrealloc((char *) treePtr->startEndRef,
+ sizeof(TkText *) * count);
+
+ if (textPtr->start != NULL) {
+ count--;
+ treePtr->startEnd[count] = textPtr->start;
+ treePtr->startEndRef[count] = textPtr;
+ }
+ if (textPtr->end != NULL) {
+ count--;
+ treePtr->startEnd[count] = textPtr->end;
+ treePtr->startEndRef[count] = textPtr;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AdjustPixelClient --
+ *
+ * Utility function used to update all data structures for the existence
+ * of a new peer widget based on this B-tree, or for the modification of
+ * the start, end lines of an existing peer widget.
+ *
+ * Immediately _after_ calling this, treePtr->pixelReferences and
+ * treePtr->clients should be adjusted if needed (i.e. if this is a new
+ * peer).
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * All the storage for Nodes and TkTextLines in the tree may be adjusted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+AdjustPixelClient(
+ BTree *treePtr, /* Pointer to tree. */
+ int defaultHeight, /* Default pixel line height, which can be
+ * zero. */
+ Node *nodePtr, /* Adjust from this node downwards. */
+ TkTextLine *start, /* First line for this pixel client. */
+ TkTextLine *end, /* Last line for this pixel client. */
+ int useReference, /* pixel reference for the client we are
+ * adding or changing. */
+ int newPixelReferences, /* New number of pixel references to this
+ * B-tree. */
+ int *counting) /* References an integer which is zero if
+ * we're outside the relevant range for this
+ * client, and 1 if we're inside. */
+{
+ int pixelCount = 0;
+
+ /*
+ * Traverse entire tree down from nodePtr, reallocating pixel structures
+ * for each Node and TkTextLine, adding room for the new peer's pixel
+ * information (1 extra int per Node, 2 extra ints per TkTextLine). Also
+ * copy the information from the last peer into the new space (so it
+ * contains something sensible).
+ */
+
+ if (nodePtr->level != 0) {
+ Node *loopPtr = nodePtr->children.nodePtr;
+
+ while (loopPtr != NULL) {
+ pixelCount += AdjustPixelClient(treePtr, defaultHeight, loopPtr,
+ start, end, useReference, newPixelReferences, counting);
+ loopPtr = loopPtr->nextPtr;
+ }
+ } else {
+ register TkTextLine *linePtr = nodePtr->children.linePtr;
+
+ while (linePtr != NULL) {
+ if (!*counting && (linePtr == start)) {
+ *counting = 1;
+ }
+ if (*counting && (linePtr == end)) {
+ *counting = 0;
+ }
+ if (newPixelReferences != treePtr->pixelReferences) {
+ linePtr->pixels = (int *) ckrealloc((char *) linePtr->pixels,
+ sizeof(int) * 2 * newPixelReferences);
+ }
+
+ /*
+ * Notice that for the very last line, we are never counting and
+ * therefore this always has a height of 0 and an epoch of 1.
+ */
+
+ linePtr->pixels[2*useReference] = (*counting ? defaultHeight : 0);
+ linePtr->pixels[2*useReference+1] = (*counting ? 0 : 1);
+ pixelCount += linePtr->pixels[2*useReference];
+
+ linePtr = linePtr->nextPtr;
+ }
+ }
+ if (newPixelReferences != treePtr->pixelReferences) {
+ nodePtr->numPixels = (int *) ckrealloc((char *) nodePtr->numPixels,
+ sizeof(int) * newPixelReferences);
+ }
+ nodePtr->numPixels[useReference] = pixelCount;
+ return pixelCount;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RemovePixelClient --
+ *
+ * Utility function used to update all data structures for the removal of
+ * a peer widget which used to be based on this B-tree.
+ *
+ * Immediately _after_ calling this, treePtr->clients should be
+ * decremented.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * All the storage for Nodes and TkTextLines in the tree may be adjusted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RemovePixelClient(
+ BTree *treePtr, /* Pointer to tree. */
+ Node *nodePtr, /* Adjust from this node downwards. */
+ int overwriteWithLast) /* Over-write this peer widget's information
+ * with the last one. */
+{
+ /*
+ * Traverse entire tree down from nodePtr, reallocating pixel structures
+ * for each Node and TkTextLine, removing space allocated for one peer. If
+ * 'overwriteWithLast' is not -1, then copy the information which was in
+ * the last slot on top of one of the others (i.e. it's not the last one
+ * we're deleting).
+ */
+
+ if (overwriteWithLast != -1) {
+ nodePtr->numPixels[overwriteWithLast] =
+ nodePtr->numPixels[treePtr->pixelReferences-1];
+ }
+ if (treePtr->pixelReferences == 1) {
+ nodePtr->numPixels = NULL;
+ } else {
+ nodePtr->numPixels = (int *) ckrealloc((char *) nodePtr->numPixels,
+ sizeof(int) * (treePtr->pixelReferences - 1));
+ }
+ if (nodePtr->level != 0) {
+ nodePtr = nodePtr->children.nodePtr;
+ while (nodePtr != NULL) {
+ RemovePixelClient(treePtr, nodePtr, overwriteWithLast);
+ nodePtr = nodePtr->nextPtr;
+ }
+ } else {
+ register TkTextLine *linePtr = nodePtr->children.linePtr;
+ while (linePtr != NULL) {
+ if (overwriteWithLast != -1) {
+ linePtr->pixels[2*overwriteWithLast] =
+ linePtr->pixels[2*(treePtr->pixelReferences-1)];
+ linePtr->pixels[1+2*overwriteWithLast] =
+ linePtr->pixels[1+2*(treePtr->pixelReferences-1)];
+ }
+ if (treePtr->pixelReferences == 1) {
+ linePtr->pixels = NULL;
+ } else {
+ linePtr->pixels = (int *) ckrealloc((char *) linePtr->pixels,
+ sizeof(int) * 2 * (treePtr->pixelReferences-1));
+ }
+ linePtr = linePtr->nextPtr;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* DestroyNode --
*
- * This is a recursive utility procedure used during the deletion
- * of a B-tree.
+ * This is a recursive utility function used during the deletion of a
+ * B-tree.
*
* Results:
* None.
@@ -306,8 +852,8 @@ TkBTreeDestroy(tree)
*/
static void
-DestroyNode(nodePtr)
- register Node *nodePtr;
+DestroyNode(
+ register Node *nodePtr) /* Destroy from this node downwards. */
{
if (nodePtr->level == 0) {
TkTextLine *linePtr;
@@ -321,6 +867,7 @@ DestroyNode(nodePtr)
linePtr->segPtr = segPtr->nextPtr;
(*segPtr->typePtr->deleteProc)(segPtr, linePtr, 1);
}
+ ckfree((char *) linePtr->pixels);
ckfree((char *) linePtr);
}
} else {
@@ -333,6 +880,7 @@ DestroyNode(nodePtr)
}
}
DeleteSummaries(nodePtr->summaryPtr);
+ ckfree((char *) nodePtr->numPixels);
ckfree((char *) nodePtr);
}
@@ -341,8 +889,8 @@ DestroyNode(nodePtr)
*
* DeleteSummaries --
*
- * Free up all of the memory in a list of tag summaries associated
- * with a node.
+ * Free up all of the memory in a list of tag summaries associated with a
+ * node.
*
* Results:
* None.
@@ -354,11 +902,12 @@ DestroyNode(nodePtr)
*/
static void
-DeleteSummaries(summaryPtr)
- register Summary *summaryPtr; /* First in list of node's tag
- * summaries. */
+DeleteSummaries(
+ register Summary *summaryPtr)
+ /* First in list of node's tag summaries. */
{
register Summary *nextPtr;
+
while (summaryPtr != NULL) {
nextPtr = summaryPtr->nextPtr;
ckfree((char *) summaryPtr);
@@ -369,6 +918,74 @@ DeleteSummaries(summaryPtr)
/*
*----------------------------------------------------------------------
*
+ * TkBTreeAdjustPixelHeight --
+ *
+ * Adjust the pixel height of a given logical line to the specified
+ * value.
+ *
+ * Results:
+ * Total number of valid pixels currently known in the tree.
+ *
+ * Side effects:
+ * Updates overall data structures so pixel height count is consistent.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkBTreeAdjustPixelHeight(
+ const TkText *textPtr, /* Client of the B-tree. */
+ register TkTextLine *linePtr,
+ /* The logical line to update. */
+ int newPixelHeight, /* The line's known height in pixels. */
+ int mergedLogicalLines) /* The number of extra logical lines which
+ * have been merged with this one (due to
+ * elided eols). They will have their pixel
+ * height set to zero, and the total pixel
+ * height associated with the given
+ * linePtr. */
+{
+ register Node *nodePtr;
+ int changeToPixelCount; /* Counts change to total number of pixels in
+ * file. */
+ int pixelReference = textPtr->pixelReference;
+
+ changeToPixelCount = newPixelHeight - linePtr->pixels[2 * pixelReference];
+
+ /*
+ * Increment the pixel counts in all the parent nodes of the current line,
+ * then rebalance the tree if necessary.
+ */
+
+ nodePtr = linePtr->parentPtr;
+ nodePtr->numPixels[pixelReference] += changeToPixelCount;
+
+ while (nodePtr->parentPtr != NULL) {
+ nodePtr = nodePtr->parentPtr;
+ nodePtr->numPixels[pixelReference] += changeToPixelCount;
+ }
+
+ linePtr->pixels[2 * pixelReference] = newPixelHeight;
+
+ /*
+ * Any merged logical lines must have their height set to zero.
+ */
+
+ while (mergedLogicalLines-- > 0) {
+ linePtr = TkBTreeNextLine(textPtr, linePtr);
+ TkBTreeAdjustPixelHeight(textPtr, linePtr, 0, 0);
+ }
+
+ /*
+ * Return total number of pixels in the tree.
+ */
+
+ return nodePtr->numPixels[pixelReference];
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkBTreeInsertChars --
*
* Insert characters at a given position in a B-tree.
@@ -377,53 +994,68 @@ DeleteSummaries(summaryPtr)
* None.
*
* Side effects:
- * Characters are added to the B-tree at the given position.
- * If the string contains newlines, new lines will be added,
- * which could cause the structure of the B-tree to change.
+ * Characters are added to the B-tree at the given position. If the
+ * string contains newlines, new lines will be added, which could cause
+ * the structure of the B-tree to change.
*
*----------------------------------------------------------------------
*/
void
-TkBTreeInsertChars(indexPtr, string)
- register TkTextIndex *indexPtr; /* Indicates where to insert text.
- * When the procedure returns, this
- * index is no longer valid because
- * of changes to the segment
- * structure. */
- CONST char *string; /* Pointer to bytes to insert (may
- * contain newlines, must be null-
- * terminated). */
+TkBTreeInsertChars(
+ TkTextBTree tree, /* Tree to insert into. */
+ register TkTextIndex *indexPtr,
+ /* Indicates where to insert text. When the
+ * function returns, this index is no longer
+ * valid because of changes to the segment
+ * structure. */
+ const char *string) /* Pointer to bytes to insert (may contain
+ * newlines, must be null-terminated). */
{
register Node *nodePtr;
- register TkTextSegment *prevPtr; /* The segment just before the first
- * new segment (NULL means new segment
- * is at beginning of line). */
- TkTextSegment *curPtr; /* Current segment; new characters
- * are inserted just after this one.
- * NULL means insert at beginning of
- * line. */
- TkTextLine *linePtr; /* Current line (new segments are
- * added to this line). */
+ register TkTextSegment *prevPtr;
+ /* The segment just before the first new
+ * segment (NULL means new segment is at
+ * beginning of line). */
+ TkTextSegment *curPtr; /* Current segment; new characters are
+ * inserted just after this one. NULL means
+ * insert at beginning of line. */
+ TkTextLine *linePtr; /* Current line (new segments are added to
+ * this line). */
register TkTextSegment *segPtr;
TkTextLine *newLinePtr;
- int chunkSize; /* # characters in current chunk. */
- register CONST char *eol; /* Pointer to character just after last
- * one in current chunk. */
- int changeToLineCount; /* Counts change to total number of
- * lines in file. */
+ int chunkSize; /* # characters in current chunk. */
+ register const char *eol; /* Pointer to character just after last one in
+ * current chunk. */
+ int changeToLineCount; /* Counts change to total number of lines in
+ * file. */
+ int *changeToPixelCount; /* Counts change to total number of pixels in
+ * file. */
+ int ref;
+ int pixels[PIXEL_CLIENTS];
+ BTree *treePtr = (BTree *) tree;
+ treePtr->stateEpoch++;
prevPtr = SplitSeg(indexPtr);
linePtr = indexPtr->linePtr;
curPtr = prevPtr;
/*
- * Chop the string up into lines and create a new segment for
- * each line, plus a new line for the leftovers from the
- * previous line.
+ * Chop the string up into lines and create a new segment for each line,
+ * plus a new line for the leftovers from the previous line.
*/
changeToLineCount = 0;
+ if (treePtr->pixelReferences > PIXEL_CLIENTS) {
+ changeToPixelCount = (int *)
+ ckalloc(sizeof(int) * treePtr->pixelReferences);
+ } else {
+ changeToPixelCount = pixels;
+ }
+ for (ref = 0; ref < treePtr->pixelReferences; ref++) {
+ changeToPixelCount[ref] = 0;
+ }
+
while (*string != 0) {
for (eol = string; *eol != 0; eol++) {
if (*eol == '\n') {
@@ -450,15 +1082,30 @@ TkBTreeInsertChars(indexPtr, string)
}
/*
- * The chunk ended with a newline, so create a new TkTextLine
- * and move the remainder of the old line to it.
+ * The chunk ended with a newline, so create a new TkTextLine and move
+ * the remainder of the old line to it.
*/
newLinePtr = (TkTextLine *) ckalloc(sizeof(TkTextLine));
+ newLinePtr->pixels = (int *)
+ ckalloc(sizeof(int) * 2 * treePtr->pixelReferences);
+
newLinePtr->parentPtr = linePtr->parentPtr;
newLinePtr->nextPtr = linePtr->nextPtr;
linePtr->nextPtr = newLinePtr;
newLinePtr->segPtr = segPtr->nextPtr;
+
+ /*
+ * Set up a starting default height, which will be re-adjusted later.
+ * We need to do this for each referenced widget.
+ */
+
+ for (ref = 0; ref < treePtr->pixelReferences; ref++) {
+ newLinePtr->pixels[2 * ref] = linePtr->pixels[2 * ref];
+ newLinePtr->pixels[2 * ref + 1] = 0;
+ changeToPixelCount[ref] += newLinePtr->pixels[2 * ref];
+ }
+
segPtr->nextPtr = NULL;
linePtr = newLinePtr;
curPtr = NULL;
@@ -468,8 +1115,18 @@ TkBTreeInsertChars(indexPtr, string)
}
/*
- * Cleanup the starting line for the insertion, plus the ending
- * line if it's different.
+ * I don't believe it's possible for either of the two lines passed to
+ * this function to be the last line of text, but the function is robust
+ * to that case anyway. (We must never re-calculated the line height of
+ * the last line).
+ */
+
+ TkTextInvalidateLineMetrics(treePtr->sharedTextPtr, NULL,
+ indexPtr->linePtr, changeToLineCount, TK_TEXT_INVALIDATE_INSERT);
+
+ /*
+ * Cleanup the starting line for the insertion, plus the ending line if
+ * it's different.
*/
CleanupLine(indexPtr->linePtr);
@@ -478,18 +1135,25 @@ TkBTreeInsertChars(indexPtr, string)
}
/*
- * Increment the line counts in all the parent nodes of the insertion
- * point, then rebalance the tree if necessary.
+ * Increment the line and pixel counts in all the parent nodes of the
+ * insertion point, then rebalance the tree if necessary.
*/
for (nodePtr = linePtr->parentPtr ; nodePtr != NULL;
nodePtr = nodePtr->parentPtr) {
nodePtr->numLines += changeToLineCount;
+ for (ref = 0; ref < treePtr->pixelReferences; ref++) {
+ nodePtr->numPixels[ref] += changeToPixelCount[ref];
+ }
+ }
+ if (treePtr->pixelReferences > PIXEL_CLIENTS) {
+ ckfree((char *) changeToPixelCount);
}
+
nodePtr = linePtr->parentPtr;
nodePtr->numChildren += changeToLineCount;
if (nodePtr->numChildren > MAX_CHILDREN) {
- Rebalance((BTree *) indexPtr->tree, nodePtr);
+ Rebalance(treePtr, nodePtr);
}
if (tkBTreeDebug) {
@@ -502,40 +1166,41 @@ TkBTreeInsertChars(indexPtr, string)
*
* SplitSeg --
*
- * This procedure is called before adding or deleting
- * segments. It does three things: (a) it finds the segment
- * containing indexPtr; (b) if there are several such
- * segments (because some segments have zero length) then
- * it picks the first segment that does not have left
- * gravity; (c) if the index refers to the middle of
- * a segment then it splits the segment so that the
- * index now refers to the beginning of a segment.
+ * This function is called before adding or deleting segments. It does
+ * three things: (a) it finds the segment containing indexPtr; (b) if
+ * there are several such segments (because some segments have zero
+ * length) then it picks the first segment that does not have left
+ * gravity; (c) if the index refers to the middle of a segment then it
+ * splits the segment so that the index now refers to the beginning of a
+ * segment.
*
* Results:
- * The return value is a pointer to the segment just
- * before the segment corresponding to indexPtr (as
- * described above). If the segment corresponding to
- * indexPtr is the first in its line then the return
+ * The return value is a pointer to the segment just before the segment
+ * corresponding to indexPtr (as described above). If the segment
+ * corresponding to indexPtr is the first in its line then the return
* value is NULL.
*
* Side effects:
- * The segment referred to by indexPtr is split unless
- * indexPtr refers to its first character.
+ * The segment referred to by indexPtr is split unless indexPtr refers to
+ * its first character.
*
*--------------------------------------------------------------
*/
static TkTextSegment *
-SplitSeg(indexPtr)
- TkTextIndex *indexPtr; /* Index identifying position
- * at which to split a segment. */
+SplitSeg(
+ TkTextIndex *indexPtr) /* Index identifying position at which to
+ * split a segment. */
{
TkTextSegment *prevPtr, *segPtr;
- int count;
+ TkTextLine *linePtr;
+ int count = indexPtr->byteIndex;
- for (count = indexPtr->byteIndex, prevPtr = NULL,
- segPtr = indexPtr->linePtr->segPtr; segPtr != NULL;
- count -= segPtr->size, prevPtr = segPtr, segPtr = segPtr->nextPtr) {
+ linePtr = indexPtr->linePtr;
+ prevPtr = NULL;
+ segPtr = linePtr->segPtr;
+
+ while (segPtr != NULL) {
if (segPtr->size > count) {
if (count == 0) {
return prevPtr;
@@ -551,8 +1216,26 @@ SplitSeg(indexPtr)
&& !segPtr->typePtr->leftGravity) {
return prevPtr;
}
+
+ count -= segPtr->size;
+ prevPtr = segPtr;
+ segPtr = segPtr->nextPtr;
+ if (segPtr == NULL) {
+ /*
+ * Two logical lines merged into one display line through eliding
+ * of a newline.
+ */
+
+ linePtr = TkBTreeNextLine(NULL, linePtr);
+ if (linePtr == NULL) {
+ /*
+ * Reached end of the text.
+ */
+ }
+ segPtr = linePtr->segPtr;
+ }
}
- panic("SplitSeg reached end of line!");
+ Tcl_Panic("SplitSeg reached end of line!");
return NULL;
}
@@ -561,36 +1244,34 @@ SplitSeg(indexPtr)
*
* CleanupLine --
*
- * This procedure is called after modifications have been
- * made to a line. It scans over all of the segments in
- * the line, giving each a chance to clean itself up, e.g.
- * by merging with the following segments, updating internal
- * information, etc.
+ * This function is called after modifications have been made to a line.
+ * It scans over all of the segments in the line, giving each a chance to
+ * clean itself up, e.g. by merging with the following segments, updating
+ * internal information, etc.
*
* Results:
* None.
*
* Side effects:
- * Depends on what the segment-specific cleanup procedures do.
+ * Depends on what the segment-specific cleanup functions do.
*
*--------------------------------------------------------------
*/
static void
-CleanupLine(linePtr)
- TkTextLine *linePtr; /* Line to be cleaned up. */
+CleanupLine(
+ TkTextLine *linePtr) /* Line to be cleaned up. */
{
TkTextSegment *segPtr, **prevPtrPtr;
int anyChanges;
/*
- * Make a pass over all of the segments in the line, giving each
- * a chance to clean itself up. This could potentially change
- * the structure of the line, e.g. by merging two segments
- * together or having two segments cancel themselves; if so,
- * then repeat the whole process again, since the first structure
- * change might make other structure changes possible. Repeat
- * until eventually there are no changes.
+ * Make a pass over all of the segments in the line, giving each a chance
+ * to clean itself up. This could potentially change the structure of the
+ * line, e.g. by merging two segments together or having two segments
+ * cancel themselves; if so, then repeat the whole process again, since
+ * the first structure change might make other structure changes possible.
+ * Repeat until eventually there are no changes.
*/
while (1) {
@@ -614,49 +1295,55 @@ CleanupLine(linePtr)
/*
*----------------------------------------------------------------------
*
- * TkBTreeDeleteChars --
+ * TkBTreeDeleteIndexRange --
*
- * Delete a range of characters from a B-tree. The caller
- * must make sure that the final newline of the B-tree is
- * never deleted.
+ * Delete a range of characters from a B-tree. The caller must make sure
+ * that the final newline of the B-tree is never deleted.
*
* Results:
* None.
*
* Side effects:
- * Information is deleted from the B-tree. This can cause the
- * internal structure of the B-tree to change. Note: because
- * of changes to the B-tree structure, the indices pointed
- * to by index1Ptr and index2Ptr should not be used after this
- * procedure returns.
+ * Information is deleted from the B-tree. This can cause the internal
+ * structure of the B-tree to change. Note: because of changes to the
+ * B-tree structure, the indices pointed to by index1Ptr and index2Ptr
+ * should not be used after this function returns.
*
*----------------------------------------------------------------------
*/
void
-TkBTreeDeleteChars(index1Ptr, index2Ptr)
- register TkTextIndex *index1Ptr; /* Indicates first character that is
- * to be deleted. */
- register TkTextIndex *index2Ptr; /* Indicates character just after the
- * last one that is to be deleted. */
+TkBTreeDeleteIndexRange(
+ TkTextBTree tree, /* Tree to delete from. */
+ register TkTextIndex *index1Ptr,
+ /* Indicates first character that is to be
+ * deleted. */
+ register TkTextIndex *index2Ptr)
+ /* Indicates character just after the last one
+ * that is to be deleted. */
{
- TkTextSegment *prevPtr; /* The segment just before the start
- * of the deletion range. */
- TkTextSegment *lastPtr; /* The segment just after the end
- * of the deletion range. */
+ TkTextSegment *prevPtr; /* The segment just before the start of the
+ * deletion range. */
+ TkTextSegment *lastPtr; /* The segment just after the end of the
+ * deletion range. */
TkTextSegment *segPtr, *nextPtr;
TkTextLine *curLinePtr;
Node *curNodePtr, *nodePtr;
+ int changeToLineCount = 0;
+ int ref;
+ BTree *treePtr = (BTree *) tree;
+
+ treePtr->stateEpoch++;
/*
- * Tricky point: split at index2Ptr first; otherwise the split
- * at index2Ptr may invalidate segPtr and/or prevPtr.
+ * Tricky point: split at index2Ptr first; otherwise the split at
+ * index2Ptr may invalidate segPtr and/or prevPtr.
*/
lastPtr = SplitSeg(index2Ptr);
if (lastPtr != NULL) {
lastPtr = lastPtr->nextPtr;
- } else {
+ } else {
lastPtr = index2Ptr->linePtr->segPtr;
}
prevPtr = SplitSeg(index1Ptr);
@@ -673,18 +1360,19 @@ TkBTreeDeleteChars(index1Ptr, index2Ptr)
*/
curLinePtr = index1Ptr->linePtr;
+
curNodePtr = curLinePtr->parentPtr;
while (segPtr != lastPtr) {
if (segPtr == NULL) {
TkTextLine *nextLinePtr;
/*
- * We just ran off the end of a line. First find the
- * next line, then go back to the old line and delete it
- * (unless it's the starting line for the range).
+ * We just ran off the end of a line. First find the next line,
+ * then go back to the old line and delete it (unless it's the
+ * starting line for the range).
*/
- nextLinePtr = TkBTreeNextLine(curLinePtr);
+ nextLinePtr = TkBTreeNextLine(NULL, curLinePtr);
if (curLinePtr != index1Ptr->linePtr) {
if (curNodePtr == index1Ptr->linePtr->parentPtr) {
index1Ptr->linePtr->nextPtr = curLinePtr->nextPtr;
@@ -694,16 +1382,50 @@ TkBTreeDeleteChars(index1Ptr, index2Ptr)
for (nodePtr = curNodePtr; nodePtr != NULL;
nodePtr = nodePtr->parentPtr) {
nodePtr->numLines--;
+ for (ref = 0; ref < treePtr->pixelReferences; ref++) {
+ nodePtr->numPixels[ref] -= curLinePtr->pixels[2*ref];
+ }
}
+ changeToLineCount++;
curNodePtr->numChildren--;
+
+ /*
+ * Check if we need to adjust any partial clients.
+ */
+
+ if (treePtr->startEnd != NULL) {
+ int checkCount = 0;
+
+ while (checkCount < treePtr->startEndCount) {
+ if (treePtr->startEnd[checkCount] == curLinePtr) {
+ TkText *peer = treePtr->startEndRef[checkCount];
+
+ /*
+ * We're deleting a line which is the start or end
+ * of a current client. This means we need to
+ * adjust that client.
+ */
+
+ treePtr->startEnd[checkCount] = nextLinePtr;
+ if (peer->start == curLinePtr) {
+ peer->start = nextLinePtr;
+ }
+ if (peer->end == curLinePtr) {
+ peer->end = nextLinePtr;
+ }
+ }
+ checkCount++;
+ }
+ }
+ ckfree((char *) curLinePtr->pixels);
ckfree((char *) curLinePtr);
}
curLinePtr = nextLinePtr;
segPtr = curLinePtr->segPtr;
/*
- * If the node is empty then delete it and its parents,
- * recursively upwards until a non-empty node is found.
+ * If the node is empty then delete it and its parents recursively
+ * upwards until a non-empty node is found.
*/
while (curNodePtr->numChildren == 0) {
@@ -730,8 +1452,8 @@ TkBTreeDeleteChars(index1Ptr, index2Ptr)
nextPtr = segPtr->nextPtr;
if ((*segPtr->typePtr->deleteProc)(segPtr, curLinePtr, 0) != 0) {
/*
- * This segment refuses to die. Move it to prevPtr and
- * advance prevPtr if the segment has left gravity.
+ * This segment refuses to die. Move it to prevPtr and advance
+ * prevPtr if the segment has left gravity.
*/
if (prevPtr == NULL) {
@@ -749,8 +1471,8 @@ TkBTreeDeleteChars(index1Ptr, index2Ptr)
}
/*
- * If the beginning and end of the deletion range are in different
- * lines, join the two lines together and discard the ending line.
+ * If the beginning and end of the deletion range are in different lines,
+ * join the two lines together and discard the ending line.
*/
if (index1Ptr->linePtr != index2Ptr->linePtr) {
@@ -766,7 +1488,11 @@ TkBTreeDeleteChars(index1Ptr, index2Ptr)
for (nodePtr = curNodePtr; nodePtr != NULL;
nodePtr = nodePtr->parentPtr) {
nodePtr->numLines--;
+ for (ref = 0; ref < treePtr->pixelReferences; ref++) {
+ nodePtr->numPixels[ref] -= index2Ptr->linePtr->pixels[2*ref];
+ }
}
+ changeToLineCount++;
curNodePtr->numChildren--;
prevLinePtr = curNodePtr->children.linePtr;
if (prevLinePtr == index2Ptr->linePtr) {
@@ -777,7 +1503,43 @@ TkBTreeDeleteChars(index1Ptr, index2Ptr)
}
prevLinePtr->nextPtr = index2Ptr->linePtr->nextPtr;
}
+
+ /*
+ * Check if we need to adjust any partial clients. In this case if
+ * we're deleting the line, we actually move back to the previous line
+ * for our (start,end) storage. We do this because we still want the
+ * portion of the second line that still exists to be in the start,end
+ * range.
+ */
+
+ if (treePtr->startEnd != NULL) {
+ int checkCount = 0;
+
+ while (checkCount < treePtr->startEndCount &&
+ treePtr->startEnd[checkCount] != NULL) {
+ if (treePtr->startEnd[checkCount] == index2Ptr->linePtr) {
+ TkText *peer = treePtr->startEndRef[checkCount];
+
+ /*
+ * We're deleting a line which is the start or end of a
+ * current client. This means we need to adjust that
+ * client.
+ */
+
+ treePtr->startEnd[checkCount] = index1Ptr->linePtr;
+ if (peer->start == index2Ptr->linePtr) {
+ peer->start = index1Ptr->linePtr;
+ }
+ if (peer->end == index2Ptr->linePtr) {
+ peer->end = index1Ptr->linePtr;
+ }
+ }
+ checkCount++;
+ }
+ }
+ ckfree((char *) index2Ptr->linePtr->pixels);
ckfree((char *) index2Ptr->linePtr);
+
Rebalance((BTree *) index2Ptr->tree, curNodePtr);
}
@@ -788,6 +1550,19 @@ TkBTreeDeleteChars(index1Ptr, index2Ptr)
CleanupLine(index1Ptr->linePtr);
/*
+ * This line now needs to have its height recalculated. For safety, ensure
+ * we don't call this function with the last artificial line of text. I
+ * _believe_ that it isn't possible to get this far with the last line,
+ * but it is good to be safe.
+ */
+
+ if (TkBTreeNextLine(NULL, index1Ptr->linePtr) != NULL) {
+ TkTextInvalidateLineMetrics(treePtr->sharedTextPtr, NULL,
+ index1Ptr->linePtr, changeToLineCount,
+ TK_TEXT_INVALIDATE_DELETE);
+ }
+
+ /*
* Lastly, rebalance the first node of the range.
*/
@@ -805,8 +1580,8 @@ TkBTreeDeleteChars(index1Ptr, index2Ptr)
* Find a particular line in a B-tree based on its line number.
*
* Results:
- * The return value is a pointer to the line structure for the
- * line whose index is "line", or NULL if no such line exists.
+ * The return value is a pointer to the line structure for the line whose
+ * index is "line", or NULL if no such line exists.
*
* Side effects:
* None.
@@ -815,34 +1590,54 @@ TkBTreeDeleteChars(index1Ptr, index2Ptr)
*/
TkTextLine *
-TkBTreeFindLine(tree, line)
- TkTextBTree tree; /* B-tree in which to find line. */
- int line; /* Index of desired line. */
+TkBTreeFindLine(
+ TkTextBTree tree, /* B-tree in which to find line. */
+ const TkText *textPtr, /* Relative to this client of the B-tree. */
+ int line) /* Index of desired line. */
{
BTree *treePtr = (BTree *) tree;
register Node *nodePtr;
register TkTextLine *linePtr;
- int linesLeft;
+
+ if (treePtr == NULL) {
+ treePtr = (BTree *) textPtr->sharedTextPtr->tree;
+ }
nodePtr = treePtr->rootPtr;
- linesLeft = line;
if ((line < 0) || (line >= nodePtr->numLines)) {
return NULL;
}
/*
- * Work down through levels of the tree until a node is found at
- * level 0.
+ * Check for any start/end offset for this text widget.
+ */
+
+ if (textPtr != NULL) {
+ if (textPtr->start != NULL) {
+ line += TkBTreeLinesTo(NULL, textPtr->start);
+ if (line >= nodePtr->numLines) {
+ return NULL;
+ }
+ }
+ if (textPtr->end != NULL) {
+ if (line > TkBTreeLinesTo(NULL, textPtr->end)) {
+ return NULL;
+ }
+ }
+ }
+
+ /*
+ * Work down through levels of the tree until a node is found at level 0.
*/
while (nodePtr->level != 0) {
for (nodePtr = nodePtr->children.nodePtr;
- nodePtr->numLines <= linesLeft;
+ nodePtr->numLines <= line;
nodePtr = nodePtr->nextPtr) {
if (nodePtr == NULL) {
- panic("TkBTreeFindLine ran out of nodes");
+ Tcl_Panic("TkBTreeFindLine ran out of nodes");
}
- linesLeft -= nodePtr->numLines;
+ line -= nodePtr->numLines;
}
}
@@ -850,12 +1645,90 @@ TkBTreeFindLine(tree, line)
* Work through the lines attached to the level-0 node.
*/
- for (linePtr = nodePtr->children.linePtr; linesLeft > 0;
+ for (linePtr = nodePtr->children.linePtr; line > 0;
linePtr = linePtr->nextPtr) {
if (linePtr == NULL) {
- panic("TkBTreeFindLine ran out of lines");
+ Tcl_Panic("TkBTreeFindLine ran out of lines");
}
- linesLeft -= 1;
+ line -= 1;
+ }
+ return linePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkBTreeFindPixelLine --
+ *
+ * Find a particular line in a B-tree based on its pixel count.
+ *
+ * Results:
+ * The return value is a pointer to the line structure for the line which
+ * contains the pixel "pixels", or NULL if no such line exists. If the
+ * first line is of height 20, then pixels 0-19 will return it, and
+ * pixels = 20 will return the next line.
+ *
+ * If pixelOffset is non-NULL, it is set to the amount by which 'pixels'
+ * exceeds the first pixel located on the returned line. This should
+ * always be non-negative.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkTextLine *
+TkBTreeFindPixelLine(
+ TkTextBTree tree, /* B-tree to use. */
+ const TkText *textPtr, /* Relative to this client of the B-tree. */
+ int pixels, /* Pixel index of desired line. */
+ int *pixelOffset) /* Used to return offset. */
+{
+ BTree *treePtr = (BTree *) tree;
+ register Node *nodePtr;
+ register TkTextLine *linePtr;
+ int pixelReference = textPtr->pixelReference;
+
+ nodePtr = treePtr->rootPtr;
+
+ if ((pixels < 0) || (pixels > nodePtr->numPixels[pixelReference])) {
+ return NULL;
+ }
+
+ if (nodePtr->numPixels[pixelReference] == 0) {
+ Tcl_Panic("TkBTreeFindPixelLine called with empty window");
+ }
+
+ /*
+ * Work down through levels of the tree until a node is found at level 0.
+ */
+
+ while (nodePtr->level != 0) {
+ for (nodePtr = nodePtr->children.nodePtr;
+ nodePtr->numPixels[pixelReference] <= pixels;
+ nodePtr = nodePtr->nextPtr) {
+ if (nodePtr == NULL) {
+ Tcl_Panic("TkBTreeFindPixelLine ran out of nodes");
+ }
+ pixels -= nodePtr->numPixels[pixelReference];
+ }
+ }
+
+ /*
+ * Work through the lines attached to the level-0 node.
+ */
+
+ for (linePtr = nodePtr->children.linePtr;
+ linePtr->pixels[2 * pixelReference] < pixels;
+ linePtr = linePtr->nextPtr) {
+ if (linePtr == NULL) {
+ Tcl_Panic("TkBTreeFindPixelLine ran out of lines");
+ }
+ pixels -= linePtr->pixels[2 * pixelReference];
+ }
+ if (pixelOffset != NULL && linePtr != NULL) {
+ *pixelOffset = pixels;
}
return linePtr;
}
@@ -865,13 +1738,13 @@ TkBTreeFindLine(tree, line)
*
* TkBTreeNextLine --
*
- * Given an existing line in a B-tree, this procedure locates the
- * next line in the B-tree. This procedure is used for scanning
- * through the B-tree.
+ * Given an existing line in a B-tree, this function locates the next
+ * line in the B-tree. This function is used for scanning through the
+ * B-tree.
*
* Results:
- * The return value is a pointer to the line that immediately
- * follows linePtr, or NULL if there is no such line.
+ * The return value is a pointer to the line that immediately follows
+ * linePtr, or NULL if there is no such line.
*
* Side effects:
* None.
@@ -880,20 +1753,25 @@ TkBTreeFindLine(tree, line)
*/
TkTextLine *
-TkBTreeNextLine(linePtr)
- register TkTextLine *linePtr; /* Pointer to existing line in
- * B-tree. */
+TkBTreeNextLine(
+ const TkText *textPtr, /* Next line in the context of this client. */
+ register TkTextLine *linePtr)
+ /* Pointer to existing line in B-tree. */
{
register Node *nodePtr;
if (linePtr->nextPtr != NULL) {
- return linePtr->nextPtr;
+ if (textPtr != NULL && (linePtr == textPtr->end)) {
+ return NULL;
+ } else {
+ return linePtr->nextPtr;
+ }
}
/*
* This was the last line associated with the particular parent node.
- * Search up the tree for the next node, then search down from that
- * node to find the first line.
+ * Search up the tree for the next node, then search down from that node
+ * to find the first line.
*/
for (nodePtr = linePtr->parentPtr; ; nodePtr = nodePtr->parentPtr) {
@@ -902,7 +1780,7 @@ TkBTreeNextLine(linePtr)
break;
}
if (nodePtr->parentPtr == NULL) {
- return (TkTextLine *) NULL;
+ return NULL;
}
}
while (nodePtr->level > 0) {
@@ -916,13 +1794,13 @@ TkBTreeNextLine(linePtr)
*
* TkBTreePreviousLine --
*
- * Given an existing line in a B-tree, this procedure locates the
- * previous line in the B-tree. This procedure is used for scanning
- * through the B-tree in the reverse direction.
+ * Given an existing line in a B-tree, this function locates the previous
+ * line in the B-tree. This function is used for scanning through the
+ * B-tree in the reverse direction.
*
* Results:
- * The return value is a pointer to the line that immediately
- * preceeds linePtr, or NULL if there is no such line.
+ * The return value is a pointer to the line that immediately preceeds
+ * linePtr, or NULL if there is no such line.
*
* Side effects:
* None.
@@ -931,25 +1809,31 @@ TkBTreeNextLine(linePtr)
*/
TkTextLine *
-TkBTreePreviousLine(linePtr)
- register TkTextLine *linePtr; /* Pointer to existing line in
- * B-tree. */
+TkBTreePreviousLine(
+ TkText *textPtr, /* Relative to this client of the B-tree. */
+ register TkTextLine *linePtr)
+ /* Pointer to existing line in B-tree. */
{
register Node *nodePtr;
register Node *node2Ptr;
register TkTextLine *prevPtr;
+ if (textPtr != NULL && textPtr->start == linePtr) {
+ return NULL;
+ }
+
/*
* Find the line under this node just before the starting line.
*/
- prevPtr = linePtr->parentPtr->children.linePtr; /* First line at leaf */
+
+ prevPtr = linePtr->parentPtr->children.linePtr; /* First line at leaf. */
while (prevPtr != linePtr) {
if (prevPtr->nextPtr == linePtr) {
return prevPtr;
}
prevPtr = prevPtr->nextPtr;
- if (prevPtr == (TkTextLine *) NULL) {
- panic("TkBTreePreviousLine ran out of lines");
+ if (prevPtr == NULL) {
+ Tcl_Panic("TkBTreePreviousLine ran out of lines");
}
}
@@ -958,15 +1842,16 @@ TkBTreePreviousLine(linePtr)
* Search up the tree for the previous node, then search down from that
* node to find its last line.
*/
+
for (nodePtr = linePtr->parentPtr; ; nodePtr = nodePtr->parentPtr) {
- if (nodePtr == (Node *) NULL || nodePtr->parentPtr == (Node *) NULL) {
- return (TkTextLine *) NULL;
+ if (nodePtr == NULL || nodePtr->parentPtr == NULL) {
+ return NULL;
}
if (nodePtr != nodePtr->parentPtr->children.nodePtr) {
break;
}
}
- for (node2Ptr = nodePtr->parentPtr->children.nodePtr; ;
+ for (node2Ptr = nodePtr->parentPtr->children.nodePtr; ;
node2Ptr = node2Ptr->children.nodePtr) {
while (node2Ptr->nextPtr != nodePtr) {
node2Ptr = node2Ptr->nextPtr;
@@ -974,10 +1859,10 @@ TkBTreePreviousLine(linePtr)
if (node2Ptr->level == 0) {
break;
}
- nodePtr = (Node *)NULL;
+ nodePtr = NULL;
}
for (prevPtr = node2Ptr->children.linePtr ; ; prevPtr = prevPtr->nextPtr) {
- if (prevPtr->nextPtr == (TkTextLine *) NULL) {
+ if (prevPtr->nextPtr == NULL) {
return prevPtr;
}
}
@@ -986,10 +1871,15 @@ TkBTreePreviousLine(linePtr)
/*
*----------------------------------------------------------------------
*
- * TkBTreeLineIndex --
+ * TkBTreePixelsTo --
*
- * Given a pointer to a line in a B-tree, return the numerical
- * index of that line.
+ * Given a pointer to a line in a B-tree, return the numerical pixel
+ * index of the top of that line (i.e. the result does not include the
+ * height of the given line).
+ *
+ * Since the last line of text (the artificial one) has zero height by
+ * defintion, calling this with the last line will return the total
+ * number of pixels in the widget.
*
* Results:
* The result is the index of linePtr within the tree, where 0
@@ -1002,17 +1892,78 @@ TkBTreePreviousLine(linePtr)
*/
int
-TkBTreeLineIndex(linePtr)
- TkTextLine *linePtr; /* Pointer to existing line in
- * B-tree. */
+TkBTreePixelsTo(
+ const TkText *textPtr, /* Relative to this client of the B-tree. */
+ TkTextLine *linePtr) /* Pointer to existing line in B-tree. */
+{
+ register TkTextLine *linePtr2;
+ register Node *nodePtr, *parentPtr;
+ int index;
+ int pixelReference = textPtr->pixelReference;
+
+ /*
+ * First count how many pixels precede this line in its level-0 node.
+ */
+
+ nodePtr = linePtr->parentPtr;
+ index = 0;
+ for (linePtr2 = nodePtr->children.linePtr; linePtr2 != linePtr;
+ linePtr2 = linePtr2->nextPtr) {
+ if (linePtr2 == NULL) {
+ Tcl_Panic("TkBTreePixelsTo couldn't find line");
+ }
+ index += linePtr2->pixels[2 * pixelReference];
+ }
+
+ /*
+ * Now work up through the levels of the tree one at a time, counting how
+ * many pixels are in nodes preceding the current node.
+ */
+
+ for (parentPtr = nodePtr->parentPtr ; parentPtr != NULL;
+ nodePtr = parentPtr, parentPtr = parentPtr->parentPtr) {
+ register Node *nodePtr2;
+
+ for (nodePtr2 = parentPtr->children.nodePtr; nodePtr2 != nodePtr;
+ nodePtr2 = nodePtr2->nextPtr) {
+ if (nodePtr2 == NULL) {
+ Tcl_Panic("TkBTreePixelsTo couldn't find node");
+ }
+ index += nodePtr2->numPixels[pixelReference];
+ }
+ }
+ return index;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkBTreeLinesTo --
+ *
+ * Given a pointer to a line in a B-tree, return the numerical index of
+ * that line.
+ *
+ * Results:
+ * The result is the index of linePtr within the tree, where 0
+ * corresponds to the first line in the tree.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkBTreeLinesTo(
+ const TkText *textPtr, /* Relative to this client of the B-tree. */
+ TkTextLine *linePtr) /* Pointer to existing line in B-tree. */
{
register TkTextLine *linePtr2;
register Node *nodePtr, *parentPtr, *nodePtr2;
int index;
/*
- * First count how many lines precede this one in its level-0
- * node.
+ * First count how many lines precede this one in its level-0 node.
*/
nodePtr = linePtr->parentPtr;
@@ -1020,15 +1971,14 @@ TkBTreeLineIndex(linePtr)
for (linePtr2 = nodePtr->children.linePtr; linePtr2 != linePtr;
linePtr2 = linePtr2->nextPtr) {
if (linePtr2 == NULL) {
- panic("TkBTreeLineIndex couldn't find line");
+ Tcl_Panic("TkBTreeLinesTo couldn't find line");
}
index += 1;
}
/*
- * Now work up through the levels of the tree one at a time,
- * counting how many lines are in nodes preceding the current
- * node.
+ * Now work up through the levels of the tree one at a time, counting how
+ * many lines are in nodes preceding the current node.
*/
for (parentPtr = nodePtr->parentPtr ; parentPtr != NULL;
@@ -1036,21 +1986,48 @@ TkBTreeLineIndex(linePtr)
for (nodePtr2 = parentPtr->children.nodePtr; nodePtr2 != nodePtr;
nodePtr2 = nodePtr2->nextPtr) {
if (nodePtr2 == NULL) {
- panic("TkBTreeLineIndex couldn't find node");
+ Tcl_Panic("TkBTreeLinesTo couldn't find node");
}
index += nodePtr2->numLines;
}
}
+ if (textPtr != NULL) {
+ /*
+ * The index to return must be relative to textPtr, not to the entire
+ * tree. Take care to never return a negative index when linePtr
+ * denotes a line before -startline, or an index larger than the
+ * number of lines in textPtr when linePtr is a line past -endline.
+ */
+
+ int indexStart, indexEnd;
+
+ if (textPtr->start != NULL) {
+ indexStart = TkBTreeLinesTo(NULL, textPtr->start);
+ } else {
+ indexStart = 0;
+ }
+ if (textPtr->end != NULL) {
+ indexEnd = TkBTreeLinesTo(NULL, textPtr->end);
+ } else {
+ indexEnd = TkBTreeNumLines(textPtr->sharedTextPtr->tree, NULL);
+ }
+ if (index < indexStart) {
+ index = 0;
+ } else if (index > indexEnd) {
+ index = TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr);
+ } else {
+ index -= indexStart;
+ }
+ }
return index;
}
-
+
/*
*----------------------------------------------------------------------
*
* TkBTreeLinkSegment --
*
- * This procedure adds a new segment to a B-tree at a given
- * location.
+ * This function adds a new segment to a B-tree at a given location.
*
* Results:
* None.
@@ -1063,13 +2040,12 @@ TkBTreeLineIndex(linePtr)
/* ARGSUSED */
void
-TkBTreeLinkSegment(segPtr, indexPtr)
- TkTextSegment *segPtr; /* Pointer to new segment to be added to
- * B-tree. Should be completely initialized
- * by caller except for nextPtr field. */
- TkTextIndex *indexPtr; /* Where to add segment: it gets linked
- * in just before the segment indicated
- * here. */
+TkBTreeLinkSegment(
+ TkTextSegment *segPtr, /* Pointer to new segment to be added to
+ * B-tree. Should be completely initialized by
+ * caller except for nextPtr field. */
+ TkTextIndex *indexPtr) /* Where to add segment: it gets linked in
+ * just before the segment indicated here. */
{
register TkTextSegment *prevPtr;
@@ -1085,6 +2061,7 @@ TkBTreeLinkSegment(segPtr, indexPtr)
if (tkBTreeDebug) {
TkBTreeCheck(indexPtr->tree);
}
+ ((BTree *)indexPtr->tree)->stateEpoch++;
}
/*
@@ -1092,34 +2069,42 @@ TkBTreeLinkSegment(segPtr, indexPtr)
*
* TkBTreeUnlinkSegment --
*
- * This procedure unlinks a segment from its line in a B-tree.
+ * This function unlinks a segment from its line in a B-tree.
*
* Results:
* None.
*
* Side effects:
- * SegPtr will be unlinked from linePtr. The segment itself
- * isn't modified by this procedure.
+ * SegPtr will be unlinked from linePtr. The segment itself isn't
+ * modified by this function.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
void
-TkBTreeUnlinkSegment(tree, segPtr, linePtr)
- TkTextBTree tree; /* Tree containing segment. */
- TkTextSegment *segPtr; /* Segment to be unlinked. */
- TkTextLine *linePtr; /* Line that currently contains
- * segment. */
+TkBTreeUnlinkSegment(
+ TkTextSegment *segPtr, /* Segment to be unlinked. */
+ TkTextLine *linePtr) /* Line that currently contains segment. */
{
register TkTextSegment *prevPtr;
if (linePtr->segPtr == segPtr) {
linePtr->segPtr = segPtr->nextPtr;
} else {
- for (prevPtr = linePtr->segPtr; prevPtr->nextPtr != segPtr;
- prevPtr = prevPtr->nextPtr) {
- /* Empty loop body. */
+ prevPtr = linePtr->segPtr;
+ while (prevPtr->nextPtr != segPtr) {
+ prevPtr = prevPtr->nextPtr;
+
+ if (prevPtr == NULL) {
+ /*
+ * Two logical lines merged into one display line through
+ * eliding of a newline.
+ */
+
+ linePtr = TkBTreeNextLine(NULL, linePtr);
+ prevPtr = linePtr->segPtr;
+ }
}
prevPtr->nextPtr = segPtr->nextPtr;
}
@@ -1131,44 +2116,44 @@ TkBTreeUnlinkSegment(tree, segPtr, linePtr)
*
* TkBTreeTag --
*
- * Turn a given tag on or off for a given range of characters in
- * a B-tree of text.
+ * Turn a given tag on or off for a given range of characters in a B-tree
+ * of text.
*
* Results:
- * None.
+ * 1 if the tags on any characters in the range were changed, and zero
+ * otherwise (i.e. if the tag was already absent (add = 0) or present
+ * (add = 1) on the index range in question).
*
* Side effects:
- * The given tag is added to the given range of characters
- * in the tree or removed from all those characters, depending
- * on the "add" argument. The structure of the btree is modified
- * enough that index1Ptr and index2Ptr are no longer valid after
- * this procedure returns, and the indexes may be modified by
- * this procedure.
+ * The given tag is added to the given range of characters in the tree or
+ * removed from all those characters, depending on the "add" argument.
+ * The structure of the btree is modified enough that index1Ptr and
+ * index2Ptr are no longer valid after this function returns, and the
+ * indexes may be modified by this function.
*
*----------------------------------------------------------------------
*/
-void
-TkBTreeTag(index1Ptr, index2Ptr, tagPtr, add)
- register TkTextIndex *index1Ptr; /* Indicates first character in
- * range. */
- register TkTextIndex *index2Ptr; /* Indicates character just after the
- * last one in range. */
- TkTextTag *tagPtr; /* Tag to add or remove. */
- int add; /* One means add tag to the given
- * range of characters; zero means
- * remove the tag from the range. */
+int
+TkBTreeTag(
+ register TkTextIndex *index1Ptr,
+ /* Indicates first character in range. */
+ register TkTextIndex *index2Ptr,
+ /* Indicates character just after the last one
+ * in range. */
+ TkTextTag *tagPtr, /* Tag to add or remove. */
+ int add) /* One means add tag to the given range of
+ * characters; zero means remove the tag from
+ * the range. */
{
TkTextSegment *segPtr, *prevPtr;
TkTextSearch search;
TkTextLine *cleanupLinePtr;
- int oldState;
- int changed;
+ int oldState, changed, anyChanges = 0;
/*
- * See whether the tag is present at the start of the range. If
- * the state doesn't already match what we want then add a toggle
- * there.
+ * See whether the tag is present at the start of the range. If the state
+ * doesn't already match what we want then add a toggle there.
*/
oldState = TkBTreeCharTagged(index1Ptr, tagPtr);
@@ -1186,17 +2171,19 @@ TkBTreeTag(index1Ptr, index2Ptr, tagPtr, add)
segPtr->size = 0;
segPtr->body.toggle.tagPtr = tagPtr;
segPtr->body.toggle.inNodeCounts = 0;
+ anyChanges = 1;
}
/*
- * Scan the range of characters and delete any internal tag
- * transitions. Keep track of what the old state was at the end
- * of the range, and add a toggle there if it's needed.
+ * Scan the range of characters and delete any internal tag transitions.
+ * Keep track of what the old state was at the end of the range, and add a
+ * toggle there if it's needed.
*/
TkBTreeStartSearch(index1Ptr, index2Ptr, tagPtr, &search);
cleanupLinePtr = index1Ptr->linePtr;
while (TkBTreeNextTag(&search)) {
+ anyChanges = 1;
oldState ^= 1;
segPtr = search.segPtr;
prevPtr = search.curIndex.linePtr->segPtr;
@@ -1219,24 +2206,24 @@ TkBTreeTag(index1Ptr, index2Ptr, tagPtr, add)
ckfree((char *) segPtr);
/*
- * The code below is a bit tricky. After deleting a toggle
- * we eventually have to call CleanupLine, in order to allow
- * character segments to be merged together. To do this, we
- * remember in cleanupLinePtr a line that needs to be
- * cleaned up, but we don't clean it up until we've moved
- * on to a different line. That way the cleanup process
- * won't goof up segPtr.
+ * The code below is a bit tricky. After deleting a toggle we
+ * eventually have to call CleanupLine, in order to allow character
+ * segments to be merged together. To do this, we remember in
+ * cleanupLinePtr a line that needs to be cleaned up, but we don't
+ * clean it up until we've moved on to a different line. That way the
+ * cleanup process won't goof up segPtr.
*/
if (cleanupLinePtr != search.curIndex.linePtr) {
CleanupLine(cleanupLinePtr);
cleanupLinePtr = search.curIndex.linePtr;
}
+
/*
- * Quick hack. ChangeNodeToggleCount may move the tag's root
- * location around and leave the search in the void. This resets
- * the search.
+ * Quick hack. ChangeNodeToggleCount may move the tag's root location
+ * around and leave the search in the void. This resets the search.
*/
+
if (changed) {
TkBTreeStartSearch(index1Ptr, index2Ptr, tagPtr, &search);
}
@@ -1255,21 +2242,26 @@ TkBTreeTag(index1Ptr, index2Ptr, tagPtr, add)
segPtr->size = 0;
segPtr->body.toggle.tagPtr = tagPtr;
segPtr->body.toggle.inNodeCounts = 0;
+ anyChanges = 1;
}
/*
- * Cleanup cleanupLinePtr and the last line of the range, if
- * these are different.
+ * Cleanup cleanupLinePtr and the last line of the range, if these are
+ * different.
*/
- CleanupLine(cleanupLinePtr);
- if (cleanupLinePtr != index2Ptr->linePtr) {
- CleanupLine(index2Ptr->linePtr);
+ if (anyChanges) {
+ CleanupLine(cleanupLinePtr);
+ if (cleanupLinePtr != index2Ptr->linePtr) {
+ CleanupLine(index2Ptr->linePtr);
+ }
+ ((BTree *)index1Ptr->tree)->stateEpoch++;
}
if (tkBTreeDebug) {
TkBTreeCheck(index1Ptr->tree);
}
+ return anyChanges;
}
/*
@@ -1277,42 +2269,42 @@ TkBTreeTag(index1Ptr, index2Ptr, tagPtr, add)
*
* ChangeNodeToggleCount --
*
- * This procedure increments or decrements the toggle count for
- * a particular tag in a particular node and all its ancestors
- * up to the per-tag root node.
+ * This function increments or decrements the toggle count for a
+ * particular tag in a particular node and all its ancestors up to the
+ * per-tag root node.
*
* Results:
* None.
*
* Side effects:
- * The toggle count for tag is adjusted up or down by "delta" in
- * nodePtr. This routine maintains the tagRootPtr that identifies
- * the root node for the tag, moving it up or down the tree as needed.
+ * The toggle count for tag is adjusted up or down by "delta" in nodePtr.
+ * This routine maintains the tagRootPtr that identifies the root node
+ * for the tag, moving it up or down the tree as needed.
*
*----------------------------------------------------------------------
*/
static void
-ChangeNodeToggleCount(nodePtr, tagPtr, delta)
- register Node *nodePtr; /* Node whose toggle count for a tag
- * must be changed. */
- TkTextTag *tagPtr; /* Information about tag. */
- int delta; /* Amount to add to current toggle
- * count for tag (may be negative). */
+ChangeNodeToggleCount(
+ register Node *nodePtr, /* Node whose toggle count for a tag must be
+ * changed. */
+ TkTextTag *tagPtr, /* Information about tag. */
+ int delta) /* Amount to add to current toggle count for
+ * tag (may be negative). */
{
register Summary *summaryPtr, *prevPtr;
register Node *node2Ptr;
- int rootLevel; /* Level of original tag root */
+ int rootLevel; /* Level of original tag root. */
tagPtr->toggleCount += delta;
- if (tagPtr->tagRootPtr == (Node *) NULL) {
+ if (tagPtr->tagRootPtr == NULL) {
tagPtr->tagRootPtr = nodePtr;
return;
}
/*
- * Note the level of the existing root for the tag so we can detect
- * if it needs to be moved because of the toggle count change.
+ * Note the level of the existing root for the tag so we can detect if it
+ * needs to be moved because of the toggle count change.
*/
rootLevel = tagPtr->tagRootPtr->level;
@@ -1325,10 +2317,10 @@ ChangeNodeToggleCount(nodePtr, tagPtr, delta)
for ( ; nodePtr != tagPtr->tagRootPtr; nodePtr = nodePtr->parentPtr) {
/*
- * See if there's already an entry for this tag for this node. If so,
+ * See if there's already an entry for this tag for this node. If so,
* perhaps all we have to do is adjust its count.
*/
-
+
for (prevPtr = NULL, summaryPtr = nodePtr->summaryPtr;
summaryPtr != NULL;
prevPtr = summaryPtr, summaryPtr = summaryPtr->nextPtr) {
@@ -1349,12 +2341,12 @@ ChangeNodeToggleCount(nodePtr, tagPtr, delta)
* first place).
*/
- panic("ChangeNodeToggleCount: bad toggle count (%d) max (%d)",
+ Tcl_Panic("ChangeNodeToggleCount: bad toggle count (%d) max (%d)",
summaryPtr->toggleCount, tagPtr->toggleCount);
}
-
+
/*
- * Zero toggle count; must remove this tag from the list.
+ * Zero toggle count; must remove this tag from the list.
*/
if (prevPtr == NULL) {
@@ -1367,21 +2359,20 @@ ChangeNodeToggleCount(nodePtr, tagPtr, delta)
/*
* This tag isn't currently in the summary information list.
*/
-
+
if (rootLevel == nodePtr->level) {
-
/*
* The old tag root is at the same level in the tree as this
- * node, but it isn't at this node. Move the tag root up
- * a level, in the hopes that it will now cover this node
- * as well as the old root (if not, we'll move it up again
- * the next time through the loop). To push it up one level
- * we copy the original toggle count into the summary
- * information at the old root and change the root to its
- * parent node.
+ * node, but it isn't at this node. Move the tag root up a
+ * level, in the hopes that it will now cover this node as
+ * well as the old root (if not, we'll move it up again the
+ * next time through the loop). To push it up one level we
+ * copy the original toggle count into the summary information
+ * at the old root and change the root to its parent node.
*/
-
+
Node *rootNodePtr = tagPtr->tagRootPtr;
+
summaryPtr = (Summary *) ckalloc(sizeof(Summary));
summaryPtr->tagPtr = tagPtr;
summaryPtr->toggleCount = tagPtr->toggleCount - delta;
@@ -1400,26 +2391,26 @@ ChangeNodeToggleCount(nodePtr, tagPtr, delta)
}
/*
- * If we've decremented the toggle count, then it may be necessary
- * to push the tag root down one or more levels.
+ * If we've decremented the toggle count, then it may be necessary to push
+ * the tag root down one or more levels.
*/
if (delta >= 0) {
return;
}
if (tagPtr->toggleCount == 0) {
- tagPtr->tagRootPtr = (Node *) NULL;
+ tagPtr->tagRootPtr = NULL;
return;
}
nodePtr = tagPtr->tagRootPtr;
while (nodePtr->level > 0) {
/*
- * See if a single child node accounts for all of the tag's
- * toggles. If so, push the root down one level.
+ * See if a single child node accounts for all of the tag's toggles.
+ * If so, push the root down one level.
*/
for (node2Ptr = nodePtr->children.nodePtr;
- node2Ptr != (Node *)NULL ;
+ node2Ptr != NULL ;
node2Ptr = node2Ptr->nextPtr) {
for (prevPtr = NULL, summaryPtr = node2Ptr->summaryPtr;
summaryPtr != NULL;
@@ -1464,10 +2455,10 @@ ChangeNodeToggleCount(nodePtr, tagPtr, delta)
* Find the start of the first range of a tag.
*
* Results:
- * The return value is a pointer to the first tag toggle segment
- * for the tag. This can be either a tagon or tagoff segments because
- * of the way TkBTreeAdd removes a tag.
- * Sets *indexPtr to be the index of the tag toggle.
+ * The return value is a pointer to the first tag toggle segment for the
+ * tag. This can be either a tagon or tagoff segments because of the way
+ * TkBTreeAdd removes a tag. Sets *indexPtr to be the index of the tag
+ * toggle.
*
* Side effects:
* None.
@@ -1476,10 +2467,10 @@ ChangeNodeToggleCount(nodePtr, tagPtr, delta)
*/
static TkTextSegment *
-FindTagStart(tree, tagPtr, indexPtr)
- TkTextBTree tree; /* Tree to search within */
- TkTextTag *tagPtr; /* Tag to search for. */
- TkTextIndex *indexPtr; /* Return - index information */
+FindTagStart(
+ TkTextBTree tree, /* Tree to search within. */
+ TkTextTag *tagPtr, /* Tag to search for. */
+ TkTextIndex *indexPtr) /* Return - index information. */
{
register Node *nodePtr;
register TkTextLine *linePtr;
@@ -1488,17 +2479,17 @@ FindTagStart(tree, tagPtr, indexPtr)
int offset;
nodePtr = tagPtr->tagRootPtr;
- if (nodePtr == (Node *) NULL) {
+ if (nodePtr == NULL) {
return NULL;
}
/*
- * Search from the root of the subtree that contains the tag down
- * to the level 0 node.
+ * Search from the root of the subtree that contains the tag down to the
+ * level 0 node.
*/
while (nodePtr->level > 0) {
- for (nodePtr = nodePtr->children.nodePtr ; nodePtr != (Node *) NULL;
+ for (nodePtr = nodePtr->children.nodePtr ; nodePtr != NULL;
nodePtr = nodePtr->nextPtr) {
for (summaryPtr = nodePtr->summaryPtr ; summaryPtr != NULL;
summaryPtr = summaryPtr->nextPtr) {
@@ -1507,7 +2498,7 @@ FindTagStart(tree, tagPtr, indexPtr)
}
}
}
- gotNodeWithTag:
+ gotNodeWithTag:
continue;
}
@@ -1515,7 +2506,7 @@ FindTagStart(tree, tagPtr, indexPtr)
* Work through the lines attached to the level-0 node.
*/
- for (linePtr = nodePtr->children.linePtr; linePtr != (TkTextLine *) NULL;
+ for (linePtr = nodePtr->children.linePtr; linePtr != NULL;
linePtr = linePtr->nextPtr) {
for (offset = 0, segPtr = linePtr->segPtr ; segPtr != NULL;
offset += segPtr->size, segPtr = segPtr->nextPtr) {
@@ -1523,9 +2514,10 @@ FindTagStart(tree, tagPtr, indexPtr)
|| (segPtr->typePtr == &tkTextToggleOffType))
&& (segPtr->body.toggle.tagPtr == tagPtr)) {
/*
- * It is possible that this is a tagoff tag, but that
- * gets cleaned up later.
+ * It is possible that this is a tagoff tag, but that gets
+ * cleaned up later.
*/
+
indexPtr->tree = tree;
indexPtr->linePtr = linePtr;
indexPtr->byteIndex = offset;
@@ -1544,10 +2536,10 @@ FindTagStart(tree, tagPtr, indexPtr)
* Find the end of the last range of a tag.
*
* Results:
- * The return value is a pointer to the last tag toggle segment
- * for the tag. This can be either a tagon or tagoff segments because
- * of the way TkBTreeAdd removes a tag.
- * Sets *indexPtr to be the index of the tag toggle.
+ * The return value is a pointer to the last tag toggle segment for the
+ * tag. This can be either a tagon or tagoff segments because of the way
+ * TkBTreeAdd removes a tag. Sets *indexPtr to be the index of the tag
+ * toggle.
*
* Side effects:
* None.
@@ -1556,10 +2548,10 @@ FindTagStart(tree, tagPtr, indexPtr)
*/
static TkTextSegment *
-FindTagEnd(tree, tagPtr, indexPtr)
- TkTextBTree tree; /* Tree to search within */
- TkTextTag *tagPtr; /* Tag to search for. */
- TkTextIndex *indexPtr; /* Return - index information */
+FindTagEnd(
+ TkTextBTree tree, /* Tree to search within. */
+ TkTextTag *tagPtr, /* Tag to search for. */
+ TkTextIndex *indexPtr) /* Return - index information. */
{
register Node *nodePtr, *lastNodePtr;
register TkTextLine *linePtr ,*lastLinePtr;
@@ -1568,18 +2560,18 @@ FindTagEnd(tree, tagPtr, indexPtr)
int lastoffset, lastoffset2, offset;
nodePtr = tagPtr->tagRootPtr;
- if (nodePtr == (Node *) NULL) {
+ if (nodePtr == NULL) {
return NULL;
}
/*
- * Search from the root of the subtree that contains the tag down
- * to the level 0 node.
+ * Search from the root of the subtree that contains the tag down to the
+ * level 0 node.
*/
while (nodePtr->level > 0) {
for (lastNodePtr = NULL, nodePtr = nodePtr->children.nodePtr ;
- nodePtr != (Node *) NULL; nodePtr = nodePtr->nextPtr) {
+ nodePtr != NULL; nodePtr = nodePtr->nextPtr) {
for (summaryPtr = nodePtr->summaryPtr ; summaryPtr != NULL;
summaryPtr = summaryPtr->nextPtr) {
if (summaryPtr->tagPtr == tagPtr) {
@@ -1594,13 +2586,14 @@ FindTagEnd(tree, tagPtr, indexPtr)
/*
* Work through the lines attached to the level-0 node.
*/
+
last2SegPtr = NULL;
lastoffset2 = 0;
lastoffset = 0;
for (lastLinePtr = NULL, linePtr = nodePtr->children.linePtr;
- linePtr != (TkTextLine *) NULL; linePtr = linePtr->nextPtr) {
+ linePtr != NULL; linePtr = linePtr->nextPtr) {
for (offset = 0, lastSegPtr = NULL, segPtr = linePtr->segPtr ;
- segPtr != NULL;
+ segPtr != NULL;
offset += segPtr->size, segPtr = segPtr->nextPtr) {
if (((segPtr->typePtr == &tkTextToggleOnType)
|| (segPtr->typePtr == &tkTextToggleOffType))
@@ -1626,51 +2619,50 @@ FindTagEnd(tree, tagPtr, indexPtr)
*
* TkBTreeStartSearch --
*
- * This procedure sets up a search for tag transitions involving
- * a given tag (or all tags) in a given range of the text.
+ * This function sets up a search for tag transitions involving a given
+ * tag (or all tags) in a given range of the text.
*
* Results:
* None.
*
* Side effects:
- * The information at *searchPtr is set up so that subsequent calls
- * to TkBTreeNextTag or TkBTreePrevTag will return information about the
- * locations of tag transitions. Note that TkBTreeNextTag or
- * TkBTreePrevTag must be called to get the first transition.
- * Note: unlike TkBTreeNextTag and TkBTreePrevTag, this routine does not
- * guarantee that searchPtr->curIndex is equal to *index1Ptr. It may be
+ * The information at *searchPtr is set up so that subsequent calls to
+ * TkBTreeNextTag or TkBTreePrevTag will return information about the
+ * locations of tag transitions. Note that TkBTreeNextTag or
+ * TkBTreePrevTag must be called to get the first transition. Note:
+ * unlike TkBTreeNextTag and TkBTreePrevTag, this routine does not
+ * guarantee that searchPtr->curIndex is equal to *index1Ptr. It may be
* greater than that if *index1Ptr is less than the first tag transition.
*
*----------------------------------------------------------------------
*/
void
-TkBTreeStartSearch(index1Ptr, index2Ptr, tagPtr, searchPtr)
- TkTextIndex *index1Ptr; /* Search starts here. Tag toggles
- * at this position will not be
- * returned. */
- TkTextIndex *index2Ptr; /* Search stops here. Tag toggles
- * at this position *will* be
- * returned. */
- TkTextTag *tagPtr; /* Tag to search for. NULL means
- * search for any tag. */
- register TkTextSearch *searchPtr; /* Where to store information about
- * search's progress. */
+TkBTreeStartSearch(
+ TkTextIndex *index1Ptr, /* Search starts here. Tag toggles at this
+ * position will not be returned. */
+ TkTextIndex *index2Ptr, /* Search stops here. Tag toggles at this
+ * position *will* be returned. */
+ TkTextTag *tagPtr, /* Tag to search for. NULL means search for
+ * any tag. */
+ register TkTextSearch *searchPtr)
+ /* Where to store information about search's
+ * progress. */
{
int offset;
- TkTextIndex index0; /* First index of the tag */
- TkTextSegment *seg0Ptr; /* First segment of the tag */
+ TkTextIndex index0; /* First index of the tag. */
+ TkTextSegment *seg0Ptr; /* First segment of the tag. */
/*
- * Find the segment that contains the first toggle for the tag. This
- * may become the starting point in the search.
+ * Find the segment that contains the first toggle for the tag. This may
+ * become the starting point in the search.
*/
seg0Ptr = FindTagStart(index1Ptr->tree, tagPtr, &index0);
- if (seg0Ptr == (TkTextSegment *) NULL) {
+ if (seg0Ptr == NULL) {
/*
- * Even though there are no toggles, the display code still
- * uses the search curIndex, so initialize that anyway.
+ * Even though there are no toggles, the display code still uses the
+ * search curIndex, so initialize that anyway.
*/
searchPtr->linesLeft = 0;
@@ -1681,12 +2673,12 @@ TkBTreeStartSearch(index1Ptr, index2Ptr, tagPtr, searchPtr)
}
if (TkTextIndexCmp(index1Ptr, &index0) < 0) {
/*
- * Adjust start of search up to the first range of the tag
+ * Adjust start of search up to the first range of the tag.
*/
searchPtr->curIndex = index0;
searchPtr->segPtr = NULL;
- searchPtr->nextPtr = seg0Ptr; /* Will be returned by NextTag */
+ searchPtr->nextPtr = seg0Ptr; /* Will be returned by NextTag. */
index1Ptr = &index0;
} else {
searchPtr->curIndex = *index1Ptr;
@@ -1694,23 +2686,24 @@ TkBTreeStartSearch(index1Ptr, index2Ptr, tagPtr, searchPtr)
searchPtr->nextPtr = TkTextIndexToSeg(index1Ptr, &offset);
searchPtr->curIndex.byteIndex -= offset;
}
- searchPtr->lastPtr = TkTextIndexToSeg(index2Ptr, (int *) NULL);
+ searchPtr->lastPtr = TkTextIndexToSeg(index2Ptr, NULL);
searchPtr->tagPtr = tagPtr;
- searchPtr->linesLeft = TkBTreeLineIndex(index2Ptr->linePtr) + 1
- - TkBTreeLineIndex(index1Ptr->linePtr);
+ searchPtr->linesLeft = TkBTreeLinesTo(NULL, index2Ptr->linePtr) + 1
+ - TkBTreeLinesTo(NULL, index1Ptr->linePtr);
searchPtr->allTags = (tagPtr == NULL);
if (searchPtr->linesLeft == 1) {
/*
* Starting and stopping segments are in the same line; mark the
* search as over immediately if the second segment is before the
- * first. A search does not return a toggle at the very start of
- * the range, unless the range is artificially moved up to index0.
+ * first. A search does not return a toggle at the very start of the
+ * range, unless the range is artificially moved up to index0.
*/
- if (((index1Ptr == &index0) &&
+
+ if (((index1Ptr == &index0) &&
(index1Ptr->byteIndex > index2Ptr->byteIndex)) ||
- ((index1Ptr != &index0) &&
+ ((index1Ptr != &index0) &&
(index1Ptr->byteIndex >= index2Ptr->byteIndex))) {
- searchPtr->linesLeft = 0;
+ searchPtr->linesLeft = 0;
}
}
}
@@ -1720,55 +2713,53 @@ TkBTreeStartSearch(index1Ptr, index2Ptr, tagPtr, searchPtr)
*
* TkBTreeStartSearchBack --
*
- * This procedure sets up a search backwards for tag transitions involving
- * a given tag (or all tags) in a given range of the text. In the
- * normal case the first index (*index1Ptr) is beyond the second
- * index (*index2Ptr).
- *
+ * This function sets up a search backwards for tag transitions involving
+ * a given tag (or all tags) in a given range of the text. In the normal
+ * case the first index (*index1Ptr) is beyond the second index
+ * (*index2Ptr).
*
* Results:
* None.
*
* Side effects:
- * The information at *searchPtr is set up so that subsequent calls
- * to TkBTreePrevTag will return information about the
- * locations of tag transitions. Note that TkBTreePrevTag must be called
- * to get the first transition.
- * Note: unlike TkBTreeNextTag and TkBTreePrevTag, this routine does not
- * guarantee that searchPtr->curIndex is equal to *index1Ptr. It may be
- * less than that if *index1Ptr is greater than the last tag transition.
+ * The information at *searchPtr is set up so that subsequent calls to
+ * TkBTreePrevTag will return information about the locations of tag
+ * transitions. Note that TkBTreePrevTag must be called to get the first
+ * transition. Note: unlike TkBTreeNextTag and TkBTreePrevTag, this
+ * routine does not guarantee that searchPtr->curIndex is equal to
+ * *index1Ptr. It may be less than that if *index1Ptr is greater than the
+ * last tag transition.
*
*----------------------------------------------------------------------
*/
void
-TkBTreeStartSearchBack(index1Ptr, index2Ptr, tagPtr, searchPtr)
- TkTextIndex *index1Ptr; /* Search starts here. Tag toggles
- * at this position will not be
- * returned. */
- TkTextIndex *index2Ptr; /* Search stops here. Tag toggles
- * at this position *will* be
- * returned. */
- TkTextTag *tagPtr; /* Tag to search for. NULL means
- * search for any tag. */
- register TkTextSearch *searchPtr; /* Where to store information about
- * search's progress. */
+TkBTreeStartSearchBack(
+ TkTextIndex *index1Ptr, /* Search starts here. Tag toggles at this
+ * position will not be returned. */
+ TkTextIndex *index2Ptr, /* Search stops here. Tag toggles at this
+ * position *will* be returned. */
+ TkTextTag *tagPtr, /* Tag to search for. NULL means search for
+ * any tag. */
+ register TkTextSearch *searchPtr)
+ /* Where to store information about search's
+ * progress. */
{
int offset;
- TkTextIndex index0; /* Last index of the tag */
- TkTextIndex backOne; /* One character before starting index */
- TkTextSegment *seg0Ptr; /* Last segment of the tag */
+ TkTextIndex index0; /* Last index of the tag. */
+ TkTextIndex backOne; /* One character before starting index. */
+ TkTextSegment *seg0Ptr; /* Last segment of the tag. */
/*
- * Find the segment that contains the last toggle for the tag. This
- * may become the starting point in the search.
+ * Find the segment that contains the last toggle for the tag. This may
+ * become the starting point in the search.
*/
seg0Ptr = FindTagEnd(index1Ptr->tree, tagPtr, &index0);
- if (seg0Ptr == (TkTextSegment *) NULL) {
+ if (seg0Ptr == NULL) {
/*
- * Even though there are no toggles, the display code still
- * uses the search curIndex, so initialize that anyway.
+ * Even though there are no toggles, the display code still uses the
+ * search curIndex, so initialize that anyway.
*/
searchPtr->linesLeft = 0;
@@ -1787,28 +2778,29 @@ TkBTreeStartSearchBack(index1Ptr, index2Ptr, tagPtr, searchPtr)
searchPtr->curIndex = index0;
index1Ptr = &index0;
} else {
- TkTextIndexBackChars(index1Ptr, 1, &searchPtr->curIndex);
+ TkTextIndexBackChars(NULL, index1Ptr, 1, &searchPtr->curIndex,
+ COUNT_INDICES);
}
searchPtr->segPtr = NULL;
searchPtr->nextPtr = TkTextIndexToSeg(&searchPtr->curIndex, &offset);
searchPtr->curIndex.byteIndex -= offset;
/*
- * Adjust the end of the search so it does find toggles that are right
- * at the second index specified by the user.
+ * Adjust the end of the search so it does find toggles that are right at
+ * the second index specified by the user.
*/
- if ((TkBTreeLineIndex(index2Ptr->linePtr) == 0) &&
+ if ((TkBTreeLinesTo(NULL, index2Ptr->linePtr) == 0) &&
(index2Ptr->byteIndex == 0)) {
backOne = *index2Ptr;
- searchPtr->lastPtr = NULL; /* Signals special case for 1.0 */
+ searchPtr->lastPtr = NULL; /* Signals special case for 1.0. */
} else {
- TkTextIndexBackChars(index2Ptr, 1, &backOne);
- searchPtr->lastPtr = TkTextIndexToSeg(&backOne, (int *) NULL);
+ TkTextIndexBackChars(NULL, index2Ptr, 1, &backOne, COUNT_INDICES);
+ searchPtr->lastPtr = TkTextIndexToSeg(&backOne, NULL);
}
searchPtr->tagPtr = tagPtr;
- searchPtr->linesLeft = TkBTreeLineIndex(index1Ptr->linePtr) + 1
- - TkBTreeLineIndex(backOne.linePtr);
+ searchPtr->linesLeft = TkBTreeLinesTo(NULL, index1Ptr->linePtr) + 1
+ - TkBTreeLinesTo(NULL, backOne.linePtr);
searchPtr->allTags = (tagPtr == NULL);
if (searchPtr->linesLeft == 1) {
/*
@@ -1828,18 +2820,18 @@ TkBTreeStartSearchBack(index1Ptr, index2Ptr, tagPtr, searchPtr)
*
* TkBTreeNextTag --
*
- * Once a tag search has begun, successive calls to this procedure
- * return successive tag toggles. Note: it is NOT SAFE to call this
- * procedure if characters have been inserted into or deleted from
- * the B-tree since the call to TkBTreeStartSearch.
+ * Once a tag search has begun, successive calls to this function return
+ * successive tag toggles. Note: it is NOT SAFE to call this function if
+ * characters have been inserted into or deleted from the B-tree since
+ * the call to TkBTreeStartSearch.
*
* Results:
* The return value is 1 if another toggle was found that met the
- * criteria specified in the call to TkBTreeStartSearch; in this
- * case searchPtr->curIndex gives the toggle's position and
- * searchPtr->curTagPtr points to its segment. 0 is returned if
- * no more matching tag transitions were found; in this case
- * searchPtr->curIndex is the same as searchPtr->stopIndex.
+ * criteria specified in the call to TkBTreeStartSearch; in this case
+ * searchPtr->curIndex gives the toggle's position and
+ * searchPtr->curTagPtr points to its segment. 0 is returned if no more
+ * matching tag transitions were found; in this case searchPtr->curIndex
+ * is the same as searchPtr->stopIndex.
*
* Side effects:
* Information in *searchPtr is modified to update the state of the
@@ -1849,10 +2841,11 @@ TkBTreeStartSearchBack(index1Ptr, index2Ptr, tagPtr, searchPtr)
*/
int
-TkBTreeNextTag(searchPtr)
- register TkTextSearch *searchPtr; /* Information about search in
- * progress; must have been set up by
- * call to TkBTreeStartSearch. */
+TkBTreeNextTag(
+ register TkTextSearch *searchPtr)
+ /* Information about search in progress; must
+ * have been set up by call to
+ * TkBTreeStartSearch. */
{
register TkTextSegment *segPtr;
register Node *nodePtr;
@@ -1863,9 +2856,9 @@ TkBTreeNextTag(searchPtr)
}
/*
- * The outermost loop iterates over lines that may potentially contain
- * a relevant tag transition, starting from the current segment in
- * the current line.
+ * The outermost loop iterates over lines that may potentially contain a
+ * relevant tag transition, starting from the current segment in the
+ * current line.
*/
segPtr = searchPtr->nextPtr;
@@ -1889,11 +2882,10 @@ TkBTreeNextTag(searchPtr)
}
searchPtr->curIndex.byteIndex += segPtr->size;
}
-
+
/*
* See if there are more lines associated with the current parent
- * node. If so, go back to the top of the loop to search the next
- * one.
+ * node. If so, go back to the top of the loop to search the next one.
*/
nodePtr = searchPtr->curIndex.linePtr->parentPtr;
@@ -1910,14 +2902,14 @@ TkBTreeNextTag(searchPtr)
if (nodePtr == searchPtr->tagPtr->tagRootPtr) {
goto searchOver;
}
-
+
/*
* Search across and up through the B-tree's node hierarchy looking
* for the next node that has a relevant tag transition somewhere in
- * its subtree. Be sure to update linesLeft as we skip over large
+ * its subtree. Be sure to update linesLeft as we skip over large
* chunks of lines.
*/
-
+
while (1) {
while (nodePtr->nextPtr == NULL) {
if (nodePtr->parentPtr == NULL ||
@@ -1936,14 +2928,14 @@ TkBTreeNextTag(searchPtr)
}
searchPtr->linesLeft -= nodePtr->numLines;
}
-
+
/*
* At this point we've found a subtree that has a relevant tag
- * transition. Now search down (and across) through that subtree
- * to find the first level-0 node that has a relevant tag transition.
+ * transition. Now search down (and across) through that subtree to
+ * find the first level-0 node that has a relevant tag transition.
*/
-
- gotNodeWithTag:
+
+ gotNodeWithTag:
while (nodePtr->level > 0) {
for (nodePtr = nodePtr->children.nodePtr; ;
nodePtr = nodePtr->nextPtr) {
@@ -1951,21 +2943,25 @@ TkBTreeNextTag(searchPtr)
summaryPtr = summaryPtr->nextPtr) {
if ((searchPtr->allTags)
|| (summaryPtr->tagPtr == searchPtr->tagPtr)) {
+ /*
+ * Would really like a multi-level continue here...
+ */
+
goto nextChild;
}
}
searchPtr->linesLeft -= nodePtr->numLines;
if (nodePtr->nextPtr == NULL) {
- panic("TkBTreeNextTag found incorrect tag summary info.");
+ Tcl_Panic("TkBTreeNextTag found incorrect tag summary info.");
}
}
- nextChild:
+ nextChild:
continue;
}
-
+
/*
* Now we're down to a level-0 node that contains a line that contains
- * a relevant tag transition. Set up line information and go back to
+ * a relevant tag transition. Set up line information and go back to
* the beginning of the loop to search through lines.
*/
@@ -1978,7 +2974,7 @@ TkBTreeNextTag(searchPtr)
continue;
}
- searchOver:
+ searchOver:
searchPtr->linesLeft = 0;
searchPtr->segPtr = NULL;
return 0;
@@ -1989,19 +2985,18 @@ TkBTreeNextTag(searchPtr)
*
* TkBTreePrevTag --
*
- * Once a tag search has begun, successive calls to this procedure
- * return successive tag toggles in the reverse direction.
- * Note: it is NOT SAFE to call this
- * procedure if characters have been inserted into or deleted from
- * the B-tree since the call to TkBTreeStartSearch.
+ * Once a tag search has begun, successive calls to this function return
+ * successive tag toggles in the reverse direction. Note: it is NOT SAFE
+ * to call this function if characters have been inserted into or deleted
+ * from the B-tree since the call to TkBTreeStartSearch.
*
* Results:
* The return value is 1 if another toggle was found that met the
- * criteria specified in the call to TkBTreeStartSearch; in this
- * case searchPtr->curIndex gives the toggle's position and
- * searchPtr->curTagPtr points to its segment. 0 is returned if
- * no more matching tag transitions were found; in this case
- * searchPtr->curIndex is the same as searchPtr->stopIndex.
+ * criteria specified in the call to TkBTreeStartSearch; in this case
+ * searchPtr->curIndex gives the toggle's position and
+ * searchPtr->curTagPtr points to its segment. 0 is returned if no more
+ * matching tag transitions were found; in this case searchPtr->curIndex
+ * is the same as searchPtr->stopIndex.
*
* Side effects:
* Information in *searchPtr is modified to update the state of the
@@ -2011,43 +3006,46 @@ TkBTreeNextTag(searchPtr)
*/
int
-TkBTreePrevTag(searchPtr)
- register TkTextSearch *searchPtr; /* Information about search in
- * progress; must have been set up by
- * call to TkBTreeStartSearch. */
+TkBTreePrevTag(
+ register TkTextSearch *searchPtr)
+ /* Information about search in progress; must
+ * have been set up by call to
+ * TkBTreeStartSearch. */
{
register TkTextSegment *segPtr, *prevPtr;
register TkTextLine *linePtr, *prevLinePtr;
register Node *nodePtr, *node2Ptr, *prevNodePtr;
register Summary *summaryPtr;
- int byteIndex;
- int pastLast; /* Saw last marker during scan */
- int linesSkipped;
+ int byteIndex, linesSkipped;
+ int pastLast; /* Saw last marker during scan. */
if (searchPtr->linesLeft <= 0) {
goto searchOver;
}
/*
- * The outermost loop iterates over lines that may potentially contain
- * a relevant tag transition, starting from the current segment in
- * the current line. "nextPtr" is maintained as the last segment in
- * a line that we can look at.
+ * The outermost loop iterates over lines that may potentially contain a
+ * relevant tag transition, starting from the current segment in the
+ * current line. "nextPtr" is maintained as the last segment in a line
+ * that we can look at.
*/
while (1) {
/*
* Check for the last toggle before the current segment on this line.
*/
+
byteIndex = 0;
if (searchPtr->lastPtr == NULL) {
- /*
+ /*
* Search back to the very beginning, so pastLast is irrelevent.
*/
- pastLast = 1;
+
+ pastLast = 1;
} else {
pastLast = 0;
}
+
for (prevPtr = NULL, segPtr = searchPtr->curIndex.linePtr->segPtr ;
segPtr != NULL && segPtr != searchPtr->nextPtr;
segPtr = segPtr->nextPtr) {
@@ -2059,7 +3057,8 @@ TkBTreePrevTag(searchPtr)
searchPtr->curIndex.byteIndex = byteIndex;
}
if (segPtr == searchPtr->lastPtr) {
- prevPtr = NULL; /* Segments earlier than last don't count */
+ prevPtr = NULL; /* Segments earlier than last don't
+ * count. */
pastLast = 1;
}
byteIndex += segPtr->size;
@@ -2067,9 +3066,10 @@ TkBTreePrevTag(searchPtr)
if (prevPtr != NULL) {
if (searchPtr->linesLeft == 1 && !pastLast) {
/*
- * We found a segment that is before the stopping index.
- * Note that it is OK if prevPtr == lastPtr.
+ * We found a segment that is before the stopping index. Note
+ * that it is OK if prevPtr == lastPtr.
*/
+
goto searchOver;
}
searchPtr->segPtr = prevPtr;
@@ -2077,7 +3077,7 @@ TkBTreePrevTag(searchPtr)
searchPtr->tagPtr = prevPtr->body.toggle.tagPtr;
return 1;
}
-
+
searchPtr->linesLeft--;
if (searchPtr->linesLeft <= 0) {
goto searchOver;
@@ -2085,7 +3085,7 @@ TkBTreePrevTag(searchPtr)
/*
* See if there are more lines associated with the current parent
- * node. If so, go back to the top of the loop to search the previous
+ * node. If so, go back to the top of the loop to search the previous
* one.
*/
@@ -2103,17 +3103,17 @@ TkBTreePrevTag(searchPtr)
if (nodePtr == searchPtr->tagPtr->tagRootPtr) {
goto searchOver;
}
-
+
/*
* Search across and up through the B-tree's node hierarchy looking
- * for the previous node that has a relevant tag transition somewhere in
- * its subtree. The search and line counting is trickier with/out
- * back pointers. We'll scan all the nodes under a parent up to
- * the current node, searching all of them for tag state. The last
- * one we find, if any, is recorded in prevNodePtr, and any nodes
- * past prevNodePtr that don't have tag state increment linesSkipped.
+ * for the previous node that has a relevant tag transition somewhere
+ * in its subtree. The search and line counting is trickier with/out
+ * back pointers. We'll scan all the nodes under a parent up to the
+ * current node, searching all of them for tag state. The last one we
+ * find, if any, is recorded in prevNodePtr, and any nodes past
+ * prevNodePtr that don't have tag state increment linesSkipped.
*/
-
+
while (1) {
for (prevNodePtr = NULL, linesSkipped = 0,
node2Ptr = nodePtr->parentPtr->children.nodePtr ;
@@ -2129,7 +3129,7 @@ TkBTreePrevTag(searchPtr)
}
linesSkipped += node2Ptr->numLines;
- keepLooking:
+ keepLooking:
continue;
}
if (prevNodePtr != NULL) {
@@ -2143,14 +3143,14 @@ TkBTreePrevTag(searchPtr)
goto searchOver;
}
}
-
+
/*
* At this point we've found a subtree that has a relevant tag
- * transition. Now search down (and across) through that subtree
- * to find the last level-0 node that has a relevant tag transition.
+ * transition. Now search down (and across) through that subtree to
+ * find the last level-0 node that has a relevant tag transition.
*/
-
- gotNodeWithTag:
+
+ gotNodeWithTag:
while (nodePtr->level > 0) {
for (linesSkipped = 0, prevNodePtr = NULL,
nodePtr = nodePtr->children.nodePtr; nodePtr != NULL ;
@@ -2166,20 +3166,20 @@ TkBTreePrevTag(searchPtr)
}
linesSkipped += nodePtr->numLines;
- keepLooking2:
+ keepLooking2:
continue;
}
if (prevNodePtr == NULL) {
- panic("TkBTreePrevTag found incorrect tag summary info.");
+ Tcl_Panic("TkBTreePrevTag found incorrect tag summary info.");
}
searchPtr->linesLeft -= linesSkipped;
nodePtr = prevNodePtr;
}
-
+
/*
* Now we're down to a level-0 node that contains a line that contains
- * a relevant tag transition. Set up line information and go back to
- * the beginning of the loop to search through lines. We start with
+ * a relevant tag transition. Set up line information and go back to
+ * the beginning of the loop to search through lines. We start with
* the last line below the node.
*/
@@ -2196,7 +3196,7 @@ TkBTreePrevTag(searchPtr)
continue;
}
- searchOver:
+ searchOver:
searchPtr->linesLeft = 0;
searchPtr->segPtr = NULL;
return 0;
@@ -2210,8 +3210,8 @@ TkBTreePrevTag(searchPtr)
* Determine whether a particular character has a particular tag.
*
* Results:
- * The return value is 1 if the given tag is in effect at the
- * character given by linePtr and ch, and 0 otherwise.
+ * The return value is 1 if the given tag is in effect at the character
+ * given by linePtr and ch, and 0 otherwise.
*
* Side effects:
* None.
@@ -2220,10 +3220,10 @@ TkBTreePrevTag(searchPtr)
*/
int
-TkBTreeCharTagged(indexPtr, tagPtr)
- TkTextIndex *indexPtr; /* Indicates a character position at
- * which to check for a tag. */
- TkTextTag *tagPtr; /* Tag of interest. */
+TkBTreeCharTagged(
+ const TkTextIndex *indexPtr,/* Indicates a character position at which to
+ * check for a tag. */
+ TkTextTag *tagPtr) /* Tag of interest. */
{
register Node *nodePtr;
register TkTextLine *siblingLinePtr;
@@ -2231,10 +3231,10 @@ TkBTreeCharTagged(indexPtr, tagPtr)
TkTextSegment *toggleSegPtr;
int toggles, index;
- /*
- * Check for toggles for the tag in indexPtr's line but before
- * indexPtr. If there is one, its type indicates whether or
- * not the character is tagged.
+ /*
+ * Check for toggles for the tag in indexPtr's line but before indexPtr.
+ * If there is one, its type indicates whether or not the character is
+ * tagged.
*/
toggleSegPtr = NULL;
@@ -2252,9 +3252,8 @@ TkBTreeCharTagged(indexPtr, tagPtr)
}
/*
- * No toggle in this line. Look for toggles for the tag in lines
- * that are predecessors of indexPtr->linePtr but under the same
- * level-0 node.
+ * No toggle in this line. Look for toggles for the tag in lines that are
+ * predecessors of indexPtr->linePtr but under the same level-0 node.
*/
for (siblingLinePtr = indexPtr->linePtr->parentPtr->children.linePtr;
@@ -2274,9 +3273,9 @@ TkBTreeCharTagged(indexPtr, tagPtr)
}
/*
- * No toggle in this node. Scan upwards through the ancestors of
- * this node, counting the number of toggles of the given tag in
- * siblings that precede that node.
+ * No toggle in this node. Scan upwards through the ancestors of this
+ * node, counting the number of toggles of the given tag in siblings that
+ * precede that node.
*/
toggles = 0;
@@ -2285,7 +3284,7 @@ TkBTreeCharTagged(indexPtr, tagPtr)
register Node *siblingPtr;
register Summary *summaryPtr;
- for (siblingPtr = nodePtr->parentPtr->children.nodePtr;
+ for (siblingPtr = nodePtr->parentPtr->children.nodePtr;
siblingPtr != nodePtr; siblingPtr = siblingPtr->nextPtr) {
for (summaryPtr = siblingPtr->summaryPtr; summaryPtr != NULL;
summaryPtr = summaryPtr->nextPtr) {
@@ -2300,8 +3299,8 @@ TkBTreeCharTagged(indexPtr, tagPtr)
}
/*
- * An odd number of toggles means that the tag is present at the
- * given point.
+ * An odd number of toggles means that the tag is present at the given
+ * point.
*/
return toggles & 1;
@@ -2312,17 +3311,17 @@ TkBTreeCharTagged(indexPtr, tagPtr)
*
* TkBTreeGetTags --
*
- * Return information about all of the tags that are associated
- * with a particular character in a B-tree of text.
+ * Return information about all of the tags that are associated with a
+ * particular character in a B-tree of text.
*
* Results:
* The return value is a malloc-ed array containing pointers to
- * information for each of the tags that is associated with
- * the character at the position given by linePtr and ch. The
- * word at *numTagsPtr is filled in with the number of pointers
- * in the array. It is up to the caller to free the array by
- * passing it to free. If there are no tags at the given character
- * then a NULL pointer is returned and *numTagsPtr will be set to 0.
+ * information for each of the tags that is associated with the character
+ * at the position given by linePtr and ch. The word at *numTagsPtr is
+ * filled in with the number of pointers in the array. It is up to the
+ * caller to free the array by passing it to free. If there are no tags
+ * at the given character then a NULL pointer is returned and *numTagsPtr
+ * will be set to 0.
*
* Side effects:
* None.
@@ -2332,38 +3331,54 @@ TkBTreeCharTagged(indexPtr, tagPtr)
/* ARGSUSED */
TkTextTag **
-TkBTreeGetTags(indexPtr, numTagsPtr)
- TkTextIndex *indexPtr; /* Indicates a particular position in
- * the B-tree. */
- int *numTagsPtr; /* Store number of tags found at this
+TkBTreeGetTags(
+ const TkTextIndex *indexPtr,/* Indicates a particular position in the
+ * B-tree. */
+ const TkText *textPtr, /* If non-NULL, then only return tags for this
+ * text widget (when there are peer
+ * widgets). */
+ int *numTagsPtr) /* Store number of tags found at this
* location. */
{
register Node *nodePtr;
register TkTextLine *siblingLinePtr;
register TkTextSegment *segPtr;
+ TkTextLine *linePtr;
int src, dst, index;
TagInfo tagInfo;
#define NUM_TAG_INFOS 10
tagInfo.numTags = 0;
tagInfo.arraySize = NUM_TAG_INFOS;
- tagInfo.tagPtrs = (TkTextTag **) ckalloc((unsigned)
- NUM_TAG_INFOS*sizeof(TkTextTag *));
- tagInfo.counts = (int *) ckalloc((unsigned)
- NUM_TAG_INFOS*sizeof(int));
+ tagInfo.tagPtrs = (TkTextTag **)
+ ckalloc((unsigned) NUM_TAG_INFOS * sizeof(TkTextTag *));
+ tagInfo.counts = (int *)
+ ckalloc((unsigned) NUM_TAG_INFOS * sizeof(int));
/*
- * Record tag toggles within the line of indexPtr but preceding
- * indexPtr.
+ * Record tag toggles within the line of indexPtr but preceding indexPtr.
*/
- for (index = 0, segPtr = indexPtr->linePtr->segPtr;
- (index + segPtr->size) <= indexPtr->byteIndex;
- index += segPtr->size, segPtr = segPtr->nextPtr) {
+ linePtr = indexPtr->linePtr;
+ index = 0;
+ segPtr = linePtr->segPtr;
+ while ((index + segPtr->size) <= indexPtr->byteIndex) {
if ((segPtr->typePtr == &tkTextToggleOnType)
|| (segPtr->typePtr == &tkTextToggleOffType)) {
IncCount(segPtr->body.toggle.tagPtr, 1, &tagInfo);
}
+ index += segPtr->size;
+ segPtr = segPtr->nextPtr;
+
+ if (segPtr == NULL) {
+ /*
+ * Two logical lines merged into one display line through eliding
+ * of a newline.
+ */
+
+ linePtr = TkBTreeNextLine(NULL, linePtr);
+ segPtr = linePtr->segPtr;
+ }
}
/*
@@ -2384,8 +3399,8 @@ TkBTreeGetTags(indexPtr, numTagsPtr)
}
/*
- * For each node in the ancestry of this line, record tag toggles
- * for all siblings that precede that node.
+ * For each node in the ancestry of this line, record tag toggles for all
+ * siblings that precede that node.
*/
for (nodePtr = indexPtr->linePtr->parentPtr; nodePtr->parentPtr != NULL;
@@ -2393,7 +3408,7 @@ TkBTreeGetTags(indexPtr, numTagsPtr)
register Node *siblingPtr;
register Summary *summaryPtr;
- for (siblingPtr = nodePtr->parentPtr->children.nodePtr;
+ for (siblingPtr = nodePtr->parentPtr->children.nodePtr;
siblingPtr != nodePtr; siblingPtr = siblingPtr->nextPtr) {
for (summaryPtr = siblingPtr->summaryPtr; summaryPtr != NULL;
summaryPtr = summaryPtr->nextPtr) {
@@ -2406,15 +3421,20 @@ TkBTreeGetTags(indexPtr, numTagsPtr)
}
/*
- * Go through the tag information and squash out all of the tags
- * that have even toggle counts (these tags exist before the point
- * of interest, but not at the desired character itself).
+ * Go through the tag information and squash out all of the tags that have
+ * even toggle counts (these tags exist before the point of interest, but
+ * not at the desired character itself). Also squash out all tags that
+ * don't belong to the requested widget.
*/
for (src = 0, dst = 0; src < tagInfo.numTags; src++) {
if (tagInfo.counts[src] & 1) {
- tagInfo.tagPtrs[dst] = tagInfo.tagPtrs[src];
- dst++;
+ const TkText *tagTextPtr = tagInfo.tagPtrs[src]->textPtr;
+
+ if (tagTextPtr==NULL || textPtr==NULL || tagTextPtr==textPtr) {
+ tagInfo.tagPtrs[dst] = tagInfo.tagPtrs[src];
+ dst++;
+ }
}
}
*numTagsPtr = dst;
@@ -2432,14 +3452,25 @@ TkBTreeGetTags(indexPtr, numTagsPtr)
* TkTextIsElided --
*
* Special case to just return information about elided attribute.
- * Specialized from TkBTreeGetTags(indexPtr, numTagsPtr)
- * and GetStyle(textPtr, indexPtr).
- * Just need to keep track of invisibility settings for each priority,
- * pick highest one active at end
+ * Specialized from TkBTreeGetTags(indexPtr, textPtr, numTagsPtr) and
+ * GetStyle(textPtr, indexPtr). Just need to keep track of invisibility
+ * settings for each priority, pick highest one active at end.
+ *
+ * Note that this returns all elide information up to and including the
+ * given index (quite obviously). However, this does mean that if
+ * indexPtr is a line-start and one then iterates from the beginning of
+ * that line forwards, one will actually revisit the segPtrs of size zero
+ * (for tag toggling, for example) which have already been seen here.
+ *
+ * For this reason we fill in the fields 'segPtr' and 'segOffset' of
+ * elideInfo, enabling our caller easily to calculate incremental changes
+ * from where we left off.
*
* Results:
* Returns whether this text should be elided or not.
*
+ * Optionally returns more detailed information in elideInfo.
+ *
* Side effects:
* None.
*
@@ -2448,93 +3479,129 @@ TkBTreeGetTags(indexPtr, numTagsPtr)
/* ARGSUSED */
int
-TkTextIsElided(textPtr, indexPtr)
- TkText *textPtr; /* Overall information about text widget. */
- TkTextIndex *indexPtr; /* The character in the text for which
- * display information is wanted. */
+TkTextIsElided(
+ const TkText *textPtr, /* Overall information about text widget. */
+ const TkTextIndex *indexPtr,/* The character in the text for which display
+ * information is wanted. */
+ TkTextElideInfo *elideInfo) /* NULL or a pointer to a structure in which
+ * indexPtr's elide state will be stored and
+ * returned. */
{
-#define LOTSA_TAGS 1000
- int elide = 0; /* if nobody says otherwise, it's visible */
-
- int deftagCnts[LOTSA_TAGS];
- int *tagCnts = deftagCnts;
- TkTextTag *deftagPtrs[LOTSA_TAGS];
- TkTextTag **tagPtrs = deftagPtrs;
- int numTags = textPtr->numTags;
register Node *nodePtr;
register TkTextLine *siblingLinePtr;
register TkTextSegment *segPtr;
- register TkTextTag *tagPtr = NULL; /* silence gcc 4 warning */
+ register TkTextTag *tagPtr = NULL;
register int i, index;
+ register TkTextElideInfo *infoPtr;
+ TkTextLine *linePtr;
+ int elide;
- /* almost always avoid malloc, so stay out of system calls */
- if (LOTSA_TAGS < numTags) {
- tagCnts = (int *)ckalloc((unsigned)sizeof(int) * numTags);
- tagPtrs = (TkTextTag **)ckalloc((unsigned)sizeof(TkTextTag *) * numTags);
+ if (elideInfo == NULL) {
+ infoPtr = (TkTextElideInfo *)
+ ckalloc((unsigned) sizeof(TkTextElideInfo));
+ } else {
+ infoPtr = elideInfo;
}
-
- for (i=0; i<numTags; i++) {
- tagCnts[i] = 0;
+
+ infoPtr->elide = 0; /* If nobody says otherwise, it's visible. */
+ infoPtr->tagCnts = infoPtr->deftagCnts;
+ infoPtr->tagPtrs = infoPtr->deftagPtrs;
+ infoPtr->numTags = textPtr->sharedTextPtr->numTags;
+
+ /*
+ * Almost always avoid malloc, so stay out of system calls.
+ */
+
+ if (LOTSA_TAGS < infoPtr->numTags) {
+ infoPtr->tagCnts = (int *)
+ ckalloc((unsigned) sizeof(int) * infoPtr->numTags);
+ infoPtr->tagPtrs = (TkTextTag **)
+ ckalloc((unsigned) sizeof(TkTextTag *) * infoPtr->numTags);
+ }
+
+ for (i=0; i<infoPtr->numTags; i++) {
+ infoPtr->tagCnts[i] = 0;
}
/*
- * Record tag toggles within the line of indexPtr but preceding
- * indexPtr.
+ * Record tag toggles within the line of indexPtr but preceding indexPtr.
*/
- for (index = 0, segPtr = indexPtr->linePtr->segPtr;
- (index + segPtr->size) <= indexPtr->byteIndex;
- index += segPtr->size, segPtr = segPtr->nextPtr) {
+ index = 0;
+ linePtr = indexPtr->linePtr;
+ segPtr = linePtr->segPtr;
+ while ((index + segPtr->size) <= indexPtr->byteIndex) {
if ((segPtr->typePtr == &tkTextToggleOnType)
|| (segPtr->typePtr == &tkTextToggleOffType)) {
tagPtr = segPtr->body.toggle.tagPtr;
if (tagPtr->elideString != NULL) {
- tagPtrs[tagPtr->priority] = tagPtr;
- tagCnts[tagPtr->priority]++;
+ infoPtr->tagPtrs[tagPtr->priority] = tagPtr;
+ infoPtr->tagCnts[tagPtr->priority]++;
}
}
+
+ index += segPtr->size;
+ segPtr = segPtr->nextPtr;
+ if (segPtr == NULL) {
+ /*
+ * Two logical lines merged into one display line through eliding
+ * of a newline.
+ */
+
+ linePtr = TkBTreeNextLine(NULL, linePtr);
+ segPtr = linePtr->segPtr;
+ }
}
/*
+ * Store the first segPtr we haven't examined completely so that our
+ * caller knows where to start.
+ */
+
+ infoPtr->segPtr = segPtr;
+ infoPtr->segOffset = index;
+
+ /*
* Record toggles for tags in lines that are predecessors of
* indexPtr->linePtr but under the same level-0 node.
*/
for (siblingLinePtr = indexPtr->linePtr->parentPtr->children.linePtr;
- siblingLinePtr != indexPtr->linePtr;
- siblingLinePtr = siblingLinePtr->nextPtr) {
+ siblingLinePtr != indexPtr->linePtr;
+ siblingLinePtr = siblingLinePtr->nextPtr) {
for (segPtr = siblingLinePtr->segPtr; segPtr != NULL;
- segPtr = segPtr->nextPtr) {
+ segPtr = segPtr->nextPtr) {
if ((segPtr->typePtr == &tkTextToggleOnType)
|| (segPtr->typePtr == &tkTextToggleOffType)) {
tagPtr = segPtr->body.toggle.tagPtr;
if (tagPtr->elideString != NULL) {
- tagPtrs[tagPtr->priority] = tagPtr;
- tagCnts[tagPtr->priority]++;
+ infoPtr->tagPtrs[tagPtr->priority] = tagPtr;
+ infoPtr->tagCnts[tagPtr->priority]++;
}
}
}
}
/*
- * For each node in the ancestry of this line, record tag toggles
- * for all siblings that precede that node.
+ * For each node in the ancestry of this line, record tag toggles for all
+ * siblings that precede that node.
*/
for (nodePtr = indexPtr->linePtr->parentPtr; nodePtr->parentPtr != NULL;
- nodePtr = nodePtr->parentPtr) {
+ nodePtr = nodePtr->parentPtr) {
register Node *siblingPtr;
register Summary *summaryPtr;
- for (siblingPtr = nodePtr->parentPtr->children.nodePtr;
- siblingPtr != nodePtr; siblingPtr = siblingPtr->nextPtr) {
+ for (siblingPtr = nodePtr->parentPtr->children.nodePtr;
+ siblingPtr != nodePtr; siblingPtr = siblingPtr->nextPtr) {
for (summaryPtr = siblingPtr->summaryPtr; summaryPtr != NULL;
- summaryPtr = summaryPtr->nextPtr) {
+ summaryPtr = summaryPtr->nextPtr) {
if (summaryPtr->toggleCount & 1) {
tagPtr = summaryPtr->tagPtr;
if (tagPtr->elideString != NULL) {
- tagPtrs[tagPtr->priority] = tagPtr;
- tagCnts[tagPtr->priority] += summaryPtr->toggleCount;
+ infoPtr->tagPtrs[tagPtr->priority] = tagPtr;
+ infoPtr->tagCnts[tagPtr->priority] +=
+ summaryPtr->toggleCount;
}
}
}
@@ -2542,32 +3609,47 @@ TkTextIsElided(textPtr, indexPtr)
}
/*
- * Now traverse from highest priority to lowest,
- * take elided value from first odd count (= on)
+ * Now traverse from highest priority to lowest, take elided value from
+ * first odd count (= on).
*/
- for (i = numTags-1; i >=0; i--) {
- if (tagCnts[i] & 1) {
- /* who would make the selection elided? */
- if (
-#ifndef MAC_OSX_TK
- !TkpAlwaysShowSelection(textPtr->tkwin)
-#else
+ infoPtr->elidePriority = -1;
+ for (i = infoPtr->numTags-1; i >=0; i--) {
+ if (infoPtr->tagCnts[i] & 1) {
+ /*
+ * Who would make the selection elided?
+ */
+
+ if ((tagPtr == textPtr->selTagPtr)
+ && !(textPtr->flags & GOT_FOCUS)
+ && (textPtr->inactiveSelBorder == NULL
+#ifdef MAC_OSX_TK
/* Don't show inactive selection in disabled widgets. */
- textPtr->state == TK_STATE_DISABLED
+ || textPtr->state == TK_TEXT_STATE_DISABLED
#endif
- && (tagPtr == textPtr->selTagPtr)
- && !(textPtr->flags & GOT_FOCUS)) {
+ )) {
continue;
}
- elide = tagPtrs[i]->elide;
+ infoPtr->elide = infoPtr->tagPtrs[i]->elide;
+
+ /*
+ * Note: i == infoPtr->tagPtrs[i]->priority
+ */
+
+ infoPtr->elidePriority = i;
break;
}
}
- if (LOTSA_TAGS < numTags) {
- ckfree((char *) tagCnts);
- ckfree((char *) tagPtrs);
+ elide = infoPtr->elide;
+
+ if (elideInfo == NULL) {
+ if (LOTSA_TAGS < infoPtr->numTags) {
+ ckfree((char *) infoPtr->tagCnts);
+ ckfree((char *) infoPtr->tagPtrs);
+ }
+
+ ckfree((char *) infoPtr);
}
return elide;
@@ -2576,27 +3658,55 @@ TkTextIsElided(textPtr, indexPtr)
/*
*----------------------------------------------------------------------
*
+ * TkTextFreeElideInfo --
+ *
+ * This is a utility function used to free up any memory allocated by the
+ * TkTextIsElided function above.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Memory may be freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkTextFreeElideInfo(
+ TkTextElideInfo *elideInfo) /* Free any allocated memory in this
+ * structure. */
+{
+ if (LOTSA_TAGS < elideInfo->numTags) {
+ ckfree((char *) elideInfo->tagCnts);
+ ckfree((char *) elideInfo->tagPtrs);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* IncCount --
*
- * This is a utility procedure used by TkBTreeGetTags. It
- * increments the count for a particular tag, adding a new
- * entry for that tag if there wasn't one previously.
+ * This is a utility function used by TkBTreeGetTags. It increments the
+ * count for a particular tag, adding a new entry for that tag if there
+ * wasn't one previously.
*
* Results:
* None.
*
* Side effects:
- * The information at *tagInfoPtr may be modified, and the arrays
- * may be reallocated to make them larger.
+ * The information at *tagInfoPtr may be modified, and the arrays may be
+ * reallocated to make them larger.
*
*----------------------------------------------------------------------
*/
static void
-IncCount(tagPtr, inc, tagInfoPtr)
- TkTextTag *tagPtr; /* Handle for tag. */
- int inc; /* Amount by which to increment tag count. */
- TagInfo *tagInfoPtr; /* Holds cumulative information about tags;
+IncCount(
+ TkTextTag *tagPtr, /* Handle for tag. */
+ int inc, /* Amount by which to increment tag count. */
+ TagInfo *tagInfoPtr) /* Holds cumulative information about tags;
* increment count here. */
{
register TkTextTag **tagPtrPtr;
@@ -2611,24 +3721,23 @@ IncCount(tagPtr, inc, tagInfoPtr)
}
/*
- * There isn't currently an entry for this tag, so we have to
- * make a new one. If the arrays are full, then enlarge the
- * arrays first.
+ * There isn't currently an entry for this tag, so we have to make a new
+ * one. If the arrays are full, then enlarge the arrays first.
*/
if (tagInfoPtr->numTags == tagInfoPtr->arraySize) {
TkTextTag **newTags;
int *newCounts, newSize;
- newSize = 2*tagInfoPtr->arraySize;
- newTags = (TkTextTag **) ckalloc((unsigned)
- (newSize*sizeof(TkTextTag *)));
- memcpy((VOID *) newTags, (VOID *) tagInfoPtr->tagPtrs,
+ newSize = 2 * tagInfoPtr->arraySize;
+ newTags = (TkTextTag **)
+ ckalloc((unsigned) newSize * sizeof(TkTextTag *));
+ memcpy(newTags, tagInfoPtr->tagPtrs,
tagInfoPtr->arraySize * sizeof(TkTextTag *));
ckfree((char *) tagInfoPtr->tagPtrs);
tagInfoPtr->tagPtrs = newTags;
- newCounts = (int *) ckalloc((unsigned) (newSize*sizeof(int)));
- memcpy((VOID *) newCounts, (VOID *) tagInfoPtr->counts,
+ newCounts = (int *) ckalloc((unsigned) newSize * sizeof(int));
+ memcpy(newCounts, tagInfoPtr->counts,
tagInfoPtr->arraySize * sizeof(int));
ckfree((char *) tagInfoPtr->counts);
tagInfoPtr->counts = newCounts;
@@ -2645,22 +3754,22 @@ IncCount(tagPtr, inc, tagInfoPtr)
*
* TkBTreeCheck --
*
- * This procedure runs a set of consistency checks over a B-tree
- * and panics if any inconsistencies are found.
+ * This function runs a set of consistency checks over a B-tree and
+ * panics if any inconsistencies are found.
*
* Results:
* None.
*
* Side effects:
- * If a structural defect is found, the procedure panics with an
- * error message.
+ * If a structural defect is found, the function panics with an error
+ * message.
*
*----------------------------------------------------------------------
*/
void
-TkBTreeCheck(tree)
- TkTextBTree tree; /* Tree to check. */
+TkBTreeCheck(
+ TkTextBTree tree) /* Tree to check. */
{
BTree *treePtr = (BTree *) tree;
register Summary *summaryPtr;
@@ -2675,27 +3784,28 @@ TkBTreeCheck(tree)
/*
* Make sure that the tag toggle counts and the tag root pointers are OK.
*/
- for (entryPtr = Tcl_FirstHashEntry(&treePtr->textPtr->tagTable, &search);
+
+ for (entryPtr=Tcl_FirstHashEntry(&treePtr->sharedTextPtr->tagTable,&search);
entryPtr != NULL ; entryPtr = Tcl_NextHashEntry(&search)) {
tagPtr = (TkTextTag *) Tcl_GetHashValue(entryPtr);
nodePtr = tagPtr->tagRootPtr;
- if (nodePtr == (Node *) NULL) {
+ if (nodePtr == NULL) {
if (tagPtr->toggleCount != 0) {
- panic("TkBTreeCheck found \"%s\" with toggles (%d) but no root",
- tagPtr->name, tagPtr->toggleCount);
+ Tcl_Panic("TkBTreeCheck found \"%s\" with toggles (%d) but no root",
+ tagPtr->name, tagPtr->toggleCount);
}
- continue; /* no ranges for the tag */
+ continue; /* No ranges for the tag. */
} else if (tagPtr->toggleCount == 0) {
- panic("TkBTreeCheck found root for \"%s\" with no toggles",
+ Tcl_Panic("TkBTreeCheck found root for \"%s\" with no toggles",
tagPtr->name);
} else if (tagPtr->toggleCount & 1) {
- panic("TkBTreeCheck found odd toggle count for \"%s\" (%d)",
+ Tcl_Panic("TkBTreeCheck found odd toggle count for \"%s\" (%d)",
tagPtr->name, tagPtr->toggleCount);
}
for (summaryPtr = nodePtr->summaryPtr; summaryPtr != NULL;
summaryPtr = summaryPtr->nextPtr) {
if (summaryPtr->tagPtr == tagPtr) {
- panic("TkBTreeCheck found root node with summary info");
+ Tcl_Panic("TkBTreeCheck found root node with summary info");
}
}
count = 0;
@@ -2723,25 +3833,25 @@ TkBTreeCheck(tree)
}
}
if (count != tagPtr->toggleCount) {
- panic("TkBTreeCheck toggleCount (%d) wrong for \"%s\" should be (%d)",
- tagPtr->toggleCount, tagPtr->name, count);
+ Tcl_Panic("TkBTreeCheck toggleCount (%d) wrong for \"%s\" should be (%d)",
+ tagPtr->toggleCount, tagPtr->name, count);
}
}
/*
- * Call a recursive procedure to do the main body of checks.
+ * Call a recursive function to do the main body of checks.
*/
nodePtr = treePtr->rootPtr;
- CheckNodeConsistency(treePtr->rootPtr);
+ CheckNodeConsistency(treePtr->rootPtr, treePtr->pixelReferences);
/*
- * Make sure that there are at least two lines in the text and
- * that the last line has no characters except a newline.
+ * Make sure that there are at least two lines in the text and that the
+ * last line has no characters except a newline.
*/
if (nodePtr->numLines < 2) {
- panic("TkBTreeCheck: less than 2 lines in tree");
+ Tcl_Panic("TkBTreeCheck: less than 2 lines in tree");
}
while (nodePtr->level > 0) {
nodePtr = nodePtr->children.nodePtr;
@@ -2758,25 +3868,24 @@ TkBTreeCheck(tree)
|| (segPtr->typePtr == &tkTextRightMarkType)
|| (segPtr->typePtr == &tkTextLeftMarkType)) {
/*
- * It's OK to toggle a tag off in the last line, but
- * not to start a new range. It's also OK to have marks
- * in the last line.
+ * It's OK to toggle a tag off in the last line, but not to start a
+ * new range. It's also OK to have marks in the last line.
*/
segPtr = segPtr->nextPtr;
}
if (segPtr->typePtr != &tkTextCharType) {
- panic("TkBTreeCheck: last line has bogus segment type");
+ Tcl_Panic("TkBTreeCheck: last line has bogus segment type");
}
if (segPtr->nextPtr != NULL) {
- panic("TkBTreeCheck: last line has too many segments");
+ Tcl_Panic("TkBTreeCheck: last line has too many segments");
}
if (segPtr->size != 1) {
- panic("TkBTreeCheck: last line has wrong # characters: %d",
+ Tcl_Panic("TkBTreeCheck: last line has wrong # characters: %d",
segPtr->size);
}
if ((segPtr->body.chars[0] != '\n') || (segPtr->body.chars[1] != 0)) {
- panic("TkBTreeCheck: last line had bad value: %s",
+ Tcl_Panic("TkBTreeCheck: last line had bad value: %s",
segPtr->body.chars);
}
}
@@ -2786,54 +3895,66 @@ TkBTreeCheck(tree)
*
* CheckNodeConsistency --
*
- * This procedure is called as part of consistency checking for
- * B-trees: it checks several aspects of a node and also runs
- * checks recursively on the node's children.
+ * This function is called as part of consistency checking for B-trees:
+ * it checks several aspects of a node and also runs checks recursively
+ * on the node's children.
*
* Results:
* None.
*
* Side effects:
- * If anything suspicious is found in the tree structure, the
- * procedure panics.
+ * If anything suspicious is found in the tree structure, the function
+ * panics.
*
*----------------------------------------------------------------------
*/
static void
-CheckNodeConsistency(nodePtr)
- register Node *nodePtr; /* Node whose subtree should be
- * checked. */
+CheckNodeConsistency(
+ register Node *nodePtr, /* Node whose subtree should be checked. */
+ int references) /* Number of referring widgets which have
+ * pixel counts. */
{
register Node *childNodePtr;
register Summary *summaryPtr, *summaryPtr2;
register TkTextLine *linePtr;
register TkTextSegment *segPtr;
- int numChildren, numLines, toggleCount, minChildren;
+ int numChildren, numLines, toggleCount, minChildren, i;
+ int *numPixels;
+ int pixels[PIXEL_CLIENTS];
if (nodePtr->parentPtr != NULL) {
minChildren = MIN_CHILDREN;
} else if (nodePtr->level > 0) {
minChildren = 2;
- } else {
+ } else {
minChildren = 1;
}
if ((nodePtr->numChildren < minChildren)
|| (nodePtr->numChildren > MAX_CHILDREN)) {
- panic("CheckNodeConsistency: bad child count (%d)",
+ Tcl_Panic("CheckNodeConsistency: bad child count (%d)",
nodePtr->numChildren);
}
numChildren = 0;
numLines = 0;
+ if (references > PIXEL_CLIENTS) {
+ numPixels = (int *) ckalloc(sizeof(int) * references);
+ } else {
+ numPixels = pixels;
+ }
+ for (i = 0; i<references; i++) {
+ numPixels[i] = 0;
+ }
+
if (nodePtr->level == 0) {
for (linePtr = nodePtr->children.linePtr; linePtr != NULL;
linePtr = linePtr->nextPtr) {
if (linePtr->parentPtr != nodePtr) {
- panic("CheckNodeConsistency: line doesn't point to parent");
+ Tcl_Panic("CheckNodeConsistency: line doesn't point to parent");
}
if (linePtr->segPtr == NULL) {
- panic("CheckNodeConsistency: line has no segments");
+ Tcl_Panic("CheckNodeConsistency: line has no segments");
}
for (segPtr = linePtr->segPtr; segPtr != NULL;
segPtr = segPtr->nextPtr) {
@@ -2844,27 +3965,30 @@ CheckNodeConsistency(nodePtr)
&& (segPtr->nextPtr != NULL)
&& (segPtr->nextPtr->size == 0)
&& (segPtr->nextPtr->typePtr->leftGravity)) {
- panic("CheckNodeConsistency: wrong segment order for gravity");
+ Tcl_Panic("CheckNodeConsistency: wrong segment order for gravity");
}
if ((segPtr->nextPtr == NULL)
&& (segPtr->typePtr != &tkTextCharType)) {
- panic("CheckNodeConsistency: line ended with wrong type");
+ Tcl_Panic("CheckNodeConsistency: line ended with wrong type");
}
}
numChildren++;
numLines++;
+ for (i = 0; i<references; i++) {
+ numPixels[i] += linePtr->pixels[2 * i];
+ }
}
} else {
for (childNodePtr = nodePtr->children.nodePtr; childNodePtr != NULL;
childNodePtr = childNodePtr->nextPtr) {
if (childNodePtr->parentPtr != nodePtr) {
- panic("CheckNodeConsistency: node doesn't point to parent");
+ Tcl_Panic("CheckNodeConsistency: node doesn't point to parent");
}
if (childNodePtr->level != (nodePtr->level-1)) {
- panic("CheckNodeConsistency: level mismatch (%d %d)",
+ Tcl_Panic("CheckNodeConsistency: level mismatch (%d %d)",
nodePtr->level, childNodePtr->level);
}
- CheckNodeConsistency(childNodePtr);
+ CheckNodeConsistency(childNodePtr, references);
for (summaryPtr = childNodePtr->summaryPtr; summaryPtr != NULL;
summaryPtr = summaryPtr->nextPtr) {
for (summaryPtr2 = nodePtr->summaryPtr; ;
@@ -2873,7 +3997,7 @@ CheckNodeConsistency(nodePtr)
if (summaryPtr->tagPtr->tagRootPtr == nodePtr) {
break;
}
- panic("CheckNodeConsistency: node tag \"%s\" not %s",
+ Tcl_Panic("CheckNodeConsistency: node tag \"%s\" not %s",
summaryPtr->tagPtr->name,
"present in parent summaries");
}
@@ -2884,22 +4008,34 @@ CheckNodeConsistency(nodePtr)
}
numChildren++;
numLines += childNodePtr->numLines;
+ for (i = 0; i<references; i++) {
+ numPixels[i] += childNodePtr->numPixels[i];
+ }
}
}
if (numChildren != nodePtr->numChildren) {
- panic("CheckNodeConsistency: mismatch in numChildren (%d %d)",
+ Tcl_Panic("CheckNodeConsistency: mismatch in numChildren (%d %d)",
numChildren, nodePtr->numChildren);
}
if (numLines != nodePtr->numLines) {
- panic("CheckNodeConsistency: mismatch in numLines (%d %d)",
+ Tcl_Panic("CheckNodeConsistency: mismatch in numLines (%d %d)",
numLines, nodePtr->numLines);
}
+ for (i = 0; i<references; i++) {
+ if (numPixels[i] != nodePtr->numPixels[i]) {
+ Tcl_Panic("CheckNodeConsistency: mismatch in numPixels (%d %d) for widget (%d)",
+ numPixels[i], nodePtr->numPixels[i], i);
+ }
+ }
+ if (references > PIXEL_CLIENTS) {
+ ckfree((char *) numPixels);
+ }
for (summaryPtr = nodePtr->summaryPtr; summaryPtr != NULL;
summaryPtr = summaryPtr->nextPtr) {
if (summaryPtr->tagPtr->toggleCount == summaryPtr->toggleCount) {
- panic("CheckNodeConsistency: found unpruned root for \"%s\"",
- summaryPtr->tagPtr->name);
+ Tcl_Panic("CheckNodeConsistency: found unpruned root for \"%s\"",
+ summaryPtr->tagPtr->name);
}
toggleCount = 0;
if (nodePtr->level == 0) {
@@ -2912,7 +4048,7 @@ CheckNodeConsistency(nodePtr)
continue;
}
if (segPtr->body.toggle.tagPtr == summaryPtr->tagPtr) {
- toggleCount ++;
+ toggleCount++;
}
}
}
@@ -2930,13 +4066,13 @@ CheckNodeConsistency(nodePtr)
}
}
if (toggleCount != summaryPtr->toggleCount) {
- panic("CheckNodeConsistency: mismatch in toggleCount (%d %d)",
+ Tcl_Panic("CheckNodeConsistency: mismatch in toggleCount (%d %d)",
toggleCount, summaryPtr->toggleCount);
}
for (summaryPtr2 = summaryPtr->nextPtr; summaryPtr2 != NULL;
summaryPtr2 = summaryPtr2->nextPtr) {
if (summaryPtr2->tagPtr == summaryPtr->tagPtr) {
- panic("CheckNodeConsistency: duplicated node tag: %s",
+ Tcl_Panic("CheckNodeConsistency: duplicated node tag: %s",
summaryPtr->tagPtr->name);
}
}
@@ -2948,9 +4084,9 @@ CheckNodeConsistency(nodePtr)
*
* Rebalance --
*
- * This procedure is called when a node of a B-tree appears to be
- * out of balance (too many children, or too few). It rebalances
- * that node and all of its ancestors in the tree.
+ * This function is called when a node of a B-tree appears to be out of
+ * balance (too many children, or too few). It rebalances that node and
+ * all of its ancestors in the tree.
*
* Results:
* None.
@@ -2962,14 +4098,13 @@ CheckNodeConsistency(nodePtr)
*/
static void
-Rebalance(treePtr, nodePtr)
- BTree *treePtr; /* Tree that is being rebalanced. */
- register Node *nodePtr; /* Node that may be out of balance. */
+Rebalance(
+ BTree *treePtr, /* Tree that is being rebalanced. */
+ register Node *nodePtr) /* Node that may be out of balance. */
{
/*
- * Loop over the entire ancestral chain of the node, working up
- * through the tree one node at a time until the root node has
- * been processed.
+ * Loop over the entire ancestral chain of the node, working up through
+ * the tree one node at a time until the root node has been processed.
*/
for ( ; nodePtr != NULL; nodePtr = nodePtr->parentPtr) {
@@ -2978,19 +4113,19 @@ Rebalance(treePtr, nodePtr)
int i;
/*
- * Check to see if the node has too many children. If it does,
- * then split off all but the first MIN_CHILDREN into a separate
- * node following the original one. Then repeat until the
- * node has a decent size.
+ * Check to see if the node has too many children. If it does, then
+ * split off all but the first MIN_CHILDREN into a separate node
+ * following the original one. Then repeat until the node has a decent
+ * size.
*/
if (nodePtr->numChildren > MAX_CHILDREN) {
while (1) {
/*
- * If the node being split is the root node, then make a
- * new root node above it first.
+ * If the node being split is the root node, then make a new
+ * root node above it first.
*/
-
+
if (nodePtr->parentPtr == NULL) {
newPtr = (Node *) ckalloc(sizeof(Node));
newPtr->parentPtr = NULL;
@@ -3000,10 +4135,20 @@ Rebalance(treePtr, nodePtr)
newPtr->children.nodePtr = nodePtr;
newPtr->numChildren = 1;
newPtr->numLines = nodePtr->numLines;
- RecomputeNodeCounts(newPtr);
+ newPtr->numPixels = (int *)
+ ckalloc(sizeof(int) * treePtr->pixelReferences);
+ for (i=0; i<treePtr->pixelReferences; i++) {
+ newPtr->numPixels[i] = nodePtr->numPixels[i];
+ }
+ RecomputeNodeCounts(treePtr, newPtr);
treePtr->rootPtr = newPtr;
}
newPtr = (Node *) ckalloc(sizeof(Node));
+ newPtr->numPixels = (int *)
+ ckalloc(sizeof(int) * treePtr->pixelReferences);
+ for (i=0; i<treePtr->pixelReferences; i++) {
+ newPtr->numPixels[i] = 0;
+ }
newPtr->parentPtr = nodePtr->parentPtr;
newPtr->nextPtr = nodePtr->nextPtr;
nodePtr->nextPtr = newPtr;
@@ -3027,11 +4172,11 @@ Rebalance(treePtr, nodePtr)
newPtr->children.nodePtr = childPtr->nextPtr;
childPtr->nextPtr = NULL;
}
- RecomputeNodeCounts(nodePtr);
+ RecomputeNodeCounts(treePtr, nodePtr);
nodePtr->parentPtr->numChildren++;
nodePtr = newPtr;
if (nodePtr->numChildren <= MAX_CHILDREN) {
- RecomputeNodeCounts(nodePtr);
+ RecomputeNodeCounts(treePtr, nodePtr);
break;
}
}
@@ -3039,16 +4184,16 @@ Rebalance(treePtr, nodePtr)
while (nodePtr->numChildren < MIN_CHILDREN) {
register Node *otherPtr;
- Node *halfwayNodePtr = NULL; /* Initialization needed only */
- TkTextLine *halfwayLinePtr = NULL; /* to prevent cc warnings. */
+ Node *halfwayNodePtr = NULL; /* Initialization needed only */
+ TkTextLine *halfwayLinePtr = NULL; /* to prevent cc warnings. */
int totalChildren, firstChildren, i;
/*
- * Too few children for this node. If this is the root then,
- * it's OK for it to have less than MIN_CHILDREN children
- * as long as it's got at least two. If it has only one
- * (and isn't at level 0), then chop the root node out of
- * the tree and use its child as the new root.
+ * Too few children for this node. If this is the root then, it's
+ * OK for it to have less than MIN_CHILDREN children as long as
+ * it's got at least two. If it has only one (and isn't at level
+ * 0), then chop the root node out of the tree and use its child
+ * as the new root.
*/
if (nodePtr->parentPtr == NULL) {
@@ -3062,8 +4207,8 @@ Rebalance(treePtr, nodePtr)
}
/*
- * Not the root. Make sure that there are siblings to
- * balance with.
+ * Not the root. Make sure that there are siblings to balance
+ * with.
*/
if (nodePtr->parentPtr->numChildren < 2) {
@@ -3072,8 +4217,8 @@ Rebalance(treePtr, nodePtr)
}
/*
- * Find a sibling neighbor to borrow from, and arrange for
- * nodePtr to be the earlier of the pair.
+ * Find a sibling neighbor to borrow from, and arrange for nodePtr
+ * to be the earlier of the pair.
*/
if (nodePtr->nextPtr == NULL) {
@@ -3087,11 +4232,10 @@ Rebalance(treePtr, nodePtr)
otherPtr = nodePtr->nextPtr;
/*
- * We're going to either merge the two siblings together
- * into one node or redivide the children among them to
- * balance their loads. As preparation, join their two
- * child lists into a single list and remember the half-way
- * point in the list.
+ * We're going to either merge the two siblings together into one
+ * node or redivide the children among them to balance their
+ * loads. As preparation, join their two child lists into a single
+ * list and remember the half-way point in the list.
*/
totalChildren = nodePtr->numChildren + otherPtr->numChildren;
@@ -3142,7 +4286,7 @@ Rebalance(treePtr, nodePtr)
*/
if (totalChildren <= MAX_CHILDREN) {
- RecomputeNodeCounts(nodePtr);
+ RecomputeNodeCounts(treePtr, nodePtr);
nodePtr->nextPtr = otherPtr->nextPtr;
nodePtr->parentPtr->numChildren--;
DeleteSummaries(otherPtr->summaryPtr);
@@ -3151,8 +4295,8 @@ Rebalance(treePtr, nodePtr)
}
/*
- * The siblings can't be merged, so just divide their
- * children evenly between them.
+ * The siblings can't be merged, so just divide their children
+ * evenly between them.
*/
if (nodePtr->level == 0) {
@@ -3162,8 +4306,8 @@ Rebalance(treePtr, nodePtr)
otherPtr->children.nodePtr = halfwayNodePtr->nextPtr;
halfwayNodePtr->nextPtr = NULL;
}
- RecomputeNodeCounts(nodePtr);
- RecomputeNodeCounts(otherPtr);
+ RecomputeNodeCounts(treePtr, nodePtr);
+ RecomputeNodeCounts(treePtr, otherPtr);
}
}
}
@@ -3173,37 +4317,38 @@ Rebalance(treePtr, nodePtr)
*
* RecomputeNodeCounts --
*
- * This procedure is called to recompute all the counts in a node
- * (tags, child information, etc.) by scanning the information in
- * its descendants. This procedure is called during rebalancing
- * when a node's child structure has changed.
+ * This function is called to recompute all the counts in a node (tags,
+ * child information, etc.) by scanning the information in its
+ * descendants. This function is called during rebalancing when a node's
+ * child structure has changed.
*
* Results:
* None.
*
* Side effects:
- * The tag counts for nodePtr are modified to reflect its current
- * child structure, as are its numChildren and numLines fields.
- * Also, all of the childrens' parentPtr fields are made to point
- * to nodePtr.
+ * The tag counts for nodePtr are modified to reflect its current child
+ * structure, as are its numChildren and numLines fields. Also, all of
+ * the childrens' parentPtr fields are made to point to nodePtr.
*
*----------------------------------------------------------------------
*/
static void
-RecomputeNodeCounts(nodePtr)
- register Node *nodePtr; /* Node whose tag summary information
- * must be recomputed. */
+RecomputeNodeCounts(
+ register BTree *treePtr, /* The whole B-tree. */
+ register Node *nodePtr) /* Node whose tag summary information must be
+ * recomputed. */
{
register Summary *summaryPtr, *summaryPtr2;
register Node *childPtr;
register TkTextLine *linePtr;
register TkTextSegment *segPtr;
TkTextTag *tagPtr;
+ int ref;
/*
- * Zero out all the existing counts for the node, but don't delete
- * the existing Summary records (most of them will probably be reused).
+ * Zero out all the existing counts for the node, but don't delete the
+ * existing Summary records (most of them will probably be reused).
*/
for (summaryPtr = nodePtr->summaryPtr; summaryPtr != NULL;
@@ -3212,11 +4357,13 @@ RecomputeNodeCounts(nodePtr)
}
nodePtr->numChildren = 0;
nodePtr->numLines = 0;
+ for (ref = 0; ref<treePtr->pixelReferences; ref++) {
+ nodePtr->numPixels[ref] = 0;
+ }
/*
- * Scan through the children, adding the childrens' tag counts into
- * the node's tag counts and adding new Summary structures if
- * necessary.
+ * Scan through the children, adding the childrens' tag counts into the
+ * node's tag counts and adding new Summary structures if necessary.
*/
if (nodePtr->level == 0) {
@@ -3224,6 +4371,9 @@ RecomputeNodeCounts(nodePtr)
linePtr = linePtr->nextPtr) {
nodePtr->numChildren++;
nodePtr->numLines++;
+ for (ref = 0; ref<treePtr->pixelReferences; ref++) {
+ nodePtr->numPixels[ref] += linePtr->pixels[2 * ref];
+ }
linePtr->parentPtr = nodePtr;
for (segPtr = linePtr->segPtr; segPtr != NULL;
segPtr = segPtr->nextPtr) {
@@ -3255,6 +4405,9 @@ RecomputeNodeCounts(nodePtr)
childPtr = childPtr->nextPtr) {
nodePtr->numChildren++;
nodePtr->numLines += childPtr->numLines;
+ for (ref = 0; ref<treePtr->pixelReferences; ref++) {
+ nodePtr->numPixels[ref] += childPtr->numPixels[ref];
+ }
childPtr->parentPtr = nodePtr;
for (summaryPtr2 = childPtr->summaryPtr; summaryPtr2 != NULL;
summaryPtr2 = summaryPtr2->nextPtr) {
@@ -3280,19 +4433,20 @@ RecomputeNodeCounts(nodePtr)
/*
* Scan through the node's tag records again and delete any Summary
* records that still have a zero count, or that have all the toggles.
- * The node with the children that account for all the tags toggles
- * have no summary information, and they become the tagRootPtr for the tag.
+ * The node with the children that account for all the tags toggles have
+ * no summary information, and they become the tagRootPtr for the tag.
*/
summaryPtr2 = NULL;
for (summaryPtr = nodePtr->summaryPtr; summaryPtr != NULL; ) {
- if (summaryPtr->toggleCount > 0 &&
+ if (summaryPtr->toggleCount > 0 &&
summaryPtr->toggleCount < summaryPtr->tagPtr->toggleCount) {
if (nodePtr->level == summaryPtr->tagPtr->tagRootPtr->level) {
/*
- * The tag's root node split and some toggles left.
- * The tag root must move up a level.
+ * The tag's root node split and some toggles left. The tag
+ * root must move up a level.
*/
+
summaryPtr->tagPtr->tagRootPtr = nodePtr->parentPtr;
}
summaryPtr2 = summaryPtr;
@@ -3301,9 +4455,10 @@ RecomputeNodeCounts(nodePtr)
}
if (summaryPtr->toggleCount == summaryPtr->tagPtr->toggleCount) {
/*
- * A node merge has collected all the toggles under one node.
- * Push the root down to this level.
+ * A node merge has collected all the toggles under one node. Push
+ * the root down to this level.
*/
+
summaryPtr->tagPtr->tagRootPtr = nodePtr;
}
if (summaryPtr2 != NULL) {
@@ -3323,13 +4478,13 @@ RecomputeNodeCounts(nodePtr)
*
* TkBTreeNumLines --
*
- * This procedure returns a count of the number of lines of
- * text present in a given B-tree.
+ * This function returns a count of the number of logical lines of text
+ * present in a given B-tree.
*
* Results:
- * The return value is a count of the number of usable lines
- * in tree (i.e. it doesn't include the dummy line that is just
- * used to mark the end of the tree).
+ * The return value is a count of the number of usable lines in tree
+ * (i.e. it doesn't include the dummy line that is just used to mark the
+ * end of the tree).
*
* Side effects:
* None.
@@ -3338,11 +4493,53 @@ RecomputeNodeCounts(nodePtr)
*/
int
-TkBTreeNumLines(tree)
- TkTextBTree tree; /* Information about tree. */
+TkBTreeNumLines(
+ TkTextBTree tree, /* Information about tree. */
+ const TkText *textPtr) /* Relative to this client of the B-tree. */
{
BTree *treePtr = (BTree *) tree;
- return treePtr->rootPtr->numLines - 1;
+ int count;
+
+ if (textPtr != NULL && textPtr->end != NULL) {
+ count = TkBTreeLinesTo(NULL, textPtr->end);
+ } else {
+ count = treePtr->rootPtr->numLines - 1;
+ }
+ if (textPtr != NULL && textPtr->start != NULL) {
+ count -= TkBTreeLinesTo(NULL, textPtr->start);
+ }
+
+ return count;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkBTreeNumPixels --
+ *
+ * This function returns a count of the number of pixels of text present
+ * in a given widget's B-tree representation.
+ *
+ * Results:
+ * The return value is a count of the number of usable pixels in tree
+ * (since the dummy line used to mark the end of the B-tree is maintained
+ * with zero height, as are any lines that are before or after the
+ * '-start -end' range of the text widget in question, the number stored
+ * at the root is the number we want).
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkBTreeNumPixels(
+ TkTextBTree tree, /* The B-tree. */
+ const TkText *textPtr) /* Relative to this client of the B-tree. */
+{
+ BTree *treePtr = (BTree *) tree;
+ return treePtr->rootPtr->numPixels[textPtr->pixelReference];
}
/*
@@ -3350,12 +4547,11 @@ TkBTreeNumLines(tree)
*
* CharSplitProc --
*
- * This procedure implements splitting for character segments.
+ * This function implements splitting for character segments.
*
* Results:
- * The return value is a pointer to a chain of two segments
- * that have the same characters as segPtr except split
- * among the two segments.
+ * The return value is a pointer to a chain of two segments that have the
+ * same characters as segPtr except split among the two segments.
*
* Side effects:
* Storage for segPtr is freed.
@@ -3364,10 +4560,10 @@ TkBTreeNumLines(tree)
*/
static TkTextSegment *
-CharSplitProc(segPtr, index)
- TkTextSegment *segPtr; /* Pointer to segment to split. */
- int index; /* Position within segment at which
- * to split. */
+CharSplitProc(
+ TkTextSegment *segPtr, /* Pointer to segment to split. */
+ int index) /* Position within segment at which to
+ * split. */
{
TkTextSegment *newPtr1, *newPtr2;
@@ -3384,7 +4580,7 @@ CharSplitProc(segPtr, index)
newPtr2->size = segPtr->size - index;
memcpy(newPtr2->body.chars, segPtr->body.chars + index, newPtr2->size);
newPtr2->body.chars[newPtr2->size] = 0;
- ckfree((char*) segPtr);
+ ckfree((char *) segPtr);
return newPtr1;
}
@@ -3393,12 +4589,12 @@ CharSplitProc(segPtr, index)
*
* CharCleanupProc --
*
- * This procedure merges adjacent character segments into
- * a single character segment, if possible.
+ * This function merges adjacent character segments into a single
+ * character segment, if possible.
*
* Results:
- * The return value is a pointer to the first segment in
- * the (new) list of segments that used to start with segPtr.
+ * The return value is a pointer to the first segment in the (new) list
+ * of segments that used to start with segPtr.
*
* Side effects:
* Storage for the segments may be allocated and freed.
@@ -3408,11 +4604,10 @@ CharSplitProc(segPtr, index)
/* ARGSUSED */
static TkTextSegment *
-CharCleanupProc(segPtr, linePtr)
- TkTextSegment *segPtr; /* Pointer to first of two adjacent
- * segments to join. */
- TkTextLine *linePtr; /* Line containing segments (not
- * used). */
+CharCleanupProc(
+ TkTextSegment *segPtr, /* Pointer to first of two adjacent segments
+ * to join. */
+ TkTextLine *linePtr) /* Line containing segments (not used). */
{
TkTextSegment *segPtr2, *newPtr;
@@ -3428,8 +4623,8 @@ CharCleanupProc(segPtr, linePtr)
memcpy(newPtr->body.chars, segPtr->body.chars, segPtr->size);
memcpy(newPtr->body.chars + segPtr->size, segPtr2->body.chars, segPtr2->size);
newPtr->body.chars[newPtr->size] = 0;
- ckfree((char*) segPtr);
- ckfree((char*) segPtr2);
+ ckfree((char *) segPtr);
+ ckfree((char *) segPtr2);
return newPtr;
}
@@ -3438,7 +4633,7 @@ CharCleanupProc(segPtr, linePtr)
*
* CharDeleteProc --
*
- * This procedure is invoked to delete a character segment.
+ * This function is invoked to delete a character segment.
*
* Results:
* Always returns 0 to indicate that the segment was deleted.
@@ -3451,14 +4646,14 @@ CharCleanupProc(segPtr, linePtr)
/* ARGSUSED */
static int
-CharDeleteProc(segPtr, linePtr, treeGone)
- TkTextSegment *segPtr; /* Segment to delete. */
- TkTextLine *linePtr; /* Line containing segment. */
- int treeGone; /* Non-zero means the entire tree is
- * being deleted, so everything must
- * get cleaned up. */
+CharDeleteProc(
+ TkTextSegment *segPtr, /* Segment to delete. */
+ TkTextLine *linePtr, /* Line containing segment. */
+ int treeGone) /* Non-zero means the entire tree is being
+ * deleted, so everything must get cleaned
+ * up. */
{
- ckfree((char*) segPtr);
+ ckfree((char *) segPtr);
return 0;
}
@@ -3467,47 +4662,43 @@ CharDeleteProc(segPtr, linePtr, treeGone)
*
* CharCheckProc --
*
- * This procedure is invoked to perform consistency checks
- * on character segments.
+ * This function is invoked to perform consistency checks on character
+ * segments.
*
* Results:
* None.
*
* Side effects:
- * If the segment isn't inconsistent then the procedure
- * panics.
+ * If the segment isn't inconsistent then the function panics.
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static void
-CharCheckProc(segPtr, linePtr)
- TkTextSegment *segPtr; /* Segment to check. */
- TkTextLine *linePtr; /* Line containing segment. */
+CharCheckProc(
+ TkTextSegment *segPtr, /* Segment to check. */
+ TkTextLine *linePtr) /* Line containing segment. */
{
/*
- * Make sure that the segment contains the number of
- * characters indicated by its header, and that the last
- * segment in a line ends in a newline. Also make sure
- * that there aren't ever two character segments adjacent
- * to each other: they should be merged together.
+ * Make sure that the segment contains the number of characters indicated
+ * by its header, and that the last segment in a line ends in a newline.
+ * Also make sure that there aren't ever two character segments adjacent
+ * to each other: they should be merged together.
*/
if (segPtr->size <= 0) {
- panic("CharCheckProc: segment has size <= 0");
+ Tcl_Panic("CharCheckProc: segment has size <= 0");
}
if (strlen(segPtr->body.chars) != (size_t) segPtr->size) {
- panic("CharCheckProc: segment has wrong size");
+ Tcl_Panic("CharCheckProc: segment has wrong size");
}
if (segPtr->nextPtr == NULL) {
if (segPtr->body.chars[segPtr->size-1] != '\n') {
- panic("CharCheckProc: line doesn't end with newline");
- }
- } else {
- if (segPtr->nextPtr->typePtr == &tkTextCharType) {
- panic("CharCheckProc: adjacent character segments weren't merged");
+ Tcl_Panic("CharCheckProc: line doesn't end with newline");
}
+ } else if (segPtr->nextPtr->typePtr == &tkTextCharType) {
+ Tcl_Panic("CharCheckProc: adjacent character segments weren't merged");
}
}
@@ -3516,27 +4707,26 @@ CharCheckProc(segPtr, linePtr)
*
* ToggleDeleteProc --
*
- * This procedure is invoked to delete toggle segments.
+ * This function is invoked to delete toggle segments.
*
* Results:
- * Returns 1 to indicate that the segment may not be deleted,
- * unless the entire B-tree is going away.
+ * Returns 1 to indicate that the segment may not be deleted, unless the
+ * entire B-tree is going away.
*
* Side effects:
- * If the tree is going away then the toggle's memory is
- * freed; otherwise the toggle counts in nodes above the
- * segment get updated.
+ * If the tree is going away then the toggle's memory is freed; otherwise
+ * the toggle counts in nodes above the segment get updated.
*
*--------------------------------------------------------------
*/
static int
-ToggleDeleteProc(segPtr, linePtr, treeGone)
- TkTextSegment *segPtr; /* Segment to check. */
- TkTextLine *linePtr; /* Line containing segment. */
- int treeGone; /* Non-zero means the entire tree is
- * being deleted, so everything must
- * get cleaned up. */
+ToggleDeleteProc(
+ TkTextSegment *segPtr, /* Segment to check. */
+ TkTextLine *linePtr, /* Line containing segment. */
+ int treeGone) /* Non-zero means the entire tree is being
+ * deleted, so everything must get cleaned
+ * up. */
{
if (treeGone) {
ckfree((char *) segPtr);
@@ -3544,11 +4734,11 @@ ToggleDeleteProc(segPtr, linePtr, treeGone)
}
/*
- * This toggle is in the middle of a range of characters that's
- * being deleted. Refuse to die. We'll be moved to the end of
- * the deleted range and our cleanup procedure will be called
- * later. Decrement node toggle counts here, and set a flag
- * so we'll re-increment them in the cleanup procedure.
+ * This toggle is in the middle of a range of characters that's being
+ * deleted. Refuse to die. We'll be moved to the end of the deleted range
+ * and our cleanup function will be called later. Decrement node toggle
+ * counts here, and set a flag so we'll re-increment them in the cleanup
+ * function.
*/
if (segPtr->body.toggle.inNodeCounts) {
@@ -3564,37 +4754,36 @@ ToggleDeleteProc(segPtr, linePtr, treeGone)
*
* ToggleCleanupProc --
*
- * This procedure is called when a toggle is part of a line that's
- * been modified in some way. It's invoked after the
- * modifications are complete.
+ * This function is called when a toggle is part of a line that's been
+ * modified in some way. It's invoked after the modifications are
+ * complete.
*
* Results:
- * The return value is the head segment in a new list
- * that is to replace the tail of the line that used to
- * start at segPtr. This allows the procedure to delete
- * or modify segPtr.
+ * The return value is the head segment in a new list that is to replace
+ * the tail of the line that used to start at segPtr. This allows the
+ * function to delete or modify segPtr.
*
* Side effects:
- * Toggle counts in the nodes above the new line will be
- * updated if they're not already. Toggles may be collapsed
- * if there are duplicate toggles at the same position.
+ * Toggle counts in the nodes above the new line will be updated if
+ * they're not already. Toggles may be collapsed if there are duplicate
+ * toggles at the same position.
*
*--------------------------------------------------------------
*/
static TkTextSegment *
-ToggleCleanupProc(segPtr, linePtr)
- TkTextSegment *segPtr; /* Segment to check. */
- TkTextLine *linePtr; /* Line that now contains segment. */
+ToggleCleanupProc(
+ TkTextSegment *segPtr, /* Segment to check. */
+ TkTextLine *linePtr) /* Line that now contains segment. */
{
TkTextSegment *segPtr2, *prevPtr;
int counts;
/*
- * If this is a toggle-off segment, look ahead through the next
- * segments to see if there's a toggle-on segment for the same tag
- * before any segments with non-zero size. If so then the two
- * toggles cancel each other; remove them both.
+ * If this is a toggle-off segment, look ahead through the next segments
+ * to see if there's a toggle-on segment for the same tag before any
+ * segments with non-zero size. If so then the two toggles cancel each
+ * other; remove them both.
*/
if (segPtr->typePtr == &tkTextToggleOffType) {
@@ -3634,8 +4823,8 @@ ToggleCleanupProc(segPtr, linePtr)
*
* ToggleLineChangeProc --
*
- * This procedure is invoked when a toggle segment is about
- * to move from one line to another.
+ * This function is invoked when a toggle segment is about to move from
+ * one line to another.
*
* Results:
* None.
@@ -3647,9 +4836,9 @@ ToggleCleanupProc(segPtr, linePtr)
*/
static void
-ToggleLineChangeProc(segPtr, linePtr)
- TkTextSegment *segPtr; /* Segment to check. */
- TkTextLine *linePtr; /* Line that used to contain segment. */
+ToggleLineChangeProc(
+ TkTextSegment *segPtr, /* Segment to check. */
+ TkTextLine *linePtr) /* Line that used to contain segment. */
{
if (segPtr->body.toggle.inNodeCounts) {
ChangeNodeToggleCount(linePtr->parentPtr,
@@ -3663,45 +4852,45 @@ ToggleLineChangeProc(segPtr, linePtr)
*
* ToggleCheckProc --
*
- * This procedure is invoked to perform consistency checks
- * on toggle segments.
+ * This function is invoked to perform consistency checks on toggle
+ * segments.
*
* Results:
* None.
*
* Side effects:
- * If a consistency problem is found the procedure panics.
+ * If a consistency problem is found the function panics.
*
*--------------------------------------------------------------
*/
static void
-ToggleCheckProc(segPtr, linePtr)
- TkTextSegment *segPtr; /* Segment to check. */
- TkTextLine *linePtr; /* Line containing segment. */
+ToggleCheckProc(
+ TkTextSegment *segPtr, /* Segment to check. */
+ TkTextLine *linePtr) /* Line containing segment. */
{
register Summary *summaryPtr;
int needSummary;
if (segPtr->size != 0) {
- panic("ToggleCheckProc: segment had non-zero size");
+ Tcl_Panic("ToggleCheckProc: segment had non-zero size");
}
if (!segPtr->body.toggle.inNodeCounts) {
- panic("ToggleCheckProc: toggle counts not updated in nodes");
+ Tcl_Panic("ToggleCheckProc: toggle counts not updated in nodes");
}
- needSummary = (segPtr->body.toggle.tagPtr->tagRootPtr != linePtr->parentPtr);
+ needSummary = (segPtr->body.toggle.tagPtr->tagRootPtr!=linePtr->parentPtr);
for (summaryPtr = linePtr->parentPtr->summaryPtr; ;
summaryPtr = summaryPtr->nextPtr) {
if (summaryPtr == NULL) {
if (needSummary) {
- panic("ToggleCheckProc: tag not present in node");
+ Tcl_Panic("ToggleCheckProc: tag not present in node");
} else {
break;
}
}
if (summaryPtr->tagPtr == segPtr->body.toggle.tagPtr) {
if (!needSummary) {
- panic("ToggleCheckProc: tag present in root node summary");
+ Tcl_Panic("ToggleCheckProc: tag present in root node summary");
}
break;
}
@@ -3709,52 +4898,9 @@ ToggleCheckProc(segPtr, linePtr)
}
/*
- *----------------------------------------------------------------------
- *
- * TkBTreeCharsInLine --
- *
- * This procedure returns a count of the number of characters
- * in a given line.
- *
- * Results:
- * The return value is the character count for linePtr.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
*/
-
-int
-TkBTreeCharsInLine(linePtr)
- TkTextLine *linePtr; /* Line whose characters should be
- * counted. */
-{
- TkTextSegment *segPtr;
- int count;
-
- 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 4637b5c..2516e1c 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -1,18 +1,18 @@
-/*
+/*
* tkTextDisp.c --
*
- * This module provides facilities to display text widgets. It is
- * the only place where information is kept about the screen layout
- * of text widgets.
+ * This module provides facilities to display text widgets. It is the
+ * only place where information is kept about the screen layout of text
+ * widgets. (Well, strictly, each TkTextLine and B-tree node caches its
+ * last observed pixel height, but that information originates here).
*
* Copyright (c) 1992-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
#include "tkText.h"
@@ -22,18 +22,102 @@
#include "tkUnixInt.h"
#endif
-#ifdef TK_NO_DOUBLE_BUFFERING
#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
#endif
-#endif /* TK_NO_DOUBLE_BUFFERING */
+
+/*
+ * "Calculations of line pixel heights and the size of the vertical
+ * scrollbar."
+ *
+ * Given that tag, font and elide changes can happen to large numbers of
+ * diverse chunks in a text widget containing megabytes of text, it is not
+ * possible to recalculate all affected height information immediately any
+ * such change takes place and maintain a responsive user-experience. Yet, for
+ * an accurate vertical scrollbar to be drawn, we must know the total number
+ * of vertical pixels shown on display versus the number available to be
+ * displayed.
+ *
+ * The way the text widget solves this problem is by maintaining cached line
+ * pixel heights (in the BTree for each logical line), and having asynchronous
+ * timer callbacks (i) to iterate through the logical lines recalculating
+ * their heights, and (ii) to recalculate the vertical scrollbar's position
+ * and size.
+ *
+ * Typically this works well but there are some situations where the overall
+ * functional design of this file causes some problems. These problems can
+ * only arise because the calculations used to display lines on screen are not
+ * connected to those in the iterating-line- recalculation-process.
+ *
+ * The reason for this disconnect is that the display calculations operate in
+ * display lines, and the iteration and cache operates in logical lines.
+ * Given that the display calculations both need not contain complete logical
+ * lines (at top or bottom of display), and that they do not actually keep
+ * track of logical lines (for simplicity of code and historical design), this
+ * means a line may be known and drawn with a different pixel height to that
+ * which is cached in the BTree, and this might cause some temporary
+ * undesirable mismatch between display and the vertical scrollbar.
+ *
+ * All such mismatches should be temporary, however, since the asynchronous
+ * height calculations will always catch up eventually.
+ *
+ * For further details see the comments before and within the following
+ * functions below: LayoutDLine, AsyncUpdateLineMetrics, GetYView,
+ * GetYPixelCount, TkTextUpdateOneLine, TkTextUpdateLineMetrics.
+ *
+ * For details of the way in which the BTree keeps track of pixel heights, see
+ * tkTextBTree.c. Basically the BTree maintains two pieces of information: the
+ * logical line indices and the pixel height cache.
+ */
+
+/*
+ * TK_LAYOUT_WITH_BASE_CHUNKS:
+ *
+ * With this macro set, collect all char chunks that have no holes
+ * between them, that are on the same line and use the same font and font
+ * size. Allocate the chars of all these chunks, the so-called "stretch",
+ * in a DString in the first chunk, the so-called "base chunk". Use the
+ * base chunk string for measuring and drawing, so that these actions are
+ * always performed with maximum context.
+ *
+ * This is necessary for text rendering engines that provide ligatures
+ * and sub-pixel layout, like ATSU on Mac. If we don't do this, the
+ * measuring will change all the time, leading to an ugly "tremble and
+ * shiver" effect. This is because of the continuous splitting and
+ * re-merging of chunks that goes on in a text widget, when the cursor or
+ * the selection move.
+ *
+ * Side effects:
+ *
+ * Memory management changes. Instead of attaching the character data to
+ * the clientData structures of the char chunks, an additional DString is
+ * used. The collection process will even lead to resizing this DString
+ * for large stretches (> TCL_DSTRING_STATIC_SIZE == 200). We could
+ * reduce the overall memory footprint by copying the result to a plain
+ * char array after the line breaking process, but that would complicate
+ * the code and make performance even worse speedwise. See also TODOs.
+ *
+ * TODOs:
+ *
+ * - Move the character collection process from the LayoutProc into
+ * LayoutDLine(), so that the collection can be done before actual
+ * layout. In this way measuring can look at the following text, too,
+ * right from the beginning. Memory handling can also be improved with
+ * this. Problem: We don't easily know which chunks are adjacent until
+ * all the other chunks have calculated their width. Apparently marks
+ * would return width==0. A separate char collection loop would have to
+ * know these things.
+ *
+ * - Use a new context parameter to pass the context from LayoutDLine() to
+ * the LayoutProc instead of using a global variable like now. Not
+ * pressing until the previous point gets implemented.
+ */
/*
* The following structure describes how to display a range of characters.
- * The information is generated by scanning all of the tags associated
- * with the characters and combining that with default information for
- * the overall widget. These structures form the hash keys for
- * dInfoPtr->styleTable.
+ * The information is generated by scanning all of the tags associated with
+ * the characters and combining that with default information for the overall
+ * widget. These structures form the hash keys for dInfoPtr->styleTable.
*/
typedef struct StyleValues {
@@ -41,13 +125,12 @@ typedef struct StyleValues {
* NULL means use widget background. */
int borderWidth; /* Width of 3-D border for background. */
int relief; /* 3-D relief for background. */
- Pixmap bgStipple; /* Stipple bitmap for background. None
- * means draw solid. */
+ Pixmap bgStipple; /* Stipple bitmap for background. None means
+ * draw solid. */
XColor *fgColor; /* Foreground color for text. */
Tk_Font tkfont; /* Font for displaying text. */
Pixmap fgStipple; /* Stipple bitmap for text and other
- * foreground stuff. None means draw
- * solid.*/
+ * foreground stuff. None means draw solid.*/
int justify; /* Justification style for text. */
int lMargin1; /* Left margin, in pixels, for first display
* line of each text line. */
@@ -61,11 +144,12 @@ typedef struct StyleValues {
int spacing1; /* Spacing above first dline in text line. */
int spacing2; /* Spacing between lines of dline. */
int spacing3; /* Spacing below last dline in text line. */
- TkTextTabArray *tabArrayPtr;/* Locations and types of tab stops (may
- * be NULL). */
+ TkTextTabArray *tabArrayPtr;/* Locations and types of tab stops (may be
+ * NULL). */
+ int tabStyle; /* One of TABULAR or WORDPROCESSOR. */
int underline; /* Non-zero means draw underline underneath
* text. */
- int elide; /* Non-zero means draw text */
+ int elide; /* Zero means draw text, otherwise not. */
TkWrapMode wrapMode; /* How to handle wrap-around for this tag.
* One of TEXT_WRAPMODE_CHAR,
* TEXT_WRAPMODE_NONE or TEXT_WRAPMODE_WORD.*/
@@ -73,128 +157,146 @@ typedef struct StyleValues {
/*
* The following structure extends the StyleValues structure above with
- * graphics contexts used to actually draw the characters. The entries
- * in dInfoPtr->styleTable point to structures of this type.
+ * graphics contexts used to actually draw the characters. The entries in
+ * dInfoPtr->styleTable point to structures of this type.
*/
typedef struct TextStyle {
int refCount; /* Number of times this structure is
* referenced in Chunks. */
- GC bgGC; /* Graphics context for background. None
- * means use widget background. */
+ GC bgGC; /* Graphics context for background. None means
+ * use widget background. */
GC fgGC; /* Graphics context for foreground. */
StyleValues *sValuePtr; /* Raw information from which GCs were
* derived. */
- Tcl_HashEntry *hPtr; /* Pointer to entry in styleTable. Used
- * to delete entry. */
+ Tcl_HashEntry *hPtr; /* Pointer to entry in styleTable. Used to
+ * delete entry. */
} TextStyle;
/*
- * The following macro determines whether two styles have the same
- * background so that, for example, no beveled border should be drawn
- * between them.
+ * The following macro determines whether two styles have the same background
+ * so that, for example, no beveled border should be drawn between them.
*/
#define SAME_BACKGROUND(s1, s2) \
(((s1)->sValuePtr->border == (s2)->sValuePtr->border) \
- && ((s1)->sValuePtr->borderWidth == (s2)->sValuePtr->borderWidth) \
- && ((s1)->sValuePtr->relief == (s2)->sValuePtr->relief) \
- && ((s1)->sValuePtr->bgStipple == (s2)->sValuePtr->bgStipple))
+ && ((s1)->sValuePtr->borderWidth == (s2)->sValuePtr->borderWidth) \
+ && ((s1)->sValuePtr->relief == (s2)->sValuePtr->relief) \
+ && ((s1)->sValuePtr->bgStipple == (s2)->sValuePtr->bgStipple))
/*
- * The following macro is used to compare two floating-point numbers
- * to within a certain degree of scale. Direct comparison fails on
- * processors where the processor and memory representations of FP
- * numbers of a particular precision is different (e.g. Intel)
+ * The following macro is used to compare two floating-point numbers to within
+ * a certain degree of scale. Direct comparison fails on processors where the
+ * processor and memory representations of FP numbers of a particular
+ * precision is different (e.g. Intel)
*/
#define FP_EQUAL_SCALE(double1, double2, scaleFactor) \
(fabs((double1)-(double2))*((scaleFactor)+1.0) < 0.3)
/*
- * The following structure describes one line of the display, which may
- * be either part or all of one line of the text.
+ * Macro to make debugging/testing logging a little easier.
+ */
+
+#define LOG(toVar,what) \
+ Tcl_SetVar2(textPtr->interp, toVar, NULL, (what), \
+ TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT)
+
+/*
+ * The following structure describes one line of the display, which may be
+ * either part or all of one line of the text.
*/
typedef struct DLine {
- TkTextIndex index; /* Identifies first character in text
- * that is displayed on this line. */
+ TkTextIndex index; /* Identifies first character in text that is
+ * displayed on this line. */
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
- * be drawn (topmost pixel of rectangular
- * area occupied by line). */
- int oldY; /* Y-position at which line currently
- * appears on display. -1 means line isn't
- * currently visible on display and must be
- * redrawn. This is used to move lines by
- * scrolling rather than re-drawing. */
+ * display line, including a trailing space or
+ * newline that isn't actually displayed. */
+ int logicalLinesMerged; /* Number of extra logical lines merged into
+ * this one due to elided newlines. */
+ int y; /* Y-position at which line is supposed to be
+ * drawn (topmost pixel of rectangular area
+ * occupied by line). */
+ int oldY; /* Y-position at which line currently appears
+ * on display. This is used to move lines by
+ * scrolling rather than re-drawing. If
+ * 'flags' have the OLD_Y_INVALID bit set,
+ * then we will never examine this field
+ * (which means line isn't currently visible
+ * on display and must be redrawn). */
int height; /* Height of line, in pixels. */
int baseline; /* Offset of text baseline from y, in
* pixels. */
- int spaceAbove; /* How much extra space was added to the
- * top of the line because of spacing
- * options. This is included in height
- * and baseline. */
+ int spaceAbove; /* How much extra space was added to the top
+ * of the line because of spacing options.
+ * This is included in height and baseline. */
int spaceBelow; /* How much extra space was added to the
* bottom of the line because of spacing
- * options. This is included in height. */
+ * options. This is included in height. */
int length; /* Total length of line, in pixels. */
- TkTextDispChunk *chunkPtr; /* Pointer to first chunk in list of all
- * of those that are displayed on this
- * line of the screen. */
- struct DLine *nextPtr; /* Next in list of all display lines for
- * this window. The list is sorted in
- * order from top to bottom. Note: the
- * next DLine doesn't always correspond
- * to the next line of text: (a) can have
- * multiple DLines for one text line, and
- * (b) can have gaps where DLine's have been
- * deleted because they're out of date. */
- int flags; /* Various flag bits: see below for values. */
+ TkTextDispChunk *chunkPtr; /* Pointer to first chunk in list of all of
+ * those that are displayed on this line of
+ * the screen. */
+ struct DLine *nextPtr; /* Next in list of all display lines for this
+ * window. The list is sorted in order from
+ * top to bottom. Note: the next DLine doesn't
+ * always correspond to the next line of text:
+ * (a) can have multiple DLines for one text
+ * line, and (b) can have gaps where DLine's
+ * have been deleted because they're out of
+ * date. */
+ int flags; /* Various flag bits: see below for values. */
} DLine;
/*
* Flag bits for DLine structures:
*
- * HAS_3D_BORDER - Non-zero means that at least one of the
- * chunks in this line has a 3D border, so
- * it potentially interacts with 3D borders
- * in neighboring lines (see
- * DisplayLineBackground).
+ * HAS_3D_BORDER - Non-zero means that at least one of the chunks
+ * in this line has a 3D border, so it
+ * potentially interacts with 3D borders in
+ * neighboring lines (see DisplayLineBackground).
* NEW_LAYOUT - Non-zero means that the line has been
- * re-layed out since the last time the
- * display was updated.
- * TOP_LINE - Non-zero means that this was the top line
+ * re-layed out since the last time the display
+ * was updated.
+ * TOP_LINE - Non-zero means that this was the top line in
* in the window the last time that the window
- * was laid out. This is important because
- * a line may be displayed differently if its
- * at the top or bottom than if it's in the
- * middle (e.g. beveled edges aren't displayed
- * for middle lines if the adjacent line has
- * a similar background).
+ * was laid out. This is important because a line
+ * may be displayed differently if its at the top
+ * or bottom than if it's in the middle
+ * (e.g. beveled edges aren't displayed for
+ * middle lines if the adjacent line has a
+ * similar background).
* BOTTOM_LINE - Non-zero means that this was the bottom line
* in the window the last time that the window
* was laid out.
- * IS_DISABLED - This Dline cannot be edited.
+ * OLD_Y_INVALID - The value of oldY in the structure is not
+ * valid or useful and should not be examined.
+ * 'oldY' is only useful when the DLine is
+ * currently displayed at a different position
+ * and we wish to re-display it via scrolling, so
+ * this means the DLine needs redrawing.
*/
#define HAS_3D_BORDER 1
#define NEW_LAYOUT 2
#define TOP_LINE 4
#define BOTTOM_LINE 8
-#define IS_DISABLED 16
+#define OLD_Y_INVALID 16
/*
* Overall display information for a text widget:
*/
typedef struct TextDInfo {
- Tcl_HashTable styleTable; /* Hash table that maps from StyleValues
- * to TextStyles for this widget. */
- DLine *dLinePtr; /* First in list of all display lines for
- * this widget, in order from top to bottom. */
+ Tcl_HashTable styleTable; /* Hash table that maps from StyleValues to
+ * TextStyles for this widget. */
+ DLine *dLinePtr; /* First in list of all display lines for this
+ * widget, in order from top to bottom. */
+ int topPixelOffset; /* Identifies first pixel in top display line
+ * to display in window. */
+ int newTopPixelOffset; /* Desired first pixel in top display line to
+ * display in window. */
GC copyGC; /* Graphics context for copying from off-
* screen pixmaps onto screen. */
GC scrollGC; /* Graphics context for copying from one place
@@ -209,12 +311,12 @@ typedef struct TextDInfo {
* Leaves space for border, etc. */
int maxX; /* First x-coordinate to right of available
* space for displaying lines. */
- int maxY; /* First y-coordinate below available
- * space for displaying lines. */
+ int maxY; /* First y-coordinate below available space
+ * for displaying lines. */
int topOfEof; /* Top-most pixel (lowest y-value) that has
* been drawn in the appropriate fashion for
* the portion of the window after the last
- * line of the text. This field is used to
+ * line of the text. This field is used to
* figure out when to redraw part or all of
* the eof field. */
@@ -222,34 +324,32 @@ typedef struct TextDInfo {
* Information used for scrolling:
*/
- 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. */
- int curPixelOffset; /* Actual x scroll position, measured as the
+ int newXPixelOffset; /* Desired x scroll position, measured as the
+ * number of pixels off-screen to the left for
+ * a line with no left margin. */
+ int curXPixelOffset; /* Actual x scroll position, measured as the
* number of pixels off-screen to the left. */
int maxLength; /* Length in pixels of longest line that's
* visible in window (length may exceed window
- * size). If there's no wrapping, this will
- * be zero. */
+ * size). If there's no wrapping, this will be
+ * zero. */
double xScrollFirst, xScrollLast;
/* Most recent values reported to horizontal
- * scrollbar; used to eliminate unnecessary
+ * scrollbar; used to eliminate unnecessary
* reports. */
double yScrollFirst, yScrollLast;
/* Most recent values reported to vertical
- * scrollbar; used to eliminate unnecessary
+ * scrollbar; used to eliminate unnecessary
* reports. */
/*
* The following information is used to implement scanning:
*/
- int scanMarkIndex; /* Byte index of character that was at the
- * left edge of the window when the scan
- * started. */
+ int scanMarkXPixel; /* Pixel index of 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
+ int scanTotalYScroll; /* Total scrolling (in screen pixels) that has
* occurred since scanMarkY was set. */
int scanMarkY; /* Y-position of mouse at time scan started. */
@@ -259,47 +359,112 @@ typedef struct TextDInfo {
int dLinesInvalidated; /* This value is set to 1 whenever something
* happens that invalidates information in
- * DLine structures; if a redisplay
- * is in progress, it will see this and
- * abort the redisplay. This is needed
- * because, for example, an embedded window
- * could change its size when it is first
- * displayed, invalidating the DLine that
- * is currently being displayed. If redisplay
- * continues, it will use freed memory and
- * could dump core. */
- int flags; /* Various flag values: see below for
+ * DLine structures; if a redisplay is in
+ * progress, it will see this and abort the
+ * redisplay. This is needed because, for
+ * example, an embedded window could change
+ * its size when it is first displayed,
+ * invalidating the DLine that is currently
+ * being displayed. If redisplay continues, it
+ * will use freed memory and could dump
+ * core. */
+ int flags; /* Various flag values: see below for
* definitions. */
+ /*
+ * Information used to handle the asynchronous updating of the y-scrollbar
+ * and the vertical height calculations:
+ */
+
+ int lineMetricUpdateEpoch; /* Stores a number which is incremented each
+ * time the text widget changes in a
+ * significant way (e.g. resizing or
+ * geometry-influencing tag changes). */
+ int currentMetricUpdateLine;/* Stores a counter which is used to iterate
+ * over the logical lines contained in the
+ * widget and update their geometry
+ * calculations, if they are out of date. */
+ TkTextIndex metricIndex; /* If the current metric update line wraps
+ * into very many display lines, then this is
+ * used to keep track of what index we've got
+ * to so far... */
+ int metricPixelHeight; /* ...and this is for the height calculation
+ * so far...*/
+ int metricEpoch; /* ...and this for the epoch of the partial
+ * calculation so it can be cancelled if
+ * things change once more. This field will be
+ * -1 if there is no long-line calculation in
+ * progress, and take a non-negative value if
+ * there is such a calculation in progress. */
+ int lastMetricUpdateLine; /* When the current update line reaches this
+ * line, we are done and should stop the
+ * asychronous callback mechanism. */
+ Tcl_TimerToken lineUpdateTimer;
+ /* A token pointing to the current line metric
+ * update callback. */
+ Tcl_TimerToken scrollbarTimer;
+ /* A token pointing to the current scrollbar
+ * update callback. */
} TextDInfo;
/*
- * In TkTextDispChunk structures for character segments, the clientData
- * field points to one of the following structures:
+ * In TkTextDispChunk structures for character segments, the clientData field
+ * points to one of the following structures:
*/
+#if !TK_LAYOUT_WITH_BASE_CHUNKS
+
typedef struct CharInfo {
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. */
+ char chars[4]; /* UTF characters to display. Actual size will
+ * be numBytes, not 4. THIS MUST BE THE LAST
+ * FIELD IN THE STRUCTURE. */
+} CharInfo;
+
+#else /* TK_LAYOUT_WITH_BASE_CHUNKS */
+
+typedef struct CharInfo {
+ TkTextDispChunk *baseChunkPtr;
+ int baseOffset; /* Starting offset in base chunk
+ * baseChars. */
+ int numBytes; /* Number of bytes that belong to this
+ * chunk. */
+ const char *chars; /* UTF characters to display. Actually points
+ * into the baseChars of the base chunk. Only
+ * valid after FinalizeBaseChunk(). */
} CharInfo;
/*
+ * The BaseCharInfo is a CharInfo with some additional data added.
+ */
+
+typedef struct BaseCharInfo {
+ CharInfo ci;
+ Tcl_DString baseChars; /* Actual characters for the stretch of text
+ * represented by this base chunk. */
+ int width; /* Width in pixels of the whole string, if
+ * known, else -1. Valid during
+ * LayoutDLine(). */
+} BaseCharInfo;
+
+static TkTextDispChunk *baseCharChunkPtr = NULL;
+
+#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
+
+/*
* Flag values for TextDInfo structures:
*
- * DINFO_OUT_OF_DATE: Non-zero means that the DLine structures
- * for this window are partially or completely
- * out of date and need to be recomputed.
+ * DINFO_OUT_OF_DATE: Non-zero means that the DLine structures for
+ * this window are partially or completely out of
+ * date and need to be recomputed.
* REDRAW_PENDING: Means that a when-idle handler has been
* scheduled to update the display.
* REDRAW_BORDERS: Means window border or pad area has
* potentially been damaged and must be redrawn.
- * REPICK_NEEDED: 1 means that the widget has been modified
- * in a way that could change the current
- * character (a different character might be
- * under the mouse cursor now). Need to
- * recompute the current character before
- * the next redisplay.
+ * REPICK_NEEDED: 1 means that the widget has been modified in a
+ * way that could change the current character (a
+ * different character might be under the mouse
+ * cursor now). Need to recompute the current
+ * character before the next redisplay.
*/
#define DINFO_OUT_OF_DATE 1
@@ -308,92 +473,140 @@ typedef struct CharInfo {
#define REPICK_NEEDED 8
/*
- * The following counters keep statistics about redisplay that can be
- * checked to see how clever this code is at reducing redisplays.
+ * Action values for FreeDLines:
+ *
+ * DLINE_FREE: Free the lines, but no need to unlink them from the
+ * current list of actual display lines.
+ * DLINE_UNLINK: Free and unlink from current display.
+ * DLINE_FREE_TEMP: Free, but don't unlink, and also don't set
+ * 'dLinesInvalidated'.
+ */
+
+#define DLINE_FREE 0
+#define DLINE_UNLINK 1
+#define DLINE_FREE_TEMP 2
+
+/*
+ * The following counters keep statistics about redisplay that can be checked
+ * to see how clever this code is at reducing redisplays.
*/
static int numRedisplays; /* Number of calls to DisplayText. */
static int linesRedrawn; /* Number of calls to DisplayDLine. */
static int numCopies; /* Number of calls to XCopyArea to copy part
* of the screen. */
-
+static int lineHeightsRecalculated;
+ /* Number of line layouts purely for height
+ * calculation purposes.*/
/*
- * Forward declarations for procedures defined later in this file:
+ * Forward declarations for functions defined later in this file:
*/
-static void AdjustForTab _ANSI_ARGS_((TkText *textPtr,
+static void AdjustForTab(TkText *textPtr,
TkTextTabArray *tabArrayPtr, int index,
- TkTextDispChunk *chunkPtr));
-static void CharBboxProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr,
- int index, int y, int lineHeight, int baseline,
- int *xPtr, int *yPtr, int *widthPtr,
- int *heightPtr));
-static void CharDisplayProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr,
- int x, int y, int height, int baseline,
- Display *display, Drawable dst, int screenY));
-static int CharMeasureProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr,
- int x));
-static void CharUndisplayProc _ANSI_ARGS_((TkText *textPtr,
- TkTextDispChunk *chunkPtr));
+ TkTextDispChunk *chunkPtr);
+static void CharBboxProc(TkText *textPtr,
+ TkTextDispChunk *chunkPtr, int index, int y,
+ int lineHeight, int baseline, int *xPtr,
+ int *yPtr, int *widthPtr, int *heightPtr);
+static int CharChunkMeasureChars(TkTextDispChunk *chunkPtr,
+ const char *chars, int charsLen,
+ int start, int end, int startX, int maxX,
+ int flags, int *nextX);
+static void CharDisplayProc(TkText *textPtr,
+ TkTextDispChunk *chunkPtr, int x, int y,
+ int height, int baseline, Display *display,
+ Drawable dst, int screenY);
+static int CharMeasureProc(TkTextDispChunk *chunkPtr, int x);
+static void CharUndisplayProc(TkText *textPtr,
+ TkTextDispChunk *chunkPtr);
+#if TK_LAYOUT_WITH_BASE_CHUNKS
+static void FinalizeBaseChunk(TkTextDispChunk *additionalChunkPtr);
+static void FreeBaseChunk(TkTextDispChunk *baseChunkPtr);
+static int IsSameFGStyle(TextStyle *style1, TextStyle *style2);
+static void RemoveFromBaseChunk(TkTextDispChunk *chunkPtr);
+#endif
+/*
+ * Definitions of elided procs. Compiler can't inline these since we use
+ * pointers to these functions. ElideDisplayProc and ElideUndisplayProc are
+ * special-cased for speed, as potentially many elided DLine chunks if large,
+ * tag toggle-filled elided region.
+ */
+static void ElideBboxProc(TkText *textPtr,
+ TkTextDispChunk *chunkPtr, int index, int y,
+ int lineHeight, int baseline, int *xPtr,
+ int *yPtr, int *widthPtr, int *heightPtr);
+static int ElideMeasureProc(TkTextDispChunk *chunkPtr, int x);
+static void DisplayDLine(TkText *textPtr, DLine *dlPtr,
+ DLine *prevPtr, Pixmap pixmap);
+static void DisplayLineBackground(TkText *textPtr, DLine *dlPtr,
+ DLine *prevPtr, Pixmap pixmap);
+static void DisplayText(ClientData clientData);
+static DLine * FindDLine(DLine *dlPtr, CONST TkTextIndex *indexPtr);
+static void FreeDLines(TkText *textPtr, DLine *firstPtr,
+ DLine *lastPtr, int action);
+static void FreeStyle(TkText *textPtr, TextStyle *stylePtr);
+static TextStyle * GetStyle(TkText *textPtr, CONST TkTextIndex *indexPtr);
+static void GetXView(Tcl_Interp *interp, TkText *textPtr,
+ int report);
+static void GetYView(Tcl_Interp *interp, TkText *textPtr,
+ int report);
+static int GetYPixelCount(TkText *textPtr, DLine *dlPtr);
+static DLine * LayoutDLine(TkText *textPtr,
+ CONST TkTextIndex *indexPtr);
+static int MeasureChars(Tk_Font tkfont, CONST char *source,
+ int maxBytes, int rangeStart, int rangeLength,
+ int startX, int maxX, int flags, int *nextXPtr);
+static void MeasureUp(TkText *textPtr,
+ CONST TkTextIndex *srcPtr, int distance,
+ TkTextIndex *dstPtr, int *overlap);
+static int NextTabStop(Tk_Font tkfont, int x, int tabOrigin);
+static void UpdateDisplayInfo(TkText *textPtr);
+static void YScrollByLines(TkText *textPtr, int offset);
+static void YScrollByPixels(TkText *textPtr, int offset);
+static int SizeOfTab(TkText *textPtr, int tabStyle,
+ TkTextTabArray *tabArrayPtr, int *indexPtr, int x,
+ int maxX);
+static void TextChanged(TkText *textPtr,
+ CONST TkTextIndex *index1Ptr,
+ CONST TkTextIndex *index2Ptr);
+static void TextInvalidateRegion(TkText *textPtr, TkRegion region);
+static void TextRedrawTag(TkText *textPtr,
+ TkTextIndex *index1Ptr, TkTextIndex *index2Ptr,
+ TkTextTag *tagPtr, int withTag);
+static void TextInvalidateLineMetrics(TkText *textPtr,
+ TkTextLine *linePtr, int lineCount, int action);
+static int CalculateDisplayLineHeight(TkText *textPtr,
+ CONST TkTextIndex *indexPtr, int *byteCountPtr,
+ int *mergedLinePtr);
+static void DlineIndexOfX(TkText *textPtr,
+ DLine *dlPtr, int x, TkTextIndex *indexPtr);
+static int DlineXOfIndex(TkText *textPtr,
+ DLine *dlPtr, int byteIndex);
+static int TextGetScrollInfoObj(Tcl_Interp *interp,
+ TkText *textPtr, int objc,
+ Tcl_Obj *CONST objv[], double *dblPtr,
+ int *intPtr);
+static void AsyncUpdateLineMetrics(ClientData clientData);
+static void AsyncUpdateYScrollbar(ClientData clientData);
/*
- Definitions of elided procs.
- Compiler can't inline these since we use pointers to these functions.
- ElideDisplayProc, ElideUndisplayProc special-cased for speed,
- as potentially many elided DLine chunks if large, tag toggle-filled
- elided region.
-*/
-static void ElideBboxProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr,
- int index, int y, int lineHeight, int baseline,
- int *xPtr, int *yPtr, int *widthPtr,
- int *heightPtr));
-static int ElideMeasureProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr,
- int x));
-
-static void DisplayDLine _ANSI_ARGS_((TkText *textPtr,
- DLine *dlPtr, DLine *prevPtr, Pixmap pixmap));
-static void DisplayLineBackground _ANSI_ARGS_((TkText *textPtr,
- DLine *dlPtr, DLine *prevPtr, Pixmap pixmap));
-static void DisplayText _ANSI_ARGS_((ClientData clientData));
-static DLine * FindDLine _ANSI_ARGS_((DLine *dlPtr,
- TkTextIndex *indexPtr));
-static void FreeDLines _ANSI_ARGS_((TkText *textPtr,
- DLine *firstPtr, DLine *lastPtr, int unlink));
-static void FreeStyle _ANSI_ARGS_((TkText *textPtr,
- TextStyle *stylePtr));
-static TextStyle * GetStyle _ANSI_ARGS_((TkText *textPtr,
- TkTextIndex *indexPtr));
-static void GetXView _ANSI_ARGS_((Tcl_Interp *interp,
- TkText *textPtr, int report));
-static void GetYView _ANSI_ARGS_((Tcl_Interp *interp,
- TkText *textPtr, int report));
-static DLine * LayoutDLine _ANSI_ARGS_((TkText *textPtr,
- TkTextIndex *indexPtr));
-static int MeasureChars _ANSI_ARGS_((Tk_Font tkfont,
- CONST char *source, int maxBytes, int startX,
- int maxX, int tabOrigin, int *nextXPtr));
-static void MeasureUp _ANSI_ARGS_((TkText *textPtr,
- TkTextIndex *srcPtr, int distance,
- TkTextIndex *dstPtr));
-static int NextTabStop _ANSI_ARGS_((Tk_Font tkfont, int x,
- int tabOrigin));
-static void UpdateDisplayInfo _ANSI_ARGS_((TkText *textPtr));
-static void ScrollByLines _ANSI_ARGS_((TkText *textPtr,
- int offset));
-static int SizeOfTab _ANSI_ARGS_((TkText *textPtr,
- TkTextTabArray *tabArrayPtr, int index, int x,
- int maxX));
-static void TextInvalidateRegion _ANSI_ARGS_((TkText *textPtr,
- TkRegion region));
+ * Result values returned by TextGetScrollInfoObj:
+ */
+#define TKTEXT_SCROLL_MOVETO 1
+#define TKTEXT_SCROLL_PAGES 2
+#define TKTEXT_SCROLL_UNITS 3
+#define TKTEXT_SCROLL_ERROR 4
+#define TKTEXT_SCROLL_PIXELS 5
/*
*----------------------------------------------------------------------
*
* TkTextCreateDInfo --
*
- * This procedure is called when a new text widget is created.
- * Its job is to set up display-related information for the widget.
+ * This function is called when a new text widget is created. Its job is
+ * to set up display-related information for the widget.
*
* Results:
* None.
@@ -406,8 +619,8 @@ static void TextInvalidateRegion _ANSI_ARGS_((TkText *textPtr,
*/
void
-TkTextCreateDInfo(textPtr)
- TkText *textPtr; /* Overall information for text widget. */
+TkTextCreateDInfo(
+ TkText *textPtr) /* Overall information for text widget. */
{
register TextDInfo *dInfoPtr;
XGCValues gcValues;
@@ -420,19 +633,39 @@ TkTextCreateDInfo(textPtr)
dInfoPtr->scrollGC = Tk_GetGC(textPtr->tkwin, GCGraphicsExposures,
&gcValues);
dInfoPtr->topOfEof = 0;
- dInfoPtr->newByteOffset = 0;
- dInfoPtr->curPixelOffset = 0;
+ dInfoPtr->newXPixelOffset = 0;
+ dInfoPtr->curXPixelOffset = 0;
dInfoPtr->maxLength = 0;
dInfoPtr->xScrollFirst = -1;
dInfoPtr->xScrollLast = -1;
dInfoPtr->yScrollFirst = -1;
dInfoPtr->yScrollLast = -1;
- dInfoPtr->scanMarkIndex = 0;
+ dInfoPtr->scanMarkXPixel = 0;
dInfoPtr->scanMarkX = 0;
- dInfoPtr->scanTotalScroll = 0;
+ dInfoPtr->scanTotalYScroll = 0;
dInfoPtr->scanMarkY = 0;
dInfoPtr->dLinesInvalidated = 0;
dInfoPtr->flags = DINFO_OUT_OF_DATE;
+ dInfoPtr->topPixelOffset = 0;
+ dInfoPtr->newTopPixelOffset = 0;
+ dInfoPtr->currentMetricUpdateLine = -1;
+ dInfoPtr->lastMetricUpdateLine = -1;
+ dInfoPtr->lineMetricUpdateEpoch = 1;
+ dInfoPtr->metricEpoch = -1;
+ dInfoPtr->metricIndex.textPtr = NULL;
+ dInfoPtr->metricIndex.linePtr = NULL;
+
+ /*
+ * Add a refCount for each of the idle call-backs.
+ */
+
+ textPtr->refCount++;
+ dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(0,
+ AsyncUpdateLineMetrics, (ClientData) textPtr);
+ textPtr->refCount++;
+ dInfoPtr->scrollbarTimer = Tcl_CreateTimerHandler(200,
+ AsyncUpdateYScrollbar, (ClientData) textPtr);
+
textPtr->dInfoPtr = dInfoPtr;
}
@@ -441,7 +674,7 @@ TkTextCreateDInfo(textPtr)
*
* TkTextFreeDInfo --
*
- * This procedure is called to free up all of the private display
+ * This function is called to free up all of the private display
* information kept by this file for a text widget.
*
* Results:
@@ -454,19 +687,19 @@ TkTextCreateDInfo(textPtr)
*/
void
-TkTextFreeDInfo(textPtr)
- TkText *textPtr; /* Overall information for text widget. */
+TkTextFreeDInfo(
+ TkText *textPtr) /* Overall information for text widget. */
{
register TextDInfo *dInfoPtr = textPtr->dInfoPtr;
/*
- * Be careful to free up styleTable *after* freeing up all the
- * DLines, so that the hash table is still intact to free up the
- * style-related information from the lines. Once the lines are
- * all free then styleTable will be empty.
+ * Be careful to free up styleTable *after* freeing up all the DLines, so
+ * that the hash table is still intact to free up the style-related
+ * information from the lines. Once the lines are all free then styleTable
+ * will be empty.
*/
- FreeDLines(textPtr, dInfoPtr->dLinePtr, (DLine *) NULL, 1);
+ FreeDLines(textPtr, dInfoPtr->dLinePtr, NULL, DLINE_UNLINK);
Tcl_DeleteHashTable(&dInfoPtr->styleTable);
if (dInfoPtr->copyGC != None) {
Tk_FreeGC(textPtr->display, dInfoPtr->copyGC);
@@ -475,6 +708,16 @@ TkTextFreeDInfo(textPtr)
if (dInfoPtr->flags & REDRAW_PENDING) {
Tcl_CancelIdleCall(DisplayText, (ClientData) textPtr);
}
+ if (dInfoPtr->lineUpdateTimer != NULL) {
+ Tcl_DeleteTimerHandler(dInfoPtr->lineUpdateTimer);
+ textPtr->refCount--;
+ dInfoPtr->lineUpdateTimer = NULL;
+ }
+ if (dInfoPtr->scrollbarTimer != NULL) {
+ Tcl_DeleteTimerHandler(dInfoPtr->scrollbarTimer);
+ textPtr->refCount--;
+ dInfoPtr->scrollbarTimer = NULL;
+ }
ckfree((char *) dInfoPtr);
}
@@ -483,8 +726,8 @@ TkTextFreeDInfo(textPtr)
*
* GetStyle --
*
- * This procedure creates all the information needed to display
- * text at a particular location.
+ * This function creates all the information needed to display text at a
+ * particular location.
*
* Results:
* The return value is a pointer to a TextStyle structure that
@@ -497,47 +740,44 @@ TkTextFreeDInfo(textPtr)
*/
static TextStyle *
-GetStyle(textPtr, indexPtr)
- TkText *textPtr; /* Overall information about text widget. */
- TkTextIndex *indexPtr; /* The character in the text for which
- * display information is wanted. */
+GetStyle(
+ TkText *textPtr, /* Overall information about text widget. */
+ CONST TkTextIndex *indexPtr)/* The character in the text for which display
+ * information is wanted. */
{
TkTextTag **tagPtrs;
register TkTextTag *tagPtr;
StyleValues styleValues;
TextStyle *stylePtr;
Tcl_HashEntry *hPtr;
- int numTags, new, i;
+ int numTags, isNew, i;
XGCValues gcValues;
unsigned long mask;
-
/*
* The variables below keep track of the highest-priority specification
* that has occurred for each of the various fields of the StyleValues.
*/
-
int borderPrio, borderWidthPrio, reliefPrio, bgStipplePrio;
int fgPrio, fontPrio, fgStipplePrio;
int underlinePrio, elidePrio, justifyPrio, offsetPrio;
int lMargin1Prio, lMargin2Prio, rMarginPrio;
int spacing1Prio, spacing2Prio, spacing3Prio;
- int overstrikePrio, tabPrio, wrapPrio;
+ int overstrikePrio, tabPrio, tabStylePrio, wrapPrio;
/*
- * Find out what tags are present for the character, then compute
- * a StyleValues structure corresponding to those tags (scan
- * through all of the tags, saving information for the highest-
- * priority tag).
+ * Find out what tags are present for the character, then compute a
+ * StyleValues structure corresponding to those tags (scan through all of
+ * the tags, saving information for the highest-priority tag).
*/
- tagPtrs = TkBTreeGetTags(indexPtr, &numTags);
+ tagPtrs = TkBTreeGetTags(indexPtr, textPtr, &numTags);
borderPrio = borderWidthPrio = reliefPrio = bgStipplePrio = -1;
fgPrio = fontPrio = fgStipplePrio = -1;
underlinePrio = elidePrio = justifyPrio = offsetPrio = -1;
lMargin1Prio = lMargin2Prio = rMarginPrio = -1;
spacing1Prio = spacing2Prio = spacing3Prio = -1;
- overstrikePrio = tabPrio = wrapPrio = -1;
- memset((VOID *) &styleValues, 0, sizeof(StyleValues));
+ overstrikePrio = tabPrio = tabStylePrio = wrapPrio = -1;
+ memset(&styleValues, 0, sizeof(StyleValues));
styleValues.relief = TK_RELIEF_FLAT;
styleValues.fgColor = textPtr->fgColor;
styleValues.tkfont = textPtr->tkfont;
@@ -546,33 +786,40 @@ GetStyle(textPtr, indexPtr)
styleValues.spacing2 = textPtr->spacing2;
styleValues.spacing3 = textPtr->spacing3;
styleValues.tabArrayPtr = textPtr->tabArrayPtr;
+ styleValues.tabStyle = textPtr->tabStyle;
styleValues.wrapMode = textPtr->wrapMode;
styleValues.elide = 0;
+
for (i = 0 ; i < numTags; i++) {
+ Tk_3DBorder border;
+
tagPtr = tagPtrs[i];
+ border = tagPtr->border;
/*
- * Skip the selection tag if we don't have focus,
- * unless we always want to show the selection.
+ * If this is the selection tag, and inactiveSelBorder is NULL (the
+ * default on Windows), then we need to skip it if we don't have the
+ * focus.
*/
- if (
-#ifndef MAC_OSX_TK
- !TkpAlwaysShowSelection(textPtr->tkwin)
-#else
- /* Don't show inactive selection in disabled widgets. */
- textPtr->state == TK_STATE_DISABLED
+ if ((tagPtr == textPtr->selTagPtr) && !(textPtr->flags & GOT_FOCUS)) {
+ if (textPtr->inactiveSelBorder == NULL
+#ifdef MAC_OSX_TK
+ /* Don't show inactive selection in disabled widgets. */
+ || textPtr->state == TK_TEXT_STATE_DISABLED
#endif
- && (tagPtr == textPtr->selTagPtr)
- && !(textPtr->flags & GOT_FOCUS)) {
- continue;
+ ) {
+ continue;
+ }
+ border = textPtr->inactiveSelBorder;
}
- if ((tagPtr->border != NULL) && (tagPtr->priority > borderPrio)) {
- styleValues.border = tagPtr->border;
+ if ((border != NULL) && (tagPtr->priority > borderPrio)) {
+ styleValues.border = border;
borderPrio = tagPtr->priority;
}
- if ((tagPtr->bdString != NULL)
+ if ((tagPtr->borderWidthPtr != NULL)
+ && (Tcl_GetString(tagPtr->borderWidthPtr)[0] != '\0')
&& (tagPtr->priority > borderWidthPrio)) {
styleValues.borderWidth = tagPtr->borderWidth;
borderWidthPrio = tagPtr->priority;
@@ -648,11 +895,16 @@ GetStyle(textPtr, indexPtr)
styleValues.spacing3 = tagPtr->spacing3;
spacing3Prio = tagPtr->priority;
}
- if ((tagPtr->tabString != NULL)
+ if ((tagPtr->tabStringPtr != NULL)
&& (tagPtr->priority > tabPrio)) {
styleValues.tabArrayPtr = tagPtr->tabArrayPtr;
tabPrio = tagPtr->priority;
}
+ if ((tagPtr->tabStyle != TK_TEXT_TABSTYLE_NONE)
+ && (tagPtr->priority > tabStylePrio)) {
+ styleValues.tabStyle = tagPtr->tabStyle;
+ tabStylePrio = tagPtr->priority;
+ }
if ((tagPtr->underlineString != NULL)
&& (tagPtr->priority > underlinePrio)) {
styleValues.underline = tagPtr->underline;
@@ -678,15 +930,15 @@ GetStyle(textPtr, indexPtr)
*/
hPtr = Tcl_CreateHashEntry(&textPtr->dInfoPtr->styleTable,
- (char *) &styleValues, &new);
- if (!new) {
+ (char *) &styleValues, &isNew);
+ if (!isNew) {
stylePtr = (TextStyle *) Tcl_GetHashValue(hPtr);
stylePtr->refCount++;
return stylePtr;
}
/*
- * No existing style matched. Make a new one.
+ * No existing style matched. Make a new one.
*/
stylePtr = (TextStyle *) ckalloc(sizeof(TextStyle));
@@ -725,25 +977,25 @@ GetStyle(textPtr, indexPtr)
*
* FreeStyle --
*
- * This procedure is called when a TextStyle structure is no longer
- * needed. It decrements the reference count and frees up the
- * space for the style structure if the reference count is 0.
+ * This function is called when a TextStyle structure is no longer
+ * needed. It decrements the reference count and frees up the space for
+ * the style structure if the reference count is 0.
*
* Results:
* None.
*
* Side effects:
- * The storage and other resources associated with the style
- * are freed up if no-one's still using it.
+ * The storage and other resources associated with the style are freed up
+ * if no-one's still using it.
*
*----------------------------------------------------------------------
*/
static void
-FreeStyle(textPtr, stylePtr)
- TkText *textPtr; /* Information about overall widget. */
- register TextStyle *stylePtr; /* Information about style to free. */
-
+FreeStyle(
+ TkText *textPtr, /* Information about overall widget. */
+ register TextStyle *stylePtr)
+ /* Information about style to free. */
{
stylePtr->refCount--;
if (stylePtr->refCount == 0) {
@@ -763,70 +1015,91 @@ FreeStyle(textPtr, stylePtr)
*
* LayoutDLine --
*
- * This procedure generates a single DLine structure for a display
- * line whose leftmost character is given by indexPtr.
- *
+ * This function generates a single DLine structure for a display line
+ * whose leftmost character is given by indexPtr.
+ *
* Results:
* The return value is a pointer to a DLine structure desribing the
- * display line. All fields are filled in and correct except for
- * y and nextPtr.
+ * display line. All fields are filled in and correct except for y and
+ * nextPtr.
*
* Side effects:
* Storage is allocated for the new DLine.
*
+ * See the comments in 'GetYView' for some thoughts on what the side-
+ * effects of this call (or its callers) should be; the synchronisation
+ * of TkTextLine->pixelHeight with the sum of the results of this
+ * function operating on all display lines within each logical line.
+ * Ideally the code should be refactored to ensure the cached pixel
+ * height is never behind what is known when this function is called
+ * elsewhere.
+ *
+ * Unfortunately, this function is currently called from many different
+ * places, not just to layout a display line for actual display, but also
+ * simply to calculate some metric or other of one or more display lines
+ * (typically the height). It would be a good idea to do some profiling
+ * of typical text widget usage and the way in which this is called and
+ * see if some optimization could or should be done.
+ *
*----------------------------------------------------------------------
*/
static DLine *
-LayoutDLine(textPtr, indexPtr)
- TkText *textPtr; /* Overall information about text widget. */
- TkTextIndex *indexPtr; /* Beginning of display line. May not
- * necessarily point to a character segment. */
+LayoutDLine(
+ TkText *textPtr, /* Overall information about text widget. */
+ CONST TkTextIndex *indexPtr)/* Beginning of display line. May not
+ * necessarily point to a character
+ * segment. */
{
- register DLine *dlPtr; /* New display line. */
- TkTextSegment *segPtr; /* Current segment in text. */
- TkTextDispChunk *lastChunkPtr; /* Last chunk allocated so far
- * for line. */
- TkTextDispChunk *chunkPtr; /* Current chunk. */
+ register DLine *dlPtr; /* New display line. */
+ TkTextSegment *segPtr; /* Current segment in text. */
+ TkTextDispChunk *lastChunkPtr;
+ /* Last chunk allocated so far for line. */
+ TkTextDispChunk *chunkPtr; /* Current chunk. */
TkTextIndex curIndex;
- TkTextDispChunk *breakChunkPtr; /* Chunk containing best word break
- * point, if any. */
- TkTextIndex breakIndex; /* Index of first character in
- * breakChunkPtr. */
- 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 the first character in
- * line. */
- int jIndent; /* Additional indentation (beyond
- * margins) due to justification. */
- int rMargin; /* Right margin width for line. */
- TkWrapMode wrapMode; /* Wrap mode to use for this line. */
- int x = 0, maxX = 0; /* Initializations needed only to
- * stop compiler warnings. */
- int wholeLine; /* Non-zero means this display line
- * runs to the end of the text line. */
- int tabIndex; /* Index of the current tab stop. */
- int gotTab; /* Non-zero means the current chunk
- * contains a tab. */
- TkTextDispChunk *tabChunkPtr; /* Pointer to the chunk containing
- * the previous tab stop. */
- int maxBytes; /* Maximum number of bytes to
- * include in this chunk. */
- 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 numBytes > 0. Used to
- * drop 0-sized chunks from the end
- * of the line. */
+ TkTextDispChunk *breakChunkPtr;
+ /* Chunk containing best word break point, if
+ * any. */
+ TkTextIndex breakIndex; /* Index of first character in
+ * breakChunkPtr. */
+ 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 paragraphStart; /* Non-zero means that we are on the first
+ * line of a paragraph (used to choose between
+ * lmargin1, lmargin2). */
+ int justify; /* How to justify line: taken from style for
+ * the first character in line. */
+ int jIndent; /* Additional indentation (beyond margins) due
+ * to justification. */
+ int rMargin; /* Right margin width for line. */
+ TkWrapMode wrapMode; /* Wrap mode to use for this line. */
+ int x = 0, maxX = 0; /* Initializations needed only to stop
+ * compiler warnings. */
+ int wholeLine; /* Non-zero means this display line runs to
+ * the end of the text line. */
+ int tabIndex; /* Index of the current tab stop. */
+ int gotTab; /* Non-zero means the current chunk contains a
+ * tab. */
+ TkTextDispChunk *tabChunkPtr;
+ /* Pointer to the chunk containing the
+ * previous tab stop. */
+ int maxBytes; /* Maximum number of bytes to include in this
+ * chunk. */
+ TkTextTabArray *tabArrayPtr;/* Tab stops for line; taken from style for
+ * the first character on line. */
+ int tabStyle; /* One of TABULAR or WORDPROCESSOR. */
+ int tabSize; /* Number of pixels consumed by current tab
+ * stop. */
+ TkTextDispChunk *lastCharChunkPtr;
+ /* Pointer to last chunk in display lines with
+ * numBytes > 0. Used to drop 0-sized chunks
+ * from the end of the line. */
int byteOffset, ascent, descent, code, elide, elidesize;
StyleValues *sValuePtr;
+ TkTextElideInfo info; /* Keep track of elide state. */
/*
* Create and initialize a new DLine structure.
@@ -836,33 +1109,91 @@ LayoutDLine(textPtr, indexPtr)
dlPtr->index = *indexPtr;
dlPtr->byteCount = 0;
dlPtr->y = 0;
- dlPtr->oldY = -1;
+ dlPtr->oldY = 0; /* Only set to avoid compiler warnings. */
dlPtr->height = 0;
dlPtr->baseline = 0;
dlPtr->chunkPtr = NULL;
dlPtr->nextPtr = NULL;
- dlPtr->flags = NEW_LAYOUT;
+ dlPtr->flags = NEW_LAYOUT | OLD_Y_INVALID;
+ dlPtr->logicalLinesMerged = 0;
/*
- * Special case entirely elide line as there may be 1000s or more
+ * This is not necessarily totally correct, where we have merged logical
+ * lines. Fixing this would require a quite significant overhaul, though,
+ * so currently we make do with this.
*/
- elide = TkTextIsElided(textPtr, indexPtr); /* save a malloc */
- if (elide && indexPtr->byteIndex==0) {
+
+ paragraphStart = (indexPtr->byteIndex == 0);
+
+ /*
+ * Special case entirely elide line as there may be 1000s or more.
+ */
+
+ elide = TkTextIsElided(textPtr, indexPtr, &info);
+ if (elide && indexPtr->byteIndex == 0) {
maxBytes = 0;
- for (segPtr = indexPtr->linePtr->segPtr;
- elide && (segPtr != NULL);
- segPtr = segPtr->nextPtr) {
- if ((elidesize = segPtr->size) > 0) {
- maxBytes += elidesize;
+ for (segPtr = info.segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) {
+ if (segPtr->size > 0) {
+ if (elide == 0) {
+ /*
+ * We toggled a tag and the elide state changed to
+ * visible, and we have something of non-zero size.
+ * Therefore we must bail out.
+ */
+
+ break;
+ }
+ maxBytes += segPtr->size;
+
/*
- * If have we have a tag toggle, there is a chance
- * that invisibility state changed, so bail out
+ * Reset tag elide priority, since we're on a new character.
*/
+
} else if ((segPtr->typePtr == &tkTextToggleOffType)
|| (segPtr->typePtr == &tkTextToggleOnType)) {
- if (segPtr->body.toggle.tagPtr->elideString != NULL) {
- elide = (segPtr->typePtr == &tkTextToggleOffType)
- ^ segPtr->body.toggle.tagPtr->elide;
+ TkTextTag *tagPtr = segPtr->body.toggle.tagPtr;
+
+ /*
+ * The elide state only changes if this tag is either the
+ * current highest priority tag (and is therefore being
+ * toggled off), or it's a new tag with higher priority.
+ */
+
+ if (tagPtr->elideString != NULL) {
+ info.tagCnts[tagPtr->priority]++;
+ if (info.tagCnts[tagPtr->priority] & 1) {
+ info.tagPtrs[tagPtr->priority] = tagPtr;
+ }
+ if (tagPtr->priority >= info.elidePriority) {
+ if (segPtr->typePtr == &tkTextToggleOffType) {
+ /*
+ * If it is being toggled off, and it has an elide
+ * string, it must actually be the current highest
+ * priority tag, so this check is redundant:
+ */
+
+ if (tagPtr->priority != info.elidePriority) {
+ Tcl_Panic("Bad tag priority being toggled off");
+ }
+
+ /*
+ * Find previous elide tag, if any (if not then
+ * elide will be zero, of course).
+ */
+
+ elide = 0;
+ while (--info.elidePriority > 0) {
+ if (info.tagCnts[info.elidePriority] & 1) {
+ elide = info.tagPtrs[info.elidePriority]
+ ->elide;
+ break;
+ }
+ }
+ } else {
+ elide = tagPtr->elide;
+ info.elidePriority = tagPtr->priority;
+ }
+ }
}
}
}
@@ -870,15 +1201,31 @@ LayoutDLine(textPtr, indexPtr)
if (elide) {
dlPtr->byteCount = maxBytes;
dlPtr->spaceAbove = dlPtr->spaceBelow = dlPtr->length = 0;
+ if (dlPtr->index.byteIndex == 0) {
+ /*
+ * Elided state goes from beginning to end of an entire
+ * logical line. This means we can update the line's pixel
+ * height, and bring its pixel calculation up to date.
+ */
+
+ TkBTreeLinePixelEpoch(textPtr, dlPtr->index.linePtr)
+ = textPtr->dInfoPtr->lineMetricUpdateEpoch;
+
+ if (TkBTreeLinePixelCount(textPtr,dlPtr->index.linePtr) != 0) {
+ TkBTreeAdjustPixelHeight(textPtr,
+ dlPtr->index.linePtr, 0, 0);
+ }
+ }
+ TkTextFreeElideInfo(&info);
return dlPtr;
}
}
+ TkTextFreeElideInfo(&info);
/*
- * Each iteration of the loop below creates one TkTextDispChunk for
- * the new display line. The line will always have at least one
- * chunk (for the newline character at the end, if there's nothing
- * else available).
+ * Each iteration of the loop below creates one TkTextDispChunk for the
+ * new display line. The line will always have at least one chunk (for the
+ * newline character at the end, if there's nothing else available).
*/
curIndex = *indexPtr;
@@ -892,53 +1239,108 @@ LayoutDLine(textPtr, indexPtr)
tabIndex = -1;
tabChunkPtr = NULL;
tabArrayPtr = NULL;
+ tabStyle = TK_TEXT_TABSTYLE_TABULAR;
rMargin = 0;
wrapMode = TEXT_WRAPMODE_CHAR;
tabSize = 0;
lastCharChunkPtr = NULL;
/*
- * Find the first segment to consider for the line. Can't call
- * TkTextIndexToSeg for this because it won't return a segment
- * with zero size (such as the insertion cursor's mark).
+ * Find the first segment to consider for the line. Can't call
+ * TkTextIndexToSeg for this because it won't return a segment with zero
+ * size (such as the insertion cursor's mark).
*/
- for (byteOffset = curIndex.byteIndex, segPtr = curIndex.linePtr->segPtr;
- (byteOffset > 0) && (byteOffset >= segPtr->size);
- byteOffset -= segPtr->size, segPtr = segPtr->nextPtr) {
- /* Empty loop body. */
+ connectNextLogicalLine:
+ byteOffset = curIndex.byteIndex;
+ segPtr = curIndex.linePtr->segPtr;
+ while ((byteOffset > 0) && (byteOffset >= segPtr->size)) {
+ byteOffset -= segPtr->size;
+ segPtr = segPtr->nextPtr;
+
+ if (segPtr == NULL) {
+ /*
+ * Two logical lines merged into one display line through eliding
+ * of a newline.
+ */
+
+ TkTextLine *linePtr = TkBTreeNextLine(NULL, curIndex.linePtr);
+ if (linePtr != NULL) {
+ dlPtr->logicalLinesMerged++;
+ curIndex.byteIndex = 0;
+ curIndex.linePtr = linePtr;
+ segPtr = curIndex.linePtr->segPtr;
+ } else {
+ break;
+ }
+ }
}
while (segPtr != NULL) {
/*
- * Every line still gets at least one chunk due to expectations
- * in the rest of the code, but we are able to skip elided portions
- * of the line quickly.
- * If current chunk is elided and last chunk was too, coalese
+ * Every logical line still gets at least one chunk due to
+ * expectations in the rest of the code, but we are able to skip
+ * elided portions of the line quickly.
+ *
+ * If current chunk is elided and last chunk was too, coalese.
+ *
+ * This also means that each logical line which is entirely elided
+ * still gets laid out into a DLine, but with zero height. This isn't
+ * particularly a problem, but it does seem somewhat unnecessary. We
+ * may wish to redesign the code to remove these zero height DLines in
+ * the future.
*/
+
if (elide && (lastChunkPtr != NULL)
&& (lastChunkPtr->displayProc == NULL /*ElideDisplayProc*/)) {
- if ((elidesize = segPtr->size - byteOffset) > 0) {
+ elidesize = segPtr->size - byteOffset;
+ if (elidesize > 0) {
curIndex.byteIndex += elidesize;
lastChunkPtr->numBytes += elidesize;
- breakByteOffset = lastChunkPtr->breakIndex = lastChunkPtr->numBytes;
+ breakByteOffset = lastChunkPtr->breakIndex
+ = lastChunkPtr->numBytes;
+
/*
- * If have we have a tag toggle, there is a chance
- * that invisibility state changed, so bail out
+ * If have we have a tag toggle, there is a chance that
+ * invisibility state changed, so bail out.
*/
} else if ((segPtr->typePtr == &tkTextToggleOffType)
|| (segPtr->typePtr == &tkTextToggleOnType)) {
if (segPtr->body.toggle.tagPtr->elideString != NULL) {
elide = (segPtr->typePtr == &tkTextToggleOffType)
- ^ segPtr->body.toggle.tagPtr->elide;
+ ^ segPtr->body.toggle.tagPtr->elide;
}
}
byteOffset = 0;
segPtr = segPtr->nextPtr;
+
+ if (segPtr == NULL) {
+ /*
+ * Two logical lines merged into one display line through
+ * eliding of a newline.
+ */
+
+ TkTextLine *linePtr = TkBTreeNextLine(NULL, curIndex.linePtr);
+
+ if (linePtr != NULL) {
+ dlPtr->logicalLinesMerged++;
+ curIndex.byteIndex = 0;
+ curIndex.linePtr = linePtr;
+ goto connectNextLogicalLine;
+ }
+ }
+
+ /*
+ * Code no longer needed, now that we allow logical lines to merge
+ * into a single display line.
+ *
if (segPtr == NULL && chunkPtr != NULL) {
ckfree((char *) chunkPtr);
+ chunkPtr = NULL;
}
+ */
+
continue;
}
@@ -950,24 +1352,44 @@ LayoutDLine(textPtr, indexPtr)
if (chunkPtr == NULL) {
chunkPtr = (TkTextDispChunk *) ckalloc(sizeof(TkTextDispChunk));
chunkPtr->nextPtr = NULL;
+ chunkPtr->clientData = NULL;
}
chunkPtr->stylePtr = GetStyle(textPtr, &curIndex);
elide = chunkPtr->stylePtr->sValuePtr->elide;
/*
- * Save style information such as justification and indentation,
- * up until the first character is encountered, then retain that
+ * Save style information such as justification and indentation, up
+ * until the first character is encountered, then retain that
* information for the rest of the line.
*/
- if (noCharsYet) {
+ if (!elide && noCharsYet) {
tabArrayPtr = chunkPtr->stylePtr->sValuePtr->tabArrayPtr;
+ tabStyle = chunkPtr->stylePtr->sValuePtr->tabStyle;
justify = chunkPtr->stylePtr->sValuePtr->justify;
rMargin = chunkPtr->stylePtr->sValuePtr->rMargin;
wrapMode = chunkPtr->stylePtr->sValuePtr->wrapMode;
- x = ((curIndex.byteIndex == 0)
- ? chunkPtr->stylePtr->sValuePtr->lMargin1
- : chunkPtr->stylePtr->sValuePtr->lMargin2);
+
+ /*
+ * See above - this test may not be entirely correct where we have
+ * partially elided lines (and therefore merged logical lines).
+ * In such a case a byteIndex of zero doesn't necessarily mean the
+ * beginning of a logical line.
+ */
+
+ if (paragraphStart) {
+ /*
+ * Beginning of logical line.
+ */
+
+ x = chunkPtr->stylePtr->sValuePtr->lMargin1;
+ } else {
+ /*
+ * Beginning of display line.
+ */
+
+ x = chunkPtr->stylePtr->sValuePtr->lMargin2;
+ }
if (wrapMode == TEXT_WRAPMODE_NONE) {
maxX = -1;
} else {
@@ -979,18 +1401,19 @@ LayoutDLine(textPtr, indexPtr)
}
}
- /*
- * See if there is a tab in the current chunk; if so, only
- * layout characters up to (and including) the tab.
- */
-
gotTab = 0;
maxBytes = segPtr->size - byteOffset;
- if (!elide && justify == TK_JUSTIFY_LEFT) {
- if (segPtr->typePtr == &tkTextCharType) {
+ if (segPtr->typePtr == &tkTextCharType) {
+
+ /*
+ * See if there is a tab in the current chunk; if so, only layout
+ * characters up to (and including) the tab.
+ */
+
+ if (!elide && justify == TK_JUSTIFY_LEFT) {
char *p;
- for (p = segPtr->body.chars + byteOffset; *p != 0; p++) {
+ for (p = segPtr->body.chars + byteOffset; *p != 0; p++) {
if (*p == '\t') {
maxBytes = (p + 1 - segPtr->body.chars) - byteOffset;
gotTab = 1;
@@ -998,25 +1421,48 @@ LayoutDLine(textPtr, indexPtr)
}
}
}
+
+#if TK_LAYOUT_WITH_BASE_CHUNKS
+ if (baseCharChunkPtr != NULL) {
+ int expectedX =
+ ((BaseCharInfo *) baseCharChunkPtr->clientData)->width
+ + baseCharChunkPtr->x;
+
+ if ((expectedX != x) || !IsSameFGStyle(
+ baseCharChunkPtr->stylePtr, chunkPtr->stylePtr)) {
+ FinalizeBaseChunk(NULL);
+ }
+ }
+#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
}
chunkPtr->x = x;
- if (elide && maxBytes) {
- /* don't free style here, as other code expects to be able to do that */
- /*breakByteOffset =*/ chunkPtr->breakIndex = chunkPtr->numBytes = maxBytes;
+ if (elide /*&& maxBytes*/) {
+ /*
+ * Don't free style here, as other code expects to be able to do
+ * that.
+ */
+
+ /* breakByteOffset =*/
+ chunkPtr->breakIndex = chunkPtr->numBytes = maxBytes;
chunkPtr->width = 0;
- chunkPtr->minAscent = chunkPtr->minDescent = chunkPtr->minHeight = 0;
+ chunkPtr->minAscent = chunkPtr->minDescent
+ = chunkPtr->minHeight = 0;
- /* would just like to point to canonical empty chunk */
- chunkPtr->displayProc = (Tk_ChunkDisplayProc *) NULL;
- chunkPtr->undisplayProc = (Tk_ChunkUndisplayProc *) NULL;
+ /*
+ * Would just like to point to canonical empty chunk.
+ */
+
+ chunkPtr->displayProc = NULL;
+ chunkPtr->undisplayProc = NULL;
chunkPtr->measureProc = ElideMeasureProc;
chunkPtr->bboxProc = ElideBboxProc;
code = 1;
- } else
- code = (*segPtr->typePtr->layoutProc)(textPtr, &curIndex, segPtr,
- byteOffset, maxX-tabSize, maxBytes, noCharsYet, wrapMode,
- chunkPtr);
+ } else {
+ code = (*segPtr->typePtr->layoutProc)(textPtr, &curIndex, segPtr,
+ byteOffset, maxX-tabSize, maxBytes, noCharsYet, wrapMode,
+ chunkPtr);
+ }
if (code <= 0) {
FreeStyle(textPtr, chunkPtr->stylePtr);
if (code < 0) {
@@ -1031,8 +1477,8 @@ LayoutDLine(textPtr, indexPtr)
}
/*
- * No characters from this segment fit in the window: this
- * means we're at the end of the display line.
+ * No characters from this segment fit in the window: this means
+ * we're at the end of the display line.
*/
if (chunkPtr != NULL) {
@@ -1040,7 +1486,19 @@ LayoutDLine(textPtr, indexPtr)
}
break;
}
- if (chunkPtr->numBytes > 0) {
+
+ /*
+ * We currently say we have some characters (and therefore something
+ * from which to examine tag values for the first character of the
+ * line) even if those characters are actually elided. This behaviour
+ * is not well documented, and it might be more consistent to
+ * completely ignore such elided characters and their tags. To do so
+ * change this to:
+ *
+ * if (!elide && chunkPtr->numBytes > 0).
+ */
+
+ if (!elide && chunkPtr->numBytes > 0) {
noCharsYet = 0;
lastCharChunkPtr = chunkPtr;
}
@@ -1062,9 +1520,9 @@ LayoutDLine(textPtr, indexPtr)
/*
* If we're at a new tab, adjust the layout for all the chunks
- * pertaining to the previous tab. Also adjust the amount of
- * space left in the line to account for space that will be eaten
- * up by the tab.
+ * pertaining to the previous tab. Also adjust the amount of space
+ * left in the line to account for space that will be eaten up by the
+ * tab.
*/
if (gotTab) {
@@ -1072,9 +1530,9 @@ LayoutDLine(textPtr, indexPtr)
AdjustForTab(textPtr, tabArrayPtr, tabIndex, tabChunkPtr);
x = chunkPtr->x + chunkPtr->width;
}
- tabIndex++;
tabChunkPtr = chunkPtr;
- tabSize = SizeOfTab(textPtr, tabArrayPtr, tabIndex, x, maxX);
+ tabSize = SizeOfTab(textPtr, tabStyle, tabArrayPtr, &tabIndex, x,
+ maxX);
if ((maxX >= 0) && (tabSize >= maxX - x)) {
break;
}
@@ -1084,28 +1542,60 @@ LayoutDLine(textPtr, indexPtr)
if (byteOffset >= segPtr->size) {
byteOffset = 0;
segPtr = segPtr->nextPtr;
+ if (elide && segPtr == NULL) {
+ /*
+ * An elided section started on this line, and carries on
+ * until the newline. Hence the newline is actually elided,
+ * and we want to merge the display of the next logical line
+ * with this one.
+ */
+
+ TkTextLine *linePtr = TkBTreeNextLine(NULL, curIndex.linePtr);
+
+ if (linePtr != NULL) {
+ dlPtr->logicalLinesMerged++;
+ curIndex.byteIndex = 0;
+ curIndex.linePtr = linePtr;
+ chunkPtr = NULL;
+ goto connectNextLogicalLine;
+ }
+ }
}
chunkPtr = NULL;
}
+#if TK_LAYOUT_WITH_BASE_CHUNKS
+ FinalizeBaseChunk(NULL);
+#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
if (noCharsYet) {
- panic("LayoutDLine couldn't place any characters on a line");
+ dlPtr->spaceAbove = 0;
+ dlPtr->spaceBelow = 0;
+ dlPtr->length = 0;
+
+ /*
+ * We used to Tcl_Panic here, saying that LayoutDLine couldn't place
+ * any characters on a line, but I believe a more appropriate response
+ * is to return a DLine with zero height. With elided lines, tag
+ * transitions and asynchronous line height calculations, it is hard
+ * to avoid this situation ever arising with the current code design.
+ */
+
+ return dlPtr;
}
wholeLine = (segPtr == NULL);
/*
- * We're at the end of the display line. Throw away everything
- * after the most recent word break, if there is one; this may
- * potentially require the last chunk to be layed out again.
+ * We're at the end of the display line. Throw away everything after the
+ * most recent word break, if there is one; this may potentially require
+ * the last chunk to be layed out again.
*/
if (breakChunkPtr == NULL) {
/*
- * This code makes sure that we don't accidentally display
- * chunks with no characters at the end of the line (such as
- * the insertion cursor). These chunks belong on the next
- * line. So, throw away everything after the last chunk that
- * has characters in it.
+ * This code makes sure that we don't accidentally display chunks with
+ * no characters at the end of the line (such as the insertion
+ * cursor). These chunks belong on the next line. So, throw away
+ * everything after the last chunk that has characters in it.
*/
breakChunkPtr = lastCharChunkPtr;
@@ -1120,21 +1610,27 @@ LayoutDLine(textPtr, indexPtr)
}
FreeStyle(textPtr, chunkPtr->stylePtr);
breakChunkPtr->nextPtr = chunkPtr->nextPtr;
- (*chunkPtr->undisplayProc)(textPtr, chunkPtr);
+ if (chunkPtr->undisplayProc != NULL) {
+ (*chunkPtr->undisplayProc)(textPtr, chunkPtr);
+ }
ckfree((char *) chunkPtr);
}
if (breakByteOffset != breakChunkPtr->numBytes) {
- (*breakChunkPtr->undisplayProc)(textPtr, breakChunkPtr);
+ if (breakChunkPtr->undisplayProc != NULL) {
+ (*breakChunkPtr->undisplayProc)(textPtr, breakChunkPtr);
+ }
segPtr = TkTextIndexToSeg(&breakIndex, &byteOffset);
(*segPtr->typePtr->layoutProc)(textPtr, &breakIndex,
- segPtr, byteOffset, maxX, breakByteOffset, 0,
+ segPtr, byteOffset, maxX, breakByteOffset, 0,
wrapMode, breakChunkPtr);
+#if TK_LAYOUT_WITH_BASE_CHUNKS
+ FinalizeBaseChunk(NULL);
+#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
}
lastChunkPtr = breakChunkPtr;
wholeLine = 0;
}
-
/*
* Make tab adjustments for the last tab stop, if there is one.
*/
@@ -1144,16 +1640,15 @@ LayoutDLine(textPtr, indexPtr)
}
/*
- * Make one more pass over the line to recompute various things
- * like its height, length, and total number of bytes. Also
- * modify the x-locations of chunks to reflect justification.
- * If we're not wrapping, I'm not sure what is the best way to
- * handle left and center justification: should the total length,
- * for purposes of justification, be (a) the window width, (b)
- * the length of the longest line in the window, or (c) the length
- * of the longest line in the text? (c) isn't available, (b) seems
- * weird, since it can change with vertical scrolling, so (a) is
- * what is implemented below.
+ * Make one more pass over the line to recompute various things like its
+ * height, length, and total number of bytes. Also modify the x-locations
+ * of chunks to reflect justification. If we're not wrapping, I'm not sure
+ * what is the best way to handle left and center justification: should
+ * the total length, for purposes of justification, be (a) the window
+ * width, (b) the length of the longest line in the window, or (c) the
+ * length of the longest line in the text? (c) isn't available, (b) seems
+ * weird, since it can change with vertical scrolling, so (a) is what is
+ * implemented below.
*/
if (wrapMode == TEXT_WRAPMODE_NONE) {
@@ -1208,10 +1703,11 @@ LayoutDLine(textPtr, indexPtr)
dlPtr->baseline += dlPtr->spaceAbove;
/*
- * Recompute line length: may have changed because of justification.
+ * Recompute line length: may have changed because of justification.
*/
dlPtr->length = lastChunkPtr->x + lastChunkPtr->width;
+
return dlPtr;
}
@@ -1220,38 +1716,37 @@ LayoutDLine(textPtr, indexPtr)
*
* UpdateDisplayInfo --
*
- * This procedure is invoked to recompute some or all of the
- * DLine structures for a text widget. At the time it is called
- * the DLine structures still left in the widget are guaranteed
- * to be correct except that (a) the y-coordinates aren't
- * necessarily correct, (b) there may be missing structures
- * (the DLine structures get removed as soon as they are potentially
- * out-of-date), and (c) DLine structures that don't start at the
- * beginning of a line may be incorrect if previous information in
- * the same line changed size in a way that moved a line boundary
- * (DLines for any info that changed will have been deleted, but
- * not DLines for unchanged info in the same text line).
+ * This function is invoked to recompute some or all of the DLine
+ * structures for a text widget. At the time it is called the DLine
+ * structures still left in the widget are guaranteed to be correct
+ * except that (a) the y-coordinates aren't necessarily correct, (b)
+ * there may be missing structures (the DLine structures get removed as
+ * soon as they are potentially out-of-date), and (c) DLine structures
+ * that don't start at the beginning of a line may be incorrect if
+ * previous information in the same line changed size in a way that moved
+ * a line boundary (DLines for any info that changed will have been
+ * deleted, but not DLines for unchanged info in the same text line).
*
* Results:
* None.
*
* Side effects:
- * Upon return, the DLine information for textPtr correctly reflects
- * the positions where characters will be displayed. However, this
- * procedure doesn't actually bring the display up-to-date.
+ * Upon return, the DLine information for textPtr correctly reflects the
+ * positions where characters will be displayed. However, this function
+ * doesn't actually bring the display up-to-date.
*
*----------------------------------------------------------------------
*/
static void
-UpdateDisplayInfo(textPtr)
- TkText *textPtr; /* Text widget to update. */
+UpdateDisplayInfo(
+ TkText *textPtr) /* Text widget to update. */
{
register TextDInfo *dInfoPtr = textPtr->dInfoPtr;
register DLine *dlPtr, *prevPtr;
TkTextIndex index;
TkTextLine *lastLinePtr;
- int y, maxY, pixelOffset, maxOffset;
+ int y, maxY, xPixelOffset, maxOffset, lineHeight;
if (!(dInfoPtr->flags & DINFO_OUT_OF_DATE)) {
return;
@@ -1265,21 +1760,24 @@ UpdateDisplayInfo(textPtr)
index = textPtr->topIndex;
dlPtr = FindDLine(dInfoPtr->dLinePtr, &index);
if ((dlPtr != NULL) && (dlPtr != dInfoPtr->dLinePtr)) {
- FreeDLines(textPtr, dInfoPtr->dLinePtr, dlPtr, 1);
+ FreeDLines(textPtr, dInfoPtr->dLinePtr, dlPtr, DLINE_UNLINK);
+ }
+ if (index.byteIndex == 0) {
+ lineHeight = 0;
+ } else {
+ lineHeight = -1;
}
/*
- *--------------------------------------------------------------
- * Scan through the contents of the window from top to bottom,
- * recomputing information for lines that are missing.
- *--------------------------------------------------------------
+ * Scan through the contents of the window from top to bottom, recomputing
+ * information for lines that are missing.
*/
- lastLinePtr = TkBTreeFindLine(textPtr->tree,
- TkBTreeNumLines(textPtr->tree));
+ lastLinePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr));
dlPtr = dInfoPtr->dLinePtr;
prevPtr = NULL;
- y = dInfoPtr->y;
+ y = dInfoPtr->y - dInfoPtr->newTopPixelOffset;
maxY = dInfoPtr->maxY;
while (1) {
register DLine *newPtr;
@@ -1292,22 +1790,20 @@ UpdateDisplayInfo(textPtr)
* There are three possibilities right now:
* (a) the next DLine (dlPtr) corresponds exactly to the next
* information we want to display: just use it as-is.
- * (b) the next DLine corresponds to a different line, or to
- * a segment that will be coming later in the same line:
- * leave this DLine alone in the hopes that we'll be able
- * to use it later, then create a new DLine in front of
- * it.
- * (c) the next DLine corresponds to a segment in the line we
- * want, but it's a segment that has already been processed
- * or will never be processed. Delete the DLine and try
- * again.
+ * (b) the next DLine corresponds to a different line, or to a segment
+ * that will be coming later in the same line: leave this DLine
+ * alone in the hopes that we'll be able to use it later, then
+ * create a new DLine in front of it.
+ * (c) the next DLine corresponds to a segment in the line we want,
+ * but it's a segment that has already been processed or will
+ * never be processed. Delete the DLine and try again.
*
- * One other twist on all this. It's possible for 3D borders
- * to interact between lines (see DisplayLineBackground) so if
- * a line is relayed out and has styles with 3D borders, its
- * neighbors have to be redrawn if they have 3D borders too,
- * since the interactions could have changed (the neighbors
- * don't have to be relayed out, just redrawn).
+ * One other twist on all this. It's possible for 3D borders to
+ * interact between lines (see DisplayLineBackground) so if a line is
+ * relayed out and has styles with 3D borders, its neighbors have to
+ * be redrawn if they have 3D borders too, since the interactions
+ * could have changed (the neighbors don't have to be relayed out,
+ * just redrawn).
*/
if ((dlPtr == NULL) || (dlPtr->index.linePtr != index.linePtr)) {
@@ -1315,20 +1811,17 @@ UpdateDisplayInfo(textPtr)
* Case (b) -- must make new DLine.
*/
- makeNewDLine:
+ makeNewDLine:
if (tkTextDebug) {
char string[TK_POS_CHARS];
/*
- * Debugging is enabled, so keep a log of all the lines
- * that were re-layed out. The test suite uses this
- * information.
+ * Debugging is enabled, so keep a log of all the lines that
+ * were re-layed out. The test suite uses this information.
*/
- TkTextPrintIndex(&index, string);
- Tcl_SetVar2(textPtr->interp, "tk_textRelayout", (char *) NULL,
- string,
- TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+ TkTextPrintIndex(textPtr, &index, string);
+ LOG("tk_textRelayout", string);
}
newPtr = LayoutDLine(textPtr, &index);
if (prevPtr == NULL) {
@@ -1336,25 +1829,25 @@ UpdateDisplayInfo(textPtr)
} else {
prevPtr->nextPtr = newPtr;
if (prevPtr->flags & HAS_3D_BORDER) {
- prevPtr->oldY = -1;
+ prevPtr->flags |= OLD_Y_INVALID;
}
}
newPtr->nextPtr = dlPtr;
dlPtr = newPtr;
} else {
/*
- * DlPtr refers to the line we want. Next check the
- * index within the line.
+ * DlPtr refers to the line we want. Next check the index within
+ * the line.
*/
if (index.byteIndex == dlPtr->index.byteIndex) {
/*
- * Case (a) -- can use existing display line as-is.
+ * Case (a) - can use existing display line as-is.
*/
if ((dlPtr->flags & HAS_3D_BORDER) && (prevPtr != NULL)
&& (prevPtr->flags & (NEW_LAYOUT))) {
- dlPtr->oldY = -1;
+ dlPtr->flags |= OLD_Y_INVALID;
}
goto lineOK;
}
@@ -1363,12 +1856,12 @@ UpdateDisplayInfo(textPtr)
}
/*
- * Case (c) -- dlPtr is useless. Discard it and start
- * again with the next display line.
+ * Case (c) - dlPtr is useless. Discard it and start again with
+ * the next display line.
*/
newPtr = dlPtr->nextPtr;
- FreeDLines(textPtr, dlPtr, newPtr, 0);
+ FreeDLines(textPtr, dlPtr, newPtr, DLINE_FREE);
dlPtr = newPtr;
if (prevPtr != NULL) {
prevPtr->nextPtr = newPtr;
@@ -1382,16 +1875,19 @@ UpdateDisplayInfo(textPtr)
* Advance to the start of the next line.
*/
- lineOK:
+ lineOK:
dlPtr->y = y;
y += dlPtr->height;
- TkTextIndexForwBytes(&index, dlPtr->byteCount, &index);
+ if (lineHeight != -1) {
+ lineHeight += dlPtr->height;
+ }
+ TkTextIndexForwBytes(textPtr, &index, dlPtr->byteCount, &index);
prevPtr = dlPtr;
dlPtr = dlPtr->nextPtr;
/*
- * If we switched text lines, delete any DLines left for the
- * old text line.
+ * If we switched text lines, delete any DLines left for the old text
+ * line.
*/
if (index.linePtr != prevPtr->index.linePtr) {
@@ -1403,17 +1899,46 @@ UpdateDisplayInfo(textPtr)
nextPtr = nextPtr->nextPtr;
}
if (nextPtr != dlPtr) {
- FreeDLines(textPtr, dlPtr, nextPtr, 0);
+ FreeDLines(textPtr, dlPtr, nextPtr, DLINE_FREE);
prevPtr->nextPtr = nextPtr;
dlPtr = nextPtr;
}
+
+ if ((lineHeight != -1) && (TkBTreeLinePixelCount(textPtr,
+ prevPtr->index.linePtr) != lineHeight)) {
+ /*
+ * The logical line height we just calculated is actually
+ * differnt to the currently cached height of the text line.
+ * That is fine (the text line heights are only calculated
+ * asynchronously), but we must update the cached height so
+ * that any counts made with DLine pointers are the same as
+ * counts made through the BTree. This helps to ensure that
+ * the scrollbar size corresponds accurately to that displayed
+ * contents, even as the window is re-sized.
+ */
+
+ TkBTreeAdjustPixelHeight(textPtr, prevPtr->index.linePtr,
+ lineHeight, 0);
+
+ /*
+ * I believe we can be 100% sure that we started at the
+ * beginning of the logical line, so we can also adjust the
+ * 'pixelCalculationEpoch' to mark it as being up to date.
+ * There is a slight concern that we might not have got this
+ * right for the first line in the re-display.
+ */
+
+ TkBTreeLinePixelEpoch(textPtr, prevPtr->index.linePtr) =
+ dInfoPtr->lineMetricUpdateEpoch;
+ }
+ lineHeight = 0;
}
/*
- * It's important to have the following check here rather than in
- * the while statement for the loop, so that there's always at least
- * one DLine generated, regardless of how small the window is. This
- * keeps a lot of other code from breaking.
+ * It's important to have the following check here rather than in the
+ * while statement for the loop, so that there's always at least one
+ * DLine generated, regardless of how small the window is. This keeps
+ * a lot of other code from breaking.
*/
if (y >= maxY) {
@@ -1425,133 +1950,240 @@ UpdateDisplayInfo(textPtr)
* Delete any DLine structures that don't fit on the screen.
*/
- FreeDLines(textPtr, dlPtr, (DLine *) NULL, 1);
+ FreeDLines(textPtr, dlPtr, NULL, DLINE_UNLINK);
/*
- *--------------------------------------------------------------
- * If there is extra space at the bottom of the window (because
- * we've hit the end of the text), then bring in more lines at
- * the top of the window, if there are any, to fill in the view.
- *--------------------------------------------------------------
+ * If there is extra space at the bottom of the window (because we've hit
+ * the end of the text), then bring in more lines at the top of the
+ * window, if there are any, to fill in the view.
+ *
+ * Since the top line may only be partially visible, we try first to
+ * simply show more pixels from that line (newTopPixelOffset). If that
+ * isn't enough, we have to layout more lines.
*/
if (y < maxY) {
- int lineNum, spaceLeft, bytesToCount;
- DLine *lowestPtr;
-
/*
- * Layout an entire text line (potentially > 1 display line),
- * then link in as many display lines as fit without moving
- * the bottom line out of the window. Repeat this until
- * all the extra space has been used up or we've reached the
- * beginning of the text.
+ * This counts how many vertical pixels we have left to fill by
+ * pulling in more display pixels either from the first currently
+ * displayed, or the lines above it.
*/
- spaceLeft = maxY - y;
- lineNum = TkBTreeLineIndex(dInfoPtr->dLinePtr->index.linePtr);
- 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.byteIndex = 0;
- lowestPtr = NULL;
+ int spaceLeft = maxY - y;
- do {
- dlPtr = LayoutDLine(textPtr, &index);
- dlPtr->nextPtr = lowestPtr;
- lowestPtr = dlPtr;
- if (dlPtr->length == 0 && dlPtr->height == 0) { bytesToCount--; break; } /* elide */
- TkTextIndexForwBytes(&index, dlPtr->byteCount, &index);
- bytesToCount -= dlPtr->byteCount;
- } while ((bytesToCount > 0)
- && (index.linePtr == lowestPtr->index.linePtr));
+ if (spaceLeft <= dInfoPtr->newTopPixelOffset) {
+ /*
+ * We can fill up all the needed space just by showing more of the
+ * current top line.
+ */
+
+ dInfoPtr->newTopPixelOffset -= spaceLeft;
+ y += spaceLeft;
+ spaceLeft = 0;
+ } else {
+ int lineNum, bytesToCount;
+ DLine *lowestPtr;
/*
- * Scan through the display lines from the bottom one up to
- * the top one.
+ * Add in all of the current top line, which won't be enough to
+ * bring y up to maxY (if it was we would be in the 'if' block
+ * above).
*/
- while (lowestPtr != NULL) {
- dlPtr = lowestPtr;
- spaceLeft -= dlPtr->height;
- if (spaceLeft < 0) {
- break;
+ y += dInfoPtr->newTopPixelOffset;
+ dInfoPtr->newTopPixelOffset = 0;
+
+ /*
+ * Layout an entire text line (potentially > 1 display line), then
+ * link in as many display lines as fit without moving the bottom
+ * line out of the window. Repeat this until all the extra space
+ * has been used up or we've reached the beginning of the text.
+ */
+
+ spaceLeft = maxY - y;
+ if (dInfoPtr->dLinePtr == NULL) {
+ /*
+ * No lines have been laid out. This must be an empty peer
+ * widget.
+ */
+
+ lineNum = TkBTreeNumLines(textPtr->sharedTextPtr->tree,
+ textPtr) - 1;
+ bytesToCount = INT_MAX;
+ } else {
+ lineNum = TkBTreeLinesTo(textPtr,
+ dInfoPtr->dLinePtr->index.linePtr);
+ bytesToCount = dInfoPtr->dLinePtr->index.byteIndex;
+ if (bytesToCount == 0) {
+ bytesToCount = INT_MAX;
+ lineNum--;
+ }
+ }
+ for ( ; (lineNum >= 0) && (spaceLeft > 0); lineNum--) {
+ int pixelHeight = 0;
+
+ index.linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree,
+ textPtr, lineNum);
+ index.byteIndex = 0;
+ lowestPtr = NULL;
+
+ do {
+ dlPtr = LayoutDLine(textPtr, &index);
+ pixelHeight += dlPtr->height;
+ dlPtr->nextPtr = lowestPtr;
+ lowestPtr = dlPtr;
+ if (dlPtr->length == 0 && dlPtr->height == 0) {
+ bytesToCount--;
+ break;
+ } /* elide */
+ TkTextIndexForwBytes(textPtr, &index, dlPtr->byteCount,
+ &index);
+ bytesToCount -= dlPtr->byteCount;
+ } while ((bytesToCount > 0)
+ && (index.linePtr == lowestPtr->index.linePtr));
+
+ /*
+ * We may not have examined the entire line (depending on the
+ * value of 'bytesToCount', so we only want to set this if it
+ * is genuinely bigger).
+ */
+
+ if (pixelHeight > TkBTreeLinePixelCount(textPtr,
+ lowestPtr->index.linePtr)) {
+ TkBTreeAdjustPixelHeight(textPtr,
+ lowestPtr->index.linePtr, pixelHeight, 0);
+ if (index.linePtr != lowestPtr->index.linePtr) {
+ /*
+ * We examined the entire line, so can update the
+ * epoch.
+ */
+
+ TkBTreeLinePixelEpoch(textPtr,
+ lowestPtr->index.linePtr) =
+ dInfoPtr->lineMetricUpdateEpoch;
+ }
}
- lowestPtr = dlPtr->nextPtr;
- dlPtr->nextPtr = dInfoPtr->dLinePtr;
- dInfoPtr->dLinePtr = dlPtr;
- if (tkTextDebug) {
- char string[TK_POS_CHARS];
- TkTextPrintIndex(&dlPtr->index, string);
- Tcl_SetVar2(textPtr->interp, "tk_textRelayout",
- (char *) NULL, string,
- TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+ /*
+ * Scan through the display lines from the bottom one up to
+ * the top one.
+ */
+
+ while (lowestPtr != NULL) {
+ dlPtr = lowestPtr;
+ spaceLeft -= dlPtr->height;
+ lowestPtr = dlPtr->nextPtr;
+ dlPtr->nextPtr = dInfoPtr->dLinePtr;
+ dInfoPtr->dLinePtr = dlPtr;
+ if (tkTextDebug) {
+ char string[TK_POS_CHARS];
+
+ TkTextPrintIndex(textPtr, &dlPtr->index, string);
+ LOG("tk_textRelayout", string);
+ }
+ if (spaceLeft <= 0) {
+ break;
+ }
+ }
+ FreeDLines(textPtr, lowestPtr, NULL, DLINE_FREE);
+ bytesToCount = INT_MAX;
+ }
+
+ /*
+ * We've either filled in the space we wanted to or we've run out
+ * of display lines at the top of the text. Note that we already
+ * set dInfoPtr->newTopPixelOffset to zero above.
+ */
+
+ if (spaceLeft < 0) {
+ /*
+ * We've laid out a few too many vertical pixels at or above
+ * the first line. Therefore we only want to show part of the
+ * first displayed line, so that the last displayed line just
+ * fits in the window.
+ */
+
+ dInfoPtr->newTopPixelOffset = -spaceLeft;
+ if (dInfoPtr->newTopPixelOffset>=dInfoPtr->dLinePtr->height) {
+ /*
+ * Somehow the entire first line we laid out is shorter
+ * than the new offset. This should not occur and would
+ * indicate a bad problem in the logic above.
+ */
+
+ Tcl_Panic("Error in pixel height consistency while filling in spacesLeft");
}
}
- FreeDLines(textPtr, lowestPtr, (DLine *) NULL, 0);
- bytesToCount = INT_MAX;
}
/*
- * Now we're all done except that the y-coordinates in all the
- * DLines are wrong and the top index for the text is wrong.
- * Update them.
+ * Now we're all done except that the y-coordinates in all the DLines
+ * are wrong and the top index for the text is wrong. Update them.
*/
- textPtr->topIndex = dInfoPtr->dLinePtr->index;
- y = dInfoPtr->y;
- for (dlPtr = dInfoPtr->dLinePtr; dlPtr != NULL;
- dlPtr = dlPtr->nextPtr) {
- if (y > dInfoPtr->maxY) {
- panic("Added too many new lines in UpdateDisplayInfo");
+ if (dInfoPtr->dLinePtr != NULL) {
+ textPtr->topIndex = dInfoPtr->dLinePtr->index;
+ y = dInfoPtr->y - dInfoPtr->newTopPixelOffset;
+ for (dlPtr = dInfoPtr->dLinePtr; dlPtr != NULL;
+ dlPtr = dlPtr->nextPtr) {
+ if (y > dInfoPtr->maxY) {
+ Tcl_Panic("Added too many new lines in UpdateDisplayInfo");
+ }
+ dlPtr->y = y;
+ y += dlPtr->height;
}
- dlPtr->y = y;
- y += dlPtr->height;
}
}
/*
- *--------------------------------------------------------------
- * If the old top or bottom line has scrolled elsewhere on the
- * screen, we may not be able to re-use its old contents by
- * copying bits (e.g., a beveled edge that was drawn when it was
- * at the top or bottom won't be drawn when the line is in the
- * middle and its neighbor has a matching background). Similarly,
- * if the new top or bottom line came from somewhere else on the
- * screen, we may not be able to copy the old bits.
- *--------------------------------------------------------------
+ * If the old top or bottom line has scrolled elsewhere on the screen, we
+ * may not be able to re-use its old contents by copying bits (e.g., a
+ * beveled edge that was drawn when it was at the top or bottom won't be
+ * drawn when the line is in the middle and its neighbor has a matching
+ * background). Similarly, if the new top or bottom line came from
+ * somewhere else on the screen, we may not be able to copy the old bits.
*/
dlPtr = dInfoPtr->dLinePtr;
- if ((dlPtr->flags & HAS_3D_BORDER) && !(dlPtr->flags & TOP_LINE)) {
- dlPtr->oldY = -1;
- }
- while (1) {
- if ((dlPtr->flags & TOP_LINE) && (dlPtr != dInfoPtr->dLinePtr)
- && (dlPtr->flags & HAS_3D_BORDER)) {
- dlPtr->oldY = -1;
- }
- if ((dlPtr->flags & BOTTOM_LINE) && (dlPtr->nextPtr != NULL)
- && (dlPtr->flags & HAS_3D_BORDER)) {
- dlPtr->oldY = -1;
+ if (dlPtr != NULL) {
+ if ((dlPtr->flags & HAS_3D_BORDER) && !(dlPtr->flags & TOP_LINE)) {
+ dlPtr->flags |= OLD_Y_INVALID;
}
- if (dlPtr->nextPtr == NULL) {
- if ((dlPtr->flags & HAS_3D_BORDER)
- && !(dlPtr->flags & BOTTOM_LINE)) {
- dlPtr->oldY = -1;
+ while (1) {
+ if ((dlPtr->flags & TOP_LINE) && (dlPtr != dInfoPtr->dLinePtr)
+ && (dlPtr->flags & HAS_3D_BORDER)) {
+ dlPtr->flags |= OLD_Y_INVALID;
}
- dlPtr->flags &= ~TOP_LINE;
- dlPtr->flags |= BOTTOM_LINE;
- break;
+
+ /*
+ * If the old top-line was not completely showing (i.e. the
+ * pixelOffset is non-zero) and is no longer the top-line, then we
+ * must re-draw it.
+ */
+
+ if ((dlPtr->flags & TOP_LINE) &&
+ dInfoPtr->topPixelOffset!=0 && dlPtr!=dInfoPtr->dLinePtr) {
+ dlPtr->flags |= OLD_Y_INVALID;
+ }
+ if ((dlPtr->flags & BOTTOM_LINE) && (dlPtr->nextPtr != NULL)
+ && (dlPtr->flags & HAS_3D_BORDER)) {
+ dlPtr->flags |= OLD_Y_INVALID;
+ }
+ if (dlPtr->nextPtr == NULL) {
+ if ((dlPtr->flags & HAS_3D_BORDER)
+ && !(dlPtr->flags & BOTTOM_LINE)) {
+ dlPtr->flags |= OLD_Y_INVALID;
+ }
+ dlPtr->flags &= ~TOP_LINE;
+ dlPtr->flags |= BOTTOM_LINE;
+ break;
+ }
+ dlPtr->flags &= ~(TOP_LINE|BOTTOM_LINE);
+ dlPtr = dlPtr->nextPtr;
}
- dlPtr->flags &= ~(TOP_LINE|BOTTOM_LINE);
- dlPtr = dlPtr->nextPtr;
+ dInfoPtr->dLinePtr->flags |= TOP_LINE;
+ dInfoPtr->topPixelOffset = dInfoPtr->newTopPixelOffset;
}
- dInfoPtr->dLinePtr->flags |= TOP_LINE;
/*
* Arrange for scrollbars to be updated.
@@ -1560,15 +2192,12 @@ UpdateDisplayInfo(textPtr)
textPtr->flags |= UPDATE_SCROLLBARS;
/*
- *--------------------------------------------------------------
* Deal with horizontal scrolling:
- * 1. If there's empty space to the right of the longest line,
- * shift the screen to the right to fill in the empty space.
- * 2. If the desired horizontal scroll position has changed,
- * force a full redisplay of all the lines in the widget.
- * 3. If the wrap mode isn't "none" then re-scroll to the base
- * position.
- *--------------------------------------------------------------
+ * 1. If there's empty space to the right of the longest line, shift the
+ * screen to the right to fill in the empty space.
+ * 2. If the desired horizontal scroll position has changed, force a full
+ * redisplay of all the lines in the widget.
+ * 3. If the wrap mode isn't "none" then re-scroll to the base position.
*/
dInfoPtr->maxLength = 0;
@@ -1578,20 +2207,35 @@ UpdateDisplayInfo(textPtr)
dInfoPtr->maxLength = dlPtr->length;
}
}
- maxOffset = (dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x)
- + textPtr->charWidth - 1)/textPtr->charWidth;
- if (dInfoPtr->newByteOffset > maxOffset) {
- dInfoPtr->newByteOffset = maxOffset;
+ maxOffset = dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x);
+
+ xPixelOffset = dInfoPtr->newXPixelOffset;
+ if (xPixelOffset > maxOffset) {
+ xPixelOffset = maxOffset;
}
- if (dInfoPtr->newByteOffset < 0) {
- dInfoPtr->newByteOffset = 0;
+ if (xPixelOffset < 0) {
+ xPixelOffset = 0;
}
- pixelOffset = dInfoPtr->newByteOffset * textPtr->charWidth;
- if (pixelOffset != dInfoPtr->curPixelOffset) {
- dInfoPtr->curPixelOffset = pixelOffset;
+
+ /*
+ * Here's a problem: see the tests textDisp-29.2.1-4
+ *
+ * If the widget is being created, but has not yet been configured it will
+ * have a maxY of 1 above, and we we won't have examined all the lines
+ * (just the first line, in fact), and so maxOffset will not be a true
+ * reflection of the widget's lines. Therefore we must not overwrite the
+ * original newXPixelOffset in this case.
+ */
+
+ if (!(((Tk_FakeWin *) (textPtr->tkwin))->flags & TK_NEED_CONFIG_NOTIFY)) {
+ dInfoPtr->newXPixelOffset = xPixelOffset;
+ }
+
+ if (xPixelOffset != dInfoPtr->curXPixelOffset) {
+ dInfoPtr->curXPixelOffset = xPixelOffset;
for (dlPtr = dInfoPtr->dLinePtr; dlPtr != NULL;
dlPtr = dlPtr->nextPtr) {
- dlPtr->oldY = -1;
+ dlPtr->flags |= OLD_Y_INVALID;
}
}
}
@@ -1601,8 +2245,8 @@ UpdateDisplayInfo(textPtr)
*
* FreeDLines --
*
- * This procedure is called to free up all of the resources
- * associated with one or more DLine structures.
+ * This function is called to free up all of the resources associated
+ * with one or more DLine structures.
*
* Results:
* None.
@@ -1614,27 +2258,43 @@ UpdateDisplayInfo(textPtr)
*/
static void
-FreeDLines(textPtr, firstPtr, lastPtr, unlink)
- TkText *textPtr; /* Information about overall text
- * widget. */
- register DLine *firstPtr; /* Pointer to first DLine to free up. */
- DLine *lastPtr; /* Pointer to DLine just after last
- * one to free (NULL means everything
- * starting with firstPtr). */
- int unlink; /* 1 means DLines are currently linked
- * into the list rooted at
- * textPtr->dInfoPtr->dLinePtr and
- * they have to be unlinked. 0 means
- * just free without unlinking. */
+FreeDLines(
+ TkText *textPtr, /* Information about overall text widget. */
+ register DLine *firstPtr, /* Pointer to first DLine to free up. */
+ DLine *lastPtr, /* Pointer to DLine just after last one to
+ * free (NULL means everything starting with
+ * firstPtr). */
+ int action) /* DLINE_UNLINK means DLines are currently
+ * linked into the list rooted at
+ * textPtr->dInfoPtr->dLinePtr and they have
+ * to be unlinked. DLINE_FREE means just free
+ * without unlinking. DLINE_FREE_TEMP means
+ * the DLine given is just a temporary one and
+ * we shouldn't invalidate anything for the
+ * overall widget. */
{
register TkTextDispChunk *chunkPtr, *nextChunkPtr;
register DLine *nextDLinePtr;
- if (unlink) {
+ if (action == DLINE_FREE_TEMP) {
+ lineHeightsRecalculated++;
+ if (tkTextDebug) {
+ char string[TK_POS_CHARS];
+
+ /*
+ * Debugging is enabled, so keep a log of all the lines whose
+ * height was recalculated. The test suite uses this information.
+ */
+
+ TkTextPrintIndex(textPtr, &firstPtr->index, string);
+ LOG("tk_textHeightCalc", string);
+ }
+ } else if (action == DLINE_UNLINK) {
if (textPtr->dInfoPtr->dLinePtr == firstPtr) {
textPtr->dInfoPtr->dLinePtr = lastPtr;
} else {
register DLine *prevPtr;
+
for (prevPtr = textPtr->dInfoPtr->dLinePtr;
prevPtr->nextPtr != firstPtr; prevPtr = prevPtr->nextPtr) {
/* Empty loop body. */
@@ -1656,7 +2316,9 @@ FreeDLines(textPtr, firstPtr, lastPtr, unlink)
ckfree((char *) firstPtr);
firstPtr = nextDLinePtr;
}
- textPtr->dInfoPtr->dLinesInvalidated = 1;
+ if (action != DLINE_FREE_TEMP) {
+ textPtr->dInfoPtr->dLinesInvalidated = 1;
+ }
}
/*
@@ -1664,38 +2326,36 @@ FreeDLines(textPtr, firstPtr, lastPtr, unlink)
*
* DisplayDLine --
*
- * This procedure is invoked to draw a single line on the
- * screen.
+ * This function is invoked to draw a single line on the screen.
*
* Results:
* None.
*
* Side effects:
- * The line given by dlPtr is drawn at its correct position in
- * textPtr's window. Note that this is one *display* line, not
- * one *text* line.
+ * The line given by dlPtr is drawn at its correct position in textPtr's
+ * window. Note that this is one *display* line, not one *text* line.
*
*----------------------------------------------------------------------
*/
static void
-DisplayDLine(textPtr, dlPtr, prevPtr, pixmap)
- TkText *textPtr; /* Text widget in which to draw line. */
- register DLine *dlPtr; /* Information about line to draw. */
- DLine *prevPtr; /* Line just before one to draw, or NULL
- * if dlPtr is the top line. */
- Pixmap pixmap; /* Pixmap to use for double-buffering.
- * Caller must make sure it's large enough
- * to hold line. */
+DisplayDLine(
+ TkText *textPtr, /* Text widget in which to draw line. */
+ register DLine *dlPtr, /* Information about line to draw. */
+ DLine *prevPtr, /* Line just before one to draw, or NULL if
+ * dlPtr is the top line. */
+ Pixmap pixmap) /* Pixmap to use for double-buffering. Caller
+ * must make sure it's large enough to hold
+ * line. */
{
register TkTextDispChunk *chunkPtr;
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
Display *display;
- int height, x;
+ int height, y_off;
#ifndef TK_NO_DOUBLE_BUFFERING
- CONST int y = 0;
+ const int y = 0;
#else
- CONST int y = dlPtr->y;
+ const int y = dlPtr->y;
#endif /* TK_NO_DOUBLE_BUFFERING */
if (dlPtr->chunkPtr == NULL) return;
@@ -1706,15 +2366,21 @@ DisplayDLine(textPtr, dlPtr, prevPtr, pixmap)
if ((height + dlPtr->y) > dInfoPtr->maxY) {
height = dInfoPtr->maxY - dlPtr->y;
}
+ if (dlPtr->y < dInfoPtr->y) {
+ y_off = dInfoPtr->y - dlPtr->y;
+ height -= y_off;
+ } else {
+ y_off = 0;
+ }
#ifdef TK_NO_DOUBLE_BUFFERING
- TkpClipDrawableToRect(display, pixmap, dInfoPtr->x, y,
+ TkpClipDrawableToRect(display, pixmap, dInfoPtr->x, y + y_off,
dInfoPtr->maxX - dInfoPtr->x, height);
#endif /* TK_NO_DOUBLE_BUFFERING */
/*
- * First, clear the area of the line to the background color for the
- * text widget.
+ * First, clear the area of the line to the background color for the text
+ * widget.
*/
Tk_Fill3DRectangle(textPtr->tkwin, pixmap, textPtr->border, 0, y,
@@ -1727,19 +2393,20 @@ DisplayDLine(textPtr, dlPtr, prevPtr, pixmap)
DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap);
/*
- * Make another pass through all of the chunks to redraw the
- * insertion cursor, if it is visible on this line. Must do
- * it here rather than in the foreground pass below because
- * otherwise a wide insertion cursor will obscure the character
- * to its left.
+ * Make another pass through all of the chunks to redraw the insertion
+ * cursor, if it is visible on this line. Must do it here rather than in
+ * the foreground pass below because otherwise a wide insertion cursor
+ * will obscure the character to its left.
*/
- if (textPtr->state == TK_STATE_NORMAL) {
+ if (textPtr->state == TK_TEXT_STATE_NORMAL) {
for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL);
chunkPtr = chunkPtr->nextPtr) {
- x = chunkPtr->x + dInfoPtr->x - dInfoPtr->curPixelOffset;
if (chunkPtr->displayProc == TkTextInsertDisplayProc) {
- (*chunkPtr->displayProc)(chunkPtr, x, y + dlPtr->spaceAbove,
+ int x = chunkPtr->x + dInfoPtr->x - dInfoPtr->curXPixelOffset;
+
+ (*chunkPtr->displayProc)(textPtr, chunkPtr, x,
+ y + dlPtr->spaceAbove,
dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
dlPtr->baseline - dlPtr->spaceAbove, display, pixmap,
dlPtr->y + dlPtr->spaceAbove);
@@ -1749,49 +2416,49 @@ DisplayDLine(textPtr, dlPtr, prevPtr, pixmap)
/*
* Make yet another pass through all of the chunks to redraw all of
- * foreground information. Note: we have to call the displayProc
- * even for chunks that are off-screen. This is needed, for
- * example, so that embedded windows can be unmapped in this case.
- * Conve
+ * foreground information. Note: we have to call the displayProc even for
+ * chunks that are off-screen. This is needed, for example, so that
+ * embedded windows can be unmapped in this case.
*/
for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL);
chunkPtr = chunkPtr->nextPtr) {
if (chunkPtr->displayProc == TkTextInsertDisplayProc) {
/*
- * Already displayed the insertion cursor above. Don't
- * do it again here.
+ * Already displayed the insertion cursor above. Don't do it again
+ * here.
*/
continue;
}
- x = chunkPtr->x + dInfoPtr->x - dInfoPtr->curPixelOffset;
- if ((x + chunkPtr->width <= 0) || (x >= dInfoPtr->maxX)) {
- /*
- * Note: we have to call the displayProc even for chunks
- * that are off-screen. This is needed, for example, so
- * that embedded windows can be unmapped in this case.
- * Display the chunk at a coordinate that can be clearly
- * identified by the displayProc as being off-screen to
- * the left (the displayProc may not be able to tell if
- * something is off to the right).
- */
- if (chunkPtr->displayProc != NULL)
- (*chunkPtr->displayProc)(chunkPtr, -chunkPtr->width,
- y + dlPtr->spaceAbove,
- dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
- dlPtr->baseline - dlPtr->spaceAbove, display, pixmap,
- dlPtr->y + dlPtr->spaceAbove);
- } else {
- /* don't call if elide. This tax ok since not very many visible DLine's in
- an area, but potentially many elide ones */
- if (chunkPtr->displayProc != NULL)
- (*chunkPtr->displayProc)(chunkPtr, x, y + dlPtr->spaceAbove,
- dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
- dlPtr->baseline - dlPtr->spaceAbove, display, pixmap,
- dlPtr->y + dlPtr->spaceAbove);
+ /*
+ * Don't call if elide. This tax OK since not very many visible DLines
+ * in an area, but potentially many elide ones.
+ */
+
+ if (chunkPtr->displayProc != NULL) {
+ int x = chunkPtr->x + dInfoPtr->x - dInfoPtr->curXPixelOffset;
+
+ if ((x + chunkPtr->width <= 0) || (x >= dInfoPtr->maxX)) {
+ /*
+ * Note: we have to call the displayProc even for chunks that
+ * are off-screen. This is needed, for example, so that
+ * embedded windows can be unmapped in this case. Display the
+ * chunk at a coordinate that can be clearly identified by the
+ * displayProc as being off-screen to the left (the
+ * displayProc may not be able to tell if something is off to
+ * the right).
+ */
+
+ x = -chunkPtr->width;
+ }
+ (*chunkPtr->displayProc)(textPtr, chunkPtr, x,
+ y + dlPtr->spaceAbove, dlPtr->height - dlPtr->spaceAbove -
+ dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove,
+ display, pixmap, dlPtr->y + dlPtr->spaceAbove);
}
+
if (dInfoPtr->dLinesInvalidated) {
return;
}
@@ -1799,17 +2466,17 @@ DisplayDLine(textPtr, dlPtr, prevPtr, pixmap)
#ifndef TK_NO_DOUBLE_BUFFERING
/*
- * Copy the pixmap onto the screen. If this is the last line on
- * the screen then copy a piece of the line, so that it doesn't
- * overflow into the border area. Another special trick: copy the
- * padding area to the left of the line; this is because the
- * insertion cursor sometimes overflows onto that area and we want
- * to get as much of the cursor as possible.
+ * Copy the pixmap onto the screen. If this is the first or last line on
+ * the screen then copy a piece of the line, so that it doesn't overflow
+ * into the border area. Another special trick: copy the padding area to
+ * the left of the line; this is because the insertion cursor sometimes
+ * overflows onto that area and we want to get as much of the cursor as
+ * possible.
*/
XCopyArea(display, pixmap, Tk_WindowId(textPtr->tkwin), dInfoPtr->copyGC,
- dInfoPtr->x, y, (unsigned) (dInfoPtr->maxX - dInfoPtr->x),
- (unsigned) height, dInfoPtr->x, dlPtr->y);
+ dInfoPtr->x, y + y_off, (unsigned) (dInfoPtr->maxX - dInfoPtr->x),
+ (unsigned) height, dInfoPtr->x, dlPtr->y + y_off);
#else
TkpClipDrawableToRect(display, pixmap, 0, 0, -1, -1);
#endif /* TK_NO_DOUBLE_BUFFERING */
@@ -1821,14 +2488,13 @@ DisplayDLine(textPtr, dlPtr, prevPtr, pixmap)
*
* DisplayLineBackground --
*
- * This procedure is called to fill in the background for
- * a display line. It draws 3D borders cleverly so that
- * adjacent chunks with the same style (whether on the same
- * line or different lines) have a single 3D border around
- * the whole region.
+ * This function is called to fill in the background for a display line.
+ * It draws 3D borders cleverly so that adjacent chunks with the same
+ * style (whether on the same line or different lines) have a single 3D
+ * border around the whole region.
*
* Results:
- * There is no return value. Pixmap is filled in with background
+ * There is no return value. Pixmap is filled in with background
* information for dlPtr.
*
* Side effects:
@@ -1838,75 +2504,71 @@ DisplayDLine(textPtr, dlPtr, prevPtr, pixmap)
*/
static void
-DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap)
- TkText *textPtr; /* Text widget containing line. */
- register DLine *dlPtr; /* Information about line to draw. */
- DLine *prevPtr; /* Line just above dlPtr, or NULL if dlPtr
- * is the top-most line in the window. */
- Pixmap pixmap; /* Pixmap to use for double-buffering.
- * Caller must make sure it's large enough
- * to hold line. Caller must also have
- * filled it with the background color for
- * the widget. */
+DisplayLineBackground(
+ TkText *textPtr, /* Text widget containing line. */
+ register DLine *dlPtr, /* Information about line to draw. */
+ DLine *prevPtr, /* Line just above dlPtr, or NULL if dlPtr is
+ * the top-most line in the window. */
+ Pixmap pixmap) /* Pixmap to use for double-buffering. Caller
+ * must make sure it's large enough to hold
+ * line. Caller must also have filled it with
+ * the background color for the widget. */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
- TkTextDispChunk *chunkPtr; /* Pointer to chunk in the current line. */
- TkTextDispChunk *chunkPtr2; /* Pointer to chunk in the line above or
- * below the current one. NULL if we're to
- * the left of or to the right of the chunks
- * in the line. */
+ TkTextDispChunk *chunkPtr; /* Pointer to chunk in the current line. */
+ TkTextDispChunk *chunkPtr2; /* Pointer to chunk in the line above or below
+ * the current one. NULL if we're to the left
+ * of or to the right of the chunks in the
+ * line. */
TkTextDispChunk *nextPtr2; /* Next chunk after chunkPtr2 (it's not the
* same as chunkPtr2->nextPtr in the case
- * where chunkPtr2 is NULL because the line
- * is indented). */
- int leftX; /* The left edge of the region we're
- * currently working on. */
+ * where chunkPtr2 is NULL because the line is
+ * indented). */
+ int leftX; /* The left edge of the region we're currently
+ * working on. */
int leftXIn; /* 1 means beveled edge at leftX slopes right
- * as it goes down, 0 means it slopes left
- * as it goes down. */
+ * as it goes down, 0 means it slopes left as
+ * it goes down. */
int rightX; /* Right edge of chunkPtr. */
int rightX2; /* Right edge of chunkPtr2. */
- int matchLeft; /* Does the style of this line match that
- * of its neighbor just to the left of
- * the current x coordinate? */
- int matchRight; /* Does line's style match its neighbor
- * just to the right of the current x-coord? */
+ int matchLeft; /* Does the style of this line match that of
+ * its neighbor just to the left of the
+ * current x coordinate? */
+ int matchRight; /* Does line's style match its neighbor just
+ * to the right of the current x-coord? */
int minX, maxX, xOffset;
StyleValues *sValuePtr;
Display *display;
#ifndef TK_NO_DOUBLE_BUFFERING
- CONST int y = 0;
+ const int y = 0;
#else
- CONST int y = dlPtr->y;
+ const int y = dlPtr->y;
#endif /* TK_NO_DOUBLE_BUFFERING */
/*
- * Pass 1: scan through dlPtr from left to right. For each range of
- * chunks with the same style, draw the main background for the style
- * plus the vertical parts of the 3D borders (the left and right
- * edges).
+ * Pass 1: scan through dlPtr from left to right. For each range of chunks
+ * with the same style, draw the main background for the style plus the
+ * vertical parts of the 3D borders (the left and right edges).
*/
display = Tk_Display(textPtr->tkwin);
- minX = dInfoPtr->curPixelOffset;
+ minX = dInfoPtr->curXPixelOffset;
xOffset = dInfoPtr->x - minX;
maxX = minX + dInfoPtr->maxX - dInfoPtr->x;
chunkPtr = dlPtr->chunkPtr;
/*
- * Note A: in the following statement, and a few others later in
- * this file marked with "See Note A above", the right side of the
- * assignment was replaced with 0 on 6/18/97. This has the effect
- * of highlighting the empty space to the left of a line whenever
- * the leftmost character of the line is highlighted. This way,
- * multi-line highlights always line up along their left edges.
- * However, this may look funny in the case where a single word is
- * highlighted. To undo the change, replace "leftX = 0" with "leftX
- * = chunkPtr->x" and "rightX2 = 0" with "rightX2 = nextPtr2->x"
- * here and at all the marked points below. This restores the old
- * behavior where empty space to the left of a line is not
- * highlighted, leaving a ragged left edge for multi-line
- * highlights.
+ * Note A: in the following statement, and a few others later in this file
+ * marked with "See Note A above", the right side of the assignment was
+ * replaced with 0 on 6/18/97. This has the effect of highlighting the
+ * empty space to the left of a line whenever the leftmost character of
+ * the line is highlighted. This way, multi-line highlights always line up
+ * along their left edges. However, this may look funny in the case where
+ * a single word is highlighted. To undo the change, replace "leftX = 0"
+ * with "leftX = chunkPtr->x" and "rightX2 = 0" with "rightX2 =
+ * nextPtr2->x" here and at all the marked points below. This restores the
+ * old behavior where empty space to the left of a line is not
+ * highlighted, leaving a ragged left edge for multi-line highlights.
*/
leftX = 0;
@@ -1922,9 +2584,12 @@ DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap)
rightX = maxX;
}
if (chunkPtr->stylePtr->bgGC != None) {
- /* Not visible - bail out now */
+ /*
+ * Not visible - bail out now.
+ */
+
if (rightX + xOffset <= 0) {
- leftX = rightX;
+ leftX = rightX;
continue;
}
@@ -1934,11 +2599,12 @@ DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap)
* -32768 (or less) to +something simply does not display
* correctly. [Patch #541999]
*/
+
if ((leftX + xOffset) < -(sValuePtr->borderWidth)) {
- leftX = -sValuePtr->borderWidth - xOffset;
+ leftX = -sValuePtr->borderWidth - xOffset;
}
if ((rightX - leftX) > 32767) {
- rightX = leftX + 32767;
+ rightX = leftX + 32767;
}
XFillRectangle(display, pixmap, chunkPtr->stylePtr->bgGC,
@@ -1958,9 +2624,9 @@ DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap)
}
/*
- * Pass 2: draw the horizontal bevels along the top of the line. To
- * do this, scan through dlPtr from left to right while simultaneously
- * scanning through the line just above dlPtr. ChunkPtr2 and nextPtr2
+ * Pass 2: draw the horizontal bevels along the top of the line. To do
+ * this, scan through dlPtr from left to right while simultaneously
+ * scanning through the line just above dlPtr. ChunkPtr2 and nextPtr2
* refer to two adjacent chunks in the line above.
*/
@@ -2001,8 +2667,8 @@ DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap)
sValuePtr = chunkPtr->stylePtr->sValuePtr;
if (rightX <= rightX2) {
/*
- * The chunk in our line is about to end. If its style
- * changes then draw the bevel for the current style.
+ * The chunk in our line is about to end. If its style changes
+ * then draw the bevel for the current style.
*/
if ((chunkPtr->nextPtr == NULL)
@@ -2018,9 +2684,8 @@ DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap)
leftXIn = 1;
/*
- * If the chunk in the line above is also ending at
- * the same point then advance to the next chunk in
- * that line.
+ * If the chunk in the line above is also ending at the same
+ * point then advance to the next chunk in that line.
*/
if ((rightX == rightX2) && (chunkPtr2 != NULL)) {
@@ -2039,11 +2704,10 @@ DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap)
}
/*
- * The chunk in the line above is ending at an x-position where
- * there is no change in the style of the current line. If the
- * style above matches the current line on one side of the change
- * but not on the other, we have to draw an L-shaped piece of
- * bevel.
+ * The chunk in the line above is ending at an x-position where there
+ * is no change in the style of the current line. If the style above
+ * matches the current line on one side of the change but not on the
+ * other, we have to draw an L-shaped piece of bevel.
*/
matchRight = (nextPtr2 != NULL)
@@ -2063,12 +2727,12 @@ DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap)
rightX2 + xOffset, y, sValuePtr->borderWidth,
sValuePtr->borderWidth, 1, sValuePtr->relief);
Tk_3DHorizontalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
- leftX + xOffset, y, rightX2 + sValuePtr->borderWidth -
+ leftX + xOffset, y, rightX2 + sValuePtr->borderWidth -
leftX, sValuePtr->borderWidth, leftXIn, 0, 1,
sValuePtr->relief);
}
- nextChunk2:
+ nextChunk2:
chunkPtr2 = nextPtr2;
if (chunkPtr2 == NULL) {
rightX2 = INT_MAX;
@@ -2080,9 +2744,10 @@ DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap)
}
}
}
+
/*
- * Pass 3: draw the horizontal bevels along the bottom of the line.
- * This uses the same approach as pass 2.
+ * Pass 3: draw the horizontal bevels along the bottom of the line. This
+ * uses the same approach as pass 2.
*/
chunkPtr = dlPtr->chunkPtr;
@@ -2173,7 +2838,7 @@ DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap)
sValuePtr->relief);
}
- nextChunk2b:
+ nextChunk2b:
chunkPtr2 = nextPtr2;
if (chunkPtr2 == NULL) {
rightX2 = INT_MAX;
@@ -2190,11 +2855,1025 @@ DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap)
/*
*----------------------------------------------------------------------
*
+ * AsyncUpdateLineMetrics --
+ *
+ * This function is invoked as a background handler to update the pixel-
+ * height calculations of individual lines in an asychronous manner.
+ *
+ * Currently a timer-handler is used for this purpose, which continuously
+ * reschedules itself. It may well be better to use some other approach
+ * (e.g., a background thread). We can't use an idle-callback because of
+ * a known bug in Tcl/Tk in which idle callbacks are not allowed to
+ * re-schedule themselves. This just causes an effective infinite loop.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Line heights may be recalculated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AsyncUpdateLineMetrics(
+ ClientData clientData) /* Information about widget. */
+{
+ register TkText *textPtr = (TkText *) clientData;
+ TextDInfo *dInfoPtr = textPtr->dInfoPtr;
+ int lineNum;
+
+ dInfoPtr->lineUpdateTimer = NULL;
+
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
+ /*
+ * The widget has been deleted. Don't do anything.
+ */
+
+ if (--textPtr->refCount == 0) {
+ ckfree((char *) textPtr);
+ }
+ return;
+ }
+
+ if (dInfoPtr->flags & REDRAW_PENDING) {
+ dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
+ AsyncUpdateLineMetrics, clientData);
+ return;
+ }
+
+ lineNum = dInfoPtr->currentMetricUpdateLine;
+ if (dInfoPtr->lastMetricUpdateLine == -1) {
+ dInfoPtr->lastMetricUpdateLine =
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr);
+ }
+
+ /*
+ * Update the lines in blocks of about 24 recalculations, or 250+ lines
+ * examined, so we pass in 256 for 'doThisMuch'.
+ */
+
+ lineNum = TkTextUpdateLineMetrics(textPtr, lineNum,
+ dInfoPtr->lastMetricUpdateLine, 256);
+
+ if (tkTextDebug) {
+ char buffer[2 * TCL_INTEGER_SPACE + 1];
+
+ sprintf(buffer, "%d %d", lineNum, dInfoPtr->lastMetricUpdateLine);
+ LOG("tk_textInvalidateLine", buffer);
+ }
+
+ /*
+ * If we're not in the middle of a long-line calculation (metricEpoch==-1)
+ * and we've reached the last line, then we're done.
+ */
+
+ if (dInfoPtr->metricEpoch == -1
+ && lineNum == dInfoPtr->lastMetricUpdateLine) {
+ /*
+ * We have looped over all lines, so we're done. We must release our
+ * refCount on the widget (the timer token was already set to NULL
+ * above).
+ */
+
+ textPtr->refCount--;
+ if (textPtr->refCount == 0) {
+ ckfree((char *) textPtr);
+ }
+ return;
+ }
+ dInfoPtr->currentMetricUpdateLine = lineNum;
+
+ /*
+ * Re-arm the timer. We already have a refCount on the text widget so no
+ * need to adjust that.
+ */
+
+ dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
+ AsyncUpdateLineMetrics, (ClientData) textPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkTextUpdateLineMetrics --
+ *
+ * This function updates the pixel height calculations of a range of
+ * lines in the widget. The range is from lineNum to endLine, but, if
+ * doThisMuch is positive, then the function may return earlier, once a
+ * certain number of lines has been examined. The line counts are from 0.
+ *
+ * If doThisMuch is -1, then all lines in the range will be updated. This
+ * will potentially take quite some time for a large text widget.
+ *
+ * Note: with bad input for lineNum and endLine, this function can loop
+ * indefinitely.
+ *
+ * Results:
+ * The index of the last line examined (or -1 if we are about to wrap
+ * around from end to beginning of the widget, and the next line will be
+ * the first line).
+ *
+ * Side effects:
+ * Line heights may be recalculated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkTextUpdateLineMetrics(
+ TkText *textPtr, /* Information about widget. */
+ int lineNum, /* Start at this line. */
+ int endLine, /* Go no further than this line. */
+ int doThisMuch) /* How many lines to check, or how many 10s of
+ * lines to recalculate. If '-1' then do
+ * everything in the range (which may take a
+ * while). */
+{
+ TkTextLine *linePtr = NULL;
+ int count = 0;
+ int totalLines = TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr);
+
+ if (totalLines == 0) {
+ /*
+ * Empty peer widget.
+ */
+
+ return endLine;
+ }
+
+ while (1) {
+ /*
+ * Get a suitable line.
+ */
+
+ if (lineNum == -1 && linePtr == NULL) {
+ lineNum = 0;
+ linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr,
+ lineNum);
+ } else {
+ if (lineNum == -1 || linePtr == NULL) {
+ if (lineNum == -1) {
+ lineNum = 0;
+ }
+ linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree,
+ textPtr, lineNum);
+ } else {
+ lineNum++;
+ linePtr = TkBTreeNextLine(textPtr, linePtr);
+ }
+
+ /*
+ * If we're in the middle of a partial-line height calculation,
+ * then we can't be done.
+ */
+
+ if (textPtr->dInfoPtr->metricEpoch == -1 && lineNum == endLine) {
+ /*
+ * We have looped over all lines, so we're done.
+ */
+
+ break;
+ }
+ }
+
+ if (lineNum < totalLines) {
+ if (tkTextDebug) {
+ char buffer[4 * TCL_INTEGER_SPACE + 3];
+
+ sprintf(buffer, "%d %d %d %d",
+ lineNum, endLine, totalLines, count);
+ LOG("tk_textInvalidateLine", buffer);
+ }
+
+ /*
+ * Now update the line's metrics if necessary.
+ */
+
+ if (TkBTreeLinePixelEpoch(textPtr, linePtr)
+ != textPtr->dInfoPtr->lineMetricUpdateEpoch) {
+ if (doThisMuch == -1) {
+ count += 8 * TkTextUpdateOneLine(textPtr, linePtr, 0,
+ NULL, 0);
+ } else {
+ TkTextIndex index;
+ TkTextIndex *indexPtr;
+ int pixelHeight;
+
+ /*
+ * If the metric epoch is the same as the widget's epoch,
+ * then we know that indexPtrs are still valid, and if the
+ * cached metricIndex (if any) is for the same line as we
+ * wish to examine, then we are looking at a long line
+ * wrapped many times, which we will examine in pieces.
+ */
+
+ if (textPtr->dInfoPtr->metricEpoch ==
+ textPtr->sharedTextPtr->stateEpoch &&
+ textPtr->dInfoPtr->metricIndex.linePtr==linePtr) {
+ indexPtr = &textPtr->dInfoPtr->metricIndex;
+ pixelHeight = textPtr->dInfoPtr->metricPixelHeight;
+ } else {
+ /*
+ * We must reset the partial line height calculation
+ * data here, so we don't use it when it is out of
+ * date.
+ */
+
+ textPtr->dInfoPtr->metricEpoch = -1;
+ index.tree = textPtr->sharedTextPtr->tree;
+ index.linePtr = linePtr;
+ index.byteIndex = 0;
+ index.textPtr = NULL;
+ indexPtr = &index;
+ pixelHeight = 0;
+ }
+
+ /*
+ * Update the line and update the counter, counting 8 for
+ * each display line we actually re-layout.
+ */
+
+ count += 8 * TkTextUpdateOneLine(textPtr, linePtr,
+ pixelHeight, indexPtr, 1);
+
+ if (indexPtr->linePtr == linePtr) {
+ /*
+ * We didn't complete the logical line, because it
+ * produced very many display lines - it must be a
+ * long line wrapped many times. So we must cache as
+ * far as we got for next time around.
+ */
+
+ if (pixelHeight == 0) {
+ /*
+ * These have already been stored, unless we just
+ * started the new line.
+ */
+
+ textPtr->dInfoPtr->metricIndex = index;
+ textPtr->dInfoPtr->metricEpoch =
+ textPtr->sharedTextPtr->stateEpoch;
+ }
+ textPtr->dInfoPtr->metricPixelHeight =
+ TkBTreeLinePixelCount(textPtr, linePtr);
+ break;
+ } else {
+ /*
+ * We're done with this long line.
+ */
+
+ textPtr->dInfoPtr->metricEpoch = -1;
+ }
+ }
+ } else {
+ /*
+ * This line is already up to date. That means there's nothing
+ * to do here.
+ */
+ }
+ } else {
+ /*
+ * We must never recalculate the height of the last artificial
+ * line. It must stay at zero, and if we recalculate it, it will
+ * change.
+ */
+
+ if (endLine >= totalLines) {
+ lineNum = endLine;
+ break;
+ }
+
+ /*
+ * Set things up for the next loop through.
+ */
+
+ lineNum = -1;
+ }
+ count++;
+
+ if (doThisMuch != -1 && count >= doThisMuch) {
+ break;
+ }
+ }
+ if (doThisMuch == -1) {
+ /*
+ * If we were requested to provide a full update, then also update the
+ * scrollbar.
+ */
+
+ GetYView(textPtr->interp, textPtr, 1);
+ }
+ return lineNum;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkTextInvalidateLineMetrics, TextInvalidateLineMetrics --
+ *
+ * Mark a number of text lines as having invalid line metric
+ * calculations. Never call this with linePtr as the last (artificial)
+ * line in the text. Depending on 'action' which indicates whether the
+ * given lines are simply invalid or have been inserted or deleted, the
+ * pre-existing asynchronous line update range may need to be adjusted.
+ *
+ * If linePtr is NULL then 'lineCount' and 'action' are ignored and all
+ * lines are invalidated.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May schedule an asychronous callback.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkTextInvalidateLineMetrics(
+ TkSharedText *sharedTextPtr,/* Shared widget section for all peers, or
+ * NULL. */
+ TkText *textPtr, /* Widget record for text widget. */
+ TkTextLine *linePtr, /* Invalidation starts from this line. */
+ int lineCount, /* And includes this many following lines. */
+ int action) /* Indicates what type of invalidation
+ * occurred (insert, delete, or simple). */
+{
+ if (sharedTextPtr == NULL) {
+ TextInvalidateLineMetrics(textPtr, linePtr, lineCount, action);
+ } else {
+ textPtr = sharedTextPtr->peers;
+ while (textPtr != NULL) {
+ TextInvalidateLineMetrics(textPtr, linePtr, lineCount, action);
+ textPtr = textPtr->next;
+ }
+ }
+}
+
+static void
+TextInvalidateLineMetrics(
+ TkText *textPtr, /* Widget record for text widget. */
+ TkTextLine *linePtr, /* Invalidation starts from this line. */
+ int lineCount, /* And includes this many following lines. */
+ int action) /* Indicates what type of invalidation
+ * occurred (insert, delete, or simple). */
+{
+ int fromLine;
+ TextDInfo *dInfoPtr = textPtr->dInfoPtr;
+
+ if (linePtr != NULL) {
+ int counter = lineCount;
+
+ fromLine = TkBTreeLinesTo(textPtr, linePtr);
+
+ /*
+ * Invalidate the height calculations of each line in the given range.
+ */
+
+ TkBTreeLinePixelEpoch(textPtr, linePtr) = 0;
+ while (counter > 0 && linePtr != NULL) {
+ linePtr = TkBTreeNextLine(textPtr, linePtr);
+ if (linePtr != NULL) {
+ TkBTreeLinePixelEpoch(textPtr, linePtr) = 0;
+ }
+ counter--;
+ }
+
+ /*
+ * Now schedule an examination of each line in the union of the old
+ * and new update ranges, including the (possibly empty) range in
+ * between. If that between range is not-empty, then we are examining
+ * more lines than is strictly necessary (but the examination of the
+ * extra lines should be quick, since their pixelCalculationEpoch will
+ * be up to date). However, to keep track of that would require more
+ * complex record-keeping than what we have.
+ */
+
+ if (dInfoPtr->lineUpdateTimer == NULL) {
+ dInfoPtr->currentMetricUpdateLine = fromLine;
+ if (action == TK_TEXT_INVALIDATE_DELETE) {
+ lineCount = 0;
+ }
+ dInfoPtr->lastMetricUpdateLine = fromLine + lineCount + 1;
+ } else {
+ int toLine = fromLine + lineCount + 1;
+
+ if (action == TK_TEXT_INVALIDATE_DELETE) {
+ if (toLine <= dInfoPtr->currentMetricUpdateLine) {
+ dInfoPtr->currentMetricUpdateLine = fromLine;
+ if (dInfoPtr->lastMetricUpdateLine != -1) {
+ dInfoPtr->lastMetricUpdateLine -= lineCount;
+ }
+ } else if (fromLine <= dInfoPtr->currentMetricUpdateLine) {
+ dInfoPtr->currentMetricUpdateLine = fromLine;
+ if (toLine <= dInfoPtr->lastMetricUpdateLine) {
+ dInfoPtr->lastMetricUpdateLine -= lineCount;
+ }
+ } else {
+ if (dInfoPtr->lastMetricUpdateLine != -1) {
+ dInfoPtr->lastMetricUpdateLine = toLine;
+ }
+ }
+ } else if (action == TK_TEXT_INVALIDATE_INSERT) {
+ if (toLine <= dInfoPtr->currentMetricUpdateLine) {
+ dInfoPtr->currentMetricUpdateLine = fromLine;
+ if (dInfoPtr->lastMetricUpdateLine != -1) {
+ dInfoPtr->lastMetricUpdateLine += lineCount;
+ }
+ } else if (fromLine <= dInfoPtr->currentMetricUpdateLine) {
+ dInfoPtr->currentMetricUpdateLine = fromLine;
+ if (toLine <= dInfoPtr->lastMetricUpdateLine) {
+ dInfoPtr->lastMetricUpdateLine += lineCount;
+ }
+ if (toLine > dInfoPtr->lastMetricUpdateLine) {
+ dInfoPtr->lastMetricUpdateLine = toLine;
+ }
+ } else {
+ if (dInfoPtr->lastMetricUpdateLine != -1) {
+ dInfoPtr->lastMetricUpdateLine = toLine;
+ }
+ }
+ } else {
+ if (fromLine < dInfoPtr->currentMetricUpdateLine) {
+ dInfoPtr->currentMetricUpdateLine = fromLine;
+ }
+ if (dInfoPtr->lastMetricUpdateLine != -1
+ && toLine > dInfoPtr->lastMetricUpdateLine) {
+ dInfoPtr->lastMetricUpdateLine = toLine;
+ }
+ }
+ }
+ } else {
+ /*
+ * This invalidates the height of all lines in the widget.
+ */
+
+ if ((++dInfoPtr->lineMetricUpdateEpoch) == 0) {
+ dInfoPtr->lineMetricUpdateEpoch++;
+ }
+
+ /*
+ * This has the effect of forcing an entire new loop of update checks
+ * on all lines in the widget.
+ */
+
+ if (dInfoPtr->lineUpdateTimer == NULL) {
+ dInfoPtr->currentMetricUpdateLine = -1;
+ }
+ dInfoPtr->lastMetricUpdateLine = dInfoPtr->currentMetricUpdateLine;
+ }
+
+ /*
+ * Now re-set the current update calculations.
+ */
+
+ if (dInfoPtr->lineUpdateTimer == NULL) {
+ textPtr->refCount++;
+ dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
+ AsyncUpdateLineMetrics, (ClientData) textPtr);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkTextFindDisplayLineEnd --
+ *
+ * This function is invoked to find the index of the beginning or end of
+ * the particular display line on which the given index sits, whether
+ * that line is displayed or not.
+ *
+ * If 'end' is zero, we look for the start, and if 'end' is one we look
+ * for the end.
+ *
+ * If the beginning of the current display line is elided, and we are
+ * looking for the start of the line, then the returned index will be the
+ * first elided index on the display line.
+ *
+ * Similarly if the end of the current display line is elided and we are
+ * looking for the end, then the returned index will be the last elided
+ * index on the display line.
+ *
+ * Results:
+ * Modifies indexPtr to point to the given end.
+ *
+ * If xOffset is non-NULL, it is set to the x-pixel offset of the given
+ * original index within the given display line.
+ *
+ * Side effects:
+ * The combination of 'LayoutDLine' and 'FreeDLines' seems like a rather
+ * time-consuming way of gathering the information we need, so this would
+ * be a good place to look to speed up the calculations. In particular
+ * these calls will map and unmap embedded windows respectively, which I
+ * would hope isn't exactly necessary!
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkTextFindDisplayLineEnd(
+ TkText *textPtr, /* Widget record for text widget. */
+ TkTextIndex *indexPtr, /* Index we will adjust to the display line
+ * start or end. */
+ int end, /* 0 = start, 1 = end. */
+ int *xOffset) /* NULL, or used to store the x-pixel offset
+ * of the original index within its display
+ * line. */
+{
+ if (!end && indexPtr->byteIndex == 0) {
+ /*
+ * Nothing to do.
+ */
+
+ if (xOffset != NULL) {
+ *xOffset = 0;
+ }
+ return;
+ } else {
+ TkTextIndex index = *indexPtr;
+
+ index.byteIndex = 0;
+ index.textPtr = NULL;
+
+ while (1) {
+ TkTextIndex endOfLastLine;
+
+ if (TkTextIndexBackBytes(textPtr, &index, 1, &endOfLastLine)) {
+ /*
+ * Reached beginning of text.
+ */
+
+ break;
+ }
+
+ if (!TkTextIsElided(textPtr, &endOfLastLine, NULL)) {
+ /*
+ * The eol is not elided, so 'index' points to the start of a
+ * display line (as well as logical line).
+ */
+
+ break;
+ }
+
+ /*
+ * indexPtr's logical line is actually merged with the previous
+ * logical line whose eol is elided. Continue searching back to
+ * get a real line start.
+ */
+
+ index = endOfLastLine;
+ index.byteIndex = 0;
+ }
+
+ while (1) {
+ DLine *dlPtr;
+ int byteCount;
+ TkTextIndex nextLineStart;
+
+ dlPtr = LayoutDLine(textPtr, &index);
+ byteCount = dlPtr->byteCount;
+
+ TkTextIndexForwBytes(textPtr, &index, byteCount, &nextLineStart);
+
+ /*
+ * 'byteCount' goes up to the beginning of the next display line,
+ * so equality here says we need one more line. We try to perform
+ * a quick comparison which is valid for the case where the
+ * logical line is the same, but otherwise fall back on a full
+ * TkTextIndexCmp.
+ */
+
+ if (((index.linePtr == indexPtr->linePtr)
+ && (index.byteIndex + byteCount > indexPtr->byteIndex))
+ || (dlPtr->logicalLinesMerged > 0
+ && TkTextIndexCmp(&nextLineStart, indexPtr) > 0)) {
+ /*
+ * It's on this display line.
+ */
+
+ if (xOffset != NULL) {
+ /*
+ * This call takes a byte index relative to the start of
+ * the current _display_ line, not logical line. We are
+ * about to overwrite indexPtr->byteIndex, so we must do
+ * this now.
+ */
+
+ *xOffset = DlineXOfIndex(textPtr, dlPtr,
+ indexPtr->byteIndex - dlPtr->index.byteIndex);
+ }
+ if (end) {
+ /*
+ * The index we want is one less than the number of bytes
+ * in the display line.
+ */
+
+ TkTextIndexBackBytes(textPtr, &nextLineStart, 1, indexPtr);
+ } else {
+ *indexPtr = index;
+ }
+ FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE_TEMP);
+ return;
+ }
+ FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE_TEMP);
+ index = nextLineStart;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CalculateDisplayLineHeight --
+ *
+ * This function is invoked to recalculate the height of the particular
+ * display line which starts with the given index, whether that line is
+ * displayed or not.
+ *
+ * This function does not, in itself, update any cached information about
+ * line heights. That should be done, where necessary, by its callers.
+ *
+ * The behaviour of this function is _undefined_ if indexPtr is not
+ * currently at the beginning of a display line.
+ *
+ * Results:
+ * The number of vertical pixels used by the display line.
+ *
+ * If 'byteCountPtr' is non-NULL, then returns in that pointer the number
+ * of byte indices on the given display line (which can be used to update
+ * indexPtr in a loop).
+ *
+ * If 'mergedLinePtr' is non-NULL, then returns in that pointer the
+ * number of extra logical lines merged into the given display line.
+ *
+ * Side effects:
+ * The combination of 'LayoutDLine' and 'FreeDLines' seems like a rather
+ * time-consuming way of gathering the information we need, so this would
+ * be a good place to look to speed up the calculations. In particular
+ * these calls will map and unmap embedded windows respectively, which I
+ * would hope isn't exactly necessary!
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CalculateDisplayLineHeight(
+ TkText *textPtr, /* Widget record for text widget. */
+ CONST TkTextIndex *indexPtr,/* The index at the beginning of the display
+ * line of interest. */
+ int *byteCountPtr, /* NULL or used to return the number of byte
+ * indices on the given display line. */
+ int *mergedLinePtr) /* NULL or used to return if the given display
+ * line merges with a following logical line
+ * (because the eol is elided). */
+{
+ DLine *dlPtr;
+ int pixelHeight;
+
+ /*
+ * Special case for artificial last line. May be better to move this
+ * inside LayoutDLine.
+ */
+
+ if (indexPtr->byteIndex == 0
+ && TkBTreeNextLine(textPtr, indexPtr->linePtr) == NULL) {
+ if (byteCountPtr != NULL) {
+ *byteCountPtr = 0;
+ }
+ if (mergedLinePtr != NULL) {
+ *mergedLinePtr = 0;
+ }
+ return 0;
+ }
+
+ /*
+ * Layout, find the information we need and then free the display-line we
+ * laid-out. We must use 'FreeDLines' because it will actually call the
+ * relevant code to unmap any embedded windows which were mapped in the
+ * LayoutDLine call!
+ */
+
+ dlPtr = LayoutDLine(textPtr, indexPtr);
+ pixelHeight = dlPtr->height;
+ if (byteCountPtr != NULL) {
+ *byteCountPtr = dlPtr->byteCount;
+ }
+ if (mergedLinePtr != NULL) {
+ *mergedLinePtr = dlPtr->logicalLinesMerged;
+ }
+ FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE_TEMP);
+
+ return pixelHeight;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkTextIndexYPixels --
+ *
+ * This function is invoked to calculate the number of vertical pixels
+ * between the first index of the text widget and the given index. The
+ * range from first logical line to given logical line is determined
+ * using the cached values, and the range inside the given logical line
+ * is calculated on the fly.
+ *
+ * Results:
+ * The pixel distance between first pixel in the widget and the
+ * top of the index's current display line (could be zero).
+ *
+ * Side effects:
+ * Just those of 'CalculateDisplayLineHeight'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkTextIndexYPixels(
+ TkText *textPtr, /* Widget record for text widget. */
+ CONST TkTextIndex *indexPtr)/* The index of which we want the pixel
+ * distance from top of logical line to top of
+ * index. */
+{
+ int pixelHeight;
+ TkTextIndex index;
+
+ pixelHeight = TkBTreePixelsTo(textPtr, indexPtr->linePtr);
+
+ /*
+ * Iterate through all display-lines corresponding to the single logical
+ * line belonging to indexPtr, adding up the pixel height of each such
+ * display line as we go along, until we go past 'indexPtr'.
+ */
+
+ if (indexPtr->byteIndex == 0) {
+ return pixelHeight;
+ }
+
+ index.tree = textPtr->sharedTextPtr->tree;
+ index.linePtr = indexPtr->linePtr;
+ index.byteIndex = 0;
+ index.textPtr = NULL;
+
+ while (1) {
+ int bytes, height;
+
+ /*
+ * Currently this call doesn't have many side-effects. However, if in
+ * the future we change the code so there are side-effects (such as
+ * adjusting linePtr->pixelHeight), then the code might not quite work
+ * as intended, specifically the 'linePtr->pixelHeight == pixelHeight'
+ * test below this while loop.
+ */
+
+ height = CalculateDisplayLineHeight(textPtr, &index, &bytes, NULL);
+
+ index.byteIndex += bytes;
+
+ if (index.byteIndex > indexPtr->byteIndex) {
+ return pixelHeight;
+ }
+
+ if (height > 0) {
+ pixelHeight += height;
+ }
+
+ if (index.byteIndex == indexPtr->byteIndex) {
+ return pixelHeight;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkTextUpdateOneLine --
+ *
+ * This function is invoked to recalculate the height of a particular
+ * logical line, whether that line is displayed or not.
+ *
+ * It must NEVER be called for the artificial last TkTextLine which is
+ * used internally for administrative purposes only. That line must
+ * retain its initial height of 0 otherwise the pixel height calculation
+ * maintained by the B-tree will be wrong.
+ *
+ * Results:
+ * The number of display lines in the logical line. This could be zero if
+ * the line is totally elided.
+ *
+ * Side effects:
+ * Line heights may be recalculated, and a timer to update the scrollbar
+ * may be installed. Also see the called function
+ * CalculateDisplayLineHeight for its side effects.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkTextUpdateOneLine(
+ TkText *textPtr, /* Widget record for text widget. */
+ TkTextLine *linePtr, /* The line of which to calculate the
+ * height. */
+ int pixelHeight, /* If indexPtr is non-NULL, then this is the
+ * number of pixels in the logical line
+ * linePtr, up to the index which has been
+ * given. */
+ TkTextIndex *indexPtr, /* Either NULL or an index at the start of a
+ * display line belonging to linePtr, at which
+ * we wish to start (e.g. up to which we have
+ * already calculated). On return this will be
+ * set to the first index on the next line. */
+ int partialCalc) /* Set to 1 if we are allowed to do partial
+ * height calculations of long-lines. In this
+ * case we'll only return what we know so
+ * far. */
+{
+ TkTextIndex index;
+ int displayLines;
+ int mergedLines;
+
+ if (indexPtr == NULL) {
+ index.tree = textPtr->sharedTextPtr->tree;
+ index.linePtr = linePtr;
+ index.byteIndex = 0;
+ index.textPtr = NULL;
+ indexPtr = &index;
+ pixelHeight = 0;
+ }
+
+ /*
+ * Iterate through all display-lines corresponding to the single logical
+ * line 'linePtr', adding up the pixel height of each such display line as
+ * we go along. The final total is, therefore, the height of the logical
+ * line.
+ */
+
+ displayLines = 0;
+ mergedLines = 0;
+
+ while (1) {
+ int bytes, height, logicalLines;
+
+ /*
+ * Currently this call doesn't have many side-effects. However, if in
+ * the future we change the code so there are side-effects (such as
+ * adjusting linePtr->pixelHeight), then the code might not quite work
+ * as intended, specifically the 'linePtr->pixelHeight == pixelHeight'
+ * test below this while loop.
+ */
+
+ height = CalculateDisplayLineHeight(textPtr, indexPtr, &bytes,
+ &logicalLines);
+
+ if (height > 0) {
+ pixelHeight += height;
+ displayLines++;
+ }
+
+ mergedLines += logicalLines;
+
+ if (TkTextIndexForwBytes(textPtr, indexPtr, bytes, indexPtr)) {
+ break;
+ }
+
+ if (logicalLines == 0) {
+ if (indexPtr->linePtr != linePtr) {
+ /*
+ * If we reached the end of the logical line, then either way
+ * we don't have a partial calculation.
+ */
+
+ partialCalc = 0;
+ break;
+ }
+ } else if (indexPtr->byteIndex != 0) {
+ /*
+ * We must still be on the same wrapped line.
+ */
+ } else {
+ /*
+ * Must check if indexPtr is really a new logical line which is
+ * not merged with the previous line. The only code that would
+ * really know this is LayoutDLine, which doesn't pass the
+ * information on, so we have to check manually here.
+ */
+
+ TkTextIndex idx;
+
+ TkTextIndexBackChars(textPtr, indexPtr, 1, &idx, COUNT_INDICES);
+ if (!TkTextIsElided(textPtr, &idx, NULL)) {
+ /*
+ * We've ended a logical line.
+ */
+
+ partialCalc = 0;
+ break;
+ }
+
+ /*
+ * We must still be on the same wrapped line.
+ */
+ }
+ if (partialCalc && displayLines > 50 && mergedLines == 0) {
+ /*
+ * Only calculate 50 display lines at a time, to avoid huge
+ * delays. In any case it is very rare that a single line wraps 50
+ * times!
+ *
+ * If we have any merged lines, we must complete the full logical
+ * line layout here and now, because the partial-calculation code
+ * isn't designed to handle merged logical lines. Hence the
+ * 'mergedLines == 0' check.
+ */
+
+ break;
+ }
+ }
+
+ if (!partialCalc) {
+ int changed = 0;
+
+ /*
+ * Cancel any partial line height calculation state.
+ */
+
+ textPtr->dInfoPtr->metricEpoch = -1;
+
+ /*
+ * Mark the logical line as being up to date (caution: it isn't yet up
+ * to date, that will happen in TkBTreeAdjustPixelHeight just below).
+ */
+
+ TkBTreeLinePixelEpoch(textPtr, linePtr)
+ = textPtr->dInfoPtr->lineMetricUpdateEpoch;
+ if (TkBTreeLinePixelCount(textPtr, linePtr) != pixelHeight) {
+ changed = 1;
+ }
+
+ if (mergedLines > 0) {
+ int i = mergedLines;
+ TkTextLine *mergedLinePtr;
+
+ /*
+ * Loop over all merged logical lines, marking them up to date
+ * (again, the pixel count setting will actually happen in
+ * TkBTreeAdjustPixelHeight).
+ */
+
+ mergedLinePtr = linePtr;
+ while (i-- > 0) {
+ mergedLinePtr = TkBTreeNextLine(textPtr, mergedLinePtr);
+ TkBTreeLinePixelEpoch(textPtr, mergedLinePtr)
+ = textPtr->dInfoPtr->lineMetricUpdateEpoch;
+ if (TkBTreeLinePixelCount(textPtr, mergedLinePtr) != 0) {
+ changed = 1;
+ }
+ }
+ }
+
+ if (!changed) {
+ /*
+ * If there's nothing to change, then we can already return.
+ */
+
+ return displayLines;
+ }
+ }
+
+ /*
+ * We set the line's height, but the return value is now the height of the
+ * entire widget, which may be used just below for reporting/debugging
+ * purposes.
+ */
+
+ pixelHeight = TkBTreeAdjustPixelHeight(textPtr, linePtr, pixelHeight,
+ mergedLines);
+
+ if (tkTextDebug) {
+ char buffer[2 * TCL_INTEGER_SPACE + 1];
+
+ if (TkBTreeNextLine(textPtr, linePtr) == NULL) {
+ Tcl_Panic("Mustn't ever update line height of last artificial line");
+ }
+
+ sprintf(buffer, "%d %d", TkBTreeLinesTo(textPtr,linePtr), pixelHeight);
+ LOG("tk_textNumPixels", buffer);
+ }
+ if (textPtr->dInfoPtr->scrollbarTimer == NULL) {
+ textPtr->refCount++;
+ textPtr->dInfoPtr->scrollbarTimer = Tcl_CreateTimerHandler(200,
+ AsyncUpdateYScrollbar, (ClientData) textPtr);
+ }
+ return displayLines;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* DisplayText --
*
- * This procedure is invoked as a when-idle handler to update the
- * display. It only redisplays the parts of the text widget that
- * are out of date.
+ * This function is invoked as a when-idle handler to update the display.
+ * It only redisplays the parts of the text widget that are out of date.
*
* Results:
* None.
@@ -2206,24 +3885,22 @@ DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap)
*/
static void
-DisplayText(clientData)
- ClientData clientData; /* Information about widget. */
+DisplayText(
+ ClientData clientData) /* Information about widget. */
{
register TkText *textPtr = (TkText *) clientData;
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
- Tk_Window tkwin;
register DLine *dlPtr;
DLine *prevPtr;
Pixmap pixmap;
int maxHeight, borders;
- int bottomY = 0; /* Initialization needed only to stop
- * compiler warnings. */
+ int bottomY = 0; /* Initialization needed only to stop compiler
+ * warnings. */
Tcl_Interp *interp;
- if (textPtr->tkwin == NULL) {
-
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
/*
- * The widget has been deleted. Don't do anything.
+ * The widget has been deleted. Don't do anything.
*/
return;
@@ -2233,17 +3910,15 @@ DisplayText(clientData)
Tcl_Preserve((ClientData) interp);
if (tkTextDebug) {
- Tcl_SetVar2(interp, "tk_textRelayout", (char *) NULL, "",
- TCL_GLOBAL_ONLY);
+ Tcl_SetVar2(interp, "tk_textRelayout", NULL, "", TCL_GLOBAL_ONLY);
}
- if (textPtr->tkwin == NULL) {
-
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
/*
- * The widget has been deleted. Don't do anything.
+ * The widget has been deleted. Don't do anything.
*/
- goto end;
+ goto end;
}
if (!Tk_IsMapped(textPtr->tkwin) || (dInfoPtr->maxX <= dInfoPtr->x)
@@ -2254,34 +3929,34 @@ DisplayText(clientData)
}
numRedisplays++;
if (tkTextDebug) {
- Tcl_SetVar2(interp, "tk_textRedraw", (char *) NULL, "",
- TCL_GLOBAL_ONLY);
+ Tcl_SetVar2(interp, "tk_textRedraw", NULL, "", TCL_GLOBAL_ONLY);
}
- if (textPtr->tkwin == NULL) {
-
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
/*
- * The widget has been deleted. Don't do anything.
+ * The widget has been deleted. Don't do anything.
*/
goto end;
}
/*
- * Choose a new current item if that is needed (this could cause
- * event handlers to be invoked, hence the preserve/release calls
- * and the loop, since the handlers could conceivably necessitate
- * yet another current item calculation). The tkwin check is because
- * the whole window could go away in the Tcl_Release call.
+ * Choose a new current item if that is needed (this could cause event
+ * handlers to be invoked, hence the preserve/release calls and the loop,
+ * since the handlers could conceivably necessitate yet another current
+ * item calculation). The tkwin check is because the whole window could go
+ * away in the Tcl_Release call.
*/
while (dInfoPtr->flags & REPICK_NEEDED) {
- Tcl_Preserve((ClientData) textPtr);
+ textPtr->refCount++;
dInfoPtr->flags &= ~REPICK_NEEDED;
TkTextPickCurrent(textPtr, &textPtr->pickEvent);
- tkwin = textPtr->tkwin;
- Tcl_Release((ClientData) textPtr);
- if (tkwin == NULL) {
+ if (--textPtr->refCount == 0) {
+ ckfree((char *) textPtr);
+ goto end;
+ }
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
goto end;
}
}
@@ -2294,8 +3969,11 @@ DisplayText(clientData)
dInfoPtr->dLinesInvalidated = 0;
/*
- * See if it's possible to bring some parts of the screen up-to-date
- * by scrolling (copying from other parts of the screen).
+ * See if it's possible to bring some parts of the screen up-to-date by
+ * scrolling (copying from other parts of the screen). We have to be
+ * particularly careful with the top and bottom lines of the display,
+ * since these may only be partially visible and therefore not helpful for
+ * some scrolling purposes.
*/
for (dlPtr = dInfoPtr->dLinePtr; dlPtr != NULL; dlPtr = dlPtr->nextPtr) {
@@ -2303,15 +3981,37 @@ DisplayText(clientData)
int offset, height, y, oldY;
TkRegion damageRgn;
- if ((dlPtr->oldY == -1) || (dlPtr->y == dlPtr->oldY)
- || ((dlPtr->oldY + dlPtr->height) > dInfoPtr->maxY)) {
+ /*
+ * These tests are, in order:
+ *
+ * 1. If the line is already marked as invalid
+ * 2. If the line hasn't moved
+ * 3. If the line overlaps the bottom of the window and we are
+ * scrolling up.
+ * 4. If the line overlaps the top of the window and we are scrolling
+ * down.
+ *
+ * If any of these tests are true, then we can't scroll this line's
+ * part of the display.
+ *
+ * Note that even if tests 3 or 4 aren't true, we may be able to
+ * scroll the line, but we still need to be sure to call embedded
+ * window display procs on top and bottom lines if they have any
+ * portion non-visible (see below).
+ */
+
+ if ((dlPtr->flags & OLD_Y_INVALID)
+ || (dlPtr->y == dlPtr->oldY)
+ || (((dlPtr->oldY + dlPtr->height) > dInfoPtr->maxY)
+ && (dlPtr->y < dlPtr->oldY))
+ || ((dlPtr->oldY < dInfoPtr->y) && (dlPtr->y > dlPtr->oldY))) {
continue;
}
/*
- * This line is already drawn somewhere in the window so it only
- * needs to be copied to its new location. See if there's a group
- * of lines that can all be copied together.
+ * This line is already drawn somewhere in the window so it only needs
+ * to be copied to its new location. See if there's a group of lines
+ * that can all be copied together.
*/
offset = dlPtr->y - dlPtr->oldY;
@@ -2319,7 +4019,7 @@ DisplayText(clientData)
y = dlPtr->y;
for (dlPtr2 = dlPtr->nextPtr; dlPtr2 != NULL;
dlPtr2 = dlPtr2->nextPtr) {
- if ((dlPtr2->oldY == -1)
+ if ((dlPtr2->flags & OLD_Y_INVALID)
|| ((dlPtr2->oldY + offset) != dlPtr2->y)
|| ((dlPtr2->oldY + dlPtr2->height) > dInfoPtr->maxY)) {
break;
@@ -2328,21 +4028,36 @@ DisplayText(clientData)
}
/*
- * Reduce the height of the area being copied if necessary to
- * avoid overwriting the border area.
+ * Reduce the height of the area being copied if necessary to avoid
+ * overwriting the border area.
*/
if ((y + height) > dInfoPtr->maxY) {
height = dInfoPtr->maxY -y;
}
oldY = dlPtr->oldY;
+ if (y < dInfoPtr->y) {
+ /*
+ * Adjust if the area being copied is going to overwrite the top
+ * border of the window (so the top line is only half onscreen).
+ */
+
+ int y_off = dInfoPtr->y - dlPtr->y;
+ height -= y_off;
+ oldY += y_off;
+ y = dInfoPtr->y;
+ }
/*
- * Update the lines we are going to scroll to show that they
- * have been copied.
+ * Update the lines we are going to scroll to show that they have been
+ * copied.
*/
while (1) {
+ /*
+ * The DLine already has OLD_Y_INVALID cleared.
+ */
+
dlPtr->oldY = dlPtr->y;
if (dlPtr->nextPtr == dlPtr2) {
break;
@@ -2351,30 +4066,28 @@ DisplayText(clientData)
}
/*
- * Scan through the lines following the copied ones to see if
- * we are going to overwrite them with the copy operation.
- * If so, mark them for redisplay.
+ * Scan through the lines following the copied ones to see if we are
+ * going to overwrite them with the copy operation. If so, mark them
+ * for redisplay.
*/
for ( ; dlPtr2 != NULL; dlPtr2 = dlPtr2->nextPtr) {
- if ((dlPtr2->oldY != -1)
+ if ((!(dlPtr2->flags & OLD_Y_INVALID))
&& ((dlPtr2->oldY + dlPtr2->height) > y)
&& (dlPtr2->oldY < (y + height))) {
- dlPtr2->oldY = -1;
+ dlPtr2->flags |= OLD_Y_INVALID;
}
}
/*
- * Now scroll the lines. This may generate damage which we
- * handle by calling TextInvalidateRegion to mark the display
- * blocks as stale.
+ * Now scroll the lines. This may generate damage which we handle by
+ * calling TextInvalidateRegion to mark the display blocks as stale.
*/
damageRgn = TkCreateRegion();
- if (TkScrollWindow(textPtr->tkwin, dInfoPtr->scrollGC,
- dInfoPtr->x, oldY,
- (dInfoPtr->maxX - dInfoPtr->x), height,
- 0, y - oldY, damageRgn)) {
+ if (TkScrollWindow(textPtr->tkwin, dInfoPtr->scrollGC, dInfoPtr->x,
+ oldY, dInfoPtr->maxX-dInfoPtr->x, height, 0, y-oldY,
+ damageRgn)) {
TextInvalidateRegion(textPtr, damageRgn);
}
numCopies++;
@@ -2382,14 +4095,13 @@ DisplayText(clientData)
}
/*
- * Clear the REDRAW_PENDING flag here. This is actually pretty
- * tricky. We want to wait until *after* doing the scrolling,
- * since that could generate more areas to redraw and don't
- * want to reschedule a redisplay for them. On the other hand,
- * we can't wait until after all the redisplaying, because the
- * act of redisplaying could actually generate more redisplays
- * (e.g. in the case of a nested window with event bindings triggered
- * by redisplay).
+ * Clear the REDRAW_PENDING flag here. This is actually pretty tricky. We
+ * want to wait until *after* doing the scrolling, since that could
+ * generate more areas to redraw and don't want to reschedule a redisplay
+ * for them. On the other hand, we can't wait until after all the
+ * redisplaying, because the act of redisplaying could actually generate
+ * more redisplays (e.g. in the case of a nested window with event
+ * bindings triggered by redisplay).
*/
dInfoPtr->flags &= ~REDRAW_PENDING;
@@ -2400,18 +4112,16 @@ DisplayText(clientData)
if (dInfoPtr->flags & REDRAW_BORDERS) {
if (tkTextDebug) {
- Tcl_SetVar2(interp, "tk_textRedraw", (char *) NULL, "borders",
- TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+ LOG("tk_textRedraw", "borders");
}
- if (textPtr->tkwin == NULL) {
-
+ if (textPtr->tkwin == NULL) {
/*
- * The widget has been deleted. Don't do anything.
- */
+ * The widget has been deleted. Don't do anything.
+ */
- goto end;
- }
+ goto end;
+ }
Tk_Draw3DRectangle(textPtr->tkwin, Tk_WindowId(textPtr->tkwin),
textPtr->border, textPtr->highlightWidth,
@@ -2421,17 +4131,17 @@ DisplayText(clientData)
textPtr->borderWidth, textPtr->relief);
if (textPtr->highlightWidth != 0) {
GC fgGC, bgGC;
-
+
bgGC = Tk_GCForColor(textPtr->highlightBgColorPtr,
- Tk_WindowId(textPtr->tkwin));
+ Tk_WindowId(textPtr->tkwin));
if (textPtr->flags & GOT_FOCUS) {
fgGC = Tk_GCForColor(textPtr->highlightColorPtr,
Tk_WindowId(textPtr->tkwin));
- TkpDrawHighlightBorder(textPtr->tkwin, fgGC, bgGC,
- textPtr->highlightWidth, Tk_WindowId(textPtr->tkwin));
+ TkpDrawHighlightBorder(textPtr->tkwin, fgGC, bgGC,
+ textPtr->highlightWidth, Tk_WindowId(textPtr->tkwin));
} else {
- TkpDrawHighlightBorder(textPtr->tkwin, bgGC, bgGC,
- textPtr->highlightWidth, Tk_WindowId(textPtr->tkwin));
+ TkpDrawHighlightBorder(textPtr->tkwin, bgGC, bgGC,
+ textPtr->highlightWidth, Tk_WindowId(textPtr->tkwin));
}
}
borders = textPtr->borderWidth + textPtr->highlightWidth;
@@ -2463,23 +4173,33 @@ DisplayText(clientData)
}
/*
- * Now we have to redraw the lines that couldn't be updated by
- * scrolling. First, compute the height of the largest line and
- * allocate an off-screen pixmap to use for double-buffered
- * displays.
+ * Now we have to redraw the lines that couldn't be updated by scrolling.
+ * First, compute the height of the largest line and allocate an off-
+ * screen pixmap to use for double-buffered displays.
*/
maxHeight = -1;
for (dlPtr = dInfoPtr->dLinePtr; dlPtr != NULL;
dlPtr = dlPtr->nextPtr) {
- if ((dlPtr->height > maxHeight) && (dlPtr->oldY != dlPtr->y)) {
+ if ((dlPtr->height > maxHeight) &&
+ ((dlPtr->flags&OLD_Y_INVALID) || (dlPtr->oldY != dlPtr->y))) {
maxHeight = dlPtr->height;
}
bottomY = dlPtr->y + dlPtr->height;
}
- if (maxHeight > dInfoPtr->maxY) {
- maxHeight = dInfoPtr->maxY;
+
+ /*
+ * There used to be a line here which restricted 'maxHeight' to be no
+ * larger than 'dInfoPtr->maxY', but this is incorrect for the case where
+ * individual lines may be taller than the widget _and_ we have smooth
+ * scrolling. What we can do is restrict maxHeight to be no larger than
+ * 'dInfoPtr->maxY + dInfoPtr->topPixelOffset'.
+ */
+
+ if (maxHeight > (dInfoPtr->maxY + dInfoPtr->topPixelOffset)) {
+ maxHeight = (dInfoPtr->maxY + dInfoPtr->topPixelOffset);
}
+
if (maxHeight > 0) {
#ifndef TK_NO_DOUBLE_BUFFERING
pixmap = Tk_GetPixmap(Tk_Display(textPtr->tkwin),
@@ -2491,14 +4211,15 @@ DisplayText(clientData)
for (prevPtr = NULL, dlPtr = textPtr->dInfoPtr->dLinePtr;
(dlPtr != NULL) && (dlPtr->y < dInfoPtr->maxY);
prevPtr = dlPtr, dlPtr = dlPtr->nextPtr) {
- if (dlPtr->chunkPtr == NULL) continue;
- if (dlPtr->oldY != dlPtr->y) {
+ if (dlPtr->chunkPtr == NULL) {
+ continue;
+ }
+ if ((dlPtr->flags & OLD_Y_INVALID) || dlPtr->oldY != dlPtr->y) {
if (tkTextDebug) {
char string[TK_POS_CHARS];
- TkTextPrintIndex(&dlPtr->index, string);
- Tcl_SetVar2(textPtr->interp, "tk_textRedraw",
- (char *) NULL, string,
- TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+
+ TkTextPrintIndex(textPtr, &dlPtr->index, string);
+ LOG("tk_textRedraw", string);
}
DisplayDLine(textPtr, dlPtr, prevPtr, pixmap);
if (dInfoPtr->dLinesInvalidated) {
@@ -2508,9 +4229,55 @@ DisplayText(clientData)
return;
}
dlPtr->oldY = dlPtr->y;
- dlPtr->flags &= ~NEW_LAYOUT;
+ dlPtr->flags &= ~(NEW_LAYOUT | OLD_Y_INVALID);
+ } else if (dlPtr->chunkPtr != NULL && ((dlPtr->y < 0)
+ || (dlPtr->y + dlPtr->height > dInfoPtr->maxY))) {
+ register TkTextDispChunk *chunkPtr;
+
+ /*
+ * It's the first or last DLine which are also overlapping the
+ * top or bottom of the window, but we decided above it wasn't
+ * necessary to display them (we were able to update them by
+ * scrolling). This is fine, except that if the lines contain
+ * any embedded windows, we must still call the display proc
+ * on them because they might need to be unmapped or they
+ * might need to be moved to reflect their new position.
+ * Otherwise, everything else moves, but the embedded window
+ * doesn't!
+ *
+ * So, we loop through all the chunks, calling the display
+ * proc of embedded windows only.
+ */
+
+ for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL);
+ chunkPtr = chunkPtr->nextPtr) {
+ int x;
+ if (chunkPtr->displayProc != TkTextEmbWinDisplayProc) {
+ continue;
+ }
+ x = chunkPtr->x + dInfoPtr->x - dInfoPtr->curXPixelOffset;
+ if ((x + chunkPtr->width <= 0) || (x >= dInfoPtr->maxX)) {
+ /*
+ * Note: we have to call the displayProc even for
+ * chunks that are off-screen. This is needed, for
+ * example, so that embedded windows can be unmapped
+ * in this case. Display the chunk at a coordinate
+ * that can be clearly identified by the displayProc
+ * as being off-screen to the left (the displayProc
+ * may not be able to tell if something is off to the
+ * right).
+ */
+
+ x = -chunkPtr->width;
+ }
+ TkTextEmbWinDisplayProc(textPtr, chunkPtr, x,
+ dlPtr->spaceAbove,
+ dlPtr->height-dlPtr->spaceAbove-dlPtr->spaceBelow,
+ dlPtr->baseline - dlPtr->spaceAbove, NULL,
+ (Drawable) None, dlPtr->y + dlPtr->spaceAbove);
+ }
+
}
- /*prevPtr = dlPtr;*/
}
#ifndef TK_NO_DOUBLE_BUFFERING
Tk_FreePixmap(Tk_Display(textPtr->tkwin), pixmap);
@@ -2518,10 +4285,10 @@ DisplayText(clientData)
}
/*
- * See if we need to refresh the part of the window below the
- * last line of text (if there is any such area). Refresh the
- * padding area on the left too, since the insertion cursor might
- * have been displayed there previously).
+ * See if we need to refresh the part of the window below the last line of
+ * text (if there is any such area). Refresh the padding area on the left
+ * too, since the insertion cursor might have been displayed there
+ * previously).
*/
if (dInfoPtr->topOfEof > dInfoPtr->maxY) {
@@ -2529,19 +4296,16 @@ DisplayText(clientData)
}
if (bottomY < dInfoPtr->topOfEof) {
if (tkTextDebug) {
- Tcl_SetVar2(textPtr->interp, "tk_textRedraw",
- (char *) NULL, "eof",
- TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+ LOG("tk_textRedraw", "eof");
}
- if (textPtr->tkwin == NULL) {
-
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
/*
- * The widget has been deleted. Don't do anything.
- */
+ * The widget has been deleted. Don't do anything.
+ */
- goto end;
- }
+ goto end;
+ }
Tk_Fill3DRectangle(textPtr->tkwin, Tk_WindowId(textPtr->tkwin),
textPtr->border, dInfoPtr->x - textPtr->padX, bottomY,
@@ -2550,28 +4314,26 @@ DisplayText(clientData)
}
dInfoPtr->topOfEof = bottomY;
- doScrollbars:
-
/*
- * Update the vertical scrollbar, if there is one. Note: it's
- * important to clear REDRAW_PENDING here, just in case the
- * scroll procedure does something that requires redisplay.
+ * Update the vertical scrollbar, if there is one. Note: it's important to
+ * clear REDRAW_PENDING here, just in case the scroll function does
+ * something that requires redisplay.
*/
-
+
+ doScrollbars:
if (textPtr->flags & UPDATE_SCROLLBARS) {
textPtr->flags &= ~UPDATE_SCROLLBARS;
if (textPtr->yScrollCmd != NULL) {
GetYView(textPtr->interp, textPtr, 1);
}
- if (textPtr->tkwin == NULL) {
-
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
/*
- * The widget has been deleted. Don't do anything.
- */
+ * The widget has been deleted. Don't do anything.
+ */
- goto end;
- }
+ goto end;
+ }
/*
* Update the horizontal scrollbar, if any.
@@ -2582,7 +4344,7 @@ DisplayText(clientData)
}
}
-end:
+ end:
Tcl_Release((ClientData) interp);
}
@@ -2591,9 +4353,8 @@ end:
*
* TkTextEventuallyRepick --
*
- * This procedure is invoked whenever something happens that
- * could change the current character or the tags associated
- * with it.
+ * This function is invoked whenever something happens that could change
+ * the current character or the tags associated with it.
*
* Results:
* None.
@@ -2604,10 +4365,9 @@ end:
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
void
-TkTextEventuallyRepick(textPtr)
- TkText *textPtr; /* Widget record for text widget. */
+TkTextEventuallyRepick(
+ TkText *textPtr) /* Widget record for text widget. */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
@@ -2623,9 +4383,9 @@ TkTextEventuallyRepick(textPtr)
*
* TkTextRedrawRegion --
*
- * This procedure is invoked to schedule a redisplay for a given
- * region of a text widget. The redisplay itself may not occur
- * immediately: it's scheduled as a when-idle handler.
+ * This function is invoked to schedule a redisplay for a given region of
+ * a text widget. The redisplay itself may not occur immediately: it's
+ * scheduled as a when-idle handler.
*
* Results:
* None.
@@ -2636,14 +4396,13 @@ TkTextEventuallyRepick(textPtr)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
void
-TkTextRedrawRegion(textPtr, x, y, width, height)
- TkText *textPtr; /* Widget record for text widget. */
- int x, y; /* Coordinates of upper-left corner of area
- * to be redrawn, in pixels relative to
- * textPtr's window. */
- int width, height; /* Width and height of area to be redrawn. */
+TkTextRedrawRegion(
+ TkText *textPtr, /* Widget record for text widget. */
+ int x, int y, /* Coordinates of upper-left corner of area to
+ * be redrawn, in pixels relative to textPtr's
+ * window. */
+ int width, int height) /* Width and height of area to be redrawn. */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
TkRegion damageRgn = TkCreateRegion();
@@ -2681,9 +4440,9 @@ TkTextRedrawRegion(textPtr, x, y, width, height)
*/
static void
-TextInvalidateRegion(textPtr, region)
- TkText *textPtr; /* Widget record for text widget. */
- TkRegion region; /* Region of area to redraw. */
+TextInvalidateRegion(
+ TkText *textPtr, /* Widget record for text widget. */
+ TkRegion region) /* Region of area to redraw. */
{
register DLine *dlPtr;
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
@@ -2699,9 +4458,10 @@ TextInvalidateRegion(textPtr, region)
maxY = rect.y + rect.height;
for (dlPtr = dInfoPtr->dLinePtr; dlPtr != NULL;
dlPtr = dlPtr->nextPtr) {
- if ((dlPtr->oldY != -1) && (TkRectInRegion(region, rect.x, dlPtr->y,
+ if ((!(dlPtr->flags & OLD_Y_INVALID))
+ && (TkRectInRegion(region, rect.x, dlPtr->y,
rect.width, (unsigned int) dlPtr->height) != RectangleOut)) {
- dlPtr->oldY = -1;
+ dlPtr->flags |= OLD_Y_INVALID;
}
}
if (dInfoPtr->topOfEof < maxY) {
@@ -2709,8 +4469,7 @@ TextInvalidateRegion(textPtr, region)
}
/*
- * Schedule the redisplay operation if there isn't one already
- * scheduled.
+ * Schedule the redisplay operation if there isn't one already scheduled.
*/
inset = textPtr->borderWidth + textPtr->highlightWidth;
@@ -2726,32 +4485,54 @@ TextInvalidateRegion(textPtr, region)
/*
*----------------------------------------------------------------------
*
- * TkTextChanged --
+ * TkTextChanged, TextChanged --
*
- * This procedure is invoked when info in a text widget is about
- * to be modified in a way that changes how it is displayed (e.g.
- * characters were inserted or deleted, or tag information was
- * changed). This procedure must be called *before* a change is
- * made, so that indexes in the display information are still
- * valid.
+ * This function is invoked when info in a text widget is about to be
+ * modified in a way that changes how it is displayed (e.g. characters
+ * were inserted or deleted, or tag information was changed). This
+ * function must be called *before* a change is made, so that indexes in
+ * the display information are still valid.
+ *
+ * Note: if the range of indices may change geometry as well as simply
+ * requiring redisplay, then the caller should also call
+ * TkTextInvalidateLineMetrics.
*
* Results:
* None.
*
* Side effects:
- * The range of character between index1Ptr (inclusive) and
- * index2Ptr (exclusive) will be redisplayed at some point in the
- * future (the actual redisplay is scheduled as a when-idle handler).
+ * The range of character between index1Ptr (inclusive) and index2Ptr
+ * (exclusive) will be redisplayed at some point in the future (the
+ * actual redisplay is scheduled as a when-idle handler).
*
*----------------------------------------------------------------------
*/
void
-TkTextChanged(textPtr, index1Ptr, index2Ptr)
- TkText *textPtr; /* Widget record for text widget. */
- TkTextIndex *index1Ptr; /* Index of first character to redisplay. */
- TkTextIndex *index2Ptr; /* Index of character just after last one
- * to redisplay. */
+TkTextChanged(
+ TkSharedText *sharedTextPtr,/* Shared widget section, or NULL. */
+ TkText *textPtr, /* Widget record for text widget, or NULL. */
+ CONST TkTextIndex*index1Ptr,/* Index of first character to redisplay. */
+ CONST TkTextIndex*index2Ptr)/* Index of character just after last one to
+ * redisplay. */
+{
+ if (sharedTextPtr == NULL) {
+ TextChanged(textPtr, index1Ptr, index2Ptr);
+ } else {
+ textPtr = sharedTextPtr->peers;
+ while (textPtr != NULL) {
+ TextChanged(textPtr, index1Ptr, index2Ptr);
+ textPtr = textPtr->next;
+ }
+ }
+}
+
+static void
+TextChanged(
+ TkText *textPtr, /* Widget record for text widget, or NULL. */
+ CONST TkTextIndex*index1Ptr,/* Index of first character to redisplay. */
+ CONST TkTextIndex*index2Ptr)/* Index of character just after last one to
+ * redisplay. */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
DLine *firstPtr, *lastPtr;
@@ -2759,18 +4540,18 @@ TkTextChanged(textPtr, index1Ptr, index2Ptr)
/*
* Schedule both a redisplay and a recomputation of display information.
- * It's done here rather than the end of the procedure for two reasons:
+ * It's done here rather than the end of the function for two reasons:
*
* 1. If there are no display lines to update we'll want to return
- * immediately, well before the end of the procedure.
+ * immediately, well before the end of the function.
* 2. It's important to arrange for the redisplay BEFORE calling
- * FreeDLines. The reason for this is subtle and has to do with
- * embedded windows. The chunk delete procedure for an embedded
- * window will schedule an idle handler to unmap the window.
- * However, we want the idle handler for redisplay to be called
- * first, so that it can put the embedded window back on the screen
- * again (if appropriate). This will prevent the window from ever
- * being unmapped, and thereby avoid flashing.
+ * FreeDLines. The reason for this is subtle and has to do with
+ * embedded windows. The chunk delete function for an embedded window
+ * will schedule an idle handler to unmap the window. However, we want
+ * the idle handler for redisplay to be called first, so that it can
+ * put the embedded window back on the screen again (if appropriate).
+ * This will prevent the window from ever being unmapped, and thereby
+ * avoid flashing.
*/
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
@@ -2779,13 +4560,13 @@ TkTextChanged(textPtr, index1Ptr, index2Ptr)
dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED;
/*
- * Find the DLines corresponding to index1Ptr and index2Ptr. There
- * is one tricky thing here, which is that we have to relayout in
- * units of whole text lines: round index1Ptr back to the beginning
- * of its text line, and include all the display lines after index2,
- * up to the end of its text line. This is necessary because the
- * indices stored in the display lines will no longer be valid. It's
- * also needed because any edit could change the way lines wrap.
+ * Find the DLines corresponding to index1Ptr and index2Ptr. There is one
+ * tricky thing here, which is that we have to relayout in units of whole
+ * text lines: round index1Ptr back to the beginning of its text line, and
+ * include all the display lines after index2, up to the end of its text
+ * line. This is necessary because the indices stored in the display lines
+ * will no longer be valid. It's also needed because any edit could change
+ * the way lines wrap.
*/
rounded = *index1Ptr;
@@ -2804,39 +4585,64 @@ TkTextChanged(textPtr, index1Ptr, index2Ptr)
* Delete all the DLines from firstPtr up to but not including lastPtr.
*/
- FreeDLines(textPtr, firstPtr, lastPtr, 1);
+ FreeDLines(textPtr, firstPtr, lastPtr, DLINE_UNLINK);
}
/*
*----------------------------------------------------------------------
*
- * TkTextRedrawTag --
+ * TkTextRedrawTag, TextRedrawTag --
*
- * This procedure is invoked to request a redraw of all characters
- * in a given range that have a particular tag on or off. It's
- * called, for example, when tag options change.
+ * This function is invoked to request a redraw of all characters in a
+ * given range that have a particular tag on or off. It's called, for
+ * example, when tag options change.
*
* Results:
* None.
*
* Side effects:
- * Information on the screen may be redrawn, and the layout of
- * the screen may change.
+ * Information on the screen may be redrawn, and the layout of the screen
+ * may change.
*
*----------------------------------------------------------------------
*/
void
-TkTextRedrawTag(textPtr, index1Ptr, index2Ptr, tagPtr, withTag)
- TkText *textPtr; /* Widget record for text widget. */
- TkTextIndex *index1Ptr; /* First character in range to consider
- * for redisplay. NULL means start at
- * beginning of text. */
- TkTextIndex *index2Ptr; /* Character just after last one to consider
- * for redisplay. NULL means process all
- * the characters in the text. */
- TkTextTag *tagPtr; /* Information about tag. */
- int withTag; /* 1 means redraw characters that have the
+TkTextRedrawTag(
+ TkSharedText *sharedTextPtr,/* Shared widget section, or NULL. */
+ TkText *textPtr, /* Widget record for text widget. */
+ TkTextIndex *index1Ptr, /* First character in range to consider for
+ * redisplay. NULL means start at beginning of
+ * text. */
+ TkTextIndex *index2Ptr, /* Character just after last one to consider
+ * for redisplay. NULL means process all the
+ * characters in the text. */
+ TkTextTag *tagPtr, /* Information about tag. */
+ int withTag) /* 1 means redraw characters that have the
+ * tag, 0 means redraw those without. */
+{
+ if (sharedTextPtr == NULL) {
+ TextRedrawTag(textPtr, index1Ptr, index2Ptr, tagPtr, withTag);
+ } else {
+ textPtr = sharedTextPtr->peers;
+ while (textPtr != NULL) {
+ TextRedrawTag(textPtr, index1Ptr, index2Ptr, tagPtr, withTag);
+ textPtr = textPtr->next;
+ }
+ }
+}
+
+static void
+TextRedrawTag(
+ TkText *textPtr, /* Widget record for text widget. */
+ TkTextIndex *index1Ptr, /* First character in range to consider for
+ * redisplay. NULL means start at beginning of
+ * text. */
+ TkTextIndex *index2Ptr, /* Character just after last one to consider
+ * for redisplay. NULL means process all the
+ * characters in the text. */
+ TkTextTag *tagPtr, /* Information about tag. */
+ int withTag) /* 1 means redraw characters that have the
* tag, 0 means redraw those without. */
{
register DLine *dlPtr;
@@ -2848,15 +4654,45 @@ TkTextRedrawTag(textPtr, index1Ptr, index2Ptr, tagPtr, withTag)
TkTextIndex endOfText, *endIndexPtr;
/*
- * Round up the starting position if it's before the first line
- * visible on the screen (we only care about what's on the screen).
+ * Invalidate the pixel calculation of all lines in the given range. This
+ * may be a bit over-aggressive, so we could consider more subtle
+ * techniques here in the future. In particular, when we create a tag for
+ * the first time with '.t tag configure foo -font "Arial 20"', say, even
+ * though that obviously can't apply to anything at all (the tag didn't
+ * exist a moment ago), we invalidate every single line in the widget.
+ */
+
+ if (tagPtr->affectsDisplayGeometry) {
+ TkTextLine *startLine, *endLine;
+ int lineCount;
+
+ if (index2Ptr == NULL) {
+ endLine = NULL;
+ lineCount = TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr);
+ } else {
+ endLine = index2Ptr->linePtr;
+ lineCount = TkBTreeLinesTo(textPtr, endLine);
+ }
+ if (index1Ptr == NULL) {
+ startLine = NULL;
+ } else {
+ startLine = index1Ptr->linePtr;
+ lineCount -= TkBTreeLinesTo(textPtr, startLine);
+ }
+ TkTextInvalidateLineMetrics(NULL, textPtr, startLine, lineCount,
+ TK_TEXT_INVALIDATE_ONLY);
+ }
+
+ /*
+ * Round up the starting position if it's before the first line visible on
+ * the screen (we only care about what's on the screen).
*/
dlPtr = dInfoPtr->dLinePtr;
if (dlPtr == NULL) {
return;
}
- if ((index1Ptr == NULL) || (TkTextIndexCmp(&dlPtr->index, index1Ptr) > 0)) {
+ if ((index1Ptr == NULL) || (TkTextIndexCmp(&dlPtr->index, index1Ptr)>0)) {
index1Ptr = &dlPtr->index;
}
@@ -2865,22 +4701,26 @@ TkTextRedrawTag(textPtr, index1Ptr, index2Ptr, tagPtr, withTag)
*/
if (index2Ptr == NULL) {
- index2Ptr = TkTextMakeByteIndex(textPtr->tree,
- TkBTreeNumLines(textPtr->tree), 0, &endOfText);
+ int lastLine = TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr);
+
+ index2Ptr = TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ lastLine, 0, &endOfText);
}
- /*
- * Initialize a search through all transitions on the tag, starting
- * with the first transition where the tag's current state is different
- * from what it will eventually be.
+ /*
+ * Initialize a search through all transitions on the tag, starting with
+ * the first transition where the tag's current state is different from
+ * what it will eventually be.
*/
TkBTreeStartSearch(index1Ptr, index2Ptr, tagPtr, &search);
+
/*
- * Make our own curIndex because at this point search.curIndex
- * may not equal index1Ptr->curIndex in the case the first tag toggle
- * comes after index1Ptr (See the use of FindTagStart in TkBTreeStartSearch)
+ * Make our own curIndex because at this point search.curIndex may not
+ * equal index1Ptr->curIndex in the case the first tag toggle comes after
+ * index1Ptr (See the use of FindTagStart in TkBTreeStartSearch).
*/
+
curIndexPtr = index1Ptr;
tagOn = TkBTreeCharTagged(index1Ptr, tagPtr);
if (tagOn != withTag) {
@@ -2891,9 +4731,9 @@ TkTextRedrawTag(textPtr, index1Ptr, index2Ptr, tagPtr, withTag)
}
/*
- * Schedule a redisplay and layout recalculation if they aren't
- * already pending. This has to be done before calling FreeDLines,
- * for the reason given in TkTextChanged.
+ * Schedule a redisplay and layout recalculation if they aren't already
+ * pending. This has to be done before calling FreeDLines, for the reason
+ * given in TkTextChanged.
*/
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
@@ -2902,21 +4742,20 @@ TkTextRedrawTag(textPtr, index1Ptr, index2Ptr, tagPtr, withTag)
dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED;
/*
- * Each loop through the loop below is for one range of characters
- * where the tag's current state is different than its eventual
- * state. At the top of the loop, search contains information about
- * the first character in the range.
+ * Each loop through the loop below is for one range of characters where
+ * the tag's current state is different than its eventual state. At the
+ * top of the loop, search contains information about the first character
+ * in the range.
*/
while (1) {
/*
- * Find the first DLine structure in the range. Note: if the
- * desired character isn't the first in its text line, then look
- * for the character just before it instead. This is needed to
- * handle the case where the first character of a wrapped
- * display line just got smaller, so that it now fits on the
- * line before: need to relayout the line containing the
- * previous character.
+ * Find the first DLine structure in the range. Note: if the desired
+ * character isn't the first in its text line, then look for the
+ * character just before it instead. This is needed to handle the case
+ * where the first character of a wrapped display line just got
+ * smaller, so that it now fits on the line before: need to relayout
+ * the line containing the previous character.
*/
if (curIndexPtr->byteIndex == 0) {
@@ -2949,11 +4788,11 @@ TkTextRedrawTag(textPtr, index1Ptr, index2Ptr, tagPtr, withTag)
}
/*
- * Delete all of the display lines in the range, so that they'll
- * be re-layed out and redrawn.
+ * Delete all of the display lines in the range, so that they'll be
+ * re-layed out and redrawn.
*/
- FreeDLines(textPtr, dlPtr, endPtr, 1);
+ FreeDLines(textPtr, dlPtr, endPtr, DLINE_UNLINK);
dlPtr = endPtr;
/*
@@ -2971,33 +4810,35 @@ TkTextRedrawTag(textPtr, index1Ptr, index2Ptr, tagPtr, withTag)
*
* TkTextRelayoutWindow --
*
- * This procedure is called when something has happened that
- * invalidates the whole layout of characters on the screen, such
- * as a change in a configuration option for the overall text
- * widget or a change in the window size. It causes all display
- * information to be recomputed and the window to be redrawn.
+ * This function is called when something has happened that invalidates
+ * the whole layout of characters on the screen, such as a change in a
+ * configuration option for the overall text widget or a change in the
+ * window size. It causes all display information to be recomputed and
+ * the window to be redrawn.
*
* Results:
* None.
*
* Side effects:
- * All the display information will be recomputed for the window
- * and the window will be redrawn.
+ * All the display information will be recomputed for the window and the
+ * window will be redrawn.
*
*----------------------------------------------------------------------
*/
void
-TkTextRelayoutWindow(textPtr)
- TkText *textPtr; /* Widget record for text widget. */
+TkTextRelayoutWindow(
+ TkText *textPtr, /* Widget record for text widget. */
+ int mask) /* OR'd collection of bits showing what has
+ * changed. */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
- GC new;
+ GC newGC;
XGCValues gcValues;
/*
- * Schedule the window redisplay. See TkTextChanged for the
- * reason why this has to be done before any calls to FreeDLines.
+ * Schedule the window redisplay. See TkTextChanged for the reason why
+ * this has to be done before any calls to FreeDLines.
*/
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
@@ -3007,28 +4848,27 @@ TkTextRelayoutWindow(textPtr)
|REPICK_NEEDED;
/*
- * (Re-)create the graphics context for drawing the traversal
- * highlight.
+ * (Re-)create the graphics context for drawing the traversal highlight.
*/
gcValues.graphics_exposures = False;
- new = Tk_GetGC(textPtr->tkwin, GCGraphicsExposures, &gcValues);
+ newGC = Tk_GetGC(textPtr->tkwin, GCGraphicsExposures, &gcValues);
if (dInfoPtr->copyGC != None) {
Tk_FreeGC(textPtr->display, dInfoPtr->copyGC);
}
- dInfoPtr->copyGC = new;
+ dInfoPtr->copyGC = newGC;
/*
* Throw away all the current layout information.
*/
- FreeDLines(textPtr, dInfoPtr->dLinePtr, (DLine *) NULL, 1);
+ FreeDLines(textPtr, dInfoPtr->dLinePtr, NULL, DLINE_UNLINK);
dInfoPtr->dLinePtr = NULL;
/*
- * Recompute some overall things for the layout. Even if the
- * window gets very small, pretend that there's at least one
- * pixel of drawing space in it.
+ * Recompute some overall things for the layout. Even if the window gets
+ * very small, pretend that there's at least one pixel of drawing space in
+ * it.
*/
if (textPtr->highlightWidth < 0) {
@@ -3043,6 +4883,11 @@ TkTextRelayoutWindow(textPtr)
if (dInfoPtr->maxX <= dInfoPtr->x) {
dInfoPtr->maxX = dInfoPtr->x + 1;
}
+
+ /*
+ * This is the only place where dInfoPtr->maxY is set.
+ */
+
dInfoPtr->maxY = Tk_Height(textPtr->tkwin) - textPtr->highlightWidth
- textPtr->borderWidth - textPtr->padY;
if (dInfoPtr->maxY <= dInfoPtr->y) {
@@ -3051,22 +4896,50 @@ TkTextRelayoutWindow(textPtr)
dInfoPtr->topOfEof = dInfoPtr->maxY;
/*
- * If the upper-left character isn't the first in a line, recompute
- * it. This is necessary because a change in the window's size
- * or options could change the way lines wrap.
+ * If the upper-left character isn't the first in a line, recompute it.
+ * This is necessary because a change in the window's size or options
+ * could change the way lines wrap.
*/
if (textPtr->topIndex.byteIndex != 0) {
- MeasureUp(textPtr, &textPtr->topIndex, 0, &textPtr->topIndex);
+ TkTextFindDisplayLineEnd(textPtr, &textPtr->topIndex, 0, NULL);
}
/*
- * Invalidate cached scrollbar positions, so that scrollbars
- * sliders will be udpated.
+ * Invalidate cached scrollbar positions, so that scrollbars sliders will
+ * be udpated.
*/
dInfoPtr->xScrollFirst = dInfoPtr->xScrollLast = -1;
dInfoPtr->yScrollFirst = dInfoPtr->yScrollLast = -1;
+
+ if (mask & TK_TEXT_LINE_GEOMETRY) {
+ /*
+ * Set up line metric recalculation.
+ *
+ * Avoid the special zero value, since that is used to mark individual
+ * lines as being out of date.
+ */
+
+ if ((++dInfoPtr->lineMetricUpdateEpoch) == 0) {
+ dInfoPtr->lineMetricUpdateEpoch++;
+ }
+
+ dInfoPtr->currentMetricUpdateLine = -1;
+
+ /*
+ * Also cancel any partial line-height calculations (for long-wrapped
+ * lines) in progress.
+ */
+
+ dInfoPtr->metricEpoch = -1;
+
+ if (dInfoPtr->lineUpdateTimer == NULL) {
+ textPtr->refCount++;
+ dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
+ AsyncUpdateLineMetrics, (ClientData) textPtr);
+ }
+ }
}
/*
@@ -3074,68 +4947,84 @@ TkTextRelayoutWindow(textPtr)
*
* TkTextSetYView --
*
- * This procedure is called to specify what lines are to be
- * displayed in a text widget.
+ * This function is called to specify what lines are to be displayed in a
+ * text widget.
*
* Results:
* None.
*
* Side effects:
- * The display will (eventually) be updated so that the position
- * given by "indexPtr" is visible on the screen at the position
- * determined by "pickPlace".
+ * The display will (eventually) be updated so that the position given by
+ * "indexPtr" is visible on the screen at the position determined by
+ * "pickPlace".
*
*----------------------------------------------------------------------
*/
void
-TkTextSetYView(textPtr, indexPtr, pickPlace)
- TkText *textPtr; /* Widget record for text widget. */
- TkTextIndex *indexPtr; /* Position that is to appear somewhere
- * in the view. */
- int pickPlace; /* 0 means topLine must appear at top of
- * screen. 1 means we get to pick where it
- * appears: minimize screen motion or else
- * display line at center of screen. */
+TkTextSetYView(
+ TkText *textPtr, /* Widget record for text widget. */
+ TkTextIndex *indexPtr, /* Position that is to appear somewhere in the
+ * view. */
+ int pickPlace) /* 0 means the given index must appear exactly
+ * at the top of the screen. TK_TEXT_PICKPLACE
+ * (-1) means we get to pick where it appears:
+ * minimize screen motion or else display line
+ * at center of screen. TK_TEXT_NOPIXELADJUST
+ * (-2) indicates to make the given index the
+ * top line, but if it is already the top
+ * line, don't nudge it up or down by a few
+ * pixels just to make sure it is entirely
+ * displayed. Positive numbers indicate the
+ * number of pixels of the index's line which
+ * are to be off the top of the screen. */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
register DLine *dlPtr;
int bottomY, close, lineIndex;
TkTextIndex tmpIndex, rounded;
- Tk_FontMetrics fm;
+ int lineHeight;
/*
- * If the specified position is the extra line at the end of the
- * text, round it back to the last real line.
+ * If the specified position is the extra line at the end of the text,
+ * round it back to the last real line.
*/
- lineIndex = TkBTreeLineIndex(indexPtr->linePtr);
- if (lineIndex == TkBTreeNumLines(indexPtr->tree)) {
- TkTextIndexBackChars(indexPtr, 1, &rounded);
+ lineIndex = TkBTreeLinesTo(textPtr, indexPtr->linePtr);
+ if (lineIndex == TkBTreeNumLines(indexPtr->tree, textPtr)) {
+ TkTextIndexBackChars(textPtr, indexPtr, 1, &rounded, COUNT_INDICES);
indexPtr = &rounded;
}
- if (!pickPlace) {
+ if (pickPlace == TK_TEXT_NOPIXELADJUST) {
+ if (textPtr->topIndex.linePtr == indexPtr->linePtr
+ && textPtr->topIndex.byteIndex == indexPtr->byteIndex) {
+ pickPlace = dInfoPtr->topPixelOffset;
+ } else {
+ pickPlace = 0;
+ }
+ }
+
+ if (pickPlace != TK_TEXT_PICKPLACE) {
/*
- * The specified position must go at the top of the screen.
- * Just leave all the DLine's alone: we may be able to reuse
- * some of the information that's currently on the screen
- * without redisplaying it all.
+ * The specified position must go at the top of the screen. Just leave
+ * all the DLine's alone: we may be able to reuse some of the
+ * information that's currently on the screen without redisplaying it
+ * all.
*/
- if (indexPtr->byteIndex == 0) {
- textPtr->topIndex = *indexPtr;
- } else {
- MeasureUp(textPtr, indexPtr, 0, &textPtr->topIndex);
+ textPtr->topIndex = *indexPtr;
+ if (indexPtr->byteIndex != 0) {
+ TkTextFindDisplayLineEnd(textPtr, &textPtr->topIndex, 0, NULL);
}
+ dInfoPtr->newTopPixelOffset = pickPlace;
goto scheduleUpdate;
}
/*
- * We have to pick where to display the index. First, bring
- * the display information up to date and see if the index will be
- * completely visible in the current screen configuration. If so
- * then there's nothing to do.
+ * We have to pick where to display the index. First, bring the display
+ * information up to date and see if the index will be completely visible
+ * in the current screen configuration. If so then there's nothing to do.
*/
if (dInfoPtr->flags & DINFO_OUT_OF_DATE) {
@@ -3145,68 +5034,92 @@ TkTextSetYView(textPtr, indexPtr, pickPlace)
if (dlPtr != NULL) {
if ((dlPtr->y + dlPtr->height) > dInfoPtr->maxY) {
/*
- * Part of the line hangs off the bottom of the screen;
- * pretend the whole line is off-screen.
+ * Part of the line hangs off the bottom of the screen; pretend
+ * the whole line is off-screen.
*/
dlPtr = NULL;
} else if ((dlPtr->index.linePtr == indexPtr->linePtr)
&& (dlPtr->index.byteIndex <= indexPtr->byteIndex)) {
+ if (dInfoPtr->dLinePtr == dlPtr && dInfoPtr->topPixelOffset != 0) {
+ /*
+ * It is on the top line, but that line is hanging off the top
+ * of the screen. Change the top overlap to zero and update.
+ */
+
+ dInfoPtr->newTopPixelOffset = 0;
+ goto scheduleUpdate;
+ }
return;
}
}
/*
- * The desired line isn't already on-screen. Figure out what
- * it means to be "close" to the top or bottom of the screen.
- * Close means within 1/3 of the screen height or within three
- * lines, whichever is greater. Add one extra line also, to
- * account for the way MeasureUp rounds.
+ * The desired line isn't already on-screen. Figure out what it means to
+ * be "close" to the top or bottom of the screen. Close means within 1/3
+ * of the screen height or within three lines, whichever is greater.
+ *
+ * If the line is not close, place it in the center of the window.
+ */
+
+ lineHeight = CalculateDisplayLineHeight(textPtr, indexPtr, NULL, NULL);
+
+ /*
+ * It would be better if 'bottomY' were calculated using the actual height
+ * of the given line, not 'textPtr->charHeight'.
*/
- Tk_GetFontMetrics(textPtr->tkfont, &fm);
- bottomY = (dInfoPtr->y + dInfoPtr->maxY + fm.linespace)/2;
+ bottomY = (dInfoPtr->y + dInfoPtr->maxY + lineHeight)/2;
close = (dInfoPtr->maxY - dInfoPtr->y)/3;
- if (close < 3*fm.linespace) {
- close = 3*fm.linespace;
+ if (close < 3*textPtr->charHeight) {
+ close = 3*textPtr->charHeight;
}
- close += fm.linespace;
if (dlPtr != NULL) {
+ int overlap;
+
/*
- * The desired line is above the top of screen. If it is
- * "close" to the top of the window then make it the top
- * line on the screen.
+ * The desired line is above the top of screen. If it is "close" to
+ * the top of the window then make it the top line on the screen.
+ * MeasureUp counts from the bottom of the given index upwards, so we
+ * add an extra half line to be sure we count far enough.
*/
- MeasureUp(textPtr, &textPtr->topIndex, close, &tmpIndex);
+ MeasureUp(textPtr, &textPtr->topIndex, close + textPtr->charHeight/2,
+ &tmpIndex, &overlap);
if (TkTextIndexCmp(&tmpIndex, indexPtr) <= 0) {
- MeasureUp(textPtr, indexPtr, 0, &textPtr->topIndex);
+ textPtr->topIndex = *indexPtr;
+ TkTextFindDisplayLineEnd(textPtr, &textPtr->topIndex, 0, NULL);
+ dInfoPtr->newTopPixelOffset = 0;
goto scheduleUpdate;
}
} else {
+ int overlap;
+
/*
- * The desired line is below the bottom of the screen. If it is
- * "close" to the bottom of the screen then position it at the
- * bottom of the screen.
+ * The desired line is below the bottom of the screen. If it is
+ * "close" to the bottom of the screen then position it at the bottom
+ * of the screen.
*/
- MeasureUp(textPtr, indexPtr, close, &tmpIndex);
+ MeasureUp(textPtr, indexPtr, close + lineHeight
+ - textPtr->charHeight/2, &tmpIndex, &overlap);
if (FindDLine(dInfoPtr->dLinePtr, &tmpIndex) != NULL) {
bottomY = dInfoPtr->maxY - dInfoPtr->y;
}
}
/*
- * Our job now is to arrange the display so that indexPtr appears
- * as low on the screen as possible but with its bottom no lower
- * than bottomY. BottomY is the bottom of the window if the
- * desired line is just below the current screen, otherwise it
- * is a half-line lower than the center of the window.
+ * Our job now is to arrange the display so that indexPtr appears as low
+ * on the screen as possible but with its bottom no lower than bottomY.
+ * BottomY is the bottom of the window if the desired line is just below
+ * the current screen, otherwise it is a half-line lower than the center
+ * of the window.
*/
- MeasureUp(textPtr, indexPtr, bottomY, &textPtr->topIndex);
+ MeasureUp(textPtr, indexPtr, bottomY, &textPtr->topIndex,
+ &dInfoPtr->newTopPixelOffset);
- scheduleUpdate:
+ scheduleUpdate:
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
}
@@ -3216,21 +5129,78 @@ TkTextSetYView(textPtr, indexPtr, pickPlace)
/*
*--------------------------------------------------------------
*
+ * TkTextMeasureDown --
+ *
+ * Given one index, find the index of the first character on the highest
+ * display line that would be displayed no more than "distance" pixels
+ * below the top of the given index.
+ *
+ * Results:
+ * The srcPtr is manipulated in place to reflect the new position. We
+ * return the number of pixels by which 'distance' overlaps the srcPtr.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+int
+TkTextMeasureDown(
+ TkText *textPtr, /* Text widget in which to measure. */
+ TkTextIndex *srcPtr, /* Index of character from which to start
+ * measuring. */
+ int distance) /* Vertical distance in pixels measured from
+ * the top pixel in srcPtr's logical line. */
+{
+ TkTextLine *lastLinePtr;
+ DLine *dlPtr;
+ TkTextIndex loop;
+
+ lastLinePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr));
+
+ do {
+ dlPtr = LayoutDLine(textPtr, srcPtr);
+ dlPtr->nextPtr = NULL;
+
+ if (distance < dlPtr->height) {
+ FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE_TEMP);
+ break;
+ }
+ distance -= dlPtr->height;
+ TkTextIndexForwBytes(textPtr, srcPtr, dlPtr->byteCount, &loop);
+ FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE_TEMP);
+ if (loop.linePtr == lastLinePtr) {
+ break;
+ }
+ *srcPtr = loop;
+ } while (distance > 0);
+
+ return distance;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
* MeasureUp --
*
- * Given one index, find the index of the first character
- * on the highest display line that would be displayed no more
- * than "distance" pixels above the given index.
+ * Given one index, find the index of the first character on the highest
+ * display line that would be displayed no more than "distance" pixels
+ * above the given index.
+ *
+ * If this function is called with distance=0, it simply finds the first
+ * index on the same display line as srcPtr. However, there is a another
+ * function TkTextFindDisplayLineEnd designed just for that task which is
+ * probably better to use.
*
* Results:
- * *dstPtr is filled in with the index of the first character
- * on a display line. The display line is found by measuring
- * up "distance" pixels above the pixel just below an imaginary
- * display line that contains srcPtr. If the display line
- * that covers this coordinate actually extends above the
- * coordinate, then return the index of the next lower line
- * instead (i.e. the returned index will be completely visible
- * at or below the given y-coordinate).
+ * *dstPtr is filled in with the index of the first character on a
+ * display line. The display line is found by measuring up "distance"
+ * pixels above the pixel just below an imaginary display line that
+ * contains srcPtr. If the display line that covers this coordinate
+ * actually extends above the coordinate, then return any excess pixels
+ * in *overlap, if that is non-NULL.
*
* Side effects:
* None.
@@ -3239,83 +5209,87 @@ TkTextSetYView(textPtr, indexPtr, pickPlace)
*/
static void
-MeasureUp(textPtr, srcPtr, distance, dstPtr)
- TkText *textPtr; /* Text widget in which to measure. */
- TkTextIndex *srcPtr; /* Index of character from which to start
+MeasureUp(
+ TkText *textPtr, /* Text widget in which to measure. */
+ CONST TkTextIndex *srcPtr, /* Index of character from which to start
* measuring. */
- int distance; /* Vertical distance in pixels measured
- * from the pixel just below the lowest
- * one in srcPtr's line. */
- TkTextIndex *dstPtr; /* Index to fill in with result. */
+ int distance, /* Vertical distance in pixels measured from
+ * the pixel just below the lowest one in
+ * srcPtr's line. */
+ TkTextIndex *dstPtr, /* Index to fill in with result. */
+ int *overlap) /* Used to store how much of the final index
+ * returned was not covered by 'distance'. */
{
int lineNum; /* Number of current line. */
int bytesToCount; /* Maximum number of bytes to measure in
* current line. */
- TkTextIndex bestIndex = {NULL, NULL, 0}; /* Best candidate seen so far for
- * result. Silence gcc 4 warning */
TkTextIndex index;
DLine *dlPtr, *lowestPtr;
- int noBestYet; /* 1 means bestIndex hasn't been set. */
- noBestYet = 1;
bytesToCount = srcPtr->byteIndex + 1;
index.tree = srcPtr->tree;
- for (lineNum = TkBTreeLineIndex(srcPtr->linePtr); lineNum >= 0;
+ for (lineNum = TkBTreeLinesTo(textPtr, 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 (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).
+ *
+ * For the first line, which contains srcPtr, only layout the 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.linePtr = TkBTreeFindLine(srcPtr->tree, textPtr, lineNum);
index.byteIndex = 0;
lowestPtr = NULL;
do {
dlPtr = LayoutDLine(textPtr, &index);
dlPtr->nextPtr = lowestPtr;
lowestPtr = dlPtr;
- TkTextIndexForwBytes(&index, dlPtr->byteCount, &index);
+ TkTextIndexForwBytes(textPtr, &index, dlPtr->byteCount, &index);
bytesToCount -= dlPtr->byteCount;
- } while ((bytesToCount > 0) && (index.linePtr == dlPtr->index.linePtr));
+ } while (bytesToCount>0 && index.linePtr==dlPtr->index.linePtr);
/*
* Scan through the display lines to see if we've covered enough
- * vertical distance. If so, save the starting index for the
- * line at the desired location.
+ * vertical distance. If so, save the starting index for the line at
+ * the desired location. If distance was zero to start with then we
+ * simply get the first index on the same display line as the original
+ * index.
*/
for (dlPtr = lowestPtr; dlPtr != NULL; dlPtr = dlPtr->nextPtr) {
distance -= dlPtr->height;
- if (distance < 0) {
- *dstPtr = (noBestYet) ? dlPtr->index : bestIndex;
+ if (distance <= 0) {
+ *dstPtr = dlPtr->index;
+ if (overlap != NULL) {
+ *overlap = -distance;
+ }
break;
}
- bestIndex = dlPtr->index;
- noBestYet = 0;
}
/*
- * Discard the display lines, then either return or prepare
- * for the next display line to lay out.
+ * Discard the display lines, then either return or prepare for the
+ * next display line to lay out.
*/
- FreeDLines(textPtr, lowestPtr, (DLine *) NULL, 0);
- if (distance < 0) {
+ FreeDLines(textPtr, lowestPtr, NULL, DLINE_FREE);
+ if (distance <= 0) {
return;
}
bytesToCount = INT_MAX; /* Consider all chars. in next line. */
}
/*
- * Ran off the beginning of the text. Return the first character
- * in the text.
+ * Ran off the beginning of the text. Return the first character in the
+ * text.
*/
- TkTextMakeByteIndex(textPtr->tree, 0, 0, dstPtr);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0, dstPtr);
+ if (overlap != NULL) {
+ *overlap = 0;
+ }
}
/*
@@ -3323,9 +5297,9 @@ MeasureUp(textPtr, srcPtr, distance, dstPtr)
*
* TkTextSeeCmd --
*
- * This procedure is invoked to process the "see" option for
- * the widget command for text widgets. See the user documentation
- * for details on what it does.
+ * This function is invoked to process the "see" option for the widget
+ * command for text widgets. See the user documentation for details on
+ * what it does.
*
* Results:
* A standard Tcl result.
@@ -3337,13 +5311,13 @@ MeasureUp(textPtr, srcPtr, distance, dstPtr)
*/
int
-TkTextSeeCmd(textPtr, interp, argc, argv)
- TkText *textPtr; /* Information about text widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. Someone else has already
+TkTextSeeCmd(
+ TkText *textPtr, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. Someone else has already
* parsed this command enough to know that
- * argv[1] is "see". */
+ * objv[1] is "see". */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
TkTextIndex index;
@@ -3351,29 +5325,29 @@ TkTextSeeCmd(textPtr, interp, argc, argv)
DLine *dlPtr;
TkTextDispChunk *chunkPtr;
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " see index\"", (char *) NULL);
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
return TCL_ERROR;
}
- if (TkTextGetIndex(interp, textPtr, argv[2], &index) != TCL_OK) {
+ if (TkTextGetObjIndex(interp, textPtr, objv[2], &index) != TCL_OK) {
return TCL_ERROR;
}
/*
- * If the specified position is the extra line at the end of the
- * text, round it back to the last real line.
+ * If the specified position is the extra line at the end of the text,
+ * round it back to the last real line.
*/
- if (TkBTreeLineIndex(index.linePtr) == TkBTreeNumLines(index.tree)) {
- TkTextIndexBackChars(&index, 1, &index);
+ if (TkBTreeLinesTo(textPtr, index.linePtr)
+ == TkBTreeNumLines(index.tree, textPtr)) {
+ TkTextIndexBackChars(textPtr, &index, 1, &index, COUNT_INDICES);
}
/*
* First get the desired position into the vertical range of the window.
*/
- TkTextSetYView(textPtr, &index, 1);
+ TkTextSetYView(textPtr, &index, TK_TEXT_PICKPLACE);
/*
* Now make sure that the character is in view horizontally.
@@ -3388,8 +5362,8 @@ TkTextSeeCmd(textPtr, interp, argc, argv)
}
/*
- * Find the chunk that contains the desired index.
- * dlPtr may be NULL if the widget is not mapped. [Bug #641778]
+ * Find the chunk that contains the desired index. dlPtr may be NULL if
+ * the widget is not mapped. [Bug #641778]
*/
dlPtr = FindDLine(dInfoPtr->dLinePtr, &index);
@@ -3399,7 +5373,7 @@ TkTextSeeCmd(textPtr, interp, argc, argv)
byteCount = index.byteIndex - dlPtr->index.byteIndex;
for (chunkPtr = dlPtr->chunkPtr; chunkPtr != NULL ;
- chunkPtr = chunkPtr->nextPtr) {
+ chunkPtr = chunkPtr->nextPtr) {
if (byteCount < chunkPtr->numBytes) {
break;
}
@@ -3407,36 +5381,32 @@ TkTextSeeCmd(textPtr, interp, argc, argv)
}
/*
- * Call a chunk-specific procedure to find the horizontal range of
- * the character within the chunk.
- * chunkPtr is NULL if trying to see in elided region.
+ * Call a chunk-specific function to find the horizontal range of the
+ * character within the chunk. chunkPtr is NULL if trying to see in elided
+ * region.
*/
if (chunkPtr != NULL) {
- (*chunkPtr->bboxProc)(chunkPtr, byteCount,
+ (*chunkPtr->bboxProc)(textPtr, chunkPtr, byteCount,
dlPtr->y + dlPtr->spaceAbove,
dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
dlPtr->baseline - dlPtr->spaceAbove, &x, &y, &width,
&height);
- delta = x - dInfoPtr->curPixelOffset;
+ delta = x - dInfoPtr->curXPixelOffset;
oneThird = lineWidth/3;
if (delta < 0) {
if (delta < -oneThird) {
- dInfoPtr->newByteOffset = (x - lineWidth/2)
- / textPtr->charWidth;
+ dInfoPtr->newXPixelOffset = (x - lineWidth/2);
} else {
- dInfoPtr->newByteOffset -= ((-delta) + textPtr->charWidth - 1)
- / textPtr->charWidth;
+ dInfoPtr->newXPixelOffset -= ((-delta) );
}
} else {
delta -= (lineWidth - width);
if (delta > 0) {
if (delta > oneThird) {
- dInfoPtr->newByteOffset = (x - lineWidth/2)
- / textPtr->charWidth;
+ dInfoPtr->newXPixelOffset = (x - lineWidth/2);
} else {
- dInfoPtr->newByteOffset += (delta + textPtr->charWidth - 1)
- / textPtr->charWidth;
+ dInfoPtr->newXPixelOffset += (delta );
}
} else {
return TCL_OK;
@@ -3456,9 +5426,9 @@ TkTextSeeCmd(textPtr, interp, argc, argv)
*
* TkTextXviewCmd --
*
- * This procedure is invoked to process the "xview" option for
- * the widget command for text widgets. See the user documentation
- * for details on what it does.
+ * This function is invoked to process the "xview" option for the widget
+ * command for text widgets. See the user documentation for details on
+ * what it does.
*
* Results:
* A standard Tcl result.
@@ -3470,56 +5440,60 @@ TkTextSeeCmd(textPtr, interp, argc, argv)
*/
int
-TkTextXviewCmd(textPtr, interp, argc, argv)
- TkText *textPtr; /* Information about text widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. Someone else has already
+TkTextXviewCmd(
+ TkText *textPtr, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. Someone else has already
* parsed this command enough to know that
- * argv[1] is "xview". */
+ * objv[1] is "xview". */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
- int type, charsPerPage, count, newOffset;
+ int type, count;
double fraction;
if (dInfoPtr->flags & DINFO_OUT_OF_DATE) {
UpdateDisplayInfo(textPtr);
}
- if (argc == 2) {
+ if (objc == 2) {
GetXView(interp, textPtr, 0);
return TCL_OK;
}
- newOffset = dInfoPtr->newByteOffset;
- type = Tk_GetScrollInfo(interp, argc, argv, &fraction, &count);
+ type = TextGetScrollInfoObj(interp, textPtr, objc, objv,
+ &fraction, &count);
switch (type) {
- case TK_SCROLL_ERROR:
- return TCL_ERROR;
- case TK_SCROLL_MOVETO:
- if (fraction > 1.0) {
- fraction = 1.0;
- }
- if (fraction < 0) {
- fraction = 0;
- }
- newOffset = (int) (((fraction * dInfoPtr->maxLength) / textPtr->charWidth)
- + 0.5);
- break;
- case TK_SCROLL_PAGES:
- charsPerPage = ((dInfoPtr->maxX - dInfoPtr->x) / textPtr->charWidth)
- - 2;
- if (charsPerPage < 1) {
- charsPerPage = 1;
- }
- newOffset += charsPerPage * count;
- break;
- case TK_SCROLL_UNITS:
- newOffset += count;
- break;
+ case TKTEXT_SCROLL_ERROR:
+ return TCL_ERROR;
+ case TKTEXT_SCROLL_MOVETO:
+ if (fraction > 1.0) {
+ fraction = 1.0;
+ }
+ if (fraction < 0) {
+ fraction = 0;
+ }
+ dInfoPtr->newXPixelOffset = (int)
+ (fraction * dInfoPtr->maxLength + 0.5);
+ break;
+ case TKTEXT_SCROLL_PAGES: {
+ int pixelsPerPage;
+
+ pixelsPerPage = (dInfoPtr->maxX-dInfoPtr->x) - 2*textPtr->charWidth;
+ if (pixelsPerPage < 1) {
+ pixelsPerPage = 1;
+ }
+ dInfoPtr->newXPixelOffset += pixelsPerPage * count;
+ break;
+ }
+ case TKTEXT_SCROLL_UNITS:
+ dInfoPtr->newXPixelOffset += count * textPtr->charWidth;
+ break;
+ case TKTEXT_SCROLL_PIXELS:
+ dInfoPtr->newXPixelOffset += count;
+ break;
}
- dInfoPtr->newByteOffset = newOffset;
dInfoPtr->flags |= DINFO_OUT_OF_DATE;
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
dInfoPtr->flags |= REDRAW_PENDING;
@@ -3531,56 +5505,141 @@ TkTextXviewCmd(textPtr, interp, argc, argv)
/*
*----------------------------------------------------------------------
*
- * ScrollByLines --
+ * YScrollByPixels --
+ *
+ * This function is called to scroll a text widget up or down by a given
+ * number of pixels.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The view in textPtr's window changes to reflect the value of "offset".
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+YScrollByPixels(
+ TkText *textPtr, /* Widget to scroll. */
+ int offset) /* Amount by which to scroll, in pixels.
+ * Positive means that information later in
+ * text becomes visible, negative means that
+ * information earlier in the text becomes
+ * visible. */
+{
+ TextDInfo *dInfoPtr = textPtr->dInfoPtr;
+
+ if (offset < 0) {
+ /*
+ * Now we want to measure up this number of pixels from the top of the
+ * screen. But the top line may not be totally visible. Note that
+ * 'count' is negative here.
+ */
+
+ offset -= CalculateDisplayLineHeight(textPtr,
+ &textPtr->topIndex, NULL, NULL) - dInfoPtr->topPixelOffset;
+ MeasureUp(textPtr, &textPtr->topIndex, -offset,
+ &textPtr->topIndex, &dInfoPtr->newTopPixelOffset);
+ } else if (offset > 0) {
+ DLine *dlPtr;
+ TkTextLine *lastLinePtr;
+ TkTextIndex newIdx;
+
+ /*
+ * Scrolling down by pixels. Layout lines starting at the top index
+ * and count through the desired vertical distance.
+ */
+
+ lastLinePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr));
+ offset += dInfoPtr->topPixelOffset;
+ dInfoPtr->newTopPixelOffset = 0;
+ while (offset > 0) {
+ dlPtr = LayoutDLine(textPtr, &textPtr->topIndex);
+ dlPtr->nextPtr = NULL;
+ TkTextIndexForwBytes(textPtr, &textPtr->topIndex,
+ dlPtr->byteCount, &newIdx);
+ if (offset <= dlPtr->height) {
+ /*
+ * Adjust the top overlap accordingly.
+ */
+
+ dInfoPtr->newTopPixelOffset = offset;
+ }
+ offset -= dlPtr->height;
+ FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE_TEMP);
+ if (newIdx.linePtr == lastLinePtr || offset <= 0) {
+ break;
+ }
+ textPtr->topIndex = newIdx;
+ }
+ } else {
+ /*
+ * offset = 0, so no scrolling required.
+ */
+
+ return;
+ }
+ if (!(dInfoPtr->flags & REDRAW_PENDING)) {
+ Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ }
+ dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * YScrollByLines --
*
- * This procedure is called to scroll a text widget up or down
- * by a given number of lines.
+ * This function is called to scroll a text widget up or down by a given
+ * number of lines.
*
* Results:
* None.
*
* Side effects:
- * The view in textPtr's window changes to reflect the value
- * of "offset".
+ * The view in textPtr's window changes to reflect the value of "offset".
*
*----------------------------------------------------------------------
*/
static void
-ScrollByLines(textPtr, offset)
- TkText *textPtr; /* Widget to scroll. */
- int offset; /* Amount by which to scroll, in *screen*
- * lines. Positive means that information
+YScrollByLines(
+ TkText *textPtr, /* Widget to scroll. */
+ int offset) /* Amount by which to scroll, in display
+ * lines. Positive means that information
* later in text becomes visible, negative
- * means that information earlier in the
- * text becomes visible. */
+ * means that information earlier in the text
+ * becomes visible. */
{
int i, bytesToCount, lineNum;
- TkTextIndex new, index;
+ TkTextIndex newIdx, index;
TkTextLine *lastLinePtr;
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
DLine *dlPtr, *lowestPtr;
if (offset < 0) {
/*
- * Must scroll up (to show earlier information in the text).
- * The code below is similar to that in MeasureUp, except that
- * it counts lines instead of pixels.
+ * Must scroll up (to show earlier information in the text). The code
+ * below is similar to that in MeasureUp, except that it counts lines
+ * instead of pixels.
*/
bytesToCount = textPtr->topIndex.byteIndex + 1;
- index.tree = textPtr->tree;
- offset--; /* Skip line containing topIndex. */
- for (lineNum = TkBTreeLineIndex(textPtr->topIndex.linePtr);
+ index.tree = textPtr->sharedTextPtr->tree;
+ offset--; /* Skip line containing topIndex. */
+ for (lineNum = TkBTreeLinesTo(textPtr, textPtr->topIndex.linePtr);
lineNum >= 0; lineNum--) {
- index.linePtr = TkBTreeFindLine(textPtr->tree, lineNum);
+ index.linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree,
+ textPtr, lineNum);
index.byteIndex = 0;
lowestPtr = NULL;
do {
dlPtr = LayoutDLine(textPtr, &index);
dlPtr->nextPtr = lowestPtr;
lowestPtr = dlPtr;
- TkTextIndexForwBytes(&index, dlPtr->byteCount, &index);
+ TkTextIndexForwBytes(textPtr, &index, dlPtr->byteCount,&index);
bytesToCount -= dlPtr->byteCount;
} while ((bytesToCount > 0)
&& (index.linePtr == dlPtr->index.linePtr));
@@ -3594,45 +5653,51 @@ ScrollByLines(textPtr, offset)
}
/*
- * Discard the display lines, then either return or prepare
- * for the next display line to lay out.
+ * Discard the display lines, then either return or prepare for
+ * the next display line to lay out.
*/
-
- FreeDLines(textPtr, lowestPtr, (DLine *) NULL, 0);
+
+ FreeDLines(textPtr, lowestPtr, NULL, DLINE_FREE);
if (offset >= 0) {
goto scheduleUpdate;
}
bytesToCount = INT_MAX;
}
-
+
/*
- * Ran off the beginning of the text. Return the first character
- * in the text.
+ * Ran off the beginning of the text. Return the first character in
+ * the text, and make sure we haven't left anything overlapping the
+ * top window border.
*/
- TkTextMakeByteIndex(textPtr->tree, 0, 0, &textPtr->topIndex);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0,
+ &textPtr->topIndex);
+ dInfoPtr->newTopPixelOffset = 0;
} else {
/*
- * Scrolling down, to show later information in the text.
- * Just count lines from the current top of the window.
+ * Scrolling down, to show later information in the text. Just count
+ * lines from the current top of the window.
*/
- lastLinePtr = TkBTreeFindLine(textPtr->tree,
- TkBTreeNumLines(textPtr->tree));
+ lastLinePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr));
for (i = 0; i < offset; i++) {
dlPtr = LayoutDLine(textPtr, &textPtr->topIndex);
- if (dlPtr->length == 0 && dlPtr->height == 0) offset++;
+ if (dlPtr->length == 0 && dlPtr->height == 0) {
+ offset++;
+ }
dlPtr->nextPtr = NULL;
- TkTextIndexForwBytes(&textPtr->topIndex, dlPtr->byteCount, &new);
- FreeDLines(textPtr, dlPtr, (DLine *) NULL, 0);
- if (new.linePtr == lastLinePtr) {
+ TkTextIndexForwBytes(textPtr, &textPtr->topIndex,
+ dlPtr->byteCount, &newIdx);
+ FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE);
+ if (newIdx.linePtr == lastLinePtr) {
break;
}
- textPtr->topIndex = new;
+ textPtr->topIndex = newIdx;
}
}
- scheduleUpdate:
+ scheduleUpdate:
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
}
@@ -3644,9 +5709,9 @@ ScrollByLines(textPtr, offset)
*
* TkTextYviewCmd --
*
- * This procedure is invoked to process the "yview" option for
- * the widget command for text widgets. See the user documentation
- * for details on what it does.
+ * This function is invoked to process the "yview" option for the widget
+ * command for text widgets. See the user documentation for details on
+ * what it does.
*
* Results:
* A standard Tcl result.
@@ -3658,29 +5723,26 @@ ScrollByLines(textPtr, offset)
*/
int
-TkTextYviewCmd(textPtr, interp, argc, argv)
- TkText *textPtr; /* Information about text widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. Someone else has already
+TkTextYviewCmd(
+ TkText *textPtr, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. Someone else has already
* parsed this command enough to know that
- * argv[1] is "yview". */
+ * objv[1] is "yview". */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
- int pickPlace, lineNum, type, bytesInLine;
- Tk_FontMetrics fm;
+ int pickPlace, type;
int pixels, count;
- size_t switchLength;
+ int switchLength;
double fraction;
- TkTextIndex index, new;
- TkTextLine *lastLinePtr;
- DLine *dlPtr;
+ TkTextIndex index;
if (dInfoPtr->flags & DINFO_OUT_OF_DATE) {
UpdateDisplayInfo(textPtr);
}
- if (argc == 2) {
+ if (objc == 2) {
GetYView(interp, textPtr, 0);
return TCL_OK;
}
@@ -3690,117 +5752,135 @@ TkTextYviewCmd(textPtr, interp, argc, argv)
*/
pickPlace = 0;
- if (argv[2][0] == '-') {
- switchLength = strlen(argv[2]);
- if ((switchLength >= 2)
- && (strncmp(argv[2], "-pickplace", switchLength) == 0)) {
+ if (Tcl_GetString(objv[2])[0] == '-') {
+ register CONST char *switchStr =
+ Tcl_GetStringFromObj(objv[2], &switchLength);
+
+ if ((switchLength >= 2) && (strncmp(switchStr, "-pickplace",
+ (unsigned) switchLength) == 0)) {
pickPlace = 1;
- if (argc != 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " yview -pickplace lineNum|index\"",
- (char *) NULL);
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "lineNum|index");
return TCL_ERROR;
}
}
}
- if ((argc == 3) || pickPlace) {
- if (Tcl_GetInt(interp, argv[2+pickPlace], &lineNum) == TCL_OK) {
- TkTextMakeByteIndex(textPtr->tree, lineNum, 0, &index);
+ if ((objc == 3) || pickPlace) {
+ int lineNum;
+
+ if (Tcl_GetIntFromObj(interp, objv[2+pickPlace], &lineNum) == TCL_OK) {
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ lineNum, 0, &index);
TkTextSetYView(textPtr, &index, 0);
return TCL_OK;
}
-
+
/*
* The argument must be a regular text index.
*/
-
+
Tcl_ResetResult(interp);
- if (TkTextGetIndex(interp, textPtr, argv[2+pickPlace],
+ if (TkTextGetObjIndex(interp, textPtr, objv[2+pickPlace],
&index) != TCL_OK) {
return TCL_ERROR;
}
- TkTextSetYView(textPtr, &index, pickPlace);
+ TkTextSetYView(textPtr, &index, (pickPlace ? TK_TEXT_PICKPLACE : 0));
return TCL_OK;
}
/*
- * New syntax: dispatch based on argv[2].
+ * New syntax: dispatch based on objv[2].
*/
- type = Tk_GetScrollInfo(interp, argc, argv, &fraction, &count);
+ type = TextGetScrollInfoObj(interp, textPtr, objc,objv, &fraction, &count);
switch (type) {
- case TK_SCROLL_ERROR:
- return TCL_ERROR;
- case TK_SCROLL_MOVETO:
- if (fraction > 1.0) {
- fraction = 1.0;
- }
- if (fraction < 0) {
- fraction = 0;
- }
- fraction *= TkBTreeNumLines(textPtr->tree);
- lineNum = (int) fraction;
- 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;
- case TK_SCROLL_PAGES:
+ case TKTEXT_SCROLL_ERROR:
+ return TCL_ERROR;
+ case TKTEXT_SCROLL_MOVETO: {
+ int numPixels = TkBTreeNumPixels(textPtr->sharedTextPtr->tree,
+ textPtr);
+ int topMostPixel;
+
+ if (numPixels == 0) {
/*
- * Scroll up or down by screenfuls. Actually, use the
- * window height minus two lines, so that there's some
- * overlap between adjacent pages.
+ * If the window is totally empty no scrolling is needed, and the
+ * TkTextMakePixelIndex call below will fail.
*/
- Tk_GetFontMetrics(textPtr->tkfont, &fm);
- if (count < 0) {
- pixels = (dInfoPtr->maxY - 2*fm.linespace - dInfoPtr->y)*(-count)
- + fm.linespace;
- MeasureUp(textPtr, &textPtr->topIndex, pixels, &new);
- if (TkTextIndexCmp(&textPtr->topIndex, &new) == 0) {
- /*
- * A page of scrolling ended up being less than one line.
- * Scroll one line anyway.
- */
+ break;
+ }
+ if (fraction > 1.0) {
+ fraction = 1.0;
+ }
+ if (fraction < 0) {
+ fraction = 0;
+ }
- count = -1;
- goto scrollByLines;
- }
- textPtr->topIndex = new;
- } else {
+ /*
+ * Calculate the pixel count for the new topmost pixel in the topmost
+ * line of the window. Note that the interpretation of 'fraction' is
+ * that it counts from 0 (top pixel in buffer) to 1.0 (one pixel past
+ * the last pixel in buffer).
+ */
+
+ topMostPixel = (int) (0.5 + fraction * numPixels);
+ if (topMostPixel >= numPixels) {
+ topMostPixel = numPixels -1;
+ }
+
+ /*
+ * This function returns the number of pixels by which the given line
+ * should overlap the top of the visible screen.
+ *
+ * This is then used to provide smooth scrolling.
+ */
+
+ pixels = TkTextMakePixelIndex(textPtr, topMostPixel, &index);
+ TkTextSetYView(textPtr, &index, pixels);
+ break;
+ }
+ case TKTEXT_SCROLL_PAGES: {
+ /*
+ * Scroll up or down by screenfuls. Actually, use the window height
+ * minus two lines, so that there's some overlap between adjacent
+ * pages.
+ */
+
+ int height = dInfoPtr->maxY - dInfoPtr->y;
+
+ if (textPtr->charHeight * 4 >= height) {
+ /*
+ * A single line is more than a quarter of the display. We choose
+ * to scroll by 3/4 of the height instead.
+ */
+
+ pixels = 3*height/4;
+ if (pixels < textPtr->charHeight) {
/*
- * Scrolling down by pages. Layout lines starting at the
- * top index and count through the desired vertical distance.
+ * But, if 3/4 of the height is actually less than a single
+ * typical character height, then scroll by the minimum of the
+ * linespace or the total height.
*/
- pixels = (dInfoPtr->maxY - 2*fm.linespace - dInfoPtr->y)*count;
- lastLinePtr = TkBTreeFindLine(textPtr->tree,
- TkBTreeNumLines(textPtr->tree));
- do {
- dlPtr = LayoutDLine(textPtr, &textPtr->topIndex);
- dlPtr->nextPtr = NULL;
- TkTextIndexForwBytes(&textPtr->topIndex, dlPtr->byteCount,
- &new);
- pixels -= dlPtr->height;
- FreeDLines(textPtr, dlPtr, (DLine *) NULL, 0);
- if (new.linePtr == lastLinePtr) {
- break;
- }
- textPtr->topIndex = new;
- } while (pixels > 0);
- }
- if (!(dInfoPtr->flags & REDRAW_PENDING)) {
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ if (textPtr->charHeight < height) {
+ pixels = textPtr->charHeight;
+ } else {
+ pixels = height;
+ }
}
- dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED;
- break;
- case TK_SCROLL_UNITS:
- scrollByLines:
- ScrollByLines(textPtr, count);
- break;
+ pixels *= count;
+ } else {
+ pixels = (height - 2*textPtr->charHeight)*count;
+ }
+ YScrollByPixels(textPtr, pixels);
+ break;
+ }
+ case TKTEXT_SCROLL_PIXELS:
+ YScrollByPixels(textPtr, count);
+ break;
+ case TKTEXT_SCROLL_UNITS:
+ YScrollByLines(textPtr, count);
+ break;
}
return TCL_OK;
}
@@ -3810,9 +5890,9 @@ TkTextYviewCmd(textPtr, interp, argc, argv)
*
* TkTextScanCmd --
*
- * This procedure is invoked to process the "scan" option for
- * the widget command for text widgets. See the user documentation
- * for details on what it does.
+ * This function is invoked to process the "scan" option for the widget
+ * command for text widgets. See the user documentation for details on
+ * what it does.
*
* Results:
* A standard Tcl result.
@@ -3824,91 +5904,93 @@ TkTextYviewCmd(textPtr, interp, argc, argv)
*/
int
-TkTextScanCmd(textPtr, interp, argc, argv)
- register TkText *textPtr; /* Information about text widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. Someone else has already
+TkTextScanCmd(
+ register TkText *textPtr, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. Someone else has already
* parsed this command enough to know that
- * argv[1] is "scan". */
+ * objv[1] is "scan". */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
TkTextIndex index;
- int c, x, y, totalScroll, newByte, maxByte, gain=10;
- Tk_FontMetrics fm;
+ int c, x, y, totalScroll, gain=10;
size_t length;
- if ((argc != 5) && (argc != 6)) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " scan mark x y\" or \"",
- argv[0], " scan dragto x y ?gain?\"", (char *) NULL);
+ if ((objc != 5) && (objc != 6)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "mark x y");
+ Tcl_AppendResult(interp, " or \"", Tcl_GetString(objv[0]),
+ " scan dragto x y ?gain?\"", NULL);
+ /*
+ * Ought to be:
+ * Tcl_WrongNumArgs(interp, 2, objc, "dragto x y ?gain?");
+ */
return TCL_ERROR;
}
- if (Tcl_GetInt(interp, argv[3], &x) != TCL_OK) {
+ if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) {
return TCL_ERROR;
}
- if (Tcl_GetInt(interp, argv[4], &y) != TCL_OK) {
+ if (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) {
return TCL_ERROR;
}
- if ((argc == 6) && (Tcl_GetInt(interp, argv[5], &gain) != TCL_OK))
+ if ((objc == 6) && (Tcl_GetIntFromObj(interp, objv[5], &gain) != TCL_OK)) {
return TCL_ERROR;
- c = argv[2][0];
- length = strlen(argv[2]);
- if ((c == 'd') && (strncmp(argv[2], "dragto", length) == 0)) {
+ }
+ c = Tcl_GetString(objv[2])[0];
+ length = strlen(Tcl_GetString(objv[2]));
+ if (c=='d' && strncmp(Tcl_GetString(objv[2]), "dragto", length)==0) {
+ int newX, maxX;
+
/*
- * Amplify the difference between the current position and the
- * mark position to compute how much the view should shift, then
- * update the mark position to correspond to the new view. If we
- * run off the edge of the text, reset the mark point so that the
- * current position continues to correspond to the edge of the
- * window. This means that the picture will start dragging as
- * soon as the mouse reverses direction (without this reset, might
- * have to slide mouse a long ways back before the picture starts
- * moving again).
+ * Amplify the difference between the current position and the mark
+ * position to compute how much the view should shift, then update the
+ * mark position to correspond to the new view. If we run off the edge
+ * of the text, reset the mark point so that the current position
+ * continues to correspond to the edge of the window. This means that
+ * the picture will start dragging as soon as the mouse reverses
+ * direction (without this reset, might have to slide mouse a long
+ * ways back before the picture starts moving again).
*/
- newByte = dInfoPtr->scanMarkIndex + (gain*(dInfoPtr->scanMarkX - x))
- / (textPtr->charWidth);
- maxByte = 1 + (dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x)
- + textPtr->charWidth - 1)/textPtr->charWidth;
- if (newByte < 0) {
- newByte = 0;
- dInfoPtr->scanMarkIndex = 0;
+ newX = dInfoPtr->scanMarkXPixel + gain*(dInfoPtr->scanMarkX - x);
+ maxX = 1 + dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x);
+ if (newX < 0) {
+ newX = 0;
+ dInfoPtr->scanMarkXPixel = 0;
dInfoPtr->scanMarkX = x;
- } else if (newByte > maxByte) {
- newByte = maxByte;
- dInfoPtr->scanMarkIndex = maxByte;
+ } else if (newX > maxX) {
+ newX = maxX;
+ dInfoPtr->scanMarkXPixel = maxX;
dInfoPtr->scanMarkX = x;
}
- dInfoPtr->newByteOffset = newByte;
+ dInfoPtr->newXPixelOffset = newX;
- Tk_GetFontMetrics(textPtr->tkfont, &fm);
- totalScroll = (gain*(dInfoPtr->scanMarkY - y)) / fm.linespace;
- if (totalScroll != dInfoPtr->scanTotalScroll) {
+ totalScroll = gain*(dInfoPtr->scanMarkY - y);
+ if (totalScroll != dInfoPtr->scanTotalYScroll) {
index = textPtr->topIndex;
- ScrollByLines(textPtr, totalScroll-dInfoPtr->scanTotalScroll);
- dInfoPtr->scanTotalScroll = totalScroll;
+ YScrollByPixels(textPtr, totalScroll-dInfoPtr->scanTotalYScroll);
+ dInfoPtr->scanTotalYScroll = totalScroll;
if ((index.linePtr == textPtr->topIndex.linePtr) &&
(index.byteIndex == textPtr->topIndex.byteIndex)) {
- dInfoPtr->scanTotalScroll = 0;
+ dInfoPtr->scanTotalYScroll = 0;
dInfoPtr->scanMarkY = y;
}
}
- } else if ((c == 'm') && (strncmp(argv[2], "mark", length) == 0)) {
- dInfoPtr->scanMarkIndex = dInfoPtr->newByteOffset;
+ dInfoPtr->flags |= DINFO_OUT_OF_DATE;
+ if (!(dInfoPtr->flags & REDRAW_PENDING)) {
+ dInfoPtr->flags |= REDRAW_PENDING;
+ Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
+ }
+ } else if (c=='m' && strncmp(Tcl_GetString(objv[2]), "mark", length)==0) {
+ dInfoPtr->scanMarkXPixel = dInfoPtr->newXPixelOffset;
dInfoPtr->scanMarkX = x;
- dInfoPtr->scanTotalScroll = 0;
+ dInfoPtr->scanTotalYScroll = 0;
dInfoPtr->scanMarkY = y;
} else {
- Tcl_AppendResult(interp, "bad scan option \"", argv[2],
- "\": must be mark or dragto", (char *) NULL);
+ Tcl_AppendResult(interp, "bad scan option \"", Tcl_GetString(objv[2]),
+ "\": must be mark or dragto", NULL);
return TCL_ERROR;
}
- dInfoPtr->flags |= DINFO_OUT_OF_DATE;
- if (!(dInfoPtr->flags & REDRAW_PENDING)) {
- dInfoPtr->flags |= REDRAW_PENDING;
- Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr);
- }
return TCL_OK;
}
@@ -3917,19 +5999,19 @@ TkTextScanCmd(textPtr, interp, argc, argv)
*
* GetXView --
*
- * This procedure computes the fractions that indicate what's
- * visible in a text window and, optionally, evaluates a
- * Tcl script to report them to the text's associated scrollbar.
+ * This function computes the fractions that indicate what's visible in a
+ * text window and, optionally, evaluates a Tcl script to report them to
+ * the text's associated scrollbar.
*
* Results:
- * 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 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).
+ * 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 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).
*
* Side effects:
* None.
@@ -3938,24 +6020,24 @@ TkTextScanCmd(textPtr, interp, argc, argv)
*/
static void
-GetXView(interp, textPtr, report)
- Tcl_Interp *interp; /* If "report" is FALSE, string
- * describing visible range gets
- * 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. */
+GetXView(
+ Tcl_Interp *interp, /* If "report" is FALSE, string describing
+ * visible range gets 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[TCL_DOUBLE_SPACE * 2 + 1];
double first, last;
int code;
+ Tcl_Obj *listObj;
if (dInfoPtr->maxLength > 0) {
- first = ((double) dInfoPtr->curPixelOffset)
- / dInfoPtr->maxLength;
- last = first + ((double) (dInfoPtr->maxX - dInfoPtr->x))
+ first = ((double) dInfoPtr->curXPixelOffset)
/ dInfoPtr->maxLength;
+ last = ((double) (dInfoPtr->curXPixelOffset + dInfoPtr->maxX
+ - dInfoPtr->x))/dInfoPtr->maxLength;
if (last > 1.0) {
last = 1.0;
}
@@ -3964,44 +6046,177 @@ GetXView(interp, textPtr, report)
last = 1.0;
}
if (!report) {
- sprintf(buffer, "%g %g", first, last);
- Tcl_SetResult(interp, buffer, TCL_VOLATILE);
+ listObj = Tcl_NewListObj(0, NULL);
+ Tcl_ListObjAppendElement(interp, listObj, Tcl_NewDoubleObj(first));
+ Tcl_ListObjAppendElement(interp, listObj, Tcl_NewDoubleObj(last));
+ Tcl_SetObjResult(interp, listObj);
return;
}
if (FP_EQUAL_SCALE(first, dInfoPtr->xScrollFirst, dInfoPtr->maxLength) &&
- FP_EQUAL_SCALE(last, dInfoPtr->xScrollLast, dInfoPtr->maxLength)) {
+ FP_EQUAL_SCALE(last, dInfoPtr->xScrollLast, dInfoPtr->maxLength)) {
return;
}
dInfoPtr->xScrollFirst = first;
dInfoPtr->xScrollLast = last;
- sprintf(buffer, " %g %g", first, last);
- code = Tcl_VarEval(interp, textPtr->xScrollCmd,
- buffer, (char *) NULL);
- if (code != TCL_OK) {
- Tcl_AddErrorInfo(interp,
- "\n (horizontal scrolling command executed by text)");
- Tcl_BackgroundError(interp);
+ if (textPtr->xScrollCmd != NULL) {
+ char buf1[TCL_DOUBLE_SPACE+1];
+ char buf2[TCL_DOUBLE_SPACE+1];
+
+ buf1[0] = ' ';
+ buf2[0] = ' ';
+ Tcl_PrintDouble(NULL, first, buf1+1);
+ Tcl_PrintDouble(NULL, last, buf2+1);
+ code = Tcl_VarEval(interp, textPtr->xScrollCmd, buf1, buf2, NULL);
+ if (code != TCL_OK) {
+ Tcl_AddErrorInfo(interp,
+ "\n (horizontal scrolling command executed by text)");
+ Tcl_BackgroundError(interp);
+ }
}
}
/*
*----------------------------------------------------------------------
*
+ * GetYPixelCount --
+ *
+ * How many pixels are there between the absolute top of the widget and
+ * the top of the given DLine.
+ *
+ * While this function will work for any valid DLine, it is only ever
+ * called when dlPtr is the first display line in the widget (by
+ * 'GetYView'). This means that usually this function is a very quick
+ * calculation, since it can use the pre-calculated linked-list of DLines
+ * for height information.
+ *
+ * The only situation where this breaks down is if dlPtr's logical line
+ * wraps enough times to fill the text widget's current view - in this
+ * case we won't have enough dlPtrs in the linked list to be able to
+ * subtract off what we want.
+ *
+ * Results:
+ * The number of pixels.
+ *
+ * This value has a valid range between '0' (the very top of the widget)
+ * and the number of pixels in the total widget minus the pixel-height of
+ * the last line.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GetYPixelCount(
+ TkText *textPtr, /* Information about text widget. */
+ DLine *dlPtr) /* Information about the layout of a given
+ * index. */
+{
+ TkTextLine *linePtr = dlPtr->index.linePtr;
+ int count;
+
+ /*
+ * Get the pixel count to the top of dlPtr's logical line. The rest of the
+ * function is then concerned with updating 'count' for any difference
+ * between the top of the logical line and the display line.
+ */
+
+ count = TkBTreePixelsTo(textPtr, linePtr);
+
+ /*
+ * For the common case where this dlPtr is also the start of the logical
+ * line, we can return right away. Note the implicit assumption here that
+ * the start of a logical line is always the start of a display line (if
+ * the 'elide won't elide first newline' bug is fixed, this will no longer
+ * necessarily be true).
+ */
+
+ if (dlPtr->index.byteIndex == 0) {
+ return count;
+ }
+
+ /*
+ * Add on the logical line's height to reach one pixel beyond the bottom
+ * of the logical line. And then subtract off the heights of all the
+ * display lines from dlPtr to the end of its logical line.
+ *
+ * A different approach would be to lay things out from the start of the
+ * logical line until we reach dlPtr, but since none of those are
+ * pre-calculated, it'll usually take a lot longer. (But there are cases
+ * where it would be more efficient: say if we're on the second of 1000
+ * wrapped lines all from a single logical line - but that sort of
+ * optimization is left for the future).
+ */
+
+ count += TkBTreeLinePixelCount(textPtr, linePtr);
+
+ do {
+ count -= dlPtr->height;
+ if (dlPtr->nextPtr == NULL) {
+ /*
+ * We've run out of pre-calculated display lines, so we have to
+ * lay them out ourselves until the end of the logical line. Here
+ * is where we could be clever and ask: what's faster, to layout
+ * all lines from here to line-end, or all lines from the original
+ * dlPtr to the line-start? We just assume the former.
+ */
+
+ TkTextIndex index;
+ int notFirst = 0;
+
+ while (1) {
+ TkTextIndexForwBytes(textPtr, &dlPtr->index,
+ dlPtr->byteCount, &index);
+ if (notFirst) {
+ FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE_TEMP);
+ }
+ if (index.linePtr != linePtr) {
+ break;
+ }
+ dlPtr = LayoutDLine(textPtr, &index);
+
+ if (tkTextDebug) {
+ char string[TK_POS_CHARS];
+
+ /*
+ * Debugging is enabled, so keep a log of all the lines
+ * whose height was recalculated. The test suite uses this
+ * information.
+ */
+
+ TkTextPrintIndex(textPtr, &index, string);
+ LOG("tk_textHeightCalc", string);
+ }
+ count -= dlPtr->height;
+ notFirst = 1;
+ }
+ break;
+ } else {
+ dlPtr = dlPtr->nextPtr;
+ }
+ } while (dlPtr->index.linePtr == linePtr);
+
+ return count;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* GetYView --
*
- * This procedure computes the fractions that indicate what's
- * visible in a text window and, optionally, evaluates a
- * Tcl script to report them to the text's associated scrollbar.
+ * This function computes the fractions that indicate what's visible in a
+ * text window and, optionally, evaluates a Tcl script to report them to
+ * the text's associated scrollbar.
*
* Results:
- * 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 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).
+ * 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
+ * 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).
*
* Side effects:
* None.
@@ -4010,62 +6225,171 @@ GetXView(interp, textPtr, report)
*/
static void
-GetYView(interp, textPtr, report)
- Tcl_Interp *interp; /* If "report" is FALSE, string
- * describing visible range gets
- * 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. */
+GetYView(
+ Tcl_Interp *interp, /* If "report" is FALSE, string describing
+ * visible range gets 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[TCL_DOUBLE_SPACE * 2 + 1];
double first, last;
DLine *dlPtr;
- int totalLines, code, count;
+ int totalPixels, code, count;
+ Tcl_Obj *listObj;
dlPtr = dInfoPtr->dLinePtr;
- totalLines = TkBTreeNumLines(textPtr->tree);
- 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) {
+
+ if (dlPtr == NULL) {
+ return;
+ }
+
+ totalPixels = TkBTreeNumPixels(textPtr->sharedTextPtr->tree, textPtr);
+
+ if (totalPixels == 0) {
+ first = 0.0;
+ last = 1.0;
+ } else {
+ /*
+ * Get the pixel count for the first visible pixel of the first
+ * visible line. If the first visible line is only partially visible,
+ * then we use 'topPixelOffset' to get the difference.
+ */
+
+ count = GetYPixelCount(textPtr, dlPtr);
+ first = (count + dInfoPtr->topPixelOffset) / (double) totalPixels;
+
+ /*
+ * Add on the total number of visible pixels to get the count to one
+ * pixel _past_ the last visible pixel. This is how the 'yview'
+ * command is documented, and also explains why we are dividing by
+ * 'totalPixels' and not 'totalPixels-1'.
+ */
+
+ while (1) {
+ int extra;
+
+ count += dlPtr->height;
+ extra = dlPtr->y + dlPtr->height - dInfoPtr->maxY;
+ if (extra > 0) {
+ /*
+ * This much of the last line is not visible, so don't count
+ * these pixels. Since we've reached the bottom of the window,
+ * we break out of the loop.
+ */
+
+ count -= extra;
+ break;
+ }
+ if (dlPtr->nextPtr == NULL) {
+ break;
+ }
+ dlPtr = dlPtr->nextPtr;
+ }
+
+ if (count > totalPixels) {
/*
- * The last line is only partially visible, so don't
- * count its characters in what's visible.
+ * It can be possible, if we do not update each line's pixelHeight
+ * cache when we lay out individual DLines that the count
+ * generated here is more up-to-date than that maintained by the
+ * BTree. In such a case, the best we can do here is to fix up
+ * 'count' and continue, which might result in small, temporary
+ * perturbations to the size of the scrollbar. This is basically
+ * harmless, but in a perfect world we would not have this
+ * problem.
+ *
+ * For debugging purposes, if anyone wishes to improve the text
+ * widget further, the following 'panic' can be activated. In
+ * principle it should be possible to ensure the BTree is always
+ * at least as up to date as the display, so in the future we
+ * might be able to leave the 'panic' in permanently when we
+ * believe we have resolved the cache synchronisation issue.
+ *
+ * However, to achieve that goal would, I think, require a fairly
+ * substantial refactorisation of the code in this file so that
+ * there is much more obvious and explicit coordination between
+ * calls to LayoutDLine and updating of each TkTextLine's
+ * pixelHeight. The complicated bit is that LayoutDLine deals with
+ * individual display lines, but pixelHeight is for a logical
+ * line.
*/
- count = 0;
- break;
- }
- if (dlPtr->nextPtr == NULL) {
- count = dlPtr->byteCount;
- break;
+
+#if 0
+ Tcl_Panic("Counted more pixels (%d) than expected (%d) total "
+ "pixels in text widget scroll bar calculation.", count,
+ totalPixels);
+#endif
+ count = totalPixels;
}
- dlPtr = dlPtr->nextPtr;
+
+ last = ((double) count)/((double)totalPixels);
}
- last = ((double) TkBTreeLineIndex(dlPtr->index.linePtr))
- + ((double) (dlPtr->index.byteIndex + count))
- / (TkBTreeBytesInLine(dlPtr->index.linePtr));
- last /= totalLines;
+
if (!report) {
- sprintf(buffer, "%g %g", first, last);
- Tcl_SetResult(interp, buffer, TCL_VOLATILE);
+ listObj = Tcl_NewListObj(0,NULL);
+ Tcl_ListObjAppendElement(interp, listObj, Tcl_NewDoubleObj(first));
+ Tcl_ListObjAppendElement(interp, listObj, Tcl_NewDoubleObj(last));
+ Tcl_SetObjResult(interp, listObj);
return;
}
- if (FP_EQUAL_SCALE(first, dInfoPtr->yScrollFirst, totalLines) &&
- FP_EQUAL_SCALE(last, dInfoPtr->yScrollLast, totalLines)) {
+
+ if (FP_EQUAL_SCALE(first, dInfoPtr->yScrollFirst, totalPixels) &&
+ FP_EQUAL_SCALE(last, dInfoPtr->yScrollLast, totalPixels)) {
return;
}
+
dInfoPtr->yScrollFirst = first;
dInfoPtr->yScrollLast = last;
- sprintf(buffer, " %g %g", first, last);
- code = Tcl_VarEval(interp, textPtr->yScrollCmd, buffer, (char *) NULL);
- if (code != TCL_OK) {
- Tcl_AddErrorInfo(interp,
- "\n (vertical scrolling command executed by text)");
- Tcl_BackgroundError(interp);
+ if (textPtr->yScrollCmd != NULL) {
+ char buf1[TCL_DOUBLE_SPACE+1];
+ char buf2[TCL_DOUBLE_SPACE+1];
+
+ buf1[0] = ' ';
+ buf2[0] = ' ';
+ Tcl_PrintDouble(NULL, first, buf1+1);
+ Tcl_PrintDouble(NULL, last, buf2+1);
+ code = Tcl_VarEval(interp, textPtr->yScrollCmd, buf1, buf2, NULL);
+ if (code != TCL_OK) {
+ Tcl_AddErrorInfo(interp,
+ "\n (vertical scrolling command executed by text)");
+ Tcl_BackgroundError(interp);
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AsyncUpdateYScrollbar --
+ *
+ * This function is called to update the vertical scrollbar asychronously
+ * as the pixel height calculations progress for lines in the widget.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * See 'GetYView'. In particular the scrollbar position and size may be
+ * changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AsyncUpdateYScrollbar(
+ ClientData clientData) /* Information about widget. */
+{
+ register TkText *textPtr = (TkText *) clientData;
+
+ textPtr->dInfoPtr->scrollbarTimer = NULL;
+
+ if (!(textPtr->flags & DESTROYED)) {
+ GetYView(textPtr->interp, textPtr, 1);
+ }
+
+ if (--textPtr->refCount == 0) {
+ ckfree((char *) textPtr);
}
}
@@ -4074,14 +6398,13 @@ GetYView(interp, textPtr, report)
*
* FindDLine --
*
- * This procedure is called to find the DLine corresponding to a
- * given text index.
+ * This function is called to find the DLine corresponding to a given
+ * text index.
*
* Results:
- * The return value is a pointer to the first DLine found in the
- * list headed by dlPtr that displays information at or after the
- * specified position. If there is no such line in the list then
- * NULL is returned.
+ * The return value is a pointer to the first DLine found in the list
+ * headed by dlPtr that displays information at or after the specified
+ * position. If there is no such line in the list then NULL is returned.
*
* Side effects:
* None.
@@ -4090,21 +6413,22 @@ GetYView(interp, textPtr, report)
*/
static DLine *
-FindDLine(dlPtr, indexPtr)
- register DLine *dlPtr; /* Pointer to first in list of DLines
- * to search. */
- TkTextIndex *indexPtr; /* Index of desired character. */
+FindDLine(
+ register DLine *dlPtr, /* Pointer to first in list of DLines to
+ * search. */
+ CONST TkTextIndex *indexPtr)/* Index of desired character. */
{
TkTextLine *linePtr;
if (dlPtr == NULL) {
return NULL;
}
- if (TkBTreeLineIndex(indexPtr->linePtr)
- < TkBTreeLineIndex(dlPtr->index.linePtr)) {
+ if (TkBTreeLinesTo(NULL, indexPtr->linePtr)
+ < TkBTreeLinesTo(NULL, dlPtr->index.linePtr)) {
/*
* The first display line is already past the desired line.
*/
+
return dlPtr;
}
@@ -4120,9 +6444,15 @@ FindDLine(dlPtr, indexPtr)
return NULL;
}
}
- linePtr = TkBTreeNextLine(linePtr);
+
+ /*
+ * VMD: some concern here as to whether this logic, or the caller's
+ * logic will work well with partial peer widgets.
+ */
+
+ linePtr = TkBTreeNextLine(NULL, linePtr);
if (linePtr == NULL) {
- panic("FindDLine reached end of text");
+ Tcl_Panic("FindDLine reached end of text");
}
}
if (indexPtr->linePtr != dlPtr->index.linePtr) {
@@ -4133,7 +6463,7 @@ FindDLine(dlPtr, indexPtr)
* Now get to the right position within the text line.
*/
- while (indexPtr->byteIndex >= (dlPtr->index.byteIndex + dlPtr->byteCount)) {
+ while (indexPtr->byteIndex >= (dlPtr->index.byteIndex+dlPtr->byteCount)) {
dlPtr = dlPtr->nextPtr;
if ((dlPtr == NULL) || (dlPtr->index.linePtr != indexPtr->linePtr)) {
break;
@@ -4147,12 +6477,12 @@ FindDLine(dlPtr, indexPtr)
*
* TkTextPixelIndex --
*
- * Given an (x,y) coordinate on the screen, find the location of
- * the character closest to that location.
+ * Given an (x,y) coordinate on the screen, find the location of the
+ * character closest to that location.
*
* Results:
- * The index at *indexPtr is modified to refer to the character
- * on the display that is closest to (x,y).
+ * The index at *indexPtr is modified to refer to the character on the
+ * display that is closest to (x,y).
*
* Side effects:
* None.
@@ -4161,20 +6491,24 @@ FindDLine(dlPtr, indexPtr)
*/
void
-TkTextPixelIndex(textPtr, x, y, indexPtr)
- TkText *textPtr; /* Widget record for text widget. */
- int x, y; /* Pixel coordinates of point in widget's
+TkTextPixelIndex(
+ TkText *textPtr, /* Widget record for text widget. */
+ int x, int y, /* Pixel coordinates of point in widget's
* window. */
- TkTextIndex *indexPtr; /* This index gets filled in with the
- * index of the character nearest to (x,y). */
+ TkTextIndex *indexPtr, /* This index gets filled in with the index of
+ * the character nearest to (x,y). */
+ int *nearest) /* If non-NULL then gets set to 0 if (x,y) is
+ * actually over the returned index, and 1 if
+ * it is just nearby (e.g. if x,y is on the
+ * border of the widget). */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
- register DLine *dlPtr, *validdlPtr;
- register TkTextDispChunk *chunkPtr;
+ register DLine *dlPtr, *validDlPtr;
+ int nearby = 0;
/*
- * Make sure that all of the layout information about what's
- * displayed where on the screen is up-to-date.
+ * Make sure that all of the layout information about what's displayed
+ * where on the screen is up-to-date.
*/
if (dInfoPtr->flags & DINFO_OUT_OF_DATE) {
@@ -4182,72 +6516,143 @@ TkTextPixelIndex(textPtr, x, y, indexPtr)
}
/*
- * If the coordinates are above the top of the window, then adjust
- * them to refer to the upper-right corner of the window. If they're
- * off to one side or the other, then adjust to the closest side.
+ * If the coordinates are above the top of the window, then adjust them to
+ * refer to the upper-right corner of the window. If they're off to one
+ * side or the other, then adjust to the closest side.
*/
if (y < dInfoPtr->y) {
y = dInfoPtr->y;
x = dInfoPtr->x;
+ nearby = 1;
}
if (x >= dInfoPtr->maxX) {
x = dInfoPtr->maxX - 1;
+ nearby = 1;
}
if (x < dInfoPtr->x) {
x = dInfoPtr->x;
+ nearby = 1;
}
/*
* Find the display line containing the desired y-coordinate.
*/
- for (dlPtr = validdlPtr = dInfoPtr->dLinePtr; y >= (dlPtr->y + dlPtr->height);
- dlPtr = dlPtr->nextPtr) {
- if (dlPtr->chunkPtr !=NULL) validdlPtr = dlPtr;
- if (dlPtr->nextPtr == NULL) {
- /*
- * Y-coordinate is off the bottom of the displayed text.
- * Use the last character on the last line.
- */
+ if (dInfoPtr->dLinePtr == NULL) {
+ if (nearest != NULL) {
+ *nearest = 1;
+ }
+ *indexPtr = textPtr->topIndex;
+ return;
+ } else {
+ for (dlPtr = validDlPtr = dInfoPtr->dLinePtr;
+ y >= (dlPtr->y + dlPtr->height);
+ dlPtr = dlPtr->nextPtr) {
+ if (dlPtr->chunkPtr != NULL) {
+ validDlPtr = dlPtr;
+ }
+ if (dlPtr->nextPtr == NULL) {
+ /*
+ * Y-coordinate is off the bottom of the displayed text. Use
+ * the last character on the last line.
+ */
- x = dInfoPtr->maxX - 1;
- break;
+ x = dInfoPtr->maxX - 1;
+ nearby = 1;
+ break;
+ }
}
+ if (dlPtr->chunkPtr == NULL) dlPtr = validDlPtr;
}
- if (dlPtr->chunkPtr == NULL) dlPtr = validdlPtr;
- *indexPtr = dlPtr->index;
+ if (nearest != NULL) {
+ *nearest = nearby;
+ }
+
+ DlineIndexOfX(textPtr, dlPtr, x, indexPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DlineIndexOfX --
+ *
+ * Given an x coordinate in a display line, find the index of the
+ * character closest to that location.
+ *
+ * This is effectively the opposite of DlineXOfIndex.
+ *
+ * Results:
+ * The index at *indexPtr is modified to refer to the character on the
+ * display line that is closest to x.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DlineIndexOfX(
+ TkText *textPtr, /* Widget record for text widget. */
+ DLine *dlPtr, /* Display information for this display
+ * line. */
+ int x, /* Pixel x coordinate of point in widget's
+ * window. */
+ TkTextIndex *indexPtr) /* This index gets filled in with the index of
+ * the character nearest to x. */
+{
+ TextDInfo *dInfoPtr = textPtr->dInfoPtr;
+ register TkTextDispChunk *chunkPtr;
/*
- * If it is still empty, we have nothing to access. [Bug 1442102]
+ * Scan through the line's chunks to find the one that contains the
+ * desired x-coordinate. Before doing this, translate the x-coordinate
+ * from the coordinate system of the window to the coordinate system of
+ * the line (to take account of x-scrolling).
*/
- if (dlPtr->chunkPtr == NULL) {
+ *indexPtr = dlPtr->index;
+ x = x - dInfoPtr->x + dInfoPtr->curXPixelOffset;
+ chunkPtr = dlPtr->chunkPtr;
+
+ if (chunkPtr == NULL || x == 0) {
+ /*
+ * This may occur if everything is elided, or if we're simply already
+ * at the beginning of the line.
+ */
+
return;
}
- /*
- * Scan through the line's chunks to find the one that contains
- * the desired x-coordinate. Before doing this, translate the
- * x-coordinate from the coordinate system of the window to the
- * coordinate system of the line (to take account of x-scrolling).
- */
+ while (x >= (chunkPtr->x + chunkPtr->width)) {
+ /*
+ * Note that this forward then backward movement of the index can be
+ * problematic at the end of the buffer (we can't move forward, and
+ * then when we move backward, we do, leading to the wrong position).
+ * Hence when x == 0 we take special action above.
+ */
- x = x - dInfoPtr->x + dInfoPtr->curPixelOffset;
- for (chunkPtr = dlPtr->chunkPtr; x >= (chunkPtr->x + chunkPtr->width);
- indexPtr->byteIndex += chunkPtr->numBytes,
- chunkPtr = chunkPtr->nextPtr) {
+ if (TkTextIndexForwBytes(NULL,indexPtr,chunkPtr->numBytes,indexPtr)) {
+ /*
+ * We've reached the end of the text.
+ */
+
+ return;
+ }
if (chunkPtr->nextPtr == NULL) {
- indexPtr->byteIndex += chunkPtr->numBytes;
- TkTextIndexBackChars(indexPtr, 1, indexPtr);
+ TkTextIndexBackChars(NULL, indexPtr, 1, indexPtr, COUNT_INDICES);
return;
}
+ chunkPtr = chunkPtr->nextPtr;
}
/*
- * If the chunk has more than one byte in it, ask it which
- * character is at the desired location.
+ * If the chunk has more than one byte in it, ask it which character is at
+ * the desired location. In this case we can manipulate
+ * 'indexPtr->byteIndex' directly, because we know we're staying inside a
+ * single logical line.
*/
if (chunkPtr->numBytes > 1) {
@@ -4258,17 +6663,119 @@ TkTextPixelIndex(textPtr, x, y, indexPtr)
/*
*----------------------------------------------------------------------
*
- * TkTextCharBbox --
+ * TkTextIndexOfX --
*
- * Given an index, find the bounding box of the screen area
- * occupied by that character.
+ * Given a logical x coordinate (i.e. distance in pixels from the
+ * beginning of the display line, not taking into account any information
+ * about the window, scrolling etc.) on the display line starting with
+ * the given index, adjust that index to refer to the object under the x
+ * coordinate.
*
* Results:
- * Zero is returned if the character is on the screen. -1
- * means the character isn't on the screen. If the return value
- * is 0, then the bounding box of the part of the character that's
- * visible on the screen is returned to *xPtr, *yPtr, *widthPtr,
- * and *heightPtr.
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkTextIndexOfX(
+ TkText *textPtr, /* Widget record for text widget. */
+ int x, /* The x coordinate for which we want the
+ * index. */
+ TkTextIndex *indexPtr) /* Index of display line start, which will be
+ * adjusted to the index under the given x
+ * coordinate. */
+{
+ DLine *dlPtr = LayoutDLine(textPtr, indexPtr);
+ DlineIndexOfX(textPtr, dlPtr, x + textPtr->dInfoPtr->x
+ - textPtr->dInfoPtr->curXPixelOffset, indexPtr);
+ FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE_TEMP);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DlineXOfIndex --
+ *
+ * Given a relative byte index on a given display line (i.e. the number
+ * of byte indices from the beginning of the given display line), find
+ * the x coordinate of that index within the abstract display line,
+ * without adjusting for the x-scroll state of the line.
+ *
+ * This is effectively the opposite of DlineIndexOfX.
+ *
+ * NB. The 'byteIndex' is relative to the display line, NOT the logical
+ * line.
+ *
+ * Results:
+ * The x coordinate.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DlineXOfIndex(
+ TkText *textPtr, /* Widget record for text widget. */
+ DLine *dlPtr, /* Display information for this display
+ * line. */
+ int byteIndex) /* The byte index for which we want the
+ * coordinate. */
+{
+ register TkTextDispChunk *chunkPtr = dlPtr->chunkPtr;
+ int x;
+
+ if (byteIndex == 0 || chunkPtr == NULL) {
+ return 0;
+ }
+
+ /*
+ * Scan through the line's chunks to find the one that contains the
+ * desired byte index.
+ */
+
+ chunkPtr = dlPtr->chunkPtr;
+ while (byteIndex > 0) {
+ if (byteIndex < chunkPtr->numBytes) {
+ int y, width, height;
+
+ (*chunkPtr->bboxProc)(textPtr, chunkPtr, byteIndex,
+ dlPtr->y + dlPtr->spaceAbove,
+ dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
+ dlPtr->baseline - dlPtr->spaceAbove, &x, &y, &width,
+ &height);
+ break;
+ } else {
+ byteIndex -= chunkPtr->numBytes;
+ }
+ if (chunkPtr->nextPtr == NULL || byteIndex == 0) {
+ x = chunkPtr->x + chunkPtr->width;
+ break;
+ }
+ chunkPtr = chunkPtr->nextPtr;
+ }
+
+ return x;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkTextIndexBbox --
+ *
+ * Given an index, find the bounding box of the screen area occupied by
+ * the entity (character, window, image) at that index.
+ *
+ * Results:
+ * Zero is returned if the index is on the screen. -1 means the index is
+ * not on the screen. If the return value is 0, then the bounding box of
+ * the part of the index that's visible on the screen is returned to
+ * *xPtr, *yPtr, *widthPtr, and *heightPtr.
*
* Side effects:
* None.
@@ -4277,13 +6784,17 @@ TkTextPixelIndex(textPtr, x, y, indexPtr)
*/
int
-TkTextCharBbox(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr)
- TkText *textPtr; /* Widget record for text widget. */
- TkTextIndex *indexPtr; /* Index of character whose bounding
- * box is desired. */
- int *xPtr, *yPtr; /* Filled with character's upper-left
+TkTextIndexBbox(
+ TkText *textPtr, /* Widget record for text widget. */
+ CONST TkTextIndex *indexPtr,/* Index whose bounding box is desired. */
+ int *xPtr, int *yPtr, /* Filled with index's upper-left
* coordinate. */
- int *widthPtr, *heightPtr; /* Filled in with character's dimensions. */
+ int *widthPtr, int *heightPtr,
+ /* Filled in with index's dimensions. */
+ int *charWidthPtr) /* If the 'index' is at the end of a display
+ * line and therefore takes up a very large
+ * width, this is used to return the smaller
+ * width actually desired by the index. */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
DLine *dlPtr;
@@ -4308,8 +6819,7 @@ TkTextCharBbox(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr)
}
/*
- * Find the chunk within the line that contains the desired
- * index.
+ * Find the chunk within the line that contains the desired index.
*/
byteIndex = indexPtr->byteIndex - dlPtr->index.byteIndex;
@@ -4324,31 +6834,52 @@ TkTextCharBbox(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr)
}
/*
- * Call a chunk-specific procedure to find the horizontal range of
- * the character within the chunk, then fill in the vertical range.
- * The x-coordinate returned by bboxProc is a coordinate within a
- * line, not a coordinate on the screen. Translate it to reflect
- * horizontal scrolling.
+ * Call a chunk-specific function to find the horizontal range of the
+ * character within the chunk, then fill in the vertical range. The
+ * x-coordinate returned by bboxProc is a coordinate within a line, not a
+ * coordinate on the screen. Translate it to reflect horizontal scrolling.
*/
- (*chunkPtr->bboxProc)(chunkPtr, byteIndex, dlPtr->y + dlPtr->spaceAbove,
+ (*chunkPtr->bboxProc)(textPtr, 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 ((byteIndex == (chunkPtr->numBytes - 1)) && (chunkPtr->nextPtr == NULL)) {
+ *xPtr = *xPtr + dInfoPtr->x - dInfoPtr->curXPixelOffset;
+ if ((byteIndex == chunkPtr->numBytes-1) && (chunkPtr->nextPtr == NULL)) {
/*
- * Last character in display line. Give it all the space up to
- * the line.
+ * Last character in display line. Give it all the space up to the
+ * line.
*/
+ if (charWidthPtr != NULL) {
+ *charWidthPtr = dInfoPtr->maxX - *xPtr;
+ if (*charWidthPtr > textPtr->charWidth) {
+ *charWidthPtr = textPtr->charWidth;
+ }
+ }
if (*xPtr > dInfoPtr->maxX) {
*xPtr = dInfoPtr->maxX;
}
*widthPtr = dInfoPtr->maxX - *xPtr;
+ } else {
+ if (charWidthPtr != NULL) {
+ *charWidthPtr = *widthPtr;
+ }
}
- if ((*xPtr + *widthPtr) <= dInfoPtr->x) {
- return -1;
+ if (*widthPtr == 0) {
+ /*
+ * With zero width (e.g. elided text) we just need to make sure it is
+ * onscreen, where the '=' case here is ok.
+ */
+
+ if (*xPtr < dInfoPtr->x) {
+ return -1;
+ }
+ } else {
+ if ((*xPtr + *widthPtr) <= dInfoPtr->x) {
+ return -1;
+ }
}
if ((*xPtr + *widthPtr) > dInfoPtr->maxX) {
*widthPtr = dInfoPtr->maxX - *xPtr;
@@ -4370,14 +6901,14 @@ TkTextCharBbox(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr)
*
* TkTextDLineInfo --
*
- * Given an index, return information about the display line
- * containing that character.
+ * Given an index, return information about the display line containing
+ * that character.
*
* Results:
- * Zero is returned if the character is on the screen. -1
- * means the character isn't on the screen. If the return value
- * is 0, then information is returned in the variables pointed
- * to by xPtr, yPtr, widthPtr, heightPtr, and basePtr.
+ * Zero is returned if the character is on the screen. -1 means the
+ * character isn't on the screen. If the return value is 0, then
+ * information is returned in the variables pointed to by xPtr, yPtr,
+ * widthPtr, heightPtr, and basePtr.
*
* Side effects:
* None.
@@ -4386,14 +6917,15 @@ TkTextCharBbox(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr)
*/
int
-TkTextDLineInfo(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr, basePtr)
- TkText *textPtr; /* Widget record for text widget. */
- TkTextIndex *indexPtr; /* Index of character whose bounding
- * box is desired. */
- int *xPtr, *yPtr; /* Filled with line's upper-left
+TkTextDLineInfo(
+ TkText *textPtr, /* Widget record for text widget. */
+ CONST TkTextIndex *indexPtr,/* Index of character whose bounding box is
+ * desired. */
+ int *xPtr, int *yPtr, /* Filled with line's upper-left
* coordinate. */
- int *widthPtr, *heightPtr; /* Filled in with line's dimensions. */
- int *basePtr; /* Filled in with the baseline position,
+ int *widthPtr, int *heightPtr,
+ /* Filled in with line's dimensions. */
+ int *basePtr) /* Filled in with the baseline position,
* measured as an offset down from *yPtr. */
{
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
@@ -4418,7 +6950,7 @@ TkTextDLineInfo(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr, basePtr)
}
dlx = (dlPtr->chunkPtr != NULL? dlPtr->chunkPtr->x: 0);
- *xPtr = dInfoPtr->x - dInfoPtr->curPixelOffset + dlx;
+ *xPtr = dInfoPtr->x - dInfoPtr->curXPixelOffset + dlx;
*widthPtr = dlPtr->length - dlx;
*yPtr = dlPtr->y;
if ((dlPtr->y + dlPtr->height) > dInfoPtr->maxY) {
@@ -4430,37 +6962,43 @@ TkTextDLineInfo(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr, basePtr)
return 0;
}
+/*
+ * Get bounding-box information about an elided chunk.
+ */
+
static void
-ElideBboxProc(chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr,
- widthPtr, heightPtr)
- TkTextDispChunk *chunkPtr; /* Chunk containing desired char. */
- int index; /* Index of desired character within
- * the chunk. */
- int y; /* Topmost pixel in area allocated
- * for this line. */
- int lineHeight; /* Height of line, in pixels. */
- int baseline; /* Location of line's baseline, in
- * pixels measured down from y. */
- int *xPtr, *yPtr; /* Gets filled in with coords of
- * character's upper-left pixel.
- * X-coord is in same coordinate
- * system as chunkPtr->x. */
- int *widthPtr; /* Gets filled in with width of
- * character, in pixels. */
- int *heightPtr; /* Gets filled in with height of
- * character, in pixels. */
+ElideBboxProc(
+ TkText *textPtr,
+ TkTextDispChunk *chunkPtr, /* Chunk containing desired char. */
+ int index, /* Index of desired character within the
+ * chunk. */
+ int y, /* Topmost pixel in area allocated for this
+ * line. */
+ int lineHeight, /* Height of line, in pixels. */
+ int baseline, /* Location of line's baseline, in pixels
+ * measured down from y. */
+ int *xPtr, int *yPtr, /* Gets filled in with coords of character's
+ * upper-left pixel. X-coord is in same
+ * coordinate system as chunkPtr->x. */
+ int *widthPtr, /* Gets filled in with width of character, in
+ * pixels. */
+ int *heightPtr) /* Gets filled in with height of character, in
+ * pixels. */
{
*xPtr = chunkPtr->x;
*yPtr = y;
*widthPtr = *heightPtr = 0;
}
-
+
+/*
+ * Measure an elided chunk.
+ */
static int
-ElideMeasureProc(chunkPtr, x)
- TkTextDispChunk *chunkPtr; /* Chunk containing desired coord. */
- int x; /* X-coordinate, in same coordinate
- * system as chunkPtr->x. */
+ElideMeasureProc(
+ TkTextDispChunk *chunkPtr, /* Chunk containing desired coord. */
+ int x) /* X-coordinate, in same coordinate system as
+ * chunkPtr->x. */
{
return 0 /*chunkPtr->numBytes - 1*/;
}
@@ -4470,45 +7008,43 @@ ElideMeasureProc(chunkPtr, x)
*
* TkTextCharLayoutProc --
*
- * This procedure is the "layoutProc" for character segments.
+ * This function is the "layoutProc" for character segments.
*
* 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
- * in tkText.h for details). If zero is returned it means
- * that no characters from this chunk fit in the window.
- * If -1 is returned it means that this segment just doesn't
- * need to be displayed (never happens for text).
+ * 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 in tkText.h for details). If zero is
+ * returned it means that no characters from this chunk fit in the
+ * window. If -1 is returned it means that this segment just doesn't need
+ * to be displayed (never happens for text).
*
* Side effects:
- * Memory is allocated to hold additional information about
- * the chunk.
+ * Memory is allocated to hold additional information about the chunk.
*
*--------------------------------------------------------------
*/
int
-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
+TkTextCharLayoutProc(
+ 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 byteOffset; /* Byte offset within segment of first
+ TkTextSegment *segPtr, /* Segment being layed out. */
+ int byteOffset, /* Byte offset within segment of first
* character to consider. */
- int maxX; /* Chunk must not occupy pixels at this
+ int maxX, /* Chunk must not occupy pixels at this
* position or higher. */
- int maxBytes; /* Chunk must not include more than this
- * many characters. */
- int noCharsYet; /* Non-zero means no characters have been
+ 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. */
- TkWrapMode wrapMode; /* How to handle line wrapping: TEXT_WRAPMODE_CHAR,
- * TEXT_WRAPMODE_NONE, or TEXT_WRAPMODE_WORD. */
- register TkTextDispChunk *chunkPtr;
- /* Structure to fill in with information
- * about this chunk. The x field has already
- * been set by the caller. */
+ TkWrapMode wrapMode, /* How to handle line wrapping:
+ * TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, or
+ * TEXT_WRAPMODE_WORD. */
+ 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, bytesThatFit, count;
@@ -4516,36 +7052,80 @@ TkTextCharLayoutProc(textPtr, indexPtr, segPtr, byteOffset, maxX, maxBytes,
char *p;
TkTextSegment *nextPtr;
Tk_FontMetrics fm;
+#if TK_LAYOUT_WITH_BASE_CHUNKS
+ const char *line;
+ int lineOffset;
+ BaseCharInfo *bciPtr;
+ Tcl_DString *baseString;
+#endif
/*
- * Figure out how many characters will fit in the space we've got.
- * Include the next character, even though it won't fit completely,
- * if any of the following is true:
- * (a) the chunk contains no characters and the display line contains
- * no characters yet (i.e. the line isn't wide enough to hold
- * even a single character).
- * (b) at least one pixel of the character is visible, we haven't
- * already exceeded the character limit, and the next character
- * is a white space character.
+ * Figure out how many characters will fit in the space we've got. Include
+ * the next character, even though it won't fit completely, if any of the
+ * following is true:
+ * (a) the chunk contains no characters and the display line contains no
+ * characters yet (i.e. the line isn't wide enough to hold even a
+ * single character).
+ * (b) at least one pixel of the character is visible, we have not
+ * already exceeded the character limit, and the next character is a
+ * white space character.
*/
p = segPtr->body.chars + byteOffset;
tkfont = chunkPtr->stylePtr->sValuePtr->tkfont;
- bytesThatFit = MeasureChars(tkfont, p, maxBytes, chunkPtr->x, maxX, 0,
- &nextX);
+
+#if TK_LAYOUT_WITH_BASE_CHUNKS
+ if (baseCharChunkPtr == NULL) {
+ baseCharChunkPtr = chunkPtr;
+ bciPtr = (BaseCharInfo *) ckalloc(sizeof(BaseCharInfo));
+ baseString = &bciPtr->baseChars;
+ Tcl_DStringInit(baseString);
+ bciPtr->width = 0;
+
+ ciPtr = &bciPtr->ci;
+ } else {
+ bciPtr = (BaseCharInfo *) baseCharChunkPtr->clientData;
+ ciPtr = (CharInfo *) ckalloc(sizeof(CharInfo));
+ baseString = &bciPtr->baseChars;
+ }
+
+ lineOffset = Tcl_DStringLength(baseString);
+ line = Tcl_DStringAppend(baseString,p,maxBytes);
+
+ chunkPtr->clientData = (ClientData) ciPtr;
+ ciPtr->baseChunkPtr = baseCharChunkPtr;
+ ciPtr->baseOffset = lineOffset;
+ ciPtr->chars = NULL;
+ ciPtr->numBytes = 0;
+
+ bytesThatFit = CharChunkMeasureChars(chunkPtr, line,
+ lineOffset + maxBytes, lineOffset, -1, chunkPtr->x, maxX,
+ TK_ISOLATE_END, &nextX);
+#else /* !TK_LAYOUT_WITH_BASE_CHUNKS */
+ bytesThatFit = CharChunkMeasureChars(chunkPtr, p, maxBytes, 0, -1,
+ chunkPtr->x, maxX, TK_ISOLATE_END, &nextX);
+#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
+
if (bytesThatFit < maxBytes) {
if ((bytesThatFit == 0) && noCharsYet) {
Tcl_UniChar ch;
-
- bytesThatFit = MeasureChars(tkfont, p, Tcl_UtfToUniChar(p, &ch),
+ int chLen = Tcl_UtfToUniChar(p, &ch);
+
+#if TK_LAYOUT_WITH_BASE_CHUNKS
+ bytesThatFit = CharChunkMeasureChars(chunkPtr, line,
+ lineOffset+chLen, lineOffset, -1, chunkPtr->x, -1, 0,
+ &nextX);
+#else /* !TK_LAYOUT_WITH_BASE_CHUNKS */
+ bytesThatFit = CharChunkMeasureChars(chunkPtr, p, chLen, 0, -1,
chunkPtr->x, -1, 0, &nextX);
+#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
}
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
- * line. Just give the space character whatever space is left.
+ * Space characters are funny, in that they are considered to fit
+ * if there is at least one pixel of space left on the line. Just
+ * give the space character whatever space is left.
*/
nextX = maxX;
@@ -4560,16 +7140,26 @@ TkTextCharLayoutProc(textPtr, indexPtr, segPtr, byteOffset, maxX, maxBytes,
bytesThatFit++;
}
if (bytesThatFit == 0) {
+#if TK_LAYOUT_WITH_BASE_CHUNKS
+ chunkPtr->clientData = NULL;
+ if (chunkPtr == baseCharChunkPtr) {
+ baseCharChunkPtr = NULL;
+ Tcl_DStringFree(baseString);
+ } else {
+ Tcl_DStringSetLength(baseString,lineOffset);
+ }
+ ckfree((char *) ciPtr);
+#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
return 0;
}
}
-
+
Tk_GetFontMetrics(tkfont, &fm);
/*
- * Fill in the chunk structure and allocate and initialize a
- * CharInfo structure. If the last character is a newline
- * then don't bother to display it.
+ * Fill in the chunk structure and allocate and initialize a CharInfo
+ * structure. If the last character is a newline then don't bother to
+ * display it.
*/
chunkPtr->displayProc = CharDisplayProc;
@@ -4582,20 +7172,41 @@ TkTextCharLayoutProc(textPtr, indexPtr, segPtr, byteOffset, maxX, maxBytes,
chunkPtr->minHeight = 0;
chunkPtr->width = nextX - chunkPtr->x;
chunkPtr->breakIndex = -1;
- ciPtr = (CharInfo *) ckalloc((unsigned)
- (sizeof(CharInfo) - 3 + bytesThatFit));
+
+#if !TK_LAYOUT_WITH_BASE_CHUNKS
+ ciPtr = (CharInfo *)
+ ckalloc((unsigned) bytesThatFit + Tk_Offset(CharInfo, chars) + 1);
chunkPtr->clientData = (ClientData) ciPtr;
+ memcpy(ciPtr->chars, p, (unsigned) bytesThatFit);
+#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
+
ciPtr->numBytes = bytesThatFit;
- memcpy(ciPtr->chars, p, (size_t) bytesThatFit);
if (p[bytesThatFit - 1] == '\n') {
ciPtr->numBytes--;
}
+#if TK_LAYOUT_WITH_BASE_CHUNKS
/*
- * Compute a break location. If we're in word wrap mode, a
- * break can occur after any space character, or at the end of
- * the chunk if the next segment (ignoring those with zero size)
- * is not a character segment.
+ * Final update for the current base chunk data.
+ */
+
+ Tcl_DStringSetLength(baseString,lineOffset+ciPtr->numBytes);
+ bciPtr->width = nextX - baseCharChunkPtr->x;
+
+ /*
+ * Finalize the base chunk if this chunk ends in a tab, which definitly
+ * breaks the context and needs to be handled on a higher level.
+ */
+
+ if (ciPtr->numBytes > 0 && p[ciPtr->numBytes - 1] == '\t') {
+ FinalizeBaseChunk(chunkPtr);
+ }
+#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
+
+ /*
+ * Compute a break location. If we're in word wrap mode, a break can occur
+ * after any space character, or at the end of the chunk if the next
+ * segment (ignoring those with zero size) is not a character segment.
*/
if (wrapMode != TEXT_WRAPMODE_WORD) {
@@ -4603,7 +7214,7 @@ TkTextCharLayoutProc(textPtr, indexPtr, segPtr, byteOffset, maxX, maxBytes,
} else {
for (count = bytesThatFit, p += bytesThatFit - 1; count > 0;
count--, p--) {
- if (isspace(UCHAR(*p))) {
+ if (UCHAR(*p) < 0x80 && isspace(UCHAR(*p))) {
chunkPtr->breakIndex = count;
break;
}
@@ -4624,12 +7235,112 @@ TkTextCharLayoutProc(textPtr, indexPtr, segPtr, byteOffset, maxX, maxBytes,
}
/*
+ *---------------------------------------------------------------------------
+ *
+ * CharChunkMeasureChars --
+ *
+ * Determine the number of characters from a char chunk that will fit in
+ * the given horizontal span.
+ *
+ * This is the same as MeasureChars (which see), but in the context of a
+ * char chunk, i.e. on a higher level of abstraction. Use this function
+ * whereever possible instead of plain MeasureChars, so that the right
+ * context is used automatically.
+ *
+ * Results:
+ * The return value is the number of bytes from the range of start to end
+ * in 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 be drawn.
+ *
+ * Side effects:
+ * None.
+ *--------------------------------------------------------------
+ */
+
+static int
+CharChunkMeasureChars(
+ TkTextDispChunk *chunkPtr, /* Chunk from which to measure. */
+ const char *chars, /* Chars to use, instead of the chunk's own.
+ * Used by the layoutproc during chunk setup.
+ * All other callers use NULL. Not
+ * NUL-terminated. */
+ int charsLen, /* Length of the "chars" parameter. */
+ int start, int end, /* The range of chars to measure inside the
+ * chunk (or inside the additional chars). */
+ int startX, /* Starting x coordinate where the measured
+ * span will begin. */
+ int maxX, /* Maximum pixel width of the span. May be -1
+ * for unlimited. */
+ int flags, /* Flags to pass to MeasureChars. */
+ int *nextXPtr) /* The function puts the newly calculated
+ * right border x-position of the span
+ * here. */
+{
+ Tk_Font tkfont = chunkPtr->stylePtr->sValuePtr->tkfont;
+ CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData;
+
+#if !TK_LAYOUT_WITH_BASE_CHUNKS
+ if (chars == NULL) {
+ chars = ciPtr->chars;
+ charsLen = ciPtr->numBytes;
+ }
+ if (end == -1) {
+ end = charsLen;
+ }
+
+ return MeasureChars(tkfont, chars, charsLen, start, end-start,
+ startX, maxX, flags, nextXPtr);
+#else
+ {
+ int xDisplacement;
+ int fit, bstart = start, bend = end;
+
+ if (chars == NULL) {
+ Tcl_DString *baseChars = &((BaseCharInfo *)
+ ciPtr->baseChunkPtr->clientData)->baseChars;
+
+ chars = Tcl_DStringValue(baseChars);
+ charsLen = Tcl_DStringLength(baseChars);
+ bstart += ciPtr->baseOffset;
+ if (bend == -1) {
+ bend = ciPtr->baseOffset + ciPtr->numBytes;
+ } else {
+ bend += ciPtr->baseOffset;
+ }
+ } else if (bend == -1) {
+ bend = charsLen;
+ }
+
+ if (bstart == ciPtr->baseOffset) {
+ xDisplacement = startX - chunkPtr->x;
+ } else {
+ int widthUntilStart = 0;
+
+ MeasureChars(tkfont, chars, charsLen, 0, bstart,
+ 0, -1, 0, &widthUntilStart);
+ xDisplacement = startX - widthUntilStart - chunkPtr->x;
+ }
+
+ fit = MeasureChars(tkfont, chars, charsLen, 0, bend,
+ ciPtr->baseChunkPtr->x + xDisplacement, maxX, flags, nextXPtr);
+
+ if (fit < bstart) {
+ return 0;
+ } else {
+ return fit - bstart;
+ }
+ }
+#endif
+}
+
+/*
*--------------------------------------------------------------
*
* CharDisplayProc --
*
- * This procedure is called to display a character chunk on
- * the screen or in an off-screen pixmap.
+ * This function is called to display a character chunk on the screen or
+ * in an off-screen pixmap.
*
* Results:
* None.
@@ -4641,26 +7352,29 @@ TkTextCharLayoutProc(textPtr, indexPtr, segPtr, byteOffset, maxX, maxBytes,
*/
static void
-CharDisplayProc(chunkPtr, x, y, height, baseline, display, dst, screenY)
- TkTextDispChunk *chunkPtr; /* Chunk that is to be drawn. */
- int x; /* X-position in dst at which to
- * draw this chunk (may differ from
- * the x-position in the chunk because
- * of scrolling). */
- int y; /* Y-position at which to draw this
- * chunk in dst. */
- int height; /* Total height of line. */
- int baseline; /* Offset of baseline from y. */
- Display *display; /* Display to use for drawing. */
- Drawable dst; /* Pixmap or window in which to draw
- * chunk. */
- int screenY; /* Y-coordinate in text window that
- * corresponds to y. */
+CharDisplayProc(
+ TkText *textPtr,
+ TkTextDispChunk *chunkPtr, /* Chunk that is to be drawn. */
+ int x, /* X-position in dst at which to draw this
+ * chunk (may differ from the x-position in
+ * the chunk because of scrolling). */
+ int y, /* Y-position at which to draw this chunk in
+ * dst. */
+ int height, /* Total height of line. */
+ int baseline, /* Offset of baseline from y. */
+ Display *display, /* Display to use for drawing. */
+ Drawable dst, /* Pixmap or window in which to draw chunk. */
+ int screenY) /* Y-coordinate in text window that
+ * corresponds to y. */
{
CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData;
+ const char *string;
TextStyle *stylePtr;
StyleValues *sValuePtr;
- int offsetBytes, offsetX;
+ int numBytes, offsetBytes, offsetX;
+#if TK_DRAW_IN_CONTEXT
+ BaseCharInfo *bciPtr;
+#endif /* TK_DRAW_IN_CONTEXT */
if ((x + chunkPtr->width) <= 0) {
/*
@@ -4670,31 +7384,90 @@ CharDisplayProc(chunkPtr, x, y, height, baseline, display, dst, screenY)
return;
}
+#if TK_DRAW_IN_CONTEXT
+ bciPtr = (BaseCharInfo *) ciPtr->baseChunkPtr->clientData;
+ numBytes = Tcl_DStringLength(&bciPtr->baseChars);
+ string = Tcl_DStringValue(&bciPtr->baseChars);
+
+#elif TK_LAYOUT_WITH_BASE_CHUNKS
+ if (ciPtr->baseChunkPtr != chunkPtr) {
+ /*
+ * Without context drawing only base chunks display their foreground.
+ */
+
+ return;
+ }
+
+ numBytes = Tcl_DStringLength(&((BaseCharInfo *) ciPtr)->baseChars);
+ string = ciPtr->chars;
+
+#else /* !TK_LAYOUT_WITH_BASE_CHUNKS */
+ numBytes = ciPtr->numBytes;
+ string = ciPtr->chars;
+#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
+
stylePtr = chunkPtr->stylePtr;
sValuePtr = stylePtr->sValuePtr;
/*
- * If the text sticks out way to the left of the window, skip
- * over the characters that aren't in the visible part of the
- * window. This is essential if x is very negative (such as
- * less than 32K); otherwise overflow problems will occur
- * in servers that use 16-bit arithmetic, like X.
+ * If the text sticks out way to the left of the window, skip over the
+ * characters that aren't in the visible part of the window. This is
+ * essential if x is very negative (such as less than 32K); otherwise
+ * overflow problems will occur in servers that use 16-bit arithmetic,
+ * like X.
*/
offsetX = x;
offsetBytes = 0;
if (x < 0) {
- offsetBytes = MeasureChars(sValuePtr->tkfont, ciPtr->chars,
- ciPtr->numBytes, x, 0, x - chunkPtr->x, &offsetX);
+ offsetBytes = CharChunkMeasureChars(chunkPtr, NULL, 0, 0, -1,
+ x, 0, 0, &offsetX);
}
/*
* Draw the text, underline, and overstrike for this chunk.
*/
- if (!sValuePtr->elide && (ciPtr->numBytes > offsetBytes) && (stylePtr->fgGC != None)) {
- int numBytes = ciPtr->numBytes - offsetBytes;
- char *string = ciPtr->chars + offsetBytes;
+ if (!sValuePtr->elide && (numBytes > offsetBytes)
+ && (stylePtr->fgGC != None)) {
+#if TK_DRAW_IN_CONTEXT
+ int start = ciPtr->baseOffset + offsetBytes;
+ int len = ciPtr->numBytes - offsetBytes;
+ int xDisplacement = x - chunkPtr->x;
+
+ if ((len > 0) && (string[start + len - 1] == '\t')) {
+ len--;
+ }
+ if (len <= 0) {
+ return;
+ }
+
+ TkpDrawCharsInContext(display, dst, stylePtr->fgGC, sValuePtr->tkfont,
+ string, numBytes, start, len,
+ ciPtr->baseChunkPtr->x + xDisplacement,
+ y + baseline - sValuePtr->offset);
+
+ if (sValuePtr->underline) {
+ TkUnderlineCharsInContext(display, dst, stylePtr->fgGC,
+ sValuePtr->tkfont, string, numBytes,
+ ciPtr->baseChunkPtr->x + xDisplacement,
+ y + baseline - sValuePtr->offset,
+ start, start+len);
+ }
+ if (sValuePtr->overstrike) {
+ Tk_FontMetrics fm;
+
+ Tk_GetFontMetrics(sValuePtr->tkfont, &fm);
+ TkUnderlineCharsInContext(display, dst, stylePtr->fgGC,
+ sValuePtr->tkfont, string, numBytes,
+ ciPtr->baseChunkPtr->x + xDisplacement,
+ y + baseline - sValuePtr->offset
+ - fm.descent - (fm.ascent * 3) / 10,
+ start, start+len);
+ }
+#else /* !TK_DRAW_IN_CONTEXT */
+ string += offsetBytes;
+ numBytes -= offsetBytes;
if ((numBytes > 0) && (string[numBytes - 1] == '\t')) {
numBytes--;
@@ -4703,20 +7476,22 @@ CharDisplayProc(chunkPtr, x, y, height, baseline, display, dst, screenY)
numBytes, offsetX, y + baseline - sValuePtr->offset);
if (sValuePtr->underline) {
Tk_UnderlineChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont,
- ciPtr->chars + offsetBytes, offsetX,
- y + baseline - sValuePtr->offset, 0, numBytes);
+ string, offsetX,
+ y + baseline - sValuePtr->offset,
+ 0, numBytes);
}
if (sValuePtr->overstrike) {
Tk_FontMetrics fm;
-
+
Tk_GetFontMetrics(sValuePtr->tkfont, &fm);
Tk_UnderlineChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont,
- ciPtr->chars + offsetBytes, offsetX,
+ string, offsetX,
y + baseline - sValuePtr->offset
- fm.descent - (fm.ascent * 3) / 10,
0, numBytes);
}
+#endif /* TK_DRAW_IN_CONTEXT */
}
}
@@ -4725,9 +7500,9 @@ CharDisplayProc(chunkPtr, x, y, height, baseline, display, dst, screenY)
*
* CharUndisplayProc --
*
- * This procedure is called when a character chunk is no
- * longer going to be displayed. It frees up resources
- * that were allocated to display the chunk.
+ * This function is called when a character chunk is no longer going to
+ * be displayed. It frees up resources that were allocated to display the
+ * chunk.
*
* Results:
* None.
@@ -4739,14 +7514,40 @@ CharDisplayProc(chunkPtr, x, y, height, baseline, display, dst, screenY)
*/
static void
-CharUndisplayProc(textPtr, chunkPtr)
- TkText *textPtr; /* Overall information about text
- * widget. */
- TkTextDispChunk *chunkPtr; /* Chunk that is about to be freed. */
+CharUndisplayProc(
+ TkText *textPtr, /* Overall information about text widget. */
+ TkTextDispChunk *chunkPtr) /* Chunk that is about to be freed. */
{
CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData;
- ckfree((char *) ciPtr);
+ if (ciPtr) {
+#if TK_LAYOUT_WITH_BASE_CHUNKS
+ if (chunkPtr == ciPtr->baseChunkPtr) {
+ /*
+ * Basechunks are undisplayed first, when DLines are freed or
+ * partially freed, so this makes sure we don't access their data
+ * any more.
+ */
+
+ FreeBaseChunk(chunkPtr);
+ } else if (ciPtr->baseChunkPtr != NULL) {
+ /*
+ * When other char chunks are undisplayed, drop their characters
+ * from the base chunk. This usually happens, when they are last
+ * in a line and need to be re-layed out.
+ */
+
+ RemoveFromBaseChunk(chunkPtr);
+ }
+
+ ciPtr->baseChunkPtr = NULL;
+ ciPtr->chars = NULL;
+ ciPtr->numBytes = 0;
+#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
+
+ ckfree((char *) ciPtr);
+ chunkPtr->clientData = NULL;
+ }
}
/*
@@ -4754,12 +7555,12 @@ CharUndisplayProc(textPtr, chunkPtr)
*
* CharMeasureProc --
*
- * This procedure is called to determine which character in
- * a character chunk lies over a given x-coordinate.
+ * This function is called to determine which character in a character
+ * chunk lies over a given x-coordinate.
*
* Results:
- * The return value is the index *within the chunk* of the
- * character that covers the position given by "x".
+ * The return value is the index *within the chunk* of the character that
+ * covers the position given by "x".
*
* Side effects:
* None.
@@ -4768,17 +7569,15 @@ CharUndisplayProc(textPtr, chunkPtr)
*/
static int
-CharMeasureProc(chunkPtr, x)
- TkTextDispChunk *chunkPtr; /* Chunk containing desired coord. */
- int x; /* X-coordinate, in same coordinate
- * system as chunkPtr->x. */
+CharMeasureProc(
+ TkTextDispChunk *chunkPtr, /* Chunk containing desired coord. */
+ int x) /* X-coordinate, in same coordinate system as
+ * chunkPtr->x. */
{
- CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData;
int endX;
- return MeasureChars(chunkPtr->stylePtr->sValuePtr->tkfont, ciPtr->chars,
- chunkPtr->numBytes - 1, chunkPtr->x, x, 0, &endX);
- /* CHAR OFFSET */
+ return CharChunkMeasureChars(chunkPtr, NULL, 0, 0, chunkPtr->numBytes-1,
+ chunkPtr->x, x, 0, &endX); /* CHAR OFFSET */
}
/*
@@ -4786,17 +7585,16 @@ CharMeasureProc(chunkPtr, x)
*
* CharBboxProc --
*
- * This procedure is called to compute the bounding box of
- * the area occupied by a single character.
+ * This function is called to compute the bounding box of the area
+ * occupied by a single character.
*
* Results:
- * There is no return value. *xPtr and *yPtr are filled in
- * with the coordinates of the upper left corner of the
- * character, and *widthPtr and *heightPtr are filled in with
- * the dimensions of the character in pixels. Note: not all
- * of the returned bbox is necessarily visible on the screen
- * (the rightmost part might be off-screen to the right,
- * and the bottommost part might be off-screen to the bottom).
+ * There is no return value. *xPtr and *yPtr are filled in with the
+ * coordinates of the upper left corner of the character, and *widthPtr
+ * and *heightPtr are filled in with the dimensions of the character in
+ * pixels. Note: not all of the returned bbox is necessarily visible on
+ * the screen (the rightmost part might be off-screen to the right, and
+ * the bottommost part might be off-screen to the bottom).
*
* Side effects:
* None.
@@ -4805,51 +7603,50 @@ CharMeasureProc(chunkPtr, x)
*/
static void
-CharBboxProc(chunkPtr, byteIndex, y, lineHeight, baseline, xPtr, yPtr,
- widthPtr, heightPtr)
- TkTextDispChunk *chunkPtr; /* Chunk containing desired char. */
- 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. */
- int baseline; /* Location of line's baseline, in
- * pixels measured down from y. */
- int *xPtr, *yPtr; /* Gets filled in with coords of
- * character's upper-left pixel.
- * X-coord is in same coordinate
- * system as chunkPtr->x. */
- int *widthPtr; /* Gets filled in with width of
- * character, in pixels. */
- int *heightPtr; /* Gets filled in with height of
- * character, in pixels. */
+CharBboxProc(
+ TkText *textPtr,
+ TkTextDispChunk *chunkPtr, /* Chunk containing desired char. */
+ 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. */
+ int baseline, /* Location of line's baseline, in pixels
+ * measured down from y. */
+ int *xPtr, int *yPtr, /* Gets filled in with coords of character's
+ * upper-left pixel. X-coord is in same
+ * coordinate system as chunkPtr->x. */
+ int *widthPtr, /* Gets filled in with width of character, in
+ * pixels. */
+ int *heightPtr) /* Gets filled in with height of character, in
+ * pixels. */
{
CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData;
int maxX;
maxX = chunkPtr->width + chunkPtr->x;
- MeasureChars(chunkPtr->stylePtr->sValuePtr->tkfont, ciPtr->chars,
- byteIndex, chunkPtr->x, -1, 0, xPtr);
+ CharChunkMeasureChars(chunkPtr, NULL, 0, 0, byteIndex,
+ chunkPtr->x, -1, 0, xPtr);
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
- * extra space in the line (see TkTextCharLayoutProc).
+ * This situation only happens if the last character in a line is a
+ * space character, in which case it absorbs all of the extra space in
+ * the line (see TkTextCharLayoutProc).
*/
*widthPtr = maxX - *xPtr;
} 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.
+ * The desired character is a tab character that terminates a chunk;
+ * give it all the space left in the chunk.
*/
*widthPtr = maxX - *xPtr;
} else {
- MeasureChars(chunkPtr->stylePtr->sValuePtr->tkfont,
- ciPtr->chars + byteIndex, 1, *xPtr, -1, 0, widthPtr);
+ CharChunkMeasureChars(chunkPtr, NULL, 0, byteIndex, byteIndex+1,
+ *xPtr, -1, 0, widthPtr);
if (*widthPtr > maxX) {
*widthPtr = maxX - *xPtr;
} else {
@@ -4865,64 +7662,73 @@ CharBboxProc(chunkPtr, byteIndex, y, lineHeight, baseline, xPtr, yPtr,
*
* AdjustForTab --
*
- * This procedure is called to move a series of chunks right
- * in order to align them with a tab stop.
+ * This function is called to move a series of chunks right in order to
+ * align them with a tab stop.
*
* Results:
* None.
*
* Side effects:
- * The width of chunkPtr gets adjusted so that it absorbs the
- * extra space due to the tab. The x locations in all the chunks
- * after chunkPtr are adjusted rightward to align with the tab
- * stop given by tabArrayPtr and index.
+ * The width of chunkPtr gets adjusted so that it absorbs the extra space
+ * due to the tab. The x locations in all the chunks after chunkPtr are
+ * adjusted rightward to align with the tab stop given by tabArrayPtr and
+ * index.
*
*----------------------------------------------------------------------
*/
static void
-AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr)
- TkText *textPtr; /* Information about the text widget as
- * a whole. */
- TkTextTabArray *tabArrayPtr; /* Information about the tab stops
- * that apply to this line. May be
- * NULL to indicate default tabbing
- * (every 8 chars). */
- int index; /* Index of current tab stop. */
- TkTextDispChunk *chunkPtr; /* Chunk whose last character is
- * the tab; the following chunks
- * contain information to be shifted
- * right. */
-
+AdjustForTab(
+ TkText *textPtr, /* Information about the text widget as a
+ * whole. */
+ TkTextTabArray *tabArrayPtr,/* Information about the tab stops that apply
+ * to this line. May be NULL to indicate
+ * default tabbing (every 8 chars). */
+ int index, /* Index of current tab stop. */
+ TkTextDispChunk *chunkPtr) /* Chunk whose last character is the tab; the
+ * following chunks contain information to be
+ * shifted right. */
{
int x, desired, delta, width, decimal, i, gotDigit;
TkTextDispChunk *chunkPtr2, *decimalChunkPtr;
CharInfo *ciPtr;
- int tabX, prev, spaceWidth;
- char *p;
+ int tabX, spaceWidth;
+ const char *p;
TkTextTabAlign alignment;
if (chunkPtr->nextPtr == NULL) {
/*
- * Nothing after the actual tab; just return.
+ * Nothing after the actual tab; just return.
*/
return;
}
+ x = chunkPtr->nextPtr->x;
+
/*
- * If no tab information has been given, do the usual thing:
- * round up to the next boundary of 8 average-sized characters.
+ * If no tab information has been given, assuming tab stops are at 8
+ * average-sized characters. Still ensure we respect the tabular versus
+ * wordprocessor tab style.
*/
- x = chunkPtr->nextPtr->x;
if ((tabArrayPtr == NULL) || (tabArrayPtr->numTabs == 0)) {
/*
* No tab information has been given, so use the default
* interpretation of tabs.
*/
- desired = NextTabStop(textPtr->tkfont, x, 0);
+ if (textPtr->tabStyle == TK_TEXT_TABSTYLE_TABULAR) {
+ int tabWidth = Tk_TextWidth(textPtr->tkfont, "0", 1) * 8;
+ if (tabWidth == 0) {
+ tabWidth = 1;
+ }
+
+ desired = tabWidth * (index + 1);
+ } else {
+ desired = NextTabStop(textPtr->tkfont, x, 0);
+ }
+
goto update;
}
@@ -4931,19 +7737,14 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr)
tabX = tabArrayPtr->tabs[index].location;
} else {
/*
- * Ran out of tab stops; compute a tab position by extrapolating
- * from the last two tab positions.
+ * Ran out of tab stops; compute a tab position by extrapolating from
+ * the last two tab positions.
*/
- if (tabArrayPtr->numTabs > 1) {
- prev = tabArrayPtr->tabs[tabArrayPtr->numTabs-2].location;
- } else {
- prev = 0;
- }
+ tabX = (int) (tabArrayPtr->lastTab +
+ (index + 1 - tabArrayPtr->numTabs)*tabArrayPtr->tabIncrement +
+ 0.5);
alignment = tabArrayPtr->tabs[tabArrayPtr->numTabs-1].alignment;
- tabX = tabArrayPtr->tabs[tabArrayPtr->numTabs-1].location
- + (index + 1 - tabArrayPtr->numTabs)
- * (tabArrayPtr->tabs[tabArrayPtr->numTabs-1].location - prev);
}
if (alignment == LEFT) {
@@ -4953,8 +7754,8 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr)
if ((alignment == CENTER) || (alignment == RIGHT)) {
/*
- * Compute the width of all the information in the tab group,
- * then use it to pick a desired location.
+ * Compute the width of all the information in the tab group, then use
+ * it to pick a desired location.
*/
width = 0;
@@ -4971,9 +7772,9 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr)
}
/*
- * Must be numeric alignment. Search through the text to be
- * tabbed, looking for the last , or . before the first character
- * that isn't a number, comma, period, or sign.
+ * Must be numeric alignment. Search through the text to be tabbed,
+ * looking for the last , or . before the first character that isn't a
+ * number, comma, period, or sign.
*/
decimalChunkPtr = NULL;
@@ -4999,20 +7800,21 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr)
}
}
}
- endOfNumber:
+
+ endOfNumber:
if (decimalChunkPtr != NULL) {
int curX;
ciPtr = (CharInfo *) decimalChunkPtr->clientData;
- MeasureChars(decimalChunkPtr->stylePtr->sValuePtr->tkfont,
- ciPtr->chars, decimal, decimalChunkPtr->x, -1, 0, &curX);
+ CharChunkMeasureChars(decimalChunkPtr, NULL, 0, 0, decimal,
+ decimalChunkPtr->x, -1, 0, &curX);
desired = tabX - (curX - x);
goto update;
} else {
/*
- * There wasn't a decimal point. Right justify the text.
+ * There wasn't a decimal point. Right justify the text.
*/
-
+
width = 0;
for (chunkPtr2 = chunkPtr->nextPtr; chunkPtr2 != NULL;
chunkPtr2 = chunkPtr2->nextPtr) {
@@ -5022,15 +7824,14 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr)
}
/*
- * Shift all of the chunks to the right so that the left edge is
- * at the desired location, then expand the chunk containing the
- * tab. Be sure that the tab occupies at least the width of a
- * space character.
+ * Shift all of the chunks to the right so that the left edge is at the
+ * desired location, then expand the chunk containing the tab. Be sure
+ * that the tab occupies at least the width of a space character.
*/
- update:
+ update:
delta = desired - x;
- MeasureChars(textPtr->tkfont, " ", 1, 0, -1, 0, &spaceWidth);
+ MeasureChars(textPtr->tkfont, " ", 1, 0, 1, 0, -1, 0, &spaceWidth);
if (delta < spaceWidth) {
delta = spaceWidth;
}
@@ -5046,15 +7847,18 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr)
*
* SizeOfTab --
*
- * This returns an estimate of the amount of white space that will
- * be consumed by a tab.
+ * This returns an estimate of the amount of white space that will be
+ * consumed by a tab.
*
* Results:
- * The return value is the minimum number of pixels that will
- * be occupied by the index'th tab of tabArrayPtr, assuming that
- * the current position on the line is x and the end of the
- * line is maxX. For numeric tabs, this is a conservative
- * estimate. The return value is always >= 0.
+ * The return value is the minimum number of pixels that will be occupied
+ * by the next tab of tabArrayPtr, assuming that the current position on
+ * the line is x and the end of the line is maxX. The 'next tab' is
+ * determined by a combination of the current position (x) which it must
+ * be equal to or beyond, and the tab count in indexPtr.
+ *
+ * For numeric tabs, this is a conservative estimate. The return value is
+ * always >= 0.
*
* Side effects:
* None.
@@ -5063,50 +7867,88 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr)
*/
static int
-SizeOfTab(textPtr, tabArrayPtr, index, x, maxX)
- TkText *textPtr; /* Information about the text widget as
- * a whole. */
- TkTextTabArray *tabArrayPtr; /* Information about the tab stops
- * that apply to this line. NULL
- * means use default tabbing (every
- * 8 chars.) */
- int index; /* Index of current tab stop. */
- int x; /* Current x-location in line. Only
- * used if tabArrayPtr == NULL. */
- int maxX; /* X-location of pixel just past the
- * right edge of the line. */
+SizeOfTab(
+ TkText *textPtr, /* Information about the text widget as a
+ * whole. */
+ int tabStyle, /* One of TK_TEXT_TABSTYLE_TABULAR
+ * or TK_TEXT_TABSTYLE_WORDPROCESSOR. */
+ TkTextTabArray *tabArrayPtr,/* Information about the tab stops that apply
+ * to this line. NULL means use default
+ * tabbing (every 8 chars.) */
+ int *indexPtr, /* Contains index of previous tab stop, will
+ * be updated to reflect the number of stops
+ * used. */
+ int x, /* Current x-location in line. */
+ int maxX) /* X-location of pixel just past the right
+ * edge of the line. */
{
- int tabX, prev, result, spaceWidth;
+ int tabX, result, index, spaceWidth, tabWidth;
TkTextTabAlign alignment;
+ index = *indexPtr;
+
if ((tabArrayPtr == NULL) || (tabArrayPtr->numTabs == 0)) {
- tabX = NextTabStop(textPtr->tkfont, x, 0);
- return tabX - x;
- }
- if (index < tabArrayPtr->numTabs) {
- tabX = tabArrayPtr->tabs[index].location;
- alignment = tabArrayPtr->tabs[index].alignment;
+ /*
+ * We're using a default tab spacing of 8 characters.
+ */
+
+ tabWidth = Tk_TextWidth(textPtr->tkfont, "0", 1) * 8;
+ if (tabWidth == 0) {
+ tabWidth = 1;
+ }
} else {
+ tabWidth = 0; /* Avoid compiler error. */
+ }
+
+ do {
/*
- * Ran out of tab stops; compute a tab position by extrapolating
- * from the last two tab positions.
+ * We were given the count before this tab, so increment it first.
*/
- if (tabArrayPtr->numTabs > 1) {
- prev = tabArrayPtr->tabs[tabArrayPtr->numTabs-2].location;
+ index++;
+
+ if ((tabArrayPtr == NULL) || (tabArrayPtr->numTabs == 0)) {
+ /*
+ * We're using a default tab spacing calculated above.
+ */
+
+ tabX = tabWidth * (index + 1);
+ alignment = LEFT;
+ } else if (index < tabArrayPtr->numTabs) {
+ tabX = tabArrayPtr->tabs[index].location;
+ alignment = tabArrayPtr->tabs[index].alignment;
} else {
- prev = 0;
+ /*
+ * Ran out of tab stops; compute a tab position by extrapolating.
+ */
+
+ tabX = (int) (tabArrayPtr->lastTab
+ + (index + 1 - tabArrayPtr->numTabs)
+ * tabArrayPtr->tabIncrement + 0.5);
+ alignment = tabArrayPtr->tabs[tabArrayPtr->numTabs-1].alignment;
}
- tabX = tabArrayPtr->tabs[tabArrayPtr->numTabs-1].location
- + (index + 1 - tabArrayPtr->numTabs)
- * (tabArrayPtr->tabs[tabArrayPtr->numTabs-1].location - prev);
- alignment = tabArrayPtr->tabs[tabArrayPtr->numTabs-1].alignment;
- }
+
+ /*
+ * If this tab stop is before the current x position, then we have two
+ * cases:
+ *
+ * With 'wordprocessor' style tabs, we must obviously continue until
+ * we reach the text tab stop.
+ *
+ * With 'tabular' style tabs, we always use the index'th tab stop.
+ */
+ } while (tabX <= x && (tabStyle == TK_TEXT_TABSTYLE_WORDPROCESSOR));
+
+ /*
+ * Inform our caller of how many tab stops we've used up.
+ */
+
+ *indexPtr = index;
+
if (alignment == CENTER) {
/*
- * Be very careful in the arithmetic below, because maxX may
- * be the largest positive number: watch out for integer
- * overflow.
+ * Be very careful in the arithmetic below, because maxX may be the
+ * largest positive number: watch out for integer overflow.
*/
if ((maxX-tabX) < (tabX - x)) {
@@ -5122,10 +7964,9 @@ SizeOfTab(textPtr, tabArrayPtr, index, x, maxX)
}
/*
- * Note: this treats NUMERIC alignment the same as LEFT
- * alignment, which is somewhat conservative. However, it's
- * pretty tricky at this point to figure out exactly where
- * the damn decimal point will be.
+ * Note: this treats NUMERIC alignment the same as LEFT alignment, which
+ * is somewhat conservative. However, it's pretty tricky at this point to
+ * figure out exactly where the damn decimal point will be.
*/
if (tabX > x) {
@@ -5134,8 +7975,8 @@ SizeOfTab(textPtr, tabArrayPtr, index, x, maxX)
result = 0;
}
- done:
- MeasureChars(textPtr->tkfont, " ", 1, 0, -1, 0, &spaceWidth);
+ done:
+ MeasureChars(textPtr->tkfont, " ", 1, 0, 1, 0, -1, 0, &spaceWidth);
if (result < spaceWidth) {
result = spaceWidth;
}
@@ -5147,10 +7988,10 @@ SizeOfTab(textPtr, tabArrayPtr, index, x, maxX)
*
* NextTabStop --
*
- * Given the current position, determine where the next default
- * tab stop would be located. This procedure is called when the
- * current chunk in the text has no tabs defined and so the default
- * tab spacing for the font should be used.
+ * Given the current position, determine where the next default tab stop
+ * would be located. This function is called when the current chunk in
+ * the text has no tabs defined and so the default tab spacing for the
+ * font should be used, provided we are using wordprocessor style tabs.
*
* Results:
* The location in pixels of the next tab stop.
@@ -5162,17 +8003,17 @@ SizeOfTab(textPtr, tabArrayPtr, index, x, maxX)
*/
static int
-NextTabStop(tkfont, x, tabOrigin)
- Tk_Font tkfont; /* Font in which chunk that contains tab
- * stop will be drawn. */
- int x; /* X-position in pixels where last
- * character was drawn. The next tab stop
- * occurs somewhere after this location. */
- int tabOrigin; /* The origin for tab stops. May be
- * non-zero if text has been scrolled. */
+NextTabStop(
+ Tk_Font tkfont, /* Font in which chunk that contains tab stop
+ * will be drawn. */
+ int x, /* X-position in pixels where last character
+ * was drawn. The next tab stop occurs
+ * somewhere after this location. */
+ int tabOrigin) /* The origin for tab stops. May be non-zero
+ * if text has been scrolled. */
{
int tabWidth, rem;
-
+
tabWidth = Tk_TextWidth(tkfont, "0", 1) * 8;
if (tabWidth == 0) {
tabWidth = 1;
@@ -5190,26 +8031,24 @@ NextTabStop(tkfont, x, tabOrigin)
/*
*---------------------------------------------------------------------------
*
- * MeasureChars --
+ * MeasureChars --
*
- * Determine the number of characters from the string that will fit
- * in the given horizontal span. The measurement is done under the
- * assumption that Tk_DrawTextLayout will be used to actually display
- * the characters.
+ * Determine the number of characters from the string that will fit in
+ * the given horizontal span. The measurement is done under the
+ * assumption that Tk_DrawChars will be used to actually display the
+ * characters.
*
- * If tabs are encountered in the string, they will be expanded
- * to the next tab stop, unless the TK_IGNORE_TABS flag is specified.
+ * If tabs are encountered in the string, they will be ignored (they
+ * should only occur as last character of the string anyway).
*
- * If a newline is encountered in the string, the line will be
- * broken at that point, unless the TK_NEWSLINES_NOT_SPECIAL flag
- * is specified.
+ * If a newline is encountered in the string, the line will be broken at
+ * that point.
*
* Results:
- * 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
- * be drawn.
+ * The return value is the number of bytes from the range of start to end
+ * in 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 be drawn.
*
* Side effects:
* None.
@@ -5218,29 +8057,31 @@ NextTabStop(tkfont, x, tabOrigin)
*/
static int
-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 maxBytes; /* Maximum # of bytes to consider from
+MeasureChars(
+ Tk_Font tkfont, /* Font in which to draw characters. */
+ CONST char *source, /* Characters to be displayed. Need not be
+ * NULL-terminated. */
+ int maxBytes, /* Maximum # of bytes to consider from
* source. */
- int startX; /* X-position at which first character will
- * be drawn. */
- int maxX; /* Don't consider any character that would
+ int rangeStart, int rangeLength,
+ /* Range of bytes to consider in source.*/
+ int startX, /* X-position at which first character will be
+ * drawn. */
+ int maxX, /* Don't consider any character that would
* cross this x-position. */
- int tabOrigin; /* X-location that serves as "origin" for
- * tab stops. */
- int *nextXPtr; /* Return x-position of terminating
- * character here. */
+ int flags, /* Flags to pass to Tk_MeasureChars. */
+ int *nextXPtr) /* Return x-position of terminating character
+ * here. */
{
int curX, width, ch;
CONST char *special, *end, *start;
ch = 0; /* lint. */
curX = startX;
- special = source;
- end = source + maxBytes;
- for (start = source; start < end; ) {
+ start = source + rangeStart;
+ end = start + rangeLength;
+ special = start;
+ while (start < end) {
if (start >= special) {
/*
* Find the next special character in the string.
@@ -5256,14 +8097,21 @@ MeasureChars(tkfont, source, maxBytes, startX, maxX, tabOrigin, nextXPtr)
/*
* Special points at the next special character (or the end of the
- * string). Process characters between start and special.
+ * string). Process characters between start and special.
*/
if ((maxX >= 0) && (curX >= maxX)) {
break;
}
- start += Tk_MeasureChars(tkfont, start, special - start, maxX - curX,
- 0, &width);
+#if TK_DRAW_IN_CONTEXT
+ start += TkpMeasureCharsInContext(tkfont, source, maxBytes,
+ start - source, special - start,
+ maxX >= 0 ? maxX - curX : -1, flags, &width);
+#else
+ (void) maxBytes;
+ start += Tk_MeasureChars(tkfont, start, special - start,
+ maxX >= 0 ? maxX - curX : -1, flags, &width);
+#endif /* TK_DRAW_IN_CONTEXT */
curX += width;
if (start < special) {
/*
@@ -5282,5 +8130,378 @@ MeasureChars(tkfont, source, maxBytes, startX, maxX, tabOrigin, nextXPtr)
}
*nextXPtr = curX;
- return start - source;
+ return start - (source+rangeStart);
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TextGetScrollInfoObj --
+ *
+ * This function is invoked to parse "xview" and "yview" scrolling
+ * commands for text widgets using the new scrolling command syntax
+ * ("moveto" or "scroll" options). It extends the public
+ * Tk_GetScrollInfoObj function with the addition of "pixels" as a valid
+ * unit alongside "pages" and "units". It is a shame the core API isn't
+ * more flexible in this regard.
+ *
+ * Results:
+ * The return value is either TKTEXT_SCROLL_MOVETO, TKTEXT_SCROLL_PAGES,
+ * TKTEXT_SCROLL_UNITS, TKTEXT_SCROLL_PIXELS or TKTEXT_SCROLL_ERROR. This
+ * indicates whether the command was successfully parsed and what form
+ * the command took. If TKTEXT_SCROLL_MOVETO, *dblPtr is filled in with
+ * the desired position; if TKTEXT_SCROLL_PAGES, TKTEXT_SCROLL_PIXELS or
+ * TKTEXT_SCROLL_UNITS, *intPtr is filled in with the number of
+ * pages/pixels/lines to move (may be negative); if TKTEXT_SCROLL_ERROR,
+ * the interp's result contains an error message.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TextGetScrollInfoObj(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ TkText *textPtr, /* Information about the text widget. */
+ 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 or
+ * pixels to scroll, if any. */
+{
+ static CONST char *subcommands[] = {
+ "moveto", "scroll", NULL
+ };
+ enum viewSubcmds {
+ VIEW_MOVETO, VIEW_SCROLL
+ };
+ static CONST char *units[] = {
+ "units", "pages", "pixels", NULL
+ };
+ enum viewUnits {
+ VIEW_SCROLL_UNITS, VIEW_SCROLL_PAGES, VIEW_SCROLL_PIXELS
+ };
+ int index;
+
+ if (Tcl_GetIndexFromObj(interp, objv[2], subcommands, "option", 0,
+ &index) != TCL_OK) {
+ return TKTEXT_SCROLL_ERROR;
+ }
+
+ switch ((enum viewSubcmds) index) {
+ case VIEW_MOVETO:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "fraction");
+ return TKTEXT_SCROLL_ERROR;
+ }
+ if (Tcl_GetDoubleFromObj(interp, objv[3], dblPtr) != TCL_OK) {
+ return TKTEXT_SCROLL_ERROR;
+ }
+ return TKTEXT_SCROLL_MOVETO;
+ case VIEW_SCROLL:
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "number units|pages|pixels");
+ return TKTEXT_SCROLL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[4], units, "argument", 0,
+ &index) != TCL_OK) {
+ return TKTEXT_SCROLL_ERROR;
+ }
+ switch ((enum viewUnits) index) {
+ case VIEW_SCROLL_PAGES:
+ if (Tcl_GetIntFromObj(interp, objv[3], intPtr) != TCL_OK) {
+ return TKTEXT_SCROLL_ERROR;
+ }
+ return TKTEXT_SCROLL_PAGES;
+ case VIEW_SCROLL_PIXELS:
+ if (Tk_GetPixelsFromObj(interp, textPtr->tkwin, objv[3],
+ intPtr) != TCL_OK) {
+ return TKTEXT_SCROLL_ERROR;
+ }
+ return TKTEXT_SCROLL_PIXELS;
+ case VIEW_SCROLL_UNITS:
+ if (Tcl_GetIntFromObj(interp, objv[3], intPtr) != TCL_OK) {
+ return TKTEXT_SCROLL_ERROR;
+ }
+ return TKTEXT_SCROLL_UNITS;
+ }
+ }
+ Tcl_Panic("unexpected switch fallthrough");
+ return TKTEXT_SCROLL_ERROR;
+}
+
+#if TK_LAYOUT_WITH_BASE_CHUNKS
+/*
+ *----------------------------------------------------------------------
+ *
+ * FinalizeBaseChunk --
+ *
+ * This procedure makes sure that all the chunks of the stretch are
+ * up-to-date. It is invoked when the LayoutProc has been called for all
+ * chunks and the base chunk is stable.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The CharInfo.chars of all dependent chunks point into
+ * BaseCharInfo.baseChars for easy access (and compatibility).
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FinalizeBaseChunk(
+ TkTextDispChunk *addChunkPtr)
+ /* An additional chunk to add to the stretch,
+ * even though it may not be in the linked
+ * list yet. Used by the LayoutProc, otherwise
+ * NULL. */
+{
+ const char *baseChars;
+ TkTextDispChunk *chunkPtr;
+ CharInfo *ciPtr;
+#if TK_DRAW_IN_CONTEXT
+ int widthAdjust = 0;
+ int newwidth;
+#endif /* TK_DRAW_IN_CONTEXT */
+
+ if (baseCharChunkPtr == NULL) {
+ return;
+ }
+
+ baseChars = Tcl_DStringValue(
+ &((BaseCharInfo *) baseCharChunkPtr->clientData)->baseChars);
+
+ for (chunkPtr = baseCharChunkPtr; chunkPtr != NULL;
+ chunkPtr = chunkPtr->nextPtr) {
+#if TK_DRAW_IN_CONTEXT
+ chunkPtr->x += widthAdjust;
+#endif /* TK_DRAW_IN_CONTEXT */
+
+ if (chunkPtr->displayProc != CharDisplayProc) {
+ continue;
+ }
+ ciPtr = (CharInfo *)chunkPtr->clientData;
+ if (ciPtr->baseChunkPtr != baseCharChunkPtr) {
+ break;
+ }
+ ciPtr->chars = baseChars + ciPtr->baseOffset;
+
+#if TK_DRAW_IN_CONTEXT
+ newwidth = 0;
+ CharChunkMeasureChars(chunkPtr, NULL, 0, 0, -1, 0, -1, 0, &newwidth);
+ if (newwidth != chunkPtr->width) {
+ widthAdjust += newwidth - chunkPtr->width;
+ chunkPtr->width = newwidth;
+ }
+#endif /* TK_DRAW_IN_CONTEXT */
+ }
+
+ if (addChunkPtr != NULL) {
+ ciPtr = (CharInfo *)addChunkPtr->clientData;
+ ciPtr->chars = baseChars + ciPtr->baseOffset;
+
+#if TK_DRAW_IN_CONTEXT
+ addChunkPtr->x += widthAdjust;
+ CharChunkMeasureChars(addChunkPtr, NULL, 0, 0, -1, 0, -1, 0,
+ &addChunkPtr->width);
+#endif /* TK_DRAW_IN_CONTEXT */
+ }
+
+ baseCharChunkPtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeBaseChunk --
+ *
+ * This procedure makes sure that all the chunks of the stretch are
+ * disconnected from the base chunk and the base chunk specific data is
+ * freed. It is invoked from the UndisplayProc. The procedure doesn't
+ * ckfree the base chunk clientData itself, that's up to the main
+ * UndisplayProc.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The CharInfo.chars of all dependent chunks are set to NULL. Memory
+ * that belongs specifically to the base chunk is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeBaseChunk(
+ TkTextDispChunk *baseChunkPtr)
+ /* The base chunk of the stretch and head of
+ * the linked list. */
+{
+ TkTextDispChunk *chunkPtr;
+ CharInfo *ciPtr;
+
+ if (baseCharChunkPtr == baseChunkPtr) {
+ baseCharChunkPtr = NULL;
+ }
+
+ for (chunkPtr=baseChunkPtr; chunkPtr!=NULL; chunkPtr=chunkPtr->nextPtr) {
+ if (chunkPtr->undisplayProc != CharUndisplayProc) {
+ continue;
+ }
+ ciPtr = (CharInfo *) chunkPtr->clientData;
+ if (ciPtr->baseChunkPtr != baseChunkPtr) {
+ break;
+ }
+
+ ciPtr->baseChunkPtr = NULL;
+ ciPtr->chars = NULL;
+ }
+
+ Tcl_DStringFree(&((BaseCharInfo *) baseChunkPtr->clientData)->baseChars);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * IsSameFGStyle --
+ *
+ * Compare the foreground attributes of two styles. Specifically must
+ * consider: foreground color, font, font style and font decorations,
+ * elide, "offset" and foreground stipple. Do *not* consider: background
+ * color, border, relief or background stipple.
+ *
+ * If we use TkpDrawCharsInContext(), we also don't need to check
+ * foreground color, font decorations, elide, offset and foreground
+ * stipple, so all that is left is font (including font size and font
+ * style) and "offset".
+ *
+ * Results:
+ * 1 if the two styles match, 0 otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+IsSameFGStyle(
+ TextStyle *style1,
+ TextStyle *style2)
+{
+ StyleValues *sv1;
+ StyleValues *sv2;
+
+ if (style1 == style2) {
+ return 1;
+ }
+
+#if !TK_DRAW_IN_CONTEXT
+ if (
+#ifdef MAC_OSX_TK
+ !TkMacOSXCompareColors(style1->fgGC->foreground,
+ style2->fgGC->foreground)
+#else
+ style1->fgGC->foreground != style2->fgGC->foreground
+#endif
+ ) {
+ return 0;
+ }
+#endif /* !TK_DRAW_IN_CONTEXT */
+
+ sv1 = style1->sValuePtr;
+ sv2 = style2->sValuePtr;
+
+#if TK_DRAW_IN_CONTEXT
+ return sv1->tkfont == sv2->tkfont && sv1->offset == sv2->offset;
+#else
+ return sv1->tkfont == sv2->tkfont
+ && sv1->underline == sv2->underline
+ && sv1->overstrike == sv2->overstrike
+ && sv1->elide == sv2->elide
+ && sv1->offset == sv2->offset
+ && sv1->fgStipple == sv1->fgStipple;
+#endif /* TK_DRAW_IN_CONTEXT */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RemoveFromBaseChunk --
+ *
+ * This procedure removes a chunk from the stretch as a result of
+ * UndisplayProc. The chunk in question should be the last in a stretch.
+ * This happens during re-layouting of the break position.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The characters that belong to this chunk are removed from the base
+ * chunk. It is assumed that LayoutProc and FinalizeBaseChunk are called
+ * next to repair any damage that this causes to the integrity of the
+ * stretch and the other chunks. For that reason the base chunk is also
+ * put into baseCharChunkPtr automatically, so that LayoutProc can resume
+ * correctly.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RemoveFromBaseChunk(
+ TkTextDispChunk *chunkPtr) /* The chunk to remove from the end of the
+ * stretch. */
+{
+ CharInfo *ciPtr;
+ BaseCharInfo *bciPtr;
+
+ if (chunkPtr->displayProc != CharDisplayProc) {
+#ifdef DEBUG_LAYOUT_WITH_BASE_CHUNKS
+ fprintf(stderr,"RemoveFromBaseChunk called with wrong chunk type\n");
+#endif
+ return;
+ }
+
+ /*
+ * Reinstitute this base chunk for re-layout.
+ */
+
+ ciPtr = (CharInfo *) chunkPtr->clientData;
+ baseCharChunkPtr = ciPtr->baseChunkPtr;
+
+ /*
+ * Remove the chunk data from the base chunk data.
+ */
+
+ bciPtr = (BaseCharInfo *) baseCharChunkPtr->clientData;
+
+ if ((ciPtr->baseOffset + ciPtr->numBytes)
+ != Tcl_DStringLength(&bciPtr->baseChars)) {
+#ifdef DEBUG_LAYOUT_WITH_BASE_CHUNKS
+ fprintf(stderr,"RemoveFromBaseChunk called with wrong chunk "
+ "(not last)\n");
+#endif
+ }
+
+ Tcl_DStringSetLength(&bciPtr->baseChars, ciPtr->baseOffset);
+
+ /*
+ * Invalidate the stored pixel width of the base chunk.
+ */
+
+ bciPtr->width = -1;
+}
+#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkTextImage.c b/generic/tkTextImage.c
index 57d444f..bc2b7c4 100644
--- a/generic/tkTextImage.c
+++ b/generic/tkTextImage.c
@@ -1,120 +1,111 @@
-/*
+/*
* tkImage.c --
*
- * This file contains code that allows images to be
- * nested inside text widgets. It also implements the "image"
- * widget command for texts.
+ * This file contains code that allows images to be nested inside text
+ * widgets. It also implements the "image" widget command for texts.
*
* 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tk.h"
-#include "tkText.h"
#include "tkPort.h"
-
-/*
- * Definitions for alignment values:
- */
-
-#define ALIGN_BOTTOM 0
-#define ALIGN_CENTER 1
-#define ALIGN_TOP 2
-#define ALIGN_BASELINE 3
+#include "tkText.h"
/*
* Macro that determines the size of an embedded image segment:
*/
-#define EI_SEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \
- + sizeof(TkTextEmbImage)))
+#define EI_SEG_SIZE \
+ ((unsigned) (Tk_Offset(TkTextSegment, body) + sizeof(TkTextEmbImage)))
/*
- * Prototypes for procedures defined in this file:
+ * Prototypes for functions defined in this file:
*/
-static int AlignParseProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, Tk_Window tkwin,
- CONST char *value, char *widgRec, int offset));
-static char * AlignPrintProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin, char *widgRec, int offset,
- Tcl_FreeProc **freeProcPtr));
-static TkTextSegment * EmbImageCleanupProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr));
-static void EmbImageCheckProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr));
-static void EmbImageBboxProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr,
- int index, int y, int lineHeight, int baseline,
- int *xPtr, int *yPtr, int *widthPtr,
- int *heightPtr));
-static int EmbImageConfigure _ANSI_ARGS_((TkText *textPtr,
- TkTextSegment *eiPtr, int argc, CONST char **argv));
-static int EmbImageDeleteProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr, int treeGone));
-static void EmbImageDisplayProc _ANSI_ARGS_((
+static TkTextSegment * EmbImageCleanupProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr);
+static void EmbImageCheckProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr);
+static void EmbImageBboxProc(TkText *textPtr,
+ TkTextDispChunk *chunkPtr, int index, int y,
+ int lineHeight, int baseline, int *xPtr, int *yPtr,
+ int *widthPtr, int *heightPtr);
+static int EmbImageConfigure(TkText *textPtr,
+ TkTextSegment *eiPtr, int objc,
+ Tcl_Obj *const objv[]);
+static int EmbImageDeleteProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr, int treeGone);
+static void EmbImageDisplayProc(TkText *textPtr,
TkTextDispChunk *chunkPtr, int x, int y,
int lineHeight, int baseline, Display *display,
- Drawable dst, int screenY));
-static int EmbImageLayoutProc _ANSI_ARGS_((TkText *textPtr,
+ Drawable dst, int screenY);
+static int EmbImageLayoutProc(TkText *textPtr,
TkTextIndex *indexPtr, TkTextSegment *segPtr,
int offset, int maxX, int maxChars,
int noCharsYet, TkWrapMode wrapMode,
- TkTextDispChunk *chunkPtr));
-static void EmbImageProc _ANSI_ARGS_((ClientData clientData,
- int x, int y, int width, int height,
- int imageWidth, int imageHeight));
+ TkTextDispChunk *chunkPtr);
+static void EmbImageProc(ClientData clientData, int x, int y,
+ int width, int height, int imageWidth,
+ int imageHeight);
/*
* The following structure declares the "embedded image" segment type.
*/
-static Tk_SegType tkTextEmbImageType = {
- "image", /* name */
- 0, /* leftGravity */
- (Tk_SegSplitProc *) NULL, /* splitProc */
- EmbImageDeleteProc, /* deleteProc */
- EmbImageCleanupProc, /* cleanupProc */
- (Tk_SegLineChangeProc *) NULL, /* lineChangeProc */
- EmbImageLayoutProc, /* layoutProc */
- EmbImageCheckProc /* checkProc */
+static const Tk_SegType tkTextEmbImageType = {
+ "image", /* name */
+ 0, /* leftGravity */
+ NULL, /* splitProc */
+ EmbImageDeleteProc, /* deleteProc */
+ EmbImageCleanupProc, /* cleanupProc */
+ NULL, /* lineChangeProc */
+ EmbImageLayoutProc, /* layoutProc */
+ EmbImageCheckProc /* checkProc */
};
/*
+ * Definitions for alignment values:
+ */
+
+static const char *alignStrings[] = {
+ "baseline", "bottom", "center", "top", NULL
+};
+
+typedef enum {
+ ALIGN_BASELINE, ALIGN_BOTTOM, ALIGN_CENTER, ALIGN_TOP
+} alignMode;
+
+/*
* Information used for parsing image configuration options:
*/
-static Tk_CustomOption alignOption = {AlignParseProc, AlignPrintProc,
- (ClientData) NULL};
-
-static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_CUSTOM, "-align", (char *) NULL, (char *) NULL,
- "center", 0, TK_CONFIG_DONT_SET_DEFAULT, &alignOption},
- {TK_CONFIG_PIXELS, "-padx", (char *) NULL, (char *) NULL,
- "0", Tk_Offset(TkTextEmbImage, padX),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_PIXELS, "-pady", (char *) NULL, (char *) NULL,
- "0", Tk_Offset(TkTextEmbImage, padY),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_STRING, "-image", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextEmbImage, imageString),
- TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-name", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextEmbImage, imageName),
- TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+static const Tk_OptionSpec optionSpecs[] = {
+ {TK_OPTION_STRING_TABLE, "-align", NULL, NULL,
+ "center", -1, Tk_Offset(TkTextEmbImage, align),
+ 0, (ClientData) alignStrings, 0},
+ {TK_OPTION_PIXELS, "-padx", NULL, NULL,
+ "0", -1, Tk_Offset(TkTextEmbImage, padX), 0, 0, 0},
+ {TK_OPTION_PIXELS, "-pady", NULL, NULL,
+ "0", -1, Tk_Offset(TkTextEmbImage, padY), 0, 0, 0},
+ {TK_OPTION_STRING, "-image", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextEmbImage, imageString),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-name", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextEmbImage, imageName),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_END}
};
+
/*
*--------------------------------------------------------------
*
* TkTextImageCmd --
*
- * This procedure implements the "image" widget command
- * for text widgets. See the user documentation for details
- * on what it does.
+ * This function implements the "image" widget command for text widgets.
+ * See the user documentation for details on what it does.
*
* Results:
* A standard Tcl result or error.
@@ -126,100 +117,121 @@ static Tk_ConfigSpec configSpecs[] = {
*/
int
-TkTextImageCmd(textPtr, interp, argc, argv)
- register TkText *textPtr; /* Information about text widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. Someone else has already
+TkTextImageCmd(
+ register TkText *textPtr, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. Someone else has already
* parsed this command enough to know that
- * argv[1] is "image". */
+ * objv[1] is "image". */
{
- size_t length;
+ int idx;
register TkTextSegment *eiPtr;
-
- if (argc < 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " image option ?arg arg ...?\"", (char *) NULL);
+ TkTextIndex index;
+ static const char *optionStrings[] = {
+ "cget", "configure", "create", "names", NULL
+ };
+ enum opts {
+ CMD_CGET, CMD_CONF, CMD_CREATE, CMD_NAMES
+ };
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], optionStrings, "option", 0,
+ &idx) != TCL_OK) {
return TCL_ERROR;
}
- length = strlen(argv[2]);
- if ((strncmp(argv[2], "cget", length) == 0) && (length >= 2)) {
- TkTextIndex index;
- TkTextSegment *eiPtr;
-
- if (argc != 5) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " image cget index option\"",
- (char *) NULL);
+ switch ((enum opts) idx) {
+ case CMD_CGET: {
+ Tcl_Obj *objPtr;
+
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index option");
return TCL_ERROR;
}
- if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {
+ if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
return TCL_ERROR;
}
- eiPtr = TkTextIndexToSeg(&index, (int *) NULL);
+ eiPtr = TkTextIndexToSeg(&index, NULL);
if (eiPtr->typePtr != &tkTextEmbImageType) {
Tcl_AppendResult(interp, "no embedded image at index \"",
- argv[3], "\"", (char *) NULL);
+ Tcl_GetString(objv[3]), "\"", NULL);
+ return TCL_ERROR;
+ }
+ objPtr = Tk_GetOptionValue(interp, (char *) &eiPtr->body.ei,
+ eiPtr->body.ei.optionTable, objv[4], textPtr->tkwin);
+ if (objPtr == NULL) {
return TCL_ERROR;
+ } else {
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
}
- return Tk_ConfigureValue(interp, textPtr->tkwin, configSpecs,
- (char *) &eiPtr->body.ei, argv[4], 0);
- } else if ((strncmp(argv[2], "configure", length) == 0) && (length >= 2)) {
- TkTextIndex index;
- TkTextSegment *eiPtr;
-
- if (argc < 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " image configure index ?option value ...?\"",
- (char *) NULL);
+ }
+ case CMD_CONF:
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?");
return TCL_ERROR;
}
- if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {
+ if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
return TCL_ERROR;
}
- eiPtr = TkTextIndexToSeg(&index, (int *) NULL);
+ eiPtr = TkTextIndexToSeg(&index, NULL);
if (eiPtr->typePtr != &tkTextEmbImageType) {
Tcl_AppendResult(interp, "no embedded image at index \"",
- argv[3], "\"", (char *) NULL);
+ Tcl_GetString(objv[3]), "\"", NULL);
return TCL_ERROR;
}
- if (argc == 4) {
- return Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs,
- (char *) &eiPtr->body.ei, (char *) NULL, 0);
- } else if (argc == 5) {
- return Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs,
- (char *) &eiPtr->body.ei, argv[4], 0);
+ if (objc <= 5) {
+ Tcl_Obj *objPtr = Tk_GetOptionInfo(interp,
+ (char *) &eiPtr->body.ei, eiPtr->body.ei.optionTable,
+ (objc == 5) ? objv[4] : NULL, textPtr->tkwin);
+ if (objPtr == NULL) {
+ return TCL_ERROR;
+ } else {
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
+ }
} else {
- TkTextChanged(textPtr, &index, &index);
- return EmbImageConfigure(textPtr, eiPtr, argc-4, argv+4);
+ TkTextChanged(textPtr->sharedTextPtr, NULL, &index, &index);
+
+ /*
+ * It's probably not true that all window configuration can change
+ * the line height, so we could be more efficient here and only
+ * call this when necessary.
+ */
+
+ TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL,
+ index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
+ return EmbImageConfigure(textPtr, eiPtr, objc-4, objv+4);
}
- } else if ((strncmp(argv[2], "create", length) == 0) && (length >= 2)) {
- TkTextIndex index;
+ case CMD_CREATE: {
int lineIndex;
/*
- * Add a new image. Find where to put the new image, and
- * mark that position for redisplay.
+ * Add a new image. Find where to put the new image, and mark that
+ * position for redisplay.
*/
- if (argc < 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " image create index ?option value ...?\"",
- (char *) NULL);
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?");
return TCL_ERROR;
}
- if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {
+ if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
return TCL_ERROR;
}
/*
* Don't allow insertions on the last (dummy) line of the text.
*/
-
- lineIndex = TkBTreeLineIndex(index.linePtr);
- if (lineIndex == TkBTreeNumLines(textPtr->tree)) {
+
+ lineIndex = TkBTreeLinesTo(textPtr, index.linePtr);
+ if (lineIndex == TkBTreeNumLines(textPtr->sharedTextPtr->tree,
+ textPtr)) {
lineIndex--;
- TkTextMakeByteIndex(textPtr->tree, lineIndex, 1000000, &index);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ lineIndex, 1000000, &index);
}
/*
@@ -229,7 +241,7 @@ TkTextImageCmd(textPtr, interp, argc, argv)
eiPtr = (TkTextSegment *) ckalloc(EI_SEG_SIZE);
eiPtr->typePtr = &tkTextEmbImageType;
eiPtr->size = 1;
- eiPtr->body.ei.textPtr = textPtr;
+ eiPtr->body.ei.sharedTextPtr = textPtr->sharedTextPtr;
eiPtr->body.ei.linePtr = NULL;
eiPtr->body.ei.imageName = NULL;
eiPtr->body.ei.imageString = NULL;
@@ -238,42 +250,45 @@ TkTextImageCmd(textPtr, interp, argc, argv)
eiPtr->body.ei.align = ALIGN_CENTER;
eiPtr->body.ei.padX = eiPtr->body.ei.padY = 0;
eiPtr->body.ei.chunkCount = 0;
+ eiPtr->body.ei.optionTable = Tk_CreateOptionTable(interp, optionSpecs);
/*
- * Link the segment into the text widget, then configure it (delete
- * it again if the configuration fails).
+ * Link the segment into the text widget, then configure it (delete it
+ * again if the configuration fails).
*/
- TkTextChanged(textPtr, &index, &index);
+ TkTextChanged(textPtr->sharedTextPtr, NULL, &index, &index);
TkBTreeLinkSegment(eiPtr, &index);
- if (EmbImageConfigure(textPtr, eiPtr, argc-4, argv+4) != TCL_OK) {
+ if (EmbImageConfigure(textPtr, eiPtr, objc-4, objv+4) != TCL_OK) {
TkTextIndex index2;
- TkTextIndexForwChars(&index, 1, &index2);
- TkBTreeDeleteChars(&index, &index2);
+ TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES);
+ TkBTreeDeleteIndexRange(textPtr->sharedTextPtr->tree, &index, &index2);
return TCL_ERROR;
}
- } else if (strncmp(argv[2], "names", length) == 0) {
+ TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL,
+ index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
+ return TCL_OK;
+ }
+ case CMD_NAMES: {
Tcl_HashSearch search;
Tcl_HashEntry *hPtr;
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " image names\"", (char *) NULL);
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
- for (hPtr = Tcl_FirstHashEntry(&textPtr->imageTable, &search);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+ for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->imageTable,
+ &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
Tcl_AppendElement(interp,
- Tcl_GetHashKey(&textPtr->markTable, hPtr));
+ Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr));
}
- } else {
- Tcl_AppendResult(interp, "bad image option \"", argv[2],
- "\": must be cget, configure, create, or names",
- (char *) NULL);
- return TCL_ERROR;
+ return TCL_OK;
}
- return TCL_OK;
+ default:
+ Tcl_Panic("unexpected switch fallthrough");
+ }
+ return TCL_ERROR;
}
/*
@@ -281,55 +296,54 @@ TkTextImageCmd(textPtr, interp, argc, argv)
*
* EmbImageConfigure --
*
- * This procedure is called to handle configuration options
- * for an embedded image, using an argc/argv list.
+ * This function is called to handle configuration options for an
+ * embedded image, using an objc/objv list.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message..
+ * 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 for the embedded image changes,
- * such as alignment, or name of the image.
+ * Configuration information for the embedded image changes, such as
+ * alignment, or name of the image.
*
*--------------------------------------------------------------
*/
static int
-EmbImageConfigure(textPtr, eiPtr, argc, argv)
- TkText *textPtr; /* Information about text widget that
- * contains embedded image. */
- TkTextSegment *eiPtr; /* Embedded image to be configured. */
- int argc; /* Number of strings in argv. */
- CONST char **argv; /* Array of strings describing configuration
+EmbImageConfigure(
+ TkText *textPtr, /* Information about text widget that contains
+ * embedded image. */
+ TkTextSegment *eiPtr, /* Embedded image to be configured. */
+ int objc, /* Number of strings in objv. */
+ Tcl_Obj *const objv[]) /* Array of strings describing configuration
* options. */
{
Tk_Image image;
Tcl_DString newName;
Tcl_HashEntry *hPtr;
Tcl_HashSearch search;
- int new;
char *name;
int count = 0; /* The counter for picking a unique name */
int conflict = 0; /* True if we have a name conflict */
- unsigned int len; /* length of image name */
+ size_t len; /* length of image name */
- if (Tk_ConfigureWidget(textPtr->interp, textPtr->tkwin, configSpecs,
- argc, argv, (char *) &eiPtr->body.ei,TK_CONFIG_ARGV_ONLY)
- != TCL_OK) {
+ if (Tk_SetOptions(textPtr->interp, (char*)&eiPtr->body.ei,
+ eiPtr->body.ei.optionTable,
+ objc, objv, textPtr->tkwin, NULL, NULL) != TCL_OK) {
return TCL_ERROR;
}
/*
- * Create the image. Save the old image around and don't free it
- * until after the new one is allocated. This keeps the reference
- * count from going to zero so the image doesn't have to be recreated
- * if it hasn't changed.
+ * Create the image. Save the old image around and don't free it until
+ * after the new one is allocated. This keeps the reference count from
+ * going to zero so the image doesn't have to be recreated if it hasn't
+ * changed.
*/
if (eiPtr->body.ei.imageString != NULL) {
- image = Tk_GetImage(textPtr->interp, textPtr->tkwin, eiPtr->body.ei.imageString,
- EmbImageProc, (ClientData) eiPtr);
+ image = Tk_GetImage(textPtr->interp, textPtr->tkwin,
+ eiPtr->body.ei.imageString, EmbImageProc, (ClientData) eiPtr);
if (image == NULL) {
return TCL_ERROR;
}
@@ -345,9 +359,9 @@ EmbImageConfigure(textPtr, eiPtr, argc, argv)
return TCL_OK;
}
- /*
- * Find a unique name for this image. Use imageName (or imageString)
- * if available, otherwise tack on a #nn and use it. If a name is already
+ /*
+ * Find a unique name for this image. Use imageName (or imageString) if
+ * available, otherwise tack on a #nn and use it. If a name is already
* associated with this image, delete the name.
*/
@@ -356,42 +370,50 @@ EmbImageConfigure(textPtr, eiPtr, argc, argv)
name = eiPtr->body.ei.imageString;
}
if (name == NULL) {
- Tcl_AppendResult(textPtr->interp,"Either a \"-name\" ",
+ Tcl_AppendResult(textPtr->interp, "Either a \"-name\" ",
"or a \"-image\" argument must be provided ",
- "to the \"image create\" subcommand.",
- (char *) NULL);
+ "to the \"image create\" subcommand.", NULL);
return TCL_ERROR;
}
len = strlen(name);
- for (hPtr = Tcl_FirstHashEntry(&textPtr->imageTable, &search);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- char *haveName = Tcl_GetHashKey(&textPtr->imageTable, hPtr);
+ for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->imageTable,
+ &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+ char *haveName =
+ Tcl_GetHashKey(&textPtr->sharedTextPtr->imageTable, hPtr);
+
if (strncmp(name, haveName, len) == 0) {
- new = 0;
- sscanf(haveName+len,"#%d",&new);
- if (new > count) {
- count = new;
+ int newVal = 0;
+
+ sscanf(haveName+len, "#%d", &newVal);
+ if (newVal > count) {
+ count = newVal;
}
- if (len == (int) strlen(haveName)) {
+ if (len == strlen(haveName)) {
conflict = 1;
}
}
}
Tcl_DStringInit(&newName);
- Tcl_DStringAppend(&newName,name, -1);
+ Tcl_DStringAppend(&newName, name, -1);
if (conflict) {
char buf[4 + TCL_INTEGER_SPACE];
- sprintf(buf, "#%d",count+1);
- Tcl_DStringAppend(&newName,buf, -1);
+
+ sprintf(buf, "#%d", count+1);
+ Tcl_DStringAppend(&newName, buf, -1);
}
name = Tcl_DStringValue(&newName);
- hPtr = Tcl_CreateHashEntry(&textPtr->imageTable, name, &new);
+ {
+ int dummy;
+
+ hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->imageTable, name,
+ &dummy);
+ }
Tcl_SetHashValue(hPtr, eiPtr);
- Tcl_AppendResult(textPtr->interp, name , (char *) NULL);
+ Tcl_AppendResult(textPtr->interp, name, NULL);
eiPtr->body.ei.name = ckalloc((unsigned) Tcl_DStringLength(&newName)+1);
- strcpy(eiPtr->body.ei.name,name);
+ strcpy(eiPtr->body.ei.name, name);
Tcl_DStringFree(&newName);
return TCL_OK;
@@ -400,103 +422,10 @@ EmbImageConfigure(textPtr, eiPtr, argc, argv)
/*
*--------------------------------------------------------------
*
- * AlignParseProc --
- *
- * This procedure is invoked by Tk_ConfigureWidget during
- * option processing to handle "-align" options for embedded
- * images.
- *
- * Results:
- * A standard Tcl return value.
- *
- * Side effects:
- * The alignment for the embedded image may change.
- *
- *--------------------------------------------------------------
- */
-
- /* ARGSUSED */
-static int
-AlignParseProc(clientData, interp, tkwin, value, widgRec, offset)
- ClientData clientData; /* Not used.*/
- Tcl_Interp *interp; /* Used for reporting errors. */
- Tk_Window tkwin; /* Window for text widget. */
- CONST char *value; /* Value of option. */
- char *widgRec; /* Pointer to TkTextEmbWindow
- * structure. */
- int offset; /* Offset into item (ignored). */
-{
- register TkTextEmbImage *embPtr = (TkTextEmbImage *) widgRec;
-
- if (strcmp(value, "baseline") == 0) {
- embPtr->align = ALIGN_BASELINE;
- } else if (strcmp(value, "bottom") == 0) {
- embPtr->align = ALIGN_BOTTOM;
- } else if (strcmp(value, "center") == 0) {
- embPtr->align = ALIGN_CENTER;
- } else if (strcmp(value, "top") == 0) {
- embPtr->align = ALIGN_TOP;
- } else {
- Tcl_AppendResult(interp, "bad alignment \"", value,
- "\": must be baseline, bottom, center, or top",
- (char *) NULL);
- return TCL_ERROR;
- }
- return TCL_OK;
-}
-
-/*
- *--------------------------------------------------------------
- *
- * AlignPrintProc --
- *
- * This procedure is invoked by the Tk configuration code
- * to produce a printable string for the "-align" configuration
- * option for embedded images.
- *
- * Results:
- * The return value is a string describing the embedded
- * images's current alignment.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
- /* ARGSUSED */
-static char *
-AlignPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
- ClientData clientData; /* Ignored. */
- Tk_Window tkwin; /* Window for text widget. */
- char *widgRec; /* Pointer to TkTextEmbImage
- * structure. */
- int offset; /* Ignored. */
- Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
- * information about how to reclaim
- * storage for return string. */
-{
- switch (((TkTextEmbImage *) widgRec)->align) {
- case ALIGN_BASELINE:
- return "baseline";
- case ALIGN_BOTTOM:
- return "bottom";
- case ALIGN_CENTER:
- return "center";
- case ALIGN_TOP:
- return "top";
- default:
- return "??";
- }
-}
-
-/*
- *--------------------------------------------------------------
- *
* EmbImageDeleteProc --
*
- * This procedure is invoked by the text B-tree code whenever
- * an embedded image lies in a range of characters being deleted.
+ * This function is invoked by the text B-tree code whenever an embedded
+ * image lies in a range of characters being deleted.
*
* Results:
* Returns 0 to indicate that the deletion has been accepted.
@@ -510,17 +439,17 @@ AlignPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
/* ARGSUSED */
static int
-EmbImageDeleteProc(eiPtr, linePtr, treeGone)
- TkTextSegment *eiPtr; /* Segment being deleted. */
- TkTextLine *linePtr; /* Line containing segment. */
- int treeGone; /* Non-zero means the entire tree is
- * being deleted, so everything must
- * get cleaned up. */
+EmbImageDeleteProc(
+ TkTextSegment *eiPtr, /* Segment being deleted. */
+ TkTextLine *linePtr, /* Line containing segment. */
+ int treeGone) /* Non-zero means the entire tree is being
+ * deleted, so everything must get cleaned
+ * up. */
{
Tcl_HashEntry *hPtr;
if (eiPtr->body.ei.image != NULL) {
- hPtr = Tcl_FindHashEntry(&eiPtr->body.ei.textPtr->imageTable,
+ hPtr = Tcl_FindHashEntry(&eiPtr->body.ei.sharedTextPtr->imageTable,
eiPtr->body.ei.name);
if (hPtr != NULL) {
/*
@@ -533,9 +462,15 @@ EmbImageDeleteProc(eiPtr, linePtr, treeGone)
}
Tk_FreeImage(eiPtr->body.ei.image);
}
- Tk_FreeOptions(configSpecs, (char *) &eiPtr->body.ei,
- eiPtr->body.ei.textPtr->display, 0);
- if (eiPtr->body.ei.name != NULL) {
+
+ /*
+ * No need to supply a tkwin argument, since we have no window-specific
+ * options.
+ */
+
+ Tk_FreeConfigOptions((char *) &eiPtr->body.ei, eiPtr->body.ei.optionTable,
+ NULL);
+ if (eiPtr->body.ei.name) {
ckfree(eiPtr->body.ei.name);
}
ckfree((char *) eiPtr);
@@ -547,9 +482,8 @@ EmbImageDeleteProc(eiPtr, linePtr, treeGone)
*
* EmbImageCleanupProc --
*
- * This procedure is invoked by the B-tree code whenever a
- * segment containing an embedded image is moved from one
- * line to another.
+ * This function is invoked by the B-tree code whenever a segment
+ * containing an embedded image is moved from one line to another.
*
* Results:
* None.
@@ -561,9 +495,9 @@ EmbImageDeleteProc(eiPtr, linePtr, treeGone)
*/
static TkTextSegment *
-EmbImageCleanupProc(eiPtr, linePtr)
- TkTextSegment *eiPtr; /* Mark segment that's being moved. */
- TkTextLine *linePtr; /* Line that now contains segment. */
+EmbImageCleanupProc(
+ TkTextSegment *eiPtr, /* Mark segment that's being moved. */
+ TkTextLine *linePtr) /* Line that now contains segment. */
{
eiPtr->body.ei.linePtr = linePtr;
return eiPtr;
@@ -574,12 +508,11 @@ EmbImageCleanupProc(eiPtr, linePtr)
*
* EmbImageLayoutProc --
*
- * This procedure is the "layoutProc" for embedded image
- * segments.
+ * This function is the "layoutProc" for embedded image segments.
*
* Results:
- * 1 is returned to indicate that the segment should be
- * displayed. The chunkPtr structure is filled in.
+ * 1 is returned to indicate that the segment should be displayed. The
+ * chunkPtr structure is filled in.
*
* Side effects:
* None, except for filling in chunkPtr.
@@ -589,30 +522,30 @@ EmbImageCleanupProc(eiPtr, linePtr)
/*ARGSUSED*/
static int
-EmbImageLayoutProc(textPtr, indexPtr, eiPtr, offset, maxX, maxChars,
- noCharsYet, wrapMode, chunkPtr)
- TkText *textPtr; /* Text widget being layed out. */
- TkTextIndex *indexPtr; /* Identifies first character in chunk. */
- TkTextSegment *eiPtr; /* Segment corresponding to indexPtr. */
- int offset; /* Offset within segPtr corresponding to
+EmbImageLayoutProc(
+ TkText *textPtr, /* Text widget being layed out. */
+ TkTextIndex *indexPtr, /* Identifies first character in chunk. */
+ TkTextSegment *eiPtr, /* Segment corresponding to indexPtr. */
+ int offset, /* Offset within segPtr corresponding to
* indexPtr (always 0). */
- int maxX; /* Chunk must not occupy pixels at this
+ int maxX, /* Chunk must not occupy pixels at this
* position or higher. */
- int maxChars; /* Chunk must not include more than this
- * many characters. */
- int noCharsYet; /* Non-zero means no characters have been
+ int maxChars, /* Chunk must not include more than this many
+ * characters. */
+ int noCharsYet, /* Non-zero means no characters have been
* assigned to this line yet. */
- TkWrapMode wrapMode; /* Wrap mode to use for line: TEXT_WRAPMODE_CHAR,
- * TEXT_WRAPMODE_NONE, or TEXT_WRAPMODE_WORD. */
- register TkTextDispChunk *chunkPtr;
- /* Structure to fill in with information
- * about this chunk. The x field has already
- * been set by the caller. */
+ TkWrapMode wrapMode, /* Wrap mode to use for line:
+ * TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, or
+ * TEXT_WRAPMODE_WORD. */
+ register TkTextDispChunk *chunkPtr)
+ /* Structure to fill in with information about
+ * this chunk. The x field has already been
+ * set by the caller. */
{
int width, height;
if (offset != 0) {
- panic("Non-zero offset in EmbImageLayoutProc");
+ Tcl_Panic("Non-zero offset in EmbImageLayoutProc");
}
/*
@@ -637,8 +570,8 @@ EmbImageLayoutProc(textPtr, indexPtr, eiPtr, offset, maxX, maxChars,
*/
chunkPtr->displayProc = EmbImageDisplayProc;
- chunkPtr->undisplayProc = (Tk_ChunkUndisplayProc *) NULL;
- chunkPtr->measureProc = (Tk_ChunkMeasureProc *) NULL;
+ chunkPtr->undisplayProc = NULL;
+ chunkPtr->measureProc = NULL;
chunkPtr->bboxProc = EmbImageBboxProc;
chunkPtr->numBytes = 1;
if (eiPtr->body.ei.align == ALIGN_BASELINE) {
@@ -663,29 +596,30 @@ EmbImageLayoutProc(textPtr, indexPtr, eiPtr, offset, maxX, maxChars,
*
* EmbImageCheckProc --
*
- * This procedure is invoked by the B-tree code to perform
- * consistency checks on embedded images.
+ * This function is invoked by the B-tree code to perform consistency
+ * checks on embedded images.
*
* Results:
* None.
*
* Side effects:
- * The procedure panics if it detects anything wrong with
- * the embedded image.
+ * The function panics if it detects anything wrong with the embedded
+ * image.
*
*--------------------------------------------------------------
*/
static void
-EmbImageCheckProc(eiPtr, linePtr)
- TkTextSegment *eiPtr; /* Segment to check. */
- TkTextLine *linePtr; /* Line containing segment. */
+EmbImageCheckProc(
+ TkTextSegment *eiPtr, /* Segment to check. */
+ TkTextLine *linePtr) /* Line containing segment. */
{
if (eiPtr->nextPtr == NULL) {
- panic("EmbImageCheckProc: embedded image is last segment in line");
+ Tcl_Panic("EmbImageCheckProc: embedded image is last segment in line");
}
if (eiPtr->size != 1) {
- panic("EmbImageCheckProc: embedded image has size %d", eiPtr->size);
+ Tcl_Panic("EmbImageCheckProc: embedded image has size %d",
+ eiPtr->size);
}
}
@@ -694,37 +628,35 @@ EmbImageCheckProc(eiPtr, linePtr)
*
* EmbImageDisplayProc --
*
- * This procedure is invoked by the text displaying code
- * when it is time to actually draw an embedded image
- * chunk on the screen.
+ * This function is invoked by the text displaying code when it is time
+ * to actually draw an embedded image chunk on the screen.
*
* Results:
* None.
*
* Side effects:
- * The embedded image gets moved to the correct location
- * and drawn onto the display.
+ * The embedded image gets moved to the correct location and drawn onto
+ * the display.
*
*--------------------------------------------------------------
*/
static void
-EmbImageDisplayProc(chunkPtr, x, y, lineHeight, baseline, display, dst, screenY)
- TkTextDispChunk *chunkPtr; /* Chunk that is to be drawn. */
- int x; /* X-position in dst at which to
- * draw this chunk (differs from
- * the x-position in the chunk because
- * of scrolling). */
- int y; /* Top of rectangular bounding box
- * for line: tells where to draw this
- * chunk in dst (x-position is in
- * the chunk itself). */
- int lineHeight; /* Total height of line. */
- int baseline; /* Offset of baseline from y. */
- Display *display; /* Display to use for drawing. */
- Drawable dst; /* Pixmap or window in which to draw */
- int screenY; /* Y-coordinate in text window that
- * corresponds to y. */
+EmbImageDisplayProc(
+ TkText *textPtr,
+ TkTextDispChunk *chunkPtr, /* Chunk that is to be drawn. */
+ int x, /* X-position in dst at which to draw this
+ * chunk (differs from the x-position in the
+ * chunk because of scrolling). */
+ int y, /* Top of rectangular bounding box for line:
+ * tells where to draw this chunk in dst
+ * (x-position is in the chunk itself). */
+ int lineHeight, /* Total height of line. */
+ int baseline, /* Offset of baseline from y. */
+ Display *display, /* Display to use for drawing. */
+ Drawable dst, /* Pixmap or window in which to draw */
+ int screenY) /* Y-coordinate in text window that
+ * corresponds to y. */
{
TkTextSegment *eiPtr = (TkTextSegment *) chunkPtr->clientData;
int lineX, imageX, imageY, width, height;
@@ -739,16 +671,15 @@ EmbImageDisplayProc(chunkPtr, x, y, lineHeight, baseline, display, dst, screenY)
}
/*
- * Compute the image's location and size in the text widget, taking
- * into account the align value for the image.
+ * Compute the image's location and size in the text widget, taking into
+ * account the align value for the image.
*/
- EmbImageBboxProc(chunkPtr, 0, y, lineHeight, baseline, &lineX,
+ EmbImageBboxProc(textPtr, chunkPtr, 0, y, lineHeight, baseline, &lineX,
&imageY, &width, &height);
imageX = lineX - chunkPtr->x + x;
- Tk_RedrawImage(image, 0, 0, width, height, dst,
- imageX, imageY);
+ Tk_RedrawImage(image, 0, 0, width, height, dst, imageX, imageY);
}
/*
@@ -756,17 +687,16 @@ EmbImageDisplayProc(chunkPtr, x, y, lineHeight, baseline, display, dst, screenY)
*
* EmbImageBboxProc --
*
- * This procedure is called to compute the bounding box of
- * the area occupied by an embedded image.
+ * This function is called to compute the bounding box of the area
+ * occupied by an embedded image.
*
* Results:
- * There is no return value. *xPtr and *yPtr are filled in
- * with the coordinates of the upper left corner of the
- * image, and *widthPtr and *heightPtr are filled in with
- * the dimensions of the image in pixels. Note: not all
- * of the returned bbox is necessarily visible on the screen
- * (the rightmost part might be off-screen to the right,
- * and the bottommost part might be off-screen to the bottom).
+ * There is no return value. *xPtr and *yPtr are filled in with the
+ * coordinates of the upper left corner of the image, and *widthPtr and
+ * *heightPtr are filled in with the dimensions of the image in pixels.
+ * Note: not all of the returned bbox is necessarily visible on the
+ * screen (the rightmost part might be off-screen to the right, and the
+ * bottommost part might be off-screen to the bottom).
*
* Side effects:
* None.
@@ -775,22 +705,22 @@ EmbImageDisplayProc(chunkPtr, x, y, lineHeight, baseline, display, dst, screenY)
*/
static void
-EmbImageBboxProc(chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr,
- widthPtr, heightPtr)
- TkTextDispChunk *chunkPtr; /* Chunk containing desired char. */
- int index; /* Index of desired character within
- * the chunk. */
- int y; /* Topmost pixel in area allocated
- * for this line. */
- int lineHeight; /* Total height of line. */
- int baseline; /* Location of line's baseline, in
- * pixels measured down from y. */
- int *xPtr, *yPtr; /* Gets filled in with coords of
- * character's upper-left pixel. */
- int *widthPtr; /* Gets filled in with width of
- * character, in pixels. */
- int *heightPtr; /* Gets filled in with height of
- * character, in pixels. */
+EmbImageBboxProc(
+ TkText *textPtr,
+ TkTextDispChunk *chunkPtr, /* Chunk containing desired char. */
+ int index, /* Index of desired character within the
+ * chunk. */
+ int y, /* Topmost pixel in area allocated for this
+ * line. */
+ int lineHeight, /* Total height of line. */
+ int baseline, /* Location of line's baseline, in pixels
+ * measured down from y. */
+ int *xPtr, int *yPtr, /* Gets filled in with coords of character's
+ * upper-left pixel. */
+ int *widthPtr, /* Gets filled in with width of image, in
+ * pixels. */
+ int *heightPtr) /* Gets filled in with height of image, in
+ * pixels. */
{
TkTextSegment *eiPtr = (TkTextSegment *) chunkPtr->clientData;
Tk_Image image;
@@ -802,20 +732,22 @@ EmbImageBboxProc(chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr,
*widthPtr = 0;
*heightPtr = 0;
}
+
*xPtr = chunkPtr->x + eiPtr->body.ei.padX;
+
switch (eiPtr->body.ei.align) {
- case ALIGN_BOTTOM:
- *yPtr = y + (lineHeight - *heightPtr - eiPtr->body.ei.padY);
- break;
- case ALIGN_CENTER:
- *yPtr = y + (lineHeight - *heightPtr)/2;
- break;
- case ALIGN_TOP:
- *yPtr = y + eiPtr->body.ei.padY;
- break;
- case ALIGN_BASELINE:
- *yPtr = y + (baseline - *heightPtr);
- break;
+ case ALIGN_BOTTOM:
+ *yPtr = y + (lineHeight - *heightPtr - eiPtr->body.ei.padY);
+ break;
+ case ALIGN_CENTER:
+ *yPtr = y + (lineHeight - *heightPtr)/2;
+ break;
+ case ALIGN_TOP:
+ *yPtr = y + eiPtr->body.ei.padY;
+ break;
+ case ALIGN_BASELINE:
+ *yPtr = y + (baseline - *heightPtr);
+ break;
}
}
@@ -824,14 +756,13 @@ EmbImageBboxProc(chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr,
*
* TkTextImageIndex --
*
- * Given the name of an embedded image within a text widget,
- * returns an index corresponding to the image's position
- * in the text.
+ * Given the name of an embedded image within a text widget, returns an
+ * index corresponding to the image's position in the text.
*
* Results:
- * The return value is 1 if there is an embedded image by
- * the given name in the text widget, 0 otherwise. If the
- * image exists, *indexPtr is filled in with its index.
+ * The return value is 1 if there is an embedded image by the given name
+ * in the text widget, 0 otherwise. If the image exists, *indexPtr is
+ * filled in with its index.
*
* Side effects:
* None.
@@ -840,20 +771,24 @@ EmbImageBboxProc(chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr,
*/
int
-TkTextImageIndex(textPtr, name, indexPtr)
- TkText *textPtr; /* Text widget containing image. */
- CONST char *name; /* Name of image. */
- TkTextIndex *indexPtr; /* Index information gets stored here. */
+TkTextImageIndex(
+ TkText *textPtr, /* Text widget containing image. */
+ const char *name, /* Name of image. */
+ TkTextIndex *indexPtr) /* Index information gets stored here. */
{
Tcl_HashEntry *hPtr;
TkTextSegment *eiPtr;
- hPtr = Tcl_FindHashEntry(&textPtr->imageTable, name);
+ if (textPtr == NULL) {
+ return 0;
+ }
+
+ hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->imageTable, name);
if (hPtr == NULL) {
return 0;
}
eiPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
- indexPtr->tree = textPtr->tree;
+ indexPtr->tree = textPtr->sharedTextPtr->tree;
indexPtr->linePtr = eiPtr->body.ei.linePtr;
indexPtr->byteIndex = TkTextSegToOffset(eiPtr, indexPtr->linePtr);
return 1;
@@ -864,8 +799,8 @@ TkTextImageIndex(textPtr, name, indexPtr)
*
* EmbImageProc --
*
- * This procedure is called by the image code whenever an
- * image or its contents changes.
+ * This function is called by the image code whenever an image or its
+ * contents changes.
*
* Results:
* None.
@@ -877,20 +812,37 @@ TkTextImageIndex(textPtr, name, indexPtr)
*/
static void
-EmbImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
- ClientData clientData; /* Pointer to widget record. */
- int x, y; /* Upper left pixel (within image)
- * that must be redisplayed. */
- int width, height; /* Dimensions of area to redisplay
- * (may be <= 0). */
- int imgWidth, imgHeight; /* New dimensions of image. */
+EmbImageProc(
+ ClientData clientData, /* Pointer to widget record. */
+ int x, int y, /* Upper left pixel (within image) that must
+ * be redisplayed. */
+ int width, int height, /* Dimensions of area to redisplay (may be
+ * <= 0). */
+ int imgWidth, int imgHeight)/* New dimensions of image. */
{
TkTextSegment *eiPtr = (TkTextSegment *) clientData;
TkTextIndex index;
- index.tree = eiPtr->body.ei.textPtr->tree;
+ index.tree = eiPtr->body.ei.sharedTextPtr->tree;
index.linePtr = eiPtr->body.ei.linePtr;
index.byteIndex = TkTextSegToOffset(eiPtr, eiPtr->body.ei.linePtr);
- TkTextChanged(eiPtr->body.ei.textPtr, &index, &index);
+ TkTextChanged(eiPtr->body.ei.sharedTextPtr, NULL, &index, &index);
+
+ /*
+ * It's probably not true that all image changes can change the line
+ * height, so we could be more efficient here and only call this when
+ * necessary.
+ */
+
+ TkTextInvalidateLineMetrics(eiPtr->body.ei.sharedTextPtr, NULL,
+ index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c
index 714a47d..70c94db 100644
--- a/generic/tkTextIndex.c
+++ b/generic/tkTextIndex.c
@@ -1,18 +1,17 @@
-/*
+/*
* tkTextIndex.c --
*
- * This module provides procedures that manipulate indices for
- * text widgets.
+ * This module provides functions that manipulate indices for text
+ * widgets.
*
* Copyright (c) 1992-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "default.h"
-#include "tkPort.h"
#include "tkInt.h"
#include "tkText.h"
@@ -23,21 +22,354 @@
#define LAST_CHAR 1000000
/*
- * Forward declarations for procedures defined later in this file:
+ * Modifiers for index parsing: 'display', 'any' or nothing.
+ */
+
+#define TKINDEX_NONE 0
+#define TKINDEX_DISPLAY 1
+#define TKINDEX_ANY 2
+
+/*
+ * Forward declarations for functions defined later in this file:
+ */
+
+static CONST char * ForwBack(TkText *textPtr, CONST char *string,
+ TkTextIndex *indexPtr);
+static CONST char * StartEnd(TkText *textPtr, CONST char *string,
+ TkTextIndex *indexPtr);
+static int GetIndex(Tcl_Interp *interp, TkSharedText *sharedPtr,
+ TkText *textPtr, CONST char *string,
+ TkTextIndex *indexPtr, int *canCachePtr);
+
+/*
+ * The "textindex" Tcl_Obj definition:
+ */
+
+static void DupTextIndexInternalRep(Tcl_Obj *srcPtr,
+ Tcl_Obj *copyPtr);
+static void FreeTextIndexInternalRep(Tcl_Obj *listPtr);
+static int SetTextIndexFromAny(Tcl_Interp *interp,
+ Tcl_Obj *objPtr);
+static void UpdateStringOfTextIndex(Tcl_Obj *objPtr);
+
+/*
+ * Accessor macros for the "textindex" type.
+ */
+
+#define GET_TEXTINDEX(objPtr) \
+ ((TkTextIndex *) (objPtr)->internalRep.twoPtrValue.ptr1)
+#define GET_INDEXEPOCH(objPtr) \
+ (PTR2INT((objPtr)->internalRep.twoPtrValue.ptr2))
+#define SET_TEXTINDEX(objPtr, indexPtr) \
+ ((objPtr)->internalRep.twoPtrValue.ptr1 = (VOID *) (indexPtr))
+#define SET_INDEXEPOCH(objPtr, epoch) \
+ ((objPtr)->internalRep.twoPtrValue.ptr2 = INT2PTR(epoch))
+
+/*
+ * Define the 'textindex' object type, which Tk uses to represent indices in
+ * text widgets internally.
+ */
+
+Tcl_ObjType tkTextIndexType = {
+ "textindex", /* name */
+ FreeTextIndexInternalRep, /* freeIntRepProc */
+ DupTextIndexInternalRep, /* dupIntRepProc */
+ NULL, /* updateStringProc */
+ SetTextIndexFromAny /* setFromAnyProc */
+};
+
+static void
+FreeTextIndexInternalRep(
+ Tcl_Obj *indexObjPtr) /* TextIndex object with internal rep to
+ * free. */
+{
+ TkTextIndex *indexPtr = GET_TEXTINDEX(indexObjPtr);
+ if (indexPtr->textPtr != NULL) {
+ if (--indexPtr->textPtr->refCount == 0) {
+ /*
+ * The text widget has been deleted and we need to free it now.
+ */
+
+ ckfree((char *) (indexPtr->textPtr));
+ }
+ }
+ ckfree((char *) indexPtr);
+}
+
+static void
+DupTextIndexInternalRep(
+ Tcl_Obj *srcPtr, /* TextIndex obj with internal rep to copy. */
+ Tcl_Obj *copyPtr) /* TextIndex obj with internal rep to set. */
+{
+ int epoch;
+ TkTextIndex *dupIndexPtr, *indexPtr;
+
+ dupIndexPtr = (TkTextIndex *) ckalloc(sizeof(TkTextIndex));
+ indexPtr = GET_TEXTINDEX(srcPtr);
+ epoch = GET_INDEXEPOCH(srcPtr);
+
+ dupIndexPtr->tree = indexPtr->tree;
+ dupIndexPtr->linePtr = indexPtr->linePtr;
+ dupIndexPtr->byteIndex = indexPtr->byteIndex;
+ dupIndexPtr->textPtr = indexPtr->textPtr;
+ if (dupIndexPtr->textPtr != NULL) {
+ dupIndexPtr->textPtr->refCount++;
+ }
+ SET_TEXTINDEX(copyPtr, dupIndexPtr);
+ SET_INDEXEPOCH(copyPtr, epoch);
+ copyPtr->typePtr = &tkTextIndexType;
+}
+
+/*
+ * This will not be called except by TkTextNewIndexObj below. This is because
+ * if a TkTextIndex is no longer valid, it is not possible to regenerate the
+ * string representation.
*/
-static CONST char * ForwBack _ANSI_ARGS_((CONST char *string,
- TkTextIndex *indexPtr));
-static CONST char * StartEnd _ANSI_ARGS_((CONST char *string,
- TkTextIndex *indexPtr));
+static void
+UpdateStringOfTextIndex(
+ Tcl_Obj *objPtr)
+{
+ char buffer[TK_POS_CHARS];
+ register int len;
+
+ CONST TkTextIndex *indexPtr = GET_TEXTINDEX(objPtr);
+
+ len = TkTextPrintIndex(indexPtr->textPtr, indexPtr, buffer);
+
+ objPtr->bytes = ckalloc((unsigned) len + 1);
+ strcpy(objPtr->bytes, buffer);
+ objPtr->length = len;
+}
+
+static int
+SetTextIndexFromAny(
+ Tcl_Interp *interp, /* Used for error reporting if not NULL. */
+ Tcl_Obj *objPtr) /* The object to convert. */
+{
+ Tcl_AppendToObj(Tcl_GetObjResult(interp),
+ "can't convert value to textindex except via TkTextGetIndexFromObj API",
+ -1);
+ return TCL_ERROR;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MakeObjIndex --
+ *
+ * This function generates a Tcl_Obj description of an index, suitable
+ * for reading in again later. If the 'textPtr' is NULL then we still
+ * generate an index object, but it's internal description is deemed
+ * non-cacheable, and therefore effectively useless (apart from as a
+ * temporary memory storage). This is used for indices whose meaning is
+ * very temporary (like @0,0 or the name of a mark or tag). The mapping
+ * from such strings/objects to actual TkTextIndex pointers is not stable
+ * to minor text widget changes which we do not track (we track
+ * insertions and deletions).
+ *
+ * Results:
+ * A pointer to an allocated TkTextIndex which will be freed
+ * automatically when the Tcl_Obj is used for other purposes.
+ *
+ * Side effects:
+ * A small amount of memory is allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static TkTextIndex *
+MakeObjIndex(
+ TkText *textPtr, /* Information about text widget. */
+ Tcl_Obj *objPtr, /* Object containing description of
+ * position. */
+ CONST TkTextIndex *origPtr) /* Pointer to index. */
+{
+ TkTextIndex *indexPtr = (TkTextIndex *) ckalloc(sizeof(TkTextIndex));
+
+ indexPtr->tree = origPtr->tree;
+ indexPtr->linePtr = origPtr->linePtr;
+ indexPtr->byteIndex = origPtr->byteIndex;
+ SET_TEXTINDEX(objPtr, indexPtr);
+ objPtr->typePtr = &tkTextIndexType;
+ indexPtr->textPtr = textPtr;
+
+ if (textPtr != NULL) {
+ textPtr->refCount++;
+ SET_INDEXEPOCH(objPtr, textPtr->sharedTextPtr->stateEpoch);
+ } else {
+ SET_INDEXEPOCH(objPtr, 0);
+ }
+ return indexPtr;
+}
+
+CONST TkTextIndex *
+TkTextGetIndexFromObj(
+ Tcl_Interp *interp, /* Use this for error reporting. */
+ TkText *textPtr, /* Information about text widget. */
+ Tcl_Obj *objPtr) /* Object containing description of
+ * position. */
+{
+ TkTextIndex index;
+ TkTextIndex *indexPtr = NULL;
+ int cache;
+
+ if (objPtr->typePtr == &tkTextIndexType) {
+ int epoch;
+
+ indexPtr = GET_TEXTINDEX(objPtr);
+ epoch = GET_INDEXEPOCH(objPtr);
+
+ if (epoch == textPtr->sharedTextPtr->stateEpoch) {
+ if (indexPtr->textPtr == textPtr) {
+ return indexPtr;
+ }
+ }
+ }
+
+ /*
+ * The object is either not an index type or referred to a different text
+ * widget, or referred to the correct widget, but it is out of date (text
+ * has been added/deleted since).
+ */
+
+ if (GetIndex(interp, NULL, textPtr, Tcl_GetString(objPtr), &index,
+ &cache) != TCL_OK) {
+ return NULL;
+ }
+
+ if (objPtr->typePtr != NULL) {
+ if (objPtr->bytes == NULL) {
+ objPtr->typePtr->updateStringProc(objPtr);
+ }
+ if ((objPtr->typePtr->freeIntRepProc) != NULL) {
+ (*objPtr->typePtr->freeIntRepProc)(objPtr);
+ }
+ }
+
+ return MakeObjIndex((cache ? textPtr : NULL), objPtr, &index);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TkTextNewIndexObj --
+ *
+ * This function generates a Tcl_Obj description of an index, suitable
+ * for reading in again later. The index generated is effectively stable
+ * to all except insertion/deletion operations on the widget.
+ *
+ * Results:
+ * A new Tcl_Obj with refCount zero.
+ *
+ * Side effects:
+ * A small amount of memory is allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TkTextNewIndexObj(
+ TkText *textPtr, /* Text widget for this index */
+ CONST TkTextIndex *indexPtr)/* Pointer to index. */
+{
+ Tcl_Obj *retVal;
+
+ retVal = Tcl_NewObj();
+ retVal->bytes = NULL;
+
+ /*
+ * Assumption that the above call returns an object with:
+ * retVal->typePtr == NULL
+ */
+
+ MakeObjIndex(textPtr, retVal, indexPtr);
+
+ /*
+ * Unfortunately, it isn't possible for us to regenerate the string
+ * representation so we have to create it here, while we can be sure the
+ * contents of the index are still valid.
+ */
+
+ UpdateStringOfTextIndex(retVal);
+ return retVal;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TkTextMakePixelIndex --
+ *
+ * Given a pixel index and a byte index, look things up in the B-tree and
+ * fill in a TkTextIndex structure.
+ *
+ * The valid input range for pixelIndex is from 0 to the number of pixels
+ * in the widget-1. Anything outside that range will be rounded to the
+ * closest acceptable value.
+ *
+ * Results:
+ *
+ * The structure at *indexPtr is filled in with information about the
+ * character at pixelIndex (or the closest existing character, if the
+ * specified one doesn't exist), and the number of excess pixels is
+ * returned as a result. This means if the given pixel index is exactly
+ * correct for the top-edge of the indexPtr, then zero will be returned,
+ * and otherwise we will return the calculation 'desired pixelIndex' -
+ * 'actual pixel index of indexPtr'.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TkTextMakePixelIndex(
+ TkText *textPtr, /* The Text Widget */
+ int pixelIndex, /* Pixel-index of desired line (0 means first
+ * pixel of first line of text). */
+ TkTextIndex *indexPtr) /* Structure to fill in. */
+{
+ int pixelOffset = 0;
+
+ indexPtr->tree = textPtr->sharedTextPtr->tree;
+ indexPtr->textPtr = textPtr;
+
+ if (pixelIndex < 0) {
+ pixelIndex = 0;
+ }
+ indexPtr->linePtr = TkBTreeFindPixelLine(textPtr->sharedTextPtr->tree,
+ textPtr, pixelIndex, &pixelOffset);
+
+ /*
+ * 'pixelIndex' was too large, so we try again, just to find the last
+ * pixel in the window.
+ */
+
+ if (indexPtr->linePtr == NULL) {
+ int lastMinusOne = TkBTreeNumPixels(textPtr->sharedTextPtr->tree,
+ textPtr)-1;
+
+ indexPtr->linePtr = TkBTreeFindPixelLine(textPtr->sharedTextPtr->tree,
+ textPtr, lastMinusOne, &pixelOffset);
+ indexPtr->byteIndex = 0;
+ return pixelOffset;
+ }
+ indexPtr->byteIndex = 0;
+
+ if (pixelOffset <= 0) {
+ return 0;
+ }
+ return TkTextMeasureDown(textPtr, indexPtr, pixelOffset);
+}
/*
*---------------------------------------------------------------------------
*
* TkTextMakeByteIndex --
*
- * Given a line index and a byte 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
@@ -52,13 +384,14 @@ static CONST char * StartEnd _ANSI_ARGS_((CONST char *string,
*/
TkTextIndex *
-TkTextMakeByteIndex(tree, lineIndex, byteIndex, indexPtr)
- TkTextBTree tree; /* Tree that lineIndex and charIndex refer
+TkTextMakeByteIndex(
+ TkTextBTree tree, /* Tree that lineIndex and byteIndex 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. */
+ CONST TkText *textPtr,
+ 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;
@@ -73,9 +406,10 @@ TkTextMakeByteIndex(tree, lineIndex, byteIndex, indexPtr)
if (byteIndex < 0) {
byteIndex = 0;
}
- indexPtr->linePtr = TkBTreeFindLine(tree, lineIndex);
+ indexPtr->linePtr = TkBTreeFindLine(tree, textPtr, lineIndex);
if (indexPtr->linePtr == NULL) {
- indexPtr->linePtr = TkBTreeFindLine(tree, TkBTreeNumLines(tree));
+ indexPtr->linePtr = TkBTreeFindLine(tree, textPtr,
+ TkBTreeNumLines(tree, textPtr));
byteIndex = 0;
}
if (byteIndex == 0) {
@@ -84,19 +418,19 @@ TkTextMakeByteIndex(tree, lineIndex, byteIndex, indexPtr)
}
/*
- * Verify that the index is within the range of the line and points
- * to a valid character boundary.
+ * 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.
+ * 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;
}
@@ -105,7 +439,7 @@ TkTextMakeByteIndex(tree, lineIndex, byteIndex, indexPtr)
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
+ * 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.
*/
@@ -127,8 +461,8 @@ TkTextMakeByteIndex(tree, lineIndex, byteIndex, indexPtr)
*
* TkTextMakeCharIndex --
*
- * 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 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
@@ -143,13 +477,14 @@ TkTextMakeByteIndex(tree, lineIndex, byteIndex, indexPtr)
*/
TkTextIndex *
-TkTextMakeCharIndex(tree, lineIndex, charIndex, indexPtr)
- TkTextBTree tree; /* Tree that lineIndex and charIndex refer
+TkTextMakeCharIndex(
+ TkTextBTree tree, /* Tree that lineIndex and charIndex refer
* to. */
- int lineIndex; /* Index of desired line (0 means first
- * line of text). */
- int charIndex; /* Index of desired character. */
- TkTextIndex *indexPtr; /* Structure to fill in. */
+ TkText *textPtr,
+ int lineIndex, /* Index of desired line (0 means first line
+ * of text). */
+ int charIndex, /* Index of desired character. */
+ TkTextIndex *indexPtr) /* Structure to fill in. */
{
register TkTextSegment *segPtr;
char *p, *start, *end;
@@ -164,26 +499,27 @@ TkTextMakeCharIndex(tree, lineIndex, charIndex, indexPtr)
if (charIndex < 0) {
charIndex = 0;
}
- indexPtr->linePtr = TkBTreeFindLine(tree, lineIndex);
+ indexPtr->linePtr = TkBTreeFindLine(tree, textPtr, lineIndex);
if (indexPtr->linePtr == NULL) {
- indexPtr->linePtr = TkBTreeFindLine(tree, TkBTreeNumLines(tree));
+ indexPtr->linePtr = TkBTreeFindLine(tree, textPtr,
+ TkBTreeNumLines(tree, textPtr));
charIndex = 0;
}
/*
- * Verify that the index is within the range of the line.
- * If not, just use the index of the last character in the line.
+ * Verify that the index is within the range of the line. If not, just use
+ * the index of the last character in the line.
*/
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.
+ * 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;
}
@@ -220,14 +556,14 @@ TkTextMakeCharIndex(tree, lineIndex, charIndex, indexPtr)
*
* TkTextIndexToSeg --
*
- * Given an index, this procedure returns the segment and offset
- * within segment for the index.
+ * Given an index, this function 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.
@@ -236,9 +572,9 @@ TkTextMakeCharIndex(tree, lineIndex, charIndex, indexPtr)
*/
TkTextSegment *
-TkTextIndexToSeg(indexPtr, offsetPtr)
- CONST TkTextIndex *indexPtr;/* Text index. */
- int *offsetPtr; /* Where to store offset within segment, or
+TkTextIndexToSeg(
+ CONST TkTextIndex *indexPtr,/* Text index. */
+ int *offsetPtr) /* Where to store offset within segment, or
* NULL if offset isn't wanted. */
{
TkTextSegment *segPtr;
@@ -260,7 +596,7 @@ TkTextIndexToSeg(indexPtr, offsetPtr)
*
* TkTextSegToOffset --
*
- * Given a segment pointer and the line containing it, this procedure
+ * Given a segment pointer and the line containing it, this function
* returns the offset of the segment within its line.
*
* Results:
@@ -274,14 +610,13 @@ TkTextIndexToSeg(indexPtr, offsetPtr)
*/
int
-TkTextSegToOffset(segPtr, linePtr)
- CONST TkTextSegment *segPtr;/* Segment whose offset is desired. */
- CONST TkTextLine *linePtr; /* Line containing segPtr. */
+TkTextSegToOffset(
+ CONST TkTextSegment *segPtr,/* Segment whose offset is desired. */
+ CONST TkTextLine *linePtr) /* Line containing segPtr. */
{
CONST TkTextSegment *segPtr2;
- int offset;
+ int offset = 0;
- offset = 0;
for (segPtr2 = linePtr->segPtr; segPtr2 != segPtr;
segPtr2 = segPtr2->nextPtr) {
offset += segPtr2->size;
@@ -292,15 +627,73 @@ TkTextSegToOffset(segPtr, linePtr)
/*
*---------------------------------------------------------------------------
*
+ * TkTextGetObjIndex --
+ *
+ * Simpler wrapper around the string based function, but could be
+ * enhanced with a new object type in the future.
+ *
+ * Results:
+ * see TkTextGetIndex
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TkTextGetObjIndex(
+ Tcl_Interp *interp, /* Use this for error reporting. */
+ TkText *textPtr, /* Information about text widget. */
+ Tcl_Obj *idxObj, /* Object containing textual description of
+ * position. */
+ TkTextIndex *indexPtr) /* Index structure to fill in. */
+{
+ return GetIndex(interp, NULL, textPtr, Tcl_GetString(idxObj), indexPtr,
+ NULL);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TkTextSharedGetObjIndex --
+ *
+ * Simpler wrapper around the string based function, but could be
+ * enhanced with a new object type in the future.
+ *
+ * Results:
+ * see TkTextGetIndex
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TkTextSharedGetObjIndex(
+ Tcl_Interp *interp, /* Use this for error reporting. */
+ TkSharedText *sharedTextPtr,/* Information about text widget. */
+ Tcl_Obj *idxObj, /* Object containing textual description of
+ * position. */
+ TkTextIndex *indexPtr) /* Index structure to fill in. */
+{
+ return GetIndex(interp, sharedTextPtr, NULL, Tcl_GetString(idxObj),
+ indexPtr, NULL);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
* TkTextGetIndex --
*
* Given a string, return the index that is described.
*
* Results:
- * The return value is a standard Tcl return result. If TCL_OK is
+ * 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.
+ * filled in; otherwise TCL_ERROR is returned and an error message is
+ * left in the interp's result.
*
* Side effects:
* None.
@@ -309,21 +702,59 @@ TkTextSegToOffset(segPtr, linePtr)
*/
int
-TkTextGetIndex(interp, textPtr, string, indexPtr)
- Tcl_Interp *interp; /* Use this for error reporting. */
- TkText *textPtr; /* Information about text widget. */
- CONST char *string; /* Textual description of position. */
- TkTextIndex *indexPtr; /* Index structure to fill in. */
+TkTextGetIndex(
+ Tcl_Interp *interp, /* Use this for error reporting. */
+ TkText *textPtr, /* Information about text widget. */
+ CONST char *string, /* Textual description of position. */
+ TkTextIndex *indexPtr) /* Index structure to fill in. */
+{
+ return GetIndex(interp, NULL, textPtr, string, indexPtr, NULL);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetIndex --
+ *
+ * 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 the interp's result.
+ *
+ * If *canCachePtr is non-NULL, and everything went well, the integer it
+ * points to is set to 1 if the indexPtr is something which can be
+ * cached, and zero otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+GetIndex(
+ Tcl_Interp *interp, /* Use this for error reporting. */
+ TkSharedText *sharedPtr,
+ TkText *textPtr, /* Information about text widget. */
+ CONST char *string, /* Textual description of position. */
+ TkTextIndex *indexPtr, /* Index structure to fill in. */
+ int *canCachePtr) /* Pointer to integer to store whether we can
+ * cache the index (or NULL). */
{
char *p, *end, *endOfBase;
- Tcl_HashEntry *hPtr;
- TkTextTag *tagPtr;
- TkTextSearch search;
TkTextIndex first, last;
int wantLast, result;
char c;
CONST char *cp;
Tcl_DString copy;
+ int canCache = 0;
+
+ if (sharedPtr == NULL) {
+ sharedPtr = textPtr->sharedTextPtr;
+ }
/*
*---------------------------------------------------------------------
@@ -336,7 +767,7 @@ TkTextGetIndex(interp, textPtr, string, indexPtr)
*/
if (TkTextMarkNameToIndex(textPtr, string, indexPtr) == TCL_OK) {
- return TCL_OK;
+ goto done;
}
if (TkTextWindowIndex(textPtr, string, indexPtr) != 0) {
@@ -353,19 +784,24 @@ TkTextGetIndex(interp, textPtr, string, indexPtr)
*------------------------------------------------
*/
- indexPtr->tree = textPtr->tree;
+ indexPtr->tree = sharedPtr->tree;
/*
- * First look for the form "tag.first" or "tag.last" where "tag"
- * is the name of a valid tag. Try to use up as much as possible
- * of the string in this check (strrchr instead of strchr below).
- * Doing the check now, and in this way, allows tag names to include
- * funny characters like "@" or "+1c".
+ * First look for the form "tag.first" or "tag.last" where "tag" is the
+ * name of a valid tag. Try to use up as much as possible of the string in
+ * this check (strrchr instead of strchr below). Doing the check now, and
+ * in this way, allows tag names to include funny characters like "@" or
+ * "+1c".
*/
Tcl_DStringInit(&copy);
p = strrchr(Tcl_DStringAppend(&copy, string, -1), '.');
if (p != NULL) {
+ TkTextSearch search;
+ TkTextTag *tagPtr;
+ Tcl_HashEntry *hPtr = NULL;
+ CONST char *tagName;
+
if ((p[1] == 'f') && (strncmp(p+1, "first", 5) == 0)) {
wantLast = 0;
endOfBase = p+6;
@@ -375,23 +811,42 @@ TkTextGetIndex(interp, textPtr, string, indexPtr)
} else {
goto tryxy;
}
- *p = 0;
- hPtr = Tcl_FindHashEntry(&textPtr->tagTable, Tcl_DStringValue(&copy));
- *p = '.';
- if (hPtr == NULL) {
+
+ tagPtr = NULL;
+ tagName = Tcl_DStringValue(&copy);
+ if (((p - tagName) == 3) && !strncmp(tagName, "sel", 3)) {
+ /*
+ * Special case for sel tag which is not stored in the hash table.
+ */
+
+ tagPtr = textPtr->selTagPtr;
+ } else {
+ *p = 0;
+ hPtr = Tcl_FindHashEntry(&sharedPtr->tagTable, tagName);
+ *p = '.';
+ if (hPtr != NULL) {
+ tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr);
+ }
+ }
+
+ if (tagPtr == NULL) {
goto tryxy;
}
- tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr);
- TkTextMakeByteIndex(textPtr->tree, 0, 0, &first);
- TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0,
- &last);
+
+ TkTextMakeByteIndex(sharedPtr->tree, textPtr, 0, 0, &first);
+ TkTextMakeByteIndex(sharedPtr->tree, textPtr,
+ TkBTreeNumLines(sharedPtr->tree, textPtr), 0, &last);
TkBTreeStartSearch(&first, &last, tagPtr, &search);
if (!TkBTreeCharTagged(&first, tagPtr) && !TkBTreeNextTag(&search)) {
+ if (tagPtr == textPtr->selTagPtr) {
+ tagName = "sel";
+ } else {
+ tagName = Tcl_GetHashKey(&sharedPtr->tagTable, hPtr);
+ }
Tcl_ResetResult(interp);
Tcl_AppendResult(interp,
"text doesn't contain any characters tagged with \"",
- Tcl_GetHashKey(&textPtr->tagTable, hPtr), "\"",
- (char *) NULL);
+ tagName, "\"", NULL);
Tcl_DStringFree(&copy);
return TCL_ERROR;
}
@@ -404,7 +859,7 @@ TkTextGetIndex(interp, textPtr, string, indexPtr)
goto gotBase;
}
- tryxy:
+ tryxy:
if (string[0] == '@') {
/*
* Find character at a given x,y location in the window.
@@ -422,9 +877,9 @@ TkTextGetIndex(interp, textPtr, string, indexPtr)
if (end == cp) {
goto error;
}
- TkTextPixelIndex(textPtr, x, y, indexPtr);
+ TkTextPixelIndex(textPtr, x, y, indexPtr, NULL);
endOfBase = end;
- goto gotBase;
+ goto gotBase;
}
if (isdigit(UCHAR(string[0])) || (string[0] == '-')) {
@@ -449,7 +904,9 @@ TkTextGetIndex(interp, textPtr, string, indexPtr)
}
endOfBase = end;
}
- TkTextMakeCharIndex(textPtr->tree, lineIndex, charIndex, indexPtr);
+ TkTextMakeCharIndex(sharedPtr->tree, textPtr, lineIndex, charIndex,
+ indexPtr);
+ canCache = 1;
goto gotBase;
}
@@ -479,8 +936,9 @@ TkTextGetIndex(interp, textPtr, string, indexPtr)
* Base position is end of text.
*/
- TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree),
- 0, indexPtr);
+ TkTextMakeByteIndex(sharedPtr->tree, textPtr,
+ TkBTreeNumLines(sharedPtr->tree, textPtr), 0, indexPtr);
+ canCache = 1;
goto gotBase;
} else {
/*
@@ -497,7 +955,7 @@ TkTextGetIndex(interp, textPtr, string, indexPtr)
}
/*
- * See if the base position is the name of an embedded image
+ * See if the base position is the name of an embedded image.
*/
c = *endOfBase;
@@ -512,14 +970,14 @@ TkTextGetIndex(interp, textPtr, string, indexPtr)
/*
*-------------------------------------------------------------------
- * Stage 3: process zero or more modifiers. Each modifier is either
- * a keyword like "wordend" or "linestart", or it has the form
- * "op count units" where op is + or -, count is a number, and units
- * is "chars" or "lines".
+ * Stage 3: process zero or more modifiers. Each modifier is either a
+ * keyword like "wordend" or "linestart", or it has the form "op count
+ * units" where op is + or -, count is a number, and units is "chars" or
+ * "lines".
*-------------------------------------------------------------------
*/
- gotBase:
+ gotBase:
cp = endOfBase;
while (1) {
while (isspace(UCHAR(*cp))) {
@@ -528,24 +986,31 @@ TkTextGetIndex(interp, textPtr, string, indexPtr)
if (*cp == 0) {
break;
}
-
+
if ((*cp == '+') || (*cp == '-')) {
- cp = ForwBack(cp, indexPtr);
+ cp = ForwBack(textPtr, cp, indexPtr);
} else {
- cp = StartEnd(cp, indexPtr);
+ cp = StartEnd(textPtr, cp, indexPtr);
}
if (cp == NULL) {
goto error;
}
}
Tcl_DStringFree(&copy);
+
+ done:
+ if (canCachePtr != NULL) {
+ *canCachePtr = canCache;
+ }
+ if (indexPtr->linePtr == NULL) {
+ Tcl_Panic("Bad index created");
+ }
return TCL_OK;
- error:
+ error:
Tcl_DStringFree(&copy);
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad text index \"", string, "\"",
- (char *) NULL);
+ Tcl_AppendResult(interp, "bad text index \"", string, "\"", NULL);
return TCL_ERROR;
}
@@ -553,12 +1018,13 @@ TkTextGetIndex(interp, textPtr, string, indexPtr)
*---------------------------------------------------------------------------
*
* TkTextPrintIndex --
- *
- * This procedure generates a string description of an index, suitable
- * for reading in again later.
+ *
+ * This function generates a string description of an index, suitable for
+ * reading in again later.
*
* Results:
- * The characters pointed to by string are modified.
+ * The characters pointed to by string are modified. Returns the number
+ * of characters in the string.
*
* Side effects:
* None.
@@ -566,18 +1032,31 @@ TkTextGetIndex(interp, textPtr, string, indexPtr)
*---------------------------------------------------------------------------
*/
-void
-TkTextPrintIndex(indexPtr, string)
- CONST TkTextIndex *indexPtr;/* Pointer to index. */
- char *string; /* Place to store the position. Must have
- * at least TK_POS_CHARS characters. */
+int
+TkTextPrintIndex(
+ CONST TkText *textPtr,
+ CONST TkTextIndex *indexPtr,/* Pointer to index. */
+ char *string) /* Place to store the position. Must have at
+ * least TK_POS_CHARS characters. */
{
TkTextSegment *segPtr;
+ TkTextLine *linePtr;
int numBytes, charIndex;
numBytes = indexPtr->byteIndex;
charIndex = 0;
- for (segPtr = indexPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr) {
+ linePtr = indexPtr->linePtr;
+
+ for (segPtr = linePtr->segPtr; ; segPtr = segPtr->nextPtr) {
+ if (segPtr == NULL) {
+ /*
+ * Two logical lines merged into one display line through eliding
+ * of a newline.
+ */
+
+ linePtr = TkBTreeNextLine(NULL, linePtr);
+ segPtr = linePtr->segPtr;
+ }
if (numBytes <= segPtr->size) {
break;
}
@@ -588,13 +1067,15 @@ TkTextPrintIndex(indexPtr, string)
}
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,
- charIndex);
+
+ return sprintf(string, "%d.%d",
+ TkBTreeLinesTo(textPtr, indexPtr->linePtr) + 1, charIndex);
}
/*
@@ -616,9 +1097,9 @@ TkTextPrintIndex(indexPtr, string)
*/
int
-TkTextIndexCmp(index1Ptr, index2Ptr)
- CONST TkTextIndex *index1Ptr; /* First index. */
- CONST TkTextIndex *index2Ptr; /* Second index. */
+TkTextIndexCmp(
+ CONST TkTextIndex*index1Ptr,/* First index. */
+ CONST TkTextIndex*index2Ptr)/* Second index. */
{
int line1, line2;
@@ -631,8 +1112,16 @@ TkTextIndexCmp(index1Ptr, index2Ptr)
return 0;
}
}
- line1 = TkBTreeLineIndex(index1Ptr->linePtr);
- line2 = TkBTreeLineIndex(index2Ptr->linePtr);
+
+ /*
+ * Assumption here that it is ok for comparisons to reflect the full
+ * B-tree and not just the portion that is available to any client. This
+ * should be true because the only indexPtr's we should be given are ones
+ * which are valid for the current client.
+ */
+
+ line1 = TkBTreeLinesTo(NULL, index1Ptr->linePtr);
+ line2 = TkBTreeLinesTo(NULL, index2Ptr->linePtr);
if (line1 < line2) {
return -1;
}
@@ -647,14 +1136,14 @@ TkTextIndexCmp(index1Ptr, index2Ptr)
*
* ForwBack --
*
- * This procedure handles +/- modifiers for indices to adjust the
- * index forwards or backwards.
+ * This function 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.
@@ -663,16 +1152,16 @@ TkTextIndexCmp(index1Ptr, index2Ptr)
*/
static CONST char *
-ForwBack(string, indexPtr)
- CONST char *string; /* String to parse for additional info
- * about modifier (count and units).
- * Points to "+" or "-" that starts
- * modifier. */
- TkTextIndex *indexPtr; /* Index to update as specified in string. */
+ForwBack(
+ TkText *textPtr, /* Information about text widget. */
+ CONST char *string, /* String to parse for additional info about
+ * modifier (count and units). Points to "+"
+ * or "-" that starts modifier. */
+ TkTextIndex *indexPtr) /* Index to update as specified in string. */
{
register CONST char *p, *units;
char *end;
- int count, lineIndex;
+ int count, lineIndex, modifier;
size_t length;
/*
@@ -693,53 +1182,193 @@ ForwBack(string, indexPtr)
}
/*
- * Find the end of this modifier (next space or + or - character),
- * then parse the unit specifier and update the position
- * accordingly.
+ * Find the end of this modifier (next space or + or - character), then
+ * check if there is a textual 'display' or 'any' modifier. These
+ * modifiers can be their own word (in which case they can be abbreviated)
+ * or they can follow on to the actual unit in a single word (in which
+ * case no abbreviation is allowed). So, 'display lines', 'd lines',
+ * 'displaylin' are all ok, but 'dline' is not.
*/
- units = p;
+ units = p;
while ((*p != '\0') && !isspace(UCHAR(*p)) && (*p != '+') && (*p != '-')) {
p++;
}
length = p - units;
+ if ((*units == 'd') &&
+ (strncmp(units, "display", (length > 7 ? 7 : length)) == 0)) {
+ modifier = TKINDEX_DISPLAY;
+ if (length > 7) {
+ p -= (length - 7);
+ }
+ } else if ((*units == 'a') &&
+ (strncmp(units, "any", (length > 3 ? 3 : length)) == 0)) {
+ modifier = TKINDEX_ANY;
+ if (length > 3) {
+ p -= (length - 3);
+ }
+ } else {
+ modifier = TKINDEX_NONE;
+ }
+
+ /*
+ * If we had a modifier, which we interpreted ok, so now forward to the
+ * actual units.
+ */
+
+ if (modifier != TKINDEX_NONE) {
+ while (isspace(UCHAR(*p))) {
+ p++;
+ }
+ units = p;
+ while (*p!='\0' && !isspace(UCHAR(*p)) && *p!='+' && *p!='-') {
+ p++;
+ }
+ length = p - units;
+ }
+
+ /*
+ * Finally parse the units.
+ */
+
if ((*units == 'c') && (strncmp(units, "chars", length) == 0)) {
+ TkTextCountType type;
+
+ if (modifier == TKINDEX_NONE) {
+ type = COUNT_INDICES;
+ } else if (modifier == TKINDEX_ANY) {
+ type = COUNT_CHARS;
+ } else {
+ type = COUNT_DISPLAY_CHARS;
+ }
+
if (*string == '+') {
- TkTextIndexForwChars(indexPtr, count, indexPtr);
+ TkTextIndexForwChars(textPtr, indexPtr, count, indexPtr, type);
} else {
- TkTextIndexBackChars(indexPtr, count, indexPtr);
+ TkTextIndexBackChars(textPtr, indexPtr, count, indexPtr, type);
}
- } else if ((*units == 'l') && (strncmp(units, "lines", length) == 0)) {
- lineIndex = TkBTreeLineIndex(indexPtr->linePtr);
+ } else if ((*units == 'i') && (strncmp(units, "indices", length) == 0)) {
+ TkTextCountType type;
+
+ if (modifier == TKINDEX_DISPLAY) {
+ type = COUNT_DISPLAY_INDICES;
+ } else {
+ type = COUNT_INDICES;
+ }
+
if (*string == '+') {
- lineIndex += count;
+ TkTextIndexForwChars(textPtr, indexPtr, count, indexPtr, type);
} else {
- lineIndex -= count;
+ TkTextIndexBackChars(textPtr, indexPtr, count, indexPtr, type);
+ }
+ } else if ((*units == 'l') && (strncmp(units, "lines", length) == 0)) {
+ if (modifier == TKINDEX_DISPLAY) {
+ /*
+ * Find the appropriate pixel offset of the current position
+ * within its display line. This also has the side-effect of
+ * moving indexPtr, but that doesn't matter since we will do it
+ * again below.
+ *
+ * Then find the right display line, and finally calculated the
+ * index we want in that display line, based on the original pixel
+ * offset.
+ */
+
+ int xOffset, forward;
+
+ if (TkTextIsElided(textPtr, indexPtr, NULL)) {
+ /*
+ * Go forward to the first non-elided index.
+ */
+
+ TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr,
+ COUNT_DISPLAY_INDICES);
+ }
/*
- * The check below retains the character position, even
- * if the line runs off the start of the file. Without
- * it, the character position will get reset to 0 by
- * TkTextMakeIndex.
+ * Unlike the Forw/BackChars code, the display line code is
+ * sensitive to whether we are genuinely going forwards or
+ * backwards. So, we need to determine that. This is important in
+ * the case where we have "+ -3 displaylines", for example.
*/
- if (lineIndex < 0) {
- lineIndex = 0;
+ if ((count < 0) ^ (*string == '-')) {
+ forward = 0;
+ } else {
+ forward = 1;
}
- }
- /*
- * 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);
+ count = abs(count);
+ if (count == 0) {
+ return p;
+ }
+
+ if (forward) {
+ TkTextFindDisplayLineEnd(textPtr, indexPtr, 1, &xOffset);
+ while (count-- > 0) {
+ /*
+ * Go to the end of the line, then forward one char/byte
+ * to get to the beginning of the next line.
+ */
+
+ TkTextFindDisplayLineEnd(textPtr, indexPtr, 1, NULL);
+ TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr,
+ COUNT_DISPLAY_INDICES);
+ }
+ } else {
+ TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, &xOffset);
+ while (count-- > 0) {
+ /*
+ * Go to the beginning of the line, then backward one
+ * char/byte to get to the end of the previous line.
+ */
+
+ TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, NULL);
+ TkTextIndexBackChars(textPtr, indexPtr, 1, indexPtr,
+ COUNT_DISPLAY_INDICES);
+ }
+ TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, NULL);
+ }
+
+ /*
+ * This call assumes indexPtr is the beginning of a display line
+ * and moves it to the 'xOffset' position of that line, which is
+ * just what we want.
+ */
+
+ TkTextIndexOfX(textPtr, xOffset, indexPtr);
+ } else {
+ lineIndex = TkBTreeLinesTo(textPtr, indexPtr->linePtr);
+ if (*string == '+') {
+ lineIndex += count;
+ } else {
+ lineIndex -= count;
+
+ /*
+ * The check below retains the character position, even if the
+ * line runs off the start of the file. Without it, the
+ * character position will get reset to 0 by TkTextMakeIndex.
+ */
+
+ if (lineIndex < 0) {
+ lineIndex = 0;
+ }
+ }
+
+ /*
+ * This doesn't work quite right if using a proportional font or
+ * UTF-8 characters with varying numbers of bytes, or if there are
+ * embedded windows, images, etc. 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, textPtr, lineIndex,
+ indexPtr->byteIndex, indexPtr);
+ }
} else {
return NULL;
}
@@ -751,13 +1380,16 @@ ForwBack(string, indexPtr)
*
* TkTextIndexForwBytes --
*
- * Given an index for a text widget, this procedure creates a new
- * index that points "count" bytes ahead of the source index.
+ * Given an index for a text widget, this function creates a new index
+ * that points "count" bytes ahead of the source index.
*
* Results:
* *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.
+ * srcPtr, or to the last character in the TkText if there aren't "count"
+ * bytes left.
+ *
+ * In this latter case, the function returns '1' to indicate that not all
+ * of 'byteCount' could be used.
*
* Side effects:
* None.
@@ -765,20 +1397,21 @@ ForwBack(string, indexPtr)
*---------------------------------------------------------------------------
*/
-void
-TkTextIndexForwBytes(srcPtr, byteCount, dstPtr)
- CONST TkTextIndex *srcPtr; /* Source index. */
- int byteCount; /* How many bytes forward to move. May be
+int
+TkTextIndexForwBytes(
+ CONST TkText *textPtr,
+ CONST TkTextIndex *srcPtr, /* Source index. */
+ int byteCount, /* How many bytes forward to move. May be
* negative. */
- TkTextIndex *dstPtr; /* Destination index: gets modified. */
+ TkTextIndex *dstPtr) /* Destination index: gets modified. */
{
TkTextLine *linePtr;
TkTextSegment *segPtr;
int lineLength;
if (byteCount < 0) {
- TkTextIndexBackBytes(srcPtr, -byteCount, dstPtr);
- return;
+ TkTextIndexBackBytes(textPtr, srcPtr, -byteCount, dstPtr);
+ return 0;
}
*dstPtr = *srcPtr;
@@ -795,18 +1428,18 @@ TkTextIndexForwBytes(srcPtr, byteCount, dstPtr)
}
/*
- * If the new index is in the same line then we're done.
- * Otherwise go on to the next line.
+ * If the new index is in the same line then we're done. Otherwise go
+ * on to the next line.
*/
if (dstPtr->byteIndex < lineLength) {
- return;
+ return 0;
}
dstPtr->byteIndex -= lineLength;
- linePtr = TkBTreeNextLine(dstPtr->linePtr);
+ linePtr = TkBTreeNextLine(textPtr, dstPtr->linePtr);
if (linePtr == NULL) {
dstPtr->byteIndex = lineLength - 1;
- return;
+ return 1;
}
dstPtr->linePtr = linePtr;
}
@@ -817,13 +1450,18 @@ TkTextIndexForwBytes(srcPtr, byteCount, dstPtr)
*
* TkTextIndexForwChars --
*
- * 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 function creates a new index
+ * that points "count" items of type given by "type" ahead of the source
+ * index. "count" can be zero, which is useful in the case where one
+ * wishes to move forward by display (non-elided) chars or indices or one
+ * wishes to move forward by chars, skipping any intervening indices. In
+ * this case dstPtr will point to the first acceptable index which is
+ * encountered.
*
* Results:
- * *dstPtr is modified to refer to the character "count" characters
- * after srcPtr, or to the last character in the TkText if there
- * aren't "count" characters left in the file.
+ * *dstPtr is modified to refer to the character "count" items after
+ * srcPtr, or to the last character in the TkText if there aren't
+ * sufficient items left in the widget.
*
* Side effects:
* None.
@@ -832,31 +1470,52 @@ TkTextIndexForwBytes(srcPtr, byteCount, dstPtr)
*/
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. */
+TkTextIndexForwChars(
+ CONST TkText *textPtr, /* Overall information about text widget. */
+ CONST TkTextIndex *srcPtr, /* Source index. */
+ int charCount, /* How many characters forward to move. May
+ * be negative. */
+ TkTextIndex *dstPtr, /* Destination index: gets modified. */
+ TkTextCountType type) /* The type of item to count */
{
TkTextLine *linePtr;
TkTextSegment *segPtr;
+ TkTextElideInfo *infoPtr = NULL;
int byteOffset;
char *start, *end, *p;
Tcl_UniChar ch;
+ int elide = 0;
+ int checkElided = (type & COUNT_DISPLAY);
if (charCount < 0) {
- TkTextIndexBackChars(srcPtr, -charCount, dstPtr);
+ TkTextIndexBackChars(textPtr, srcPtr, -charCount, dstPtr, type);
return;
}
+ if (checkElided) {
+ infoPtr = (TkTextElideInfo *)
+ ckalloc((unsigned) sizeof(TkTextElideInfo));
+ elide = TkTextIsElided(textPtr, srcPtr, infoPtr);
+ }
*dstPtr = *srcPtr;
/*
- * Find seg that contains src byteIndex.
- * Move forward specified number of chars.
+ * Find seg that contains src byteIndex. Move forward specified number of
+ * chars.
*/
- segPtr = TkTextIndexToSeg(dstPtr, &byteOffset);
+ if (checkElided) {
+ /*
+ * In this case we have already calculated the information we need, so
+ * no need to use TkTextIndexToSeg()
+ */
+
+ segPtr = infoPtr->segPtr;
+ byteOffset = dstPtr->byteIndex - infoPtr->segOffset;
+ } else {
+ segPtr = TkTextIndexToSeg(dstPtr, &byteOffset);
+ }
+
while (1) {
/*
* Go through each segment in line looking for specified character
@@ -864,76 +1523,341 @@ TkTextIndexForwChars(srcPtr, charCount, dstPtr)
*/
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;
+ /*
+ * If we do need to pay attention to the visibility of
+ * characters/indices, check that first. If the current segment
+ * isn't visible, then we simply continue the loop.
+ */
+
+ if (checkElided && ((segPtr->typePtr == &tkTextToggleOffType)
+ || (segPtr->typePtr == &tkTextToggleOnType))) {
+ TkTextTag *tagPtr = segPtr->body.toggle.tagPtr;
+
+ /*
+ * The elide state only changes if this tag is either the
+ * current highest priority tag (and is therefore being
+ * toggled off), or it's a new tag with higher priority.
+ */
+
+ if (tagPtr->elideString != NULL) {
+ infoPtr->tagCnts[tagPtr->priority]++;
+ if (infoPtr->tagCnts[tagPtr->priority] & 1) {
+ infoPtr->tagPtrs[tagPtr->priority] = tagPtr;
+ }
+
+ if (tagPtr->priority >= infoPtr->elidePriority) {
+ if (segPtr->typePtr == &tkTextToggleOffType) {
+ /*
+ * If it is being toggled off, and it has an elide
+ * string, it must actually be the current highest
+ * priority tag, so this check is redundant:
+ */
+
+ if (tagPtr->priority != infoPtr->elidePriority) {
+ Tcl_Panic("Bad tag priority being toggled off");
+ }
+
+ /*
+ * Find previous elide tag, if any (if not then
+ * elide will be zero, of course).
+ */
+
+ elide = 0;
+ while (--infoPtr->elidePriority > 0) {
+ if (infoPtr->tagCnts[infoPtr->elidePriority]
+ & 1) {
+ elide = infoPtr->tagPtrs
+ [infoPtr->elidePriority]->elide;
+ break;
+ }
+ }
+ } else {
+ elide = tagPtr->elide;
+ infoPtr->elidePriority = tagPtr->priority;
+ }
}
- charCount--;
}
- } else {
- if (charCount < segPtr->size - byteOffset) {
- dstPtr->byteIndex += charCount;
- return;
+ }
+
+ if (!elide) {
+ 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);
+ goto forwardCharDone;
+ }
+ charCount--;
+ }
+ } else if (type & COUNT_INDICES) {
+ if (charCount < segPtr->size - byteOffset) {
+ dstPtr->byteIndex += charCount;
+ goto forwardCharDone;
+ }
+ charCount -= segPtr->size - byteOffset;
}
- 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.
+ * 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);
+
+ linePtr = TkBTreeNextLine(textPtr, dstPtr->linePtr);
if (linePtr == NULL) {
dstPtr->byteIndex -= sizeof(char);
- return;
+ goto forwardCharDone;
}
dstPtr->linePtr = linePtr;
dstPtr->byteIndex = 0;
segPtr = dstPtr->linePtr->segPtr;
}
+
+ forwardCharDone:
+ if (infoPtr != NULL) {
+ TkTextFreeElideInfo(infoPtr);
+ ckfree((char *) infoPtr);
+ }
}
/*
*---------------------------------------------------------------------------
*
+ * TkTextIndexCount --
+ *
+ * Given an ordered pair of indices in a text widget, this function
+ * counts how many characters (not bytes) are between the two indices.
+ *
+ * It is illegal to call this function with unordered indices.
+ *
+ * Note that 'textPtr' is only used if we need to check for elided
+ * attributes, i.e. if type is COUNT_DISPLAY_INDICES or
+ * COUNT_DISPLAY_CHARS.
+ *
+ * Results:
+ * The number of characters in the given range, which meet the
+ * appropriate 'type' attributes.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TkTextIndexCount(
+ CONST TkText *textPtr, /* Overall information about text widget. */
+ CONST TkTextIndex *indexPtr1,
+ /* Index describing location of character from
+ * which to count. */
+ CONST TkTextIndex *indexPtr2,
+ /* Index describing location of last character
+ * at which to stop the count. */
+ TkTextCountType type) /* The kind of indices to count. */
+{
+ TkTextLine *linePtr1;
+ TkTextSegment *segPtr, *seg2Ptr = NULL;
+ TkTextElideInfo *infoPtr = NULL;
+ int byteOffset, maxBytes, count = 0, elide = 0;
+ int checkElided = (type & COUNT_DISPLAY);
+
+ /*
+ * Find seg that contains src index, and remember how many bytes not to
+ * count in the given segment.
+ */
+
+ segPtr = TkTextIndexToSeg(indexPtr1, &byteOffset);
+ linePtr1 = indexPtr1->linePtr;
+
+ seg2Ptr = TkTextIndexToSeg(indexPtr2, &maxBytes);
+
+ if (checkElided) {
+ infoPtr = (TkTextElideInfo *)
+ ckalloc((unsigned) sizeof(TkTextElideInfo));
+ elide = TkTextIsElided(textPtr, indexPtr1, infoPtr);
+ }
+
+ while (1) {
+ /*
+ * Go through each segment in line adding up the number of characters.
+ */
+
+ for ( ; segPtr != NULL; segPtr = segPtr->nextPtr) {
+ /*
+ * If we do need to pay attention to the visibility of
+ * characters/indices, check that first. If the current segment
+ * isn't visible, then we simply continue the loop.
+ */
+
+ if (checkElided) {
+ if ((segPtr->typePtr == &tkTextToggleOffType)
+ || (segPtr->typePtr == &tkTextToggleOnType)) {
+ TkTextTag *tagPtr = segPtr->body.toggle.tagPtr;
+
+ /*
+ * The elide state only changes if this tag is either the
+ * current highest priority tag (and is therefore being
+ * toggled off), or it's a new tag with higher priority.
+ */
+
+ if (tagPtr->elideString != NULL) {
+ infoPtr->tagCnts[tagPtr->priority]++;
+ if (infoPtr->tagCnts[tagPtr->priority] & 1) {
+ infoPtr->tagPtrs[tagPtr->priority] = tagPtr;
+ }
+ if (tagPtr->priority >= infoPtr->elidePriority) {
+ if (segPtr->typePtr == &tkTextToggleOffType) {
+ /*
+ * If it is being toggled off, and it has an
+ * elide string, it must actually be the
+ * current highest priority tag, so this check
+ * is redundant:
+ */
+
+ if (tagPtr->priority!=infoPtr->elidePriority) {
+ Tcl_Panic("Bad tag priority being toggled off");
+ }
+
+ /*
+ * Find previous elide tag, if any (if not
+ * then elide will be zero, of course).
+ */
+
+ elide = 0;
+ while (--infoPtr->elidePriority > 0) {
+ if (infoPtr->tagCnts[
+ infoPtr->elidePriority] & 1) {
+ elide = infoPtr->tagPtrs[
+ infoPtr->elidePriority]->elide;
+ break;
+ }
+ }
+ } else {
+ elide = tagPtr->elide;
+ infoPtr->elidePriority = tagPtr->priority;
+ }
+ }
+ }
+ }
+ if (elide) {
+ if (segPtr == seg2Ptr) {
+ goto countDone;
+ }
+ byteOffset = 0;
+ continue;
+ }
+ }
+
+ if (segPtr->typePtr == &tkTextCharType) {
+ int byteLen = segPtr->size - byteOffset;
+ register unsigned char *str = (unsigned char *)
+ segPtr->body.chars + byteOffset;
+ register int i;
+
+ if (segPtr == seg2Ptr) {
+ if (byteLen > (maxBytes - byteOffset)) {
+ byteLen = maxBytes - byteOffset;
+ }
+ }
+ i = byteLen;
+
+ /*
+ * This is a speed sensitive function, so run specially over
+ * the string to count continuous ascii characters before
+ * resorting to the Tcl_NumUtfChars call. This is a long form
+ * of:
+ *
+ * stringPtr->numChars =
+ * Tcl_NumUtfChars(objPtr->bytes, objPtr->length);
+ */
+
+ while (i && (*str < 0xC0)) {
+ i--;
+ str++;
+ }
+ count += byteLen - i;
+ if (i) {
+ count += Tcl_NumUtfChars(segPtr->body.chars + byteOffset
+ + (byteLen - i), i);
+ }
+ } else {
+ if (type & COUNT_INDICES) {
+ int byteLen = segPtr->size - byteOffset;
+
+ if (segPtr == seg2Ptr) {
+ if (byteLen > (maxBytes - byteOffset)) {
+ byteLen = maxBytes - byteOffset;
+ }
+ }
+ count += byteLen;
+ }
+ }
+ if (segPtr == seg2Ptr) {
+ goto countDone;
+ }
+ 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.
+ */
+
+ linePtr1 = TkBTreeNextLine(textPtr, linePtr1);
+ if (linePtr1 == NULL) {
+ Tcl_Panic("Reached end of text widget when counting characters");
+ }
+ segPtr = linePtr1->segPtr;
+ }
+
+ countDone:
+ if (infoPtr != NULL) {
+ TkTextFreeElideInfo(infoPtr);
+ ckfree((char *) infoPtr);
+ }
+ return count;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
* TkTextIndexBackBytes --
*
- * Given an index for a text widget, this procedure creates a new
- * index that points "count" bytes earlier than the source index.
+ * Given an index for a text widget, this function 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.
*
+ * Returns 1 if we couldn't use all of 'byteCount' because we have run
+ * into the beginning or end of the text, and zero otherwise.
+ *
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
-void
-TkTextIndexBackBytes(srcPtr, byteCount, dstPtr)
- CONST TkTextIndex *srcPtr; /* Source index. */
- int byteCount; /* How many bytes backward to move. May be
+int
+TkTextIndexBackBytes(
+ CONST TkText *textPtr,
+ CONST TkTextIndex *srcPtr, /* Source index. */
+ int byteCount, /* How many bytes backward to move. May be
* negative. */
- TkTextIndex *dstPtr; /* Destination index: gets modified. */
+ TkTextIndex *dstPtr) /* Destination index: gets modified. */
{
TkTextSegment *segPtr;
int lineIndex;
if (byteCount < 0) {
- TkTextIndexForwBytes(srcPtr, -byteCount, dstPtr);
- return;
+ return TkTextIndexForwBytes(textPtr, srcPtr, -byteCount, dstPtr);
}
*dstPtr = *srcPtr;
@@ -941,19 +1865,19 @@ TkTextIndexBackBytes(srcPtr, byteCount, dstPtr)
lineIndex = -1;
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.
+ * 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.
*/
if (lineIndex < 0) {
- lineIndex = TkBTreeLineIndex(dstPtr->linePtr);
+ lineIndex = TkBTreeLinesTo(textPtr, dstPtr->linePtr);
}
if (lineIndex == 0) {
dstPtr->byteIndex = 0;
- return;
+ return 1;
}
lineIndex--;
- dstPtr->linePtr = TkBTreeFindLine(dstPtr->tree, lineIndex);
+ dstPtr->linePtr = TkBTreeFindLine(dstPtr->tree, textPtr, lineIndex);
/*
* Compute the length of the line and add that to dstPtr->charIndex.
@@ -964,6 +1888,7 @@ TkTextIndexBackBytes(srcPtr, byteCount, dstPtr)
dstPtr->byteIndex += segPtr->size;
}
}
+ return 0;
}
/*
@@ -971,13 +1896,18 @@ TkTextIndexBackBytes(srcPtr, byteCount, dstPtr)
*
* TkTextIndexBackChars --
*
- * 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 function creates a new index
+ * that points "count" items of type given by "type" earlier than the
+ * source index. "count" can be zero, which is useful in the case where
+ * one wishes to move backward by display (non-elided) chars or indices
+ * or one wishes to move backward by chars, skipping any intervening
+ * indices. In this case the returned index *dstPtr will point just
+ * _after_ the first acceptable index which is encountered.
*
* 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.
+ * *dstPtr is modified to refer to the character "count" items before
+ * srcPtr, or to the first index in the window if there aren't sufficient
+ * items earlier than srcPtr.
*
* Side effects:
* None.
@@ -986,57 +1916,145 @@ TkTextIndexBackBytes(srcPtr, byteCount, dstPtr)
*/
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. */
+TkTextIndexBackChars(
+ CONST TkText *textPtr, /* Overall information about text widget. */
+ CONST TkTextIndex *srcPtr, /* Source index. */
+ int charCount, /* How many characters backward to move. May
+ * be negative. */
+ TkTextIndex *dstPtr, /* Destination index: gets modified. */
+ TkTextCountType type) /* The type of item to count */
{
TkTextSegment *segPtr, *oldPtr;
+ TkTextElideInfo *infoPtr = NULL;
int lineIndex, segSize;
CONST char *p, *start, *end;
+ int elide = 0;
+ int checkElided = (type & COUNT_DISPLAY);
- if (charCount <= 0) {
- TkTextIndexForwChars(srcPtr, -charCount, dstPtr);
+ if (charCount < 0) {
+ TkTextIndexForwChars(textPtr, srcPtr, -charCount, dstPtr, type);
return;
}
+ if (checkElided) {
+ infoPtr = (TkTextElideInfo *) ckalloc(sizeof(TkTextElideInfo));
+ elide = TkTextIsElided(textPtr, srcPtr, infoPtr);
+ }
*dstPtr = *srcPtr;
/*
- * Find offset within seg that contains byteIndex.
- * Move backward specified number of chars.
+ * 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;
+
+ if (checkElided) {
+ segPtr = infoPtr->segPtr;
+ segSize -= infoPtr->segOffset;
+ } else {
+ TkTextLine *linePtr = dstPtr->linePtr;
+ for (segPtr = linePtr->segPtr; ; segPtr = segPtr->nextPtr) {
+ if (segPtr == NULL) {
+ /*
+ * Two logical lines merged into one display line through
+ * eliding of a newline.
+ */
+
+ linePtr = TkBTreeNextLine(NULL, linePtr);
+ segPtr = linePtr->segPtr;
+ }
+ if (segSize <= segPtr->size) {
+ break;
+ }
+ segSize -= segPtr->size;
}
- segSize -= segPtr->size;
}
+
+ /*
+ * Now segPtr points to the segment containing the starting index.
+ */
+
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 we do need to pay attention to the visibility of
+ * characters/indices, check that first. If the current segment isn't
+ * visible, then we simply continue the loop.
+ */
+
+ if (checkElided && ((segPtr->typePtr == &tkTextToggleOffType)
+ || (segPtr->typePtr == &tkTextToggleOnType))) {
+ TkTextTag *tagPtr = segPtr->body.toggle.tagPtr;
+
+ /*
+ * The elide state only changes if this tag is either the current
+ * highest priority tag (and is therefore being toggled off), or
+ * it's a new tag with higher priority.
+ */
+
+ if (tagPtr->elideString != NULL) {
+ infoPtr->tagCnts[tagPtr->priority]++;
+ if (infoPtr->tagCnts[tagPtr->priority] & 1) {
+ infoPtr->tagPtrs[tagPtr->priority] = tagPtr;
}
- if (p == start) {
- break;
+ if (tagPtr->priority >= infoPtr->elidePriority) {
+ if (segPtr->typePtr == &tkTextToggleOnType) {
+ /*
+ * If it is being toggled on, and it has an elide
+ * string, it must actually be the current highest
+ * priority tag, so this check is redundant:
+ */
+
+ if (tagPtr->priority != infoPtr->elidePriority) {
+ Tcl_Panic("Bad tag priority being toggled on");
+ }
+
+ /*
+ * Find previous elide tag, if any (if not then elide
+ * will be zero, of course).
+ */
+
+ elide = 0;
+ while (--infoPtr->elidePriority > 0) {
+ if (infoPtr->tagCnts[infoPtr->elidePriority] & 1) {
+ elide = infoPtr->tagPtrs[
+ infoPtr->elidePriority]->elide;
+ break;
+ }
+ }
+ } else {
+ elide = tagPtr->elide;
+ infoPtr->elidePriority = tagPtr->priority;
+ }
}
- charCount--;
}
- } else {
- if (charCount <= segSize) {
- dstPtr->byteIndex -= charCount;
- return;
+ }
+
+ if (!elide) {
+ 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);
+ goto backwardCharDone;
+ }
+ if (p == start) {
+ break;
+ }
+ charCount--;
+ }
+ } else {
+ if (type & COUNT_INDICES) {
+ if (charCount <= segSize) {
+ dstPtr->byteIndex -= charCount;
+ goto backwardCharDone;
+ }
+ charCount -= segSize;
+ }
}
- charCount -= segSize;
}
dstPtr->byteIndex -= segSize;
@@ -1059,14 +2077,14 @@ TkTextIndexBackChars(srcPtr, charCount, dstPtr)
*/
if (lineIndex < 0) {
- lineIndex = TkBTreeLineIndex(dstPtr->linePtr);
+ lineIndex = TkBTreeLinesTo(textPtr, dstPtr->linePtr);
}
if (lineIndex == 0) {
dstPtr->byteIndex = 0;
- return;
+ goto backwardCharDone;
}
lineIndex--;
- dstPtr->linePtr = TkBTreeFindLine(dstPtr->tree, lineIndex);
+ dstPtr->linePtr = TkBTreeFindLine(dstPtr->tree, textPtr, lineIndex);
/*
* Compute the length of the line and add that to dstPtr->byteIndex.
@@ -1080,6 +2098,12 @@ TkTextIndexBackChars(srcPtr, charCount, dstPtr)
segPtr = oldPtr;
segSize = segPtr->size;
}
+
+ backwardCharDone:
+ if (infoPtr != NULL) {
+ TkTextFreeElideInfo(infoPtr);
+ ckfree((char *) infoPtr);
+ }
}
/*
@@ -1087,14 +2111,14 @@ TkTextIndexBackChars(srcPtr, charCount, dstPtr)
*
* StartEnd --
*
- * This procedure handles modifiers like "wordstart" and "lineend"
- * to adjust indices forwards or backwards.
+ * This function handles modifiers like "wordstart" and "lineend" to
+ * adjust indices forwards or backwards.
*
* Results:
- * If the modifier 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 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.
@@ -1103,17 +2127,17 @@ TkTextIndexBackChars(srcPtr, charCount, dstPtr)
*/
static CONST char *
-StartEnd(string, indexPtr)
- CONST char *string; /* String to parse for additional info
- * about modifier (count and units).
- * Points to first character of modifer
- * word. */
- TkTextIndex *indexPtr; /* Index to mdoify based on string. */
+StartEnd(
+ TkText *textPtr, /* Information about text widget. */
+ CONST char *string, /* String to parse for additional info about
+ * modifier (count and units). Points to first
+ * character of modifer word. */
+ TkTextIndex *indexPtr) /* Index to modify based on string. */
{
CONST char *p;
- int c, offset;
size_t length;
register TkTextSegment *segPtr;
+ int modifier;
/*
* Find the end of the modifier word.
@@ -1122,68 +2146,144 @@ StartEnd(string, indexPtr)
for (p = string; isalnum(UCHAR(*p)); p++) {
/* Empty loop body. */
}
+
length = p-string;
+ if ((*string == 'd') &&
+ (strncmp(string, "display", (length > 7 ? 7 : length)) == 0)) {
+ modifier = TKINDEX_DISPLAY;
+ if (length > 7) {
+ p -= (length - 7);
+ }
+ } else if ((*string == 'a') &&
+ (strncmp(string, "any", (length > 3 ? 3 : length)) == 0)) {
+ modifier = TKINDEX_ANY;
+ if (length > 3) {
+ p -= (length - 3);
+ }
+ } else {
+ modifier = TKINDEX_NONE;
+ }
+
+ /*
+ * If we had a modifier, which we interpreted ok, so now forward to the
+ * actual units.
+ */
+
+ if (modifier != TKINDEX_NONE) {
+ while (isspace(UCHAR(*p))) {
+ p++;
+ }
+ string = p;
+ while ((*p!='\0') && !isspace(UCHAR(*p)) && (*p!='+') && (*p!='-')) {
+ p++;
+ }
+ length = p - string;
+ }
+
if ((*string == 'l') && (strncmp(string, "lineend", length) == 0)
&& (length >= 5)) {
- indexPtr->byteIndex = 0;
- for (segPtr = indexPtr->linePtr->segPtr; segPtr != NULL;
- segPtr = segPtr->nextPtr) {
- indexPtr->byteIndex += segPtr->size;
+ if (modifier == TKINDEX_DISPLAY) {
+ TkTextFindDisplayLineEnd(textPtr, indexPtr, 1, NULL);
+ } else {
+ indexPtr->byteIndex = 0;
+ for (segPtr = indexPtr->linePtr->segPtr; segPtr != NULL;
+ segPtr = segPtr->nextPtr) {
+ indexPtr->byteIndex += segPtr->size;
+ }
+
+ /*
+ * We know '\n' is encoded with a single byte index.
+ */
+
+ indexPtr->byteIndex -= sizeof(char);
}
- indexPtr->byteIndex -= sizeof(char);
} else if ((*string == 'l') && (strncmp(string, "linestart", length) == 0)
&& (length >= 5)) {
- indexPtr->byteIndex = 0;
+ if (modifier == TKINDEX_DISPLAY) {
+ TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, NULL);
+ } else {
+ indexPtr->byteIndex = 0;
+ }
} else if ((*string == 'w') && (strncmp(string, "wordend", length) == 0)
&& (length >= 5)) {
int firstChar = 1;
+ int offset;
/*
* If the current character isn't part of a word then just move
- * forward one character. Otherwise move forward until finding
- * a character that isn't part of a word and stop there.
+ * forward one character. Otherwise move forward until finding a
+ * character that isn't part of a word and stop there.
*/
+ if (modifier == TKINDEX_DISPLAY) {
+ TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr,
+ COUNT_DISPLAY_INDICES);
+ }
segPtr = TkTextIndexToSeg(indexPtr, &offset);
while (1) {
+ int chSize = 1;
+
if (segPtr->typePtr == &tkTextCharType) {
- c = segPtr->body.chars[offset];
- if (!isalnum(UCHAR(c)) && (c != '_')) {
+ Tcl_UniChar ch;
+
+ chSize = Tcl_UtfToUniChar(segPtr->body.chars + offset, &ch);
+ if (!Tcl_UniCharIsWordChar(ch)) {
break;
}
firstChar = 0;
}
- offset += 1;
- indexPtr->byteIndex += sizeof(char);
+ offset += chSize;
+ indexPtr->byteIndex += chSize;
if (offset >= segPtr->size) {
segPtr = TkTextIndexToSeg(indexPtr, &offset);
}
}
if (firstChar) {
- TkTextIndexForwChars(indexPtr, 1, indexPtr);
+ if (modifier == TKINDEX_DISPLAY) {
+ TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr,
+ COUNT_DISPLAY_INDICES);
+ } else {
+ TkTextIndexForwChars(NULL, indexPtr, 1, indexPtr,
+ COUNT_INDICES);
+ }
}
} else if ((*string == 'w') && (strncmp(string, "wordstart", length) == 0)
&& (length >= 5)) {
int firstChar = 1;
+ int offset;
+
+ if (modifier == TKINDEX_DISPLAY) {
+ TkTextIndexForwChars(NULL, indexPtr, 0, indexPtr,
+ COUNT_DISPLAY_INDICES);
+ }
/*
- * Starting with the current character, look for one that's not
- * part of a word and keep moving backward until you find one.
- * Then if the character found wasn't the first one, move forward
- * again one position.
+ * Starting with the current character, look for one that's not part
+ * of a word and keep moving backward until you find one. Then if the
+ * character found wasn't the first one, move forward again one
+ * position.
*/
segPtr = TkTextIndexToSeg(indexPtr, &offset);
while (1) {
+ int chSize = 1;
+
if (segPtr->typePtr == &tkTextCharType) {
- c = segPtr->body.chars[offset];
- if (!isalnum(UCHAR(c)) && (c != '_')) {
+ Tcl_UniChar ch;
+
+ Tcl_UtfToUniChar(segPtr->body.chars + offset, &ch);
+ if (!Tcl_UniCharIsWordChar(ch)) {
break;
}
+ if (offset > 0) {
+ chSize = (segPtr->body.chars + offset
+ - Tcl_UtfPrev(segPtr->body.chars + offset,
+ segPtr->body.chars));
+ }
firstChar = 0;
}
- offset -= 1;
- indexPtr->byteIndex -= sizeof(char);
+ offset -= chSize;
+ indexPtr->byteIndex -= chSize;
if (offset < 0) {
if (indexPtr->byteIndex < 0) {
indexPtr->byteIndex = 0;
@@ -1192,12 +2292,28 @@ StartEnd(string, indexPtr)
segPtr = TkTextIndexToSeg(indexPtr, &offset);
}
}
+
if (!firstChar) {
- TkTextIndexForwChars(indexPtr, 1, indexPtr);
+ if (modifier == TKINDEX_DISPLAY) {
+ TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr,
+ COUNT_DISPLAY_INDICES);
+ } else {
+ TkTextIndexForwChars(NULL, indexPtr, 1, indexPtr,
+ COUNT_INDICES);
+ }
}
} else {
return NULL;
}
- done:
+
+ done:
return p;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkTextMark.c b/generic/tkTextMark.c
index c84bc9c..71a7949 100644
--- a/generic/tkTextMark.c
+++ b/generic/tkTextMark.c
@@ -1,19 +1,18 @@
-/*
+/*
* tkTextMark.c --
*
- * This file contains the procedure that implement marks for
- * text widgets.
+ * This file contains the functions that implement marks for text
+ * widgets.
*
* Copyright (c) 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
#include "tkText.h"
-#include "tkPort.h"
/*
* Macro that determines the size of a mark segment:
@@ -23,55 +22,53 @@
+ sizeof(TkTextMark)))
/*
- * Forward references for procedures defined in this file:
+ * Forward references for functions defined in this file:
*/
-static void InsertUndisplayProc _ANSI_ARGS_((TkText *textPtr,
- TkTextDispChunk *chunkPtr));
-static int MarkDeleteProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr, int treeGone));
-static TkTextSegment * MarkCleanupProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr));
-static void MarkCheckProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr));
-static int MarkLayoutProc _ANSI_ARGS_((TkText *textPtr,
- TkTextIndex *indexPtr, TkTextSegment *segPtr,
- int offset, int maxX, int maxChars,
- int noCharsYet, TkWrapMode wrapMode,
- TkTextDispChunk *chunkPtr));
-static int MarkFindNext _ANSI_ARGS_((Tcl_Interp *interp,
- TkText *textPtr, CONST char *markName));
-static int MarkFindPrev _ANSI_ARGS_((Tcl_Interp *interp,
- TkText *textPtr, CONST char *markName));
+static void InsertUndisplayProc(TkText *textPtr,
+ TkTextDispChunk *chunkPtr);
+static int MarkDeleteProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr, int treeGone);
+static TkTextSegment * MarkCleanupProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr);
+static void MarkCheckProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr);
+static int MarkLayoutProc(TkText *textPtr, TkTextIndex *indexPtr,
+ TkTextSegment *segPtr, int offset, int maxX,
+ int maxChars, int noCharsYet, TkWrapMode wrapMode,
+ TkTextDispChunk *chunkPtr);
+static int MarkFindNext(Tcl_Interp *interp,
+ TkText *textPtr, const char *markName);
+static int MarkFindPrev(Tcl_Interp *interp,
+ TkText *textPtr, const char *markName);
/*
- * The following structures declare the "mark" segment types.
- * There are actually two types for marks, one with left gravity
- * and one with right gravity. They are identical except for
- * their gravity property.
+ * The following structures declare the "mark" segment types. There are
+ * actually two types for marks, one with left gravity and one with right
+ * gravity. They are identical except for their gravity property.
*/
-Tk_SegType tkTextRightMarkType = {
- "mark", /* name */
- 0, /* leftGravity */
- (Tk_SegSplitProc *) NULL, /* splitProc */
- MarkDeleteProc, /* deleteProc */
- MarkCleanupProc, /* cleanupProc */
- (Tk_SegLineChangeProc *) NULL, /* lineChangeProc */
- MarkLayoutProc, /* layoutProc */
- MarkCheckProc /* checkProc */
+const Tk_SegType tkTextRightMarkType = {
+ "mark", /* name */
+ 0, /* leftGravity */
+ NULL, /* splitProc */
+ MarkDeleteProc, /* deleteProc */
+ MarkCleanupProc, /* cleanupProc */
+ NULL, /* lineChangeProc */
+ MarkLayoutProc, /* layoutProc */
+ MarkCheckProc /* checkProc */
};
-Tk_SegType tkTextLeftMarkType = {
- "mark", /* name */
- 1, /* leftGravity */
- (Tk_SegSplitProc *) NULL, /* splitProc */
- MarkDeleteProc, /* deleteProc */
- MarkCleanupProc, /* cleanupProc */
- (Tk_SegLineChangeProc *) NULL, /* lineChangeProc */
- MarkLayoutProc, /* layoutProc */
- MarkCheckProc /* checkProc */
+const Tk_SegType tkTextLeftMarkType = {
+ "mark", /* name */
+ 1, /* leftGravity */
+ NULL, /* splitProc */
+ MarkDeleteProc, /* deleteProc */
+ MarkCleanupProc, /* cleanupProc */
+ NULL, /* lineChangeProc */
+ MarkLayoutProc, /* layoutProc */
+ MarkCheckProc /* checkProc */
};
/*
@@ -79,9 +76,9 @@ Tk_SegType tkTextLeftMarkType = {
*
* TkTextMarkCmd --
*
- * This procedure is invoked to process the "mark" options of
- * the widget command for text widgets. See the user documentation
- * for details on what it does.
+ * This function is invoked to process the "mark" options of the widget
+ * command for text widgets. See the user documentation for details on
+ * what it does.
*
* Results:
* A standard Tcl result.
@@ -93,44 +90,62 @@ Tk_SegType tkTextLeftMarkType = {
*/
int
-TkTextMarkCmd(textPtr, interp, argc, argv)
- register TkText *textPtr; /* Information about text widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. Someone else has already
+TkTextMarkCmd(
+ register TkText *textPtr, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. Someone else has already
* parsed this command enough to know that
- * argv[1] is "mark". */
+ * objv[1] is "mark". */
{
- int c, i;
- size_t length;
Tcl_HashEntry *hPtr;
TkTextSegment *markPtr;
Tcl_HashSearch search;
TkTextIndex index;
- Tk_SegType *newTypePtr;
-
- if (argc < 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " mark option ?arg arg ...?\"", (char *) NULL);
+ const Tk_SegType *newTypePtr;
+ int optionIndex;
+ static const char *markOptionStrings[] = {
+ "gravity", "names", "next", "previous", "set", "unset", NULL
+ };
+ enum markOptions {
+ MARK_GRAVITY, MARK_NAMES, MARK_NEXT, MARK_PREVIOUS, MARK_SET,
+ MARK_UNSET
+ };
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], markOptionStrings, "mark option",
+ 0, &optionIndex) != TCL_OK) {
return TCL_ERROR;
}
- c = argv[2][0];
- length = strlen(argv[2]);
- if ((c == 'g') && (strncmp(argv[2], "gravity", length) == 0)) {
- if (argc < 4 || argc > 5) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " mark gravity markName ?gravity?\"",
- (char *) NULL);
+
+ switch ((enum markOptions) optionIndex) {
+ case MARK_GRAVITY: {
+ char c;
+ int length;
+ char *str;
+
+ if (objc < 4 || objc > 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "markName ?gravity?");
return TCL_ERROR;
}
- hPtr = Tcl_FindHashEntry(&textPtr->markTable, argv[3]);
- if (hPtr == NULL) {
- Tcl_AppendResult(interp, "there is no mark named \"",
- argv[3], "\"", (char *) NULL);
- return TCL_ERROR;
+ str = Tcl_GetStringFromObj(objv[3],&length);
+ if (length == 6 && !strcmp(str, "insert")) {
+ markPtr = textPtr->insertMarkPtr;
+ } else if (length == 7 && !strcmp(str, "current")) {
+ markPtr = textPtr->currentMarkPtr;
+ } else {
+ hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, str);
+ if (hPtr == NULL) {
+ Tcl_AppendResult(interp, "there is no mark named \"",
+ Tcl_GetString(objv[3]), "\"", NULL);
+ return TCL_ERROR;
+ }
+ markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
}
- markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
- if (argc == 4) {
+ if (objc == 4) {
if (markPtr->typePtr == &tkTextRightMarkType) {
Tcl_SetResult(interp, "right", TCL_STATIC);
} else {
@@ -138,77 +153,83 @@ TkTextMarkCmd(textPtr, interp, argc, argv)
}
return TCL_OK;
}
- length = strlen(argv[4]);
- c = argv[4][0];
- if ((c == 'l') && (strncmp(argv[4], "left", length) == 0)) {
+ str = Tcl_GetStringFromObj(objv[4],&length);
+ c = str[0];
+ if ((c == 'l') && (strncmp(str, "left", (unsigned)length) == 0)) {
newTypePtr = &tkTextLeftMarkType;
- } else if ((c == 'r') && (strncmp(argv[4], "right", length) == 0)) {
+ } else if ((c == 'r') &&
+ (strncmp(str, "right", (unsigned)length) == 0)) {
newTypePtr = &tkTextRightMarkType;
} else {
- Tcl_AppendResult(interp, "bad mark gravity \"",
- argv[4], "\": must be left or right", (char *) NULL);
+ Tcl_AppendResult(interp, "bad mark gravity \"", str,
+ "\": must be left or right", NULL);
return TCL_ERROR;
}
TkTextMarkSegToIndex(textPtr, markPtr, &index);
- TkBTreeUnlinkSegment(textPtr->tree, markPtr,
- markPtr->body.mark.linePtr);
+ TkBTreeUnlinkSegment(markPtr, markPtr->body.mark.linePtr);
markPtr->typePtr = newTypePtr;
TkBTreeLinkSegment(markPtr, &index);
- } else if ((c == 'n') && (strncmp(argv[2], "names", length) == 0)) {
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " mark names\"", (char *) NULL);
+ break;
+ }
+ case MARK_NAMES:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
- for (hPtr = Tcl_FirstHashEntry(&textPtr->markTable, &search);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+ Tcl_AppendElement(interp, "insert");
+ Tcl_AppendElement(interp, "current");
+ for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->markTable,
+ &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
Tcl_AppendElement(interp,
- Tcl_GetHashKey(&textPtr->markTable, hPtr));
+ Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr));
}
- } else if ((c == 'n') && (strncmp(argv[2], "next", length) == 0)) {
- if (argc != 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " mark next index\"", (char *) NULL);
+ break;
+ case MARK_NEXT:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index");
return TCL_ERROR;
}
- return MarkFindNext(interp, textPtr, argv[3]);
- } else if ((c == 'p') && (strncmp(argv[2], "previous", length) == 0)) {
- if (argc != 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " mark previous index\"", (char *) NULL);
+ return MarkFindNext(interp, textPtr, Tcl_GetString(objv[3]));
+ case MARK_PREVIOUS:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index");
return TCL_ERROR;
}
- return MarkFindPrev(interp, textPtr, argv[3]);
- } else if ((c == 's') && (strncmp(argv[2], "set", length) == 0)) {
- if (argc != 5) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " mark set markName index\"", (char *) NULL);
+ return MarkFindPrev(interp, textPtr, Tcl_GetString(objv[3]));
+ case MARK_SET:
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "markName index");
return TCL_ERROR;
}
- if (TkTextGetIndex(interp, textPtr, argv[4], &index) != TCL_OK) {
+ if (TkTextGetObjIndex(interp, textPtr, objv[4], &index) != TCL_OK) {
return TCL_ERROR;
}
- TkTextSetMark(textPtr, argv[3], &index);
- } else if ((c == 'u') && (strncmp(argv[2], "unset", length) == 0)) {
- for (i = 3; i < argc; i++) {
- hPtr = Tcl_FindHashEntry(&textPtr->markTable, argv[i]);
+ TkTextSetMark(textPtr, Tcl_GetString(objv[3]), &index);
+ return TCL_OK;
+ case MARK_UNSET: {
+ int i;
+
+ for (i = 3; i < objc; i++) {
+ hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable,
+ Tcl_GetString(objv[i]));
if (hPtr != NULL) {
markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+
+ /*
+ * Special case not needed with peer widgets.
+ */
+
if ((markPtr == textPtr->insertMarkPtr)
|| (markPtr == textPtr->currentMarkPtr)) {
continue;
}
- TkBTreeUnlinkSegment(textPtr->tree, markPtr,
- markPtr->body.mark.linePtr);
+ TkBTreeUnlinkSegment(markPtr, markPtr->body.mark.linePtr);
Tcl_DeleteHashEntry(hPtr);
ckfree((char *) markPtr);
}
}
- } else {
- Tcl_AppendResult(interp, "bad mark option \"", argv[2],
- "\": must be gravity, names, next, previous, set, or unset",
- (char *) NULL);
- return TCL_ERROR;
+ break;
+ }
}
return TCL_OK;
}
@@ -218,8 +239,8 @@ TkTextMarkCmd(textPtr, interp, argc, argv)
*
* TkTextSetMark --
*
- * Set a mark to a particular position, creating a new mark if
- * one doesn't already exist.
+ * Set a mark to a particular position, creating a new mark if one
+ * doesn't already exist.
*
* Results:
* The return value is a pointer to the mark that was just set.
@@ -231,39 +252,67 @@ TkTextMarkCmd(textPtr, interp, argc, argv)
*/
TkTextSegment *
-TkTextSetMark(textPtr, name, indexPtr)
- TkText *textPtr; /* Text widget in which to create mark. */
- CONST char *name; /* Name of mark to set. */
- TkTextIndex *indexPtr; /* Where to set mark. */
+TkTextSetMark(
+ TkText *textPtr, /* Text widget in which to create mark. */
+ const char *name, /* Name of mark to set. */
+ TkTextIndex *indexPtr) /* Where to set mark. */
{
- Tcl_HashEntry *hPtr;
+ Tcl_HashEntry *hPtr = NULL;
TkTextSegment *markPtr;
TkTextIndex insertIndex;
- int new;
-
- hPtr = Tcl_CreateHashEntry(&textPtr->markTable, name, &new);
- markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
- if (!new) {
+ int isNew, widgetSpecific;
+
+ if (!strcmp(name, "insert")) {
+ widgetSpecific = 1;
+ markPtr = textPtr->insertMarkPtr;
+ isNew = (markPtr == NULL ? 1 : 0);
+ } else if (!strcmp(name, "current")) {
+ widgetSpecific = 2;
+ markPtr = textPtr->currentMarkPtr;
+ isNew = (markPtr == NULL ? 1 : 0);
+ } else {
+ widgetSpecific = 0;
+ hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->markTable, name,
+ &isNew);
+ markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+ }
+ if (!isNew) {
/*
- * If this is the insertion point that's being moved, be sure
- * to force a display update at the old position. Also, don't
- * let the insertion cursor be after the final newline of the
- * file.
+ * If this is the insertion point that's being moved, be sure to force
+ * a display update at the old position. Also, don't let the insertion
+ * cursor be after the final newline of the file.
*/
if (markPtr == textPtr->insertMarkPtr) {
TkTextIndex index, index2;
+ int nblines;
+
TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
- TkTextIndexForwChars(&index, 1, &index2);
- TkTextChanged(textPtr, &index, &index2);
- if (TkBTreeLineIndex(indexPtr->linePtr)
- == TkBTreeNumLines(textPtr->tree)) {
- TkTextIndexBackChars(indexPtr, 1, &insertIndex);
+ TkTextIndexForwChars(NULL,&index, 1, &index2, COUNT_INDICES);
+
+ /*
+ * While we wish to redisplay, no heights have changed, so no need
+ * to call TkTextInvalidateLineMetrics.
+ */
+
+ TkTextChanged(NULL, textPtr, &index, &index2);
+
+ /*
+ * The number of lines in the widget is zero if and only if it is
+ * a partial peer with -startline == -endline, i.e. an empty
+ * peer. In this case the mark shall be set exactly at the given
+ * index, and not one character backwards (bug 3487407).
+ */
+
+ nblines = TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr);
+ if ((TkBTreeLinesTo(textPtr, indexPtr->linePtr) == nblines)
+ && (nblines > 0)) {
+ TkTextIndexBackChars(NULL,indexPtr, 1, &insertIndex,
+ COUNT_INDICES);
indexPtr = &insertIndex;
}
}
- TkBTreeUnlinkSegment(textPtr->tree, markPtr,
- markPtr->body.mark.linePtr);
+ TkBTreeUnlinkSegment(markPtr, markPtr->body.mark.linePtr);
} else {
markPtr = (TkTextSegment *) ckalloc(MSEG_SIZE);
markPtr->typePtr = &tkTextRightMarkType;
@@ -271,7 +320,13 @@ TkTextSetMark(textPtr, name, indexPtr)
markPtr->body.mark.textPtr = textPtr;
markPtr->body.mark.linePtr = indexPtr->linePtr;
markPtr->body.mark.hPtr = hPtr;
- Tcl_SetHashValue(hPtr, markPtr);
+ if (widgetSpecific == 0) {
+ Tcl_SetHashValue(hPtr, markPtr);
+ } else if (widgetSpecific == 1) {
+ textPtr->insertMarkPtr = markPtr;
+ } else {
+ textPtr->currentMarkPtr = markPtr;
+ }
}
TkBTreeLinkSegment(markPtr, indexPtr);
@@ -283,8 +338,14 @@ TkTextSetMark(textPtr, name, indexPtr)
if (markPtr == textPtr->insertMarkPtr) {
TkTextIndex index2;
- TkTextIndexForwChars(indexPtr, 1, &index2);
- TkTextChanged(textPtr, indexPtr, &index2);
+ TkTextIndexForwChars(NULL,indexPtr, 1, &index2, COUNT_INDICES);
+
+ /*
+ * While we wish to redisplay, no heights have changed, so no need to
+ * call TkTextInvalidateLineMetrics
+ */
+
+ TkTextChanged(NULL, textPtr, indexPtr, &index2);
}
return markPtr;
}
@@ -294,9 +355,9 @@ TkTextSetMark(textPtr, name, indexPtr)
*
* TkTextMarkSegToIndex --
*
- * Given a segment that is a mark, create an index that
- * refers to the next text character (or other text segment
- * with non-zero size) after the mark.
+ * Given a segment that is a mark, create an index that refers to the
+ * next text character (or other text segment with non-zero size) after
+ * the mark.
*
* Results:
* *IndexPtr is filled in with index information.
@@ -308,14 +369,14 @@ TkTextSetMark(textPtr, name, indexPtr)
*/
void
-TkTextMarkSegToIndex(textPtr, markPtr, indexPtr)
- TkText *textPtr; /* Text widget containing mark. */
- TkTextSegment *markPtr; /* Mark segment. */
- TkTextIndex *indexPtr; /* Index information gets stored here. */
+TkTextMarkSegToIndex(
+ TkText *textPtr, /* Text widget containing mark. */
+ TkTextSegment *markPtr, /* Mark segment. */
+ TkTextIndex *indexPtr) /* Index information gets stored here. */
{
TkTextSegment *segPtr;
- indexPtr->tree = textPtr->tree;
+ indexPtr->tree = textPtr->sharedTextPtr->tree;
indexPtr->linePtr = markPtr->body.mark.linePtr;
indexPtr->byteIndex = 0;
for (segPtr = indexPtr->linePtr->segPtr; segPtr != markPtr;
@@ -329,15 +390,20 @@ TkTextMarkSegToIndex(textPtr, markPtr, indexPtr)
*
* TkTextMarkNameToIndex --
*
- * Given the name of a mark, return an index corresponding
- * to the mark name.
+ * Given the name of a mark, return an index corresponding to the mark
+ * name.
*
* Results:
- * The return value is TCL_OK if "name" exists as a mark in
- * the text widget. In this case *indexPtr is filled in with
- * the next segment whose after the mark whose size is
- * non-zero. TCL_ERROR is returned if the mark doesn't exist
- * in the text widget.
+ * The return value is TCL_OK if "name" exists as a mark in the text
+ * widget and is located within its -starline/-endline range. In this
+ * case *indexPtr is filled in with the next segment who is after the
+ * mark whose size is non-zero. TCL_ERROR is returned if the mark
+ * doesn't exist in the text widget, or if it is out of its -starline/
+ * -endline range. In this latter case *indexPtr still contains valid
+ * information, in particular TkTextMarkNameToIndex called with the
+ * "insert" or "current" mark name may return TCL_ERROR, but *indexPtr
+ * contains the correct index of this mark before -startline or after
+ * -endline.
*
* Side effects:
* None.
@@ -346,19 +412,55 @@ TkTextMarkSegToIndex(textPtr, markPtr, indexPtr)
*/
int
-TkTextMarkNameToIndex(textPtr, name, indexPtr)
- TkText *textPtr; /* Text widget containing mark. */
- CONST char *name; /* Name of mark. */
- TkTextIndex *indexPtr; /* Index information gets stored here. */
+TkTextMarkNameToIndex(
+ TkText *textPtr, /* Text widget containing mark. */
+ const char *name, /* Name of mark. */
+ TkTextIndex *indexPtr) /* Index information gets stored here. */
{
- Tcl_HashEntry *hPtr;
+ TkTextSegment *segPtr;
+ TkTextIndex index;
+ int start, end;
- hPtr = Tcl_FindHashEntry(&textPtr->markTable, name);
- if (hPtr == NULL) {
- return TCL_ERROR;
+ if (textPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ if (!strcmp(name, "insert")) {
+ segPtr = textPtr->insertMarkPtr;
+ } else if (!strcmp(name, "current")) {
+ segPtr = textPtr->currentMarkPtr;
+ } else {
+ Tcl_HashEntry *hPtr;
+ hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, name);
+ if (hPtr == NULL) {
+ return TCL_ERROR;
+ }
+ segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+ }
+ TkTextMarkSegToIndex(textPtr, segPtr, indexPtr);
+
+ /* If indexPtr refers to somewhere outside the -startline/-endline
+ * range limits of the widget, error out since the mark indeed is not
+ * reachable from this text widget (it may be reachable from a peer)
+ * (bug 1630271).
+ */
+
+ if (textPtr->start != NULL) {
+ start = TkBTreeLinesTo(NULL, textPtr->start);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, start, 0,
+ &index);
+ if (TkTextIndexCmp(indexPtr, &index) < 0) {
+ return TCL_ERROR;
+ }
+ }
+ if (textPtr->end != NULL) {
+ end = TkBTreeLinesTo(NULL, textPtr->end);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, end, 0,
+ &index);
+ if (TkTextIndexCmp(indexPtr, &index) > 0) {
+ return TCL_ERROR;
+ }
}
- TkTextMarkSegToIndex(textPtr, (TkTextSegment *) Tcl_GetHashValue(hPtr),
- indexPtr);
return TCL_OK;
}
@@ -367,27 +469,27 @@ TkTextMarkNameToIndex(textPtr, name, indexPtr)
*
* MarkDeleteProc --
*
- * This procedure is invoked by the text B-tree code whenever
- * a mark lies in a range of characters being deleted.
+ * This function is invoked by the text B-tree code whenever a mark lies
+ * in a range of characters being deleted.
*
* Results:
* Returns 1 to indicate that deletion has been rejected.
*
* Side effects:
- * None (even if the whole tree is being deleted we don't
- * free up the mark; it will be done elsewhere).
+ * None (even if the whole tree is being deleted we don't free up the
+ * mark; it will be done elsewhere).
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static int
-MarkDeleteProc(segPtr, linePtr, treeGone)
- TkTextSegment *segPtr; /* Segment being deleted. */
- TkTextLine *linePtr; /* Line containing segment. */
- int treeGone; /* Non-zero means the entire tree is
- * being deleted, so everything must
- * get cleaned up. */
+MarkDeleteProc(
+ TkTextSegment *segPtr, /* Segment being deleted. */
+ TkTextLine *linePtr, /* Line containing segment. */
+ int treeGone) /* Non-zero means the entire tree is being
+ * deleted, so everything must get cleaned
+ * up. */
{
return 1;
}
@@ -397,8 +499,8 @@ MarkDeleteProc(segPtr, linePtr, treeGone)
*
* MarkCleanupProc --
*
- * This procedure is invoked by the B-tree code whenever a
- * mark segment is moved from one line to another.
+ * This function is invoked by the B-tree code whenever a mark segment is
+ * moved from one line to another.
*
* Results:
* None.
@@ -410,9 +512,9 @@ MarkDeleteProc(segPtr, linePtr, treeGone)
*/
static TkTextSegment *
-MarkCleanupProc(markPtr, linePtr)
- TkTextSegment *markPtr; /* Mark segment that's being moved. */
- TkTextLine *linePtr; /* Line that now contains segment. */
+MarkCleanupProc(
+ TkTextSegment *markPtr, /* Mark segment that's being moved. */
+ TkTextLine *linePtr) /* Line that now contains segment. */
{
markPtr->body.mark.linePtr = linePtr;
return markPtr;
@@ -423,13 +525,13 @@ MarkCleanupProc(markPtr, linePtr)
*
* MarkLayoutProc --
*
- * This procedure is the "layoutProc" for mark segments.
+ * This function is the "layoutProc" for mark segments.
*
* Results:
- * If the mark isn't the insertion cursor then the return
- * value is -1 to indicate that this segment shouldn't be
- * displayed. If the mark is the insertion character then
- * 1 is returned and the chunkPtr structure is filled in.
+ * If the mark isn't the insertion cursor then the return value is -1 to
+ * indicate that this segment shouldn't be displayed. If the mark is the
+ * insertion character then 1 is returned and the chunkPtr structure is
+ * filled in.
*
* Side effects:
* None, except for filling in chunkPtr.
@@ -437,26 +539,24 @@ MarkCleanupProc(markPtr, linePtr)
*--------------------------------------------------------------
*/
- /*ARGSUSED*/
static int
-MarkLayoutProc(textPtr, indexPtr, segPtr, offset, maxX, maxChars,
- noCharsYet, wrapMode, chunkPtr)
- TkText *textPtr; /* Text widget being layed out. */
- TkTextIndex *indexPtr; /* Identifies first character in chunk. */
- TkTextSegment *segPtr; /* Segment corresponding to indexPtr. */
- int offset; /* Offset within segPtr corresponding to
+MarkLayoutProc(
+ TkText *textPtr, /* Text widget being layed out. */
+ TkTextIndex *indexPtr, /* Identifies first character in chunk. */
+ TkTextSegment *segPtr, /* Segment corresponding to indexPtr. */
+ int offset, /* Offset within segPtr corresponding to
* indexPtr (always 0). */
- int maxX; /* Chunk must not occupy pixels at this
+ int maxX, /* Chunk must not occupy pixels at this
* position or higher. */
- int maxChars; /* Chunk must not include more than this
- * many characters. */
- int noCharsYet; /* Non-zero means no characters have been
+ int maxChars, /* Chunk must not include more than this many
+ * characters. */
+ int noCharsYet, /* Non-zero means no characters have been
* assigned to this line yet. */
- TkWrapMode wrapMode; /* Not used. */
- register TkTextDispChunk *chunkPtr;
- /* Structure to fill in with information
- * about this chunk. The x field has already
- * been set by the caller. */
+ TkWrapMode wrapMode, /* Not used. */
+ register TkTextDispChunk *chunkPtr)
+ /* Structure to fill in with information about
+ * this chunk. The x field has already been
+ * set by the caller. */
{
if (segPtr != textPtr->insertMarkPtr) {
return -1;
@@ -464,8 +564,8 @@ MarkLayoutProc(textPtr, indexPtr, segPtr, offset, maxX, maxChars,
chunkPtr->displayProc = TkTextInsertDisplayProc;
chunkPtr->undisplayProc = InsertUndisplayProc;
- chunkPtr->measureProc = (Tk_ChunkMeasureProc *) NULL;
- chunkPtr->bboxProc = (Tk_ChunkBboxProc *) NULL;
+ chunkPtr->measureProc = NULL;
+ chunkPtr->bboxProc = NULL;
chunkPtr->numBytes = 0;
chunkPtr->minAscent = 0;
chunkPtr->minDescent = 0;
@@ -473,9 +573,8 @@ MarkLayoutProc(textPtr, indexPtr, segPtr, offset, maxX, maxChars,
chunkPtr->width = 0;
/*
- * Note: can't break a line after the insertion cursor: this
- * prevents the insertion cursor from being stranded at the end
- * of a line.
+ * Note: can't break a line after the insertion cursor: this prevents the
+ * insertion cursor from being stranded at the end of a line.
*/
chunkPtr->breakIndex = -1;
@@ -488,8 +587,7 @@ MarkLayoutProc(textPtr, indexPtr, segPtr, offset, maxX, maxChars,
*
* TkTextInsertDisplayProc --
*
- * This procedure is called to display the insertion
- * cursor.
+ * This function is called to display the insertion cursor.
*
* Results:
* None.
@@ -502,30 +600,43 @@ MarkLayoutProc(textPtr, indexPtr, segPtr, offset, maxX, maxChars,
/* ARGSUSED */
void
-TkTextInsertDisplayProc(chunkPtr, x, y, height, baseline, display, dst, screenY)
- TkTextDispChunk *chunkPtr; /* Chunk that is to be drawn. */
- int x; /* X-position in dst at which to
- * draw this chunk (may differ from
- * the x-position in the chunk because
- * of scrolling). */
- int y; /* Y-position at which to draw this
- * chunk in dst (x-position is in
- * the chunk itself). */
- int height; /* Total height of line. */
- int baseline; /* Offset of baseline from y. */
- Display *display; /* Display to use for drawing. */
- Drawable dst; /* Pixmap or window in which to draw
- * chunk. */
- int screenY; /* Y-coordinate in text window that
- * corresponds to y. */
+TkTextInsertDisplayProc(
+ TkText *textPtr, /* The current text widget. */
+ TkTextDispChunk *chunkPtr, /* Chunk that is to be drawn. */
+ int x, /* X-position in dst at which to draw this
+ * chunk (may differ from the x-position in
+ * the chunk because of scrolling). */
+ int y, /* Y-position at which to draw this chunk in
+ * dst (x-position is in the chunk itself). */
+ int height, /* Total height of line. */
+ int baseline, /* Offset of baseline from y. */
+ Display *display, /* Display to use for drawing. */
+ Drawable dst, /* Pixmap or window in which to draw chunk. */
+ int screenY) /* Y-coordinate in text window that
+ * corresponds to y. */
{
- TkText *textPtr = (TkText *) chunkPtr->clientData;
+ /*
+ * We have no need for the clientData.
+ */
+
+ /* TkText *textPtr = (TkText *) chunkPtr->clientData; */
+ TkTextIndex index;
int halfWidth = textPtr->insertWidth/2;
+ int rightSideWidth;
+ int ix = 0, iy = 0, iw = 0, ih = 0, charWidth = 0;
+
+ if(textPtr->insertCursorType) {
+ TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
+ TkTextIndexBbox(textPtr, &index, &ix, &iy, &iw, &ih, &charWidth);
+ rightSideWidth = charWidth + halfWidth;
+ } else {
+ rightSideWidth = halfWidth;
+ }
- if ((x + halfWidth) < 0) {
+ if ((x + rightSideWidth) < 0) {
/*
- * The insertion cursor is off-screen.
- * Indicate caret at 0,0 and return.
+ * The insertion cursor is off-screen. Indicate caret at 0,0 and
+ * return.
*/
Tk_SetCaretPos(textPtr->tkwin, 0, 0, height);
@@ -535,20 +646,20 @@ TkTextInsertDisplayProc(chunkPtr, x, y, height, baseline, display, dst, screenY)
Tk_SetCaretPos(textPtr->tkwin, x - halfWidth, screenY, height);
/*
- * As a special hack to keep the cursor visible on mono displays
- * (or anywhere else that the selection and insertion cursors
- * have the same color) write the default background in the cursor
- * area (instead of nothing) when the cursor isn't on. Otherwise
- * the selection might hide the cursor.
+ * As a special hack to keep the cursor visible on mono displays (or
+ * anywhere else that the selection and insertion cursors have the same
+ * color) write the default background in the cursor area (instead of
+ * nothing) when the cursor isn't on. Otherwise the selection might hide
+ * the cursor.
*/
if (textPtr->flags & INSERT_ON) {
Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder,
- x - halfWidth, y, textPtr->insertWidth, height,
+ x - halfWidth, y, charWidth + textPtr->insertWidth, height,
textPtr->insertBorderWidth, TK_RELIEF_RAISED);
} else if (textPtr->selBorder == textPtr->insertBorder) {
Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->border,
- x - halfWidth, y, textPtr->insertWidth, height,
+ x - halfWidth, y, charWidth + textPtr->insertWidth, height,
0, TK_RELIEF_FLAT);
}
}
@@ -558,9 +669,8 @@ TkTextInsertDisplayProc(chunkPtr, x, y, height, baseline, display, dst, screenY)
*
* InsertUndisplayProc --
*
- * This procedure is called when the insertion cursor is no
- * longer at a visible point on the display. It does nothing
- * right now.
+ * This function is called when the insertion cursor is no longer at a
+ * visible point on the display. It does nothing right now.
*
* Results:
* None.
@@ -573,10 +683,9 @@ TkTextInsertDisplayProc(chunkPtr, x, y, height, baseline, display, dst, screenY)
/* ARGSUSED */
static void
-InsertUndisplayProc(textPtr, chunkPtr)
- TkText *textPtr; /* Overall information about text
- * widget. */
- TkTextDispChunk *chunkPtr; /* Chunk that is about to be freed. */
+InsertUndisplayProc(
+ TkText *textPtr, /* Overall information about text widget. */
+ TkTextDispChunk *chunkPtr) /* Chunk that is about to be freed. */
{
return;
}
@@ -586,41 +695,52 @@ InsertUndisplayProc(textPtr, chunkPtr)
*
* MarkCheckProc --
*
- * This procedure is invoked by the B-tree code to perform
- * consistency checks on mark segments.
+ * This function is invoked by the B-tree code to perform consistency
+ * checks on mark segments.
*
* Results:
* None.
*
* Side effects:
- * The procedure panics if it detects anything wrong with
+ * The function panics if it detects anything wrong with
* the mark.
*
*--------------------------------------------------------------
*/
static void
-MarkCheckProc(markPtr, linePtr)
- TkTextSegment *markPtr; /* Segment to check. */
- TkTextLine *linePtr; /* Line containing segment. */
+MarkCheckProc(
+ TkTextSegment *markPtr, /* Segment to check. */
+ TkTextLine *linePtr) /* Line containing segment. */
{
Tcl_HashSearch search;
Tcl_HashEntry *hPtr;
if (markPtr->body.mark.linePtr != linePtr) {
- panic("MarkCheckProc: markPtr->body.mark.linePtr bogus");
+ Tcl_Panic("MarkCheckProc: markPtr->body.mark.linePtr bogus");
}
/*
- * Make sure that the mark is still present in the text's mark
- * hash table.
+ * These two marks are not in the hash table
*/
- for (hPtr = Tcl_FirstHashEntry(&markPtr->body.mark.textPtr->markTable,
+ if (markPtr->body.mark.textPtr->insertMarkPtr == markPtr) {
+ return;
+ }
+ if (markPtr->body.mark.textPtr->currentMarkPtr == markPtr) {
+ return;
+ }
+
+ /*
+ * Make sure that the mark is still present in the text's mark hash table.
+ */
+
+ for (hPtr = Tcl_FirstHashEntry(
+ &markPtr->body.mark.textPtr->sharedTextPtr->markTable,
&search); hPtr != markPtr->body.mark.hPtr;
hPtr = Tcl_NextHashEntry(&search)) {
if (hPtr == NULL) {
- panic("MarkCheckProc couldn't find hash table entry for mark");
+ Tcl_Panic("MarkCheckProc couldn't find hash table entry for mark");
}
}
}
@@ -630,7 +750,7 @@ MarkCheckProc(markPtr, linePtr)
*
* MarkFindNext --
*
- * This procedure searches forward for the next mark.
+ * This function searches forward for the next mark.
*
* Results:
* A standard Tcl result, which is a mark name or an empty string.
@@ -642,56 +762,88 @@ MarkCheckProc(markPtr, linePtr)
*/
static int
-MarkFindNext(interp, textPtr, string)
- Tcl_Interp *interp; /* For error reporting */
- TkText *textPtr; /* The widget */
- CONST char *string; /* The starting index or mark name */
+MarkFindNext(
+ Tcl_Interp *interp, /* For error reporting */
+ TkText *textPtr, /* The widget */
+ const char *string) /* The starting index or mark name */
{
TkTextIndex index;
Tcl_HashEntry *hPtr;
register TkTextSegment *segPtr;
int offset;
-
- hPtr = Tcl_FindHashEntry(&textPtr->markTable, string);
- if (hPtr != NULL) {
- /*
- * If given a mark name, return the next mark in the list of
- * segments, even if it happens to be at the same character position.
- */
- segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+ if (!strcmp(string, "insert")) {
+ segPtr = textPtr->insertMarkPtr;
+ TkTextMarkSegToIndex(textPtr, segPtr, &index);
+ segPtr = segPtr->nextPtr;
+ } else if (!strcmp(string, "current")) {
+ segPtr = textPtr->currentMarkPtr;
TkTextMarkSegToIndex(textPtr, segPtr, &index);
segPtr = segPtr->nextPtr;
} else {
- /*
- * For non-mark name indices we want to return any marks that
- * are right at the index.
- */
- if (TkTextGetIndex(interp, textPtr, string, &index) != TCL_OK) {
- return TCL_ERROR;
- }
- for (offset = 0, segPtr = index.linePtr->segPtr;
- segPtr != NULL && offset < index.byteIndex;
- offset += segPtr->size, segPtr = segPtr->nextPtr) {
- /* Empty loop body */ ;
+ hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, string);
+ if (hPtr != NULL) {
+ /*
+ * If given a mark name, return the next mark in the list of
+ * segments, even if it happens to be at the same character
+ * position.
+ */
+
+ segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+ TkTextMarkSegToIndex(textPtr, segPtr, &index);
+ segPtr = segPtr->nextPtr;
+ } else {
+ /*
+ * For non-mark name indices we want to return any marks that are
+ * right at the index.
+ */
+
+ if (TkTextGetIndex(interp, textPtr, string, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ for (offset = 0, segPtr = index.linePtr->segPtr;
+ segPtr != NULL && offset < index.byteIndex;
+ offset += segPtr->size, segPtr = segPtr->nextPtr) {
+ /* Empty loop body */ ;
+ }
}
}
+
while (1) {
/*
- * segPtr points at the first possible candidate,
- * or NULL if we ran off the end of the line.
+ * segPtr points at the first possible candidate, or NULL if we ran
+ * off the end of the line.
*/
+
for ( ; segPtr != NULL ; segPtr = segPtr->nextPtr) {
if (segPtr->typePtr == &tkTextRightMarkType ||
segPtr->typePtr == &tkTextLeftMarkType) {
- Tcl_SetResult(interp,
- Tcl_GetHashKey(&textPtr->markTable, segPtr->body.mark.hPtr),
- TCL_STATIC);
+ if (segPtr == textPtr->currentMarkPtr) {
+ Tcl_SetResult(interp, "current", TCL_STATIC);
+ } else if (segPtr == textPtr->insertMarkPtr) {
+ Tcl_SetResult(interp, "insert", TCL_STATIC);
+ } else if (segPtr->body.mark.hPtr == NULL) {
+ /*
+ * Ignore widget-specific marks for the other widgets.
+ * This is either an insert or a current mark
+ * (markPtr->body.mark.hPtr actually receives NULL
+ * for these marks in TkTextSetMark).
+ * The insert and current marks for textPtr having
+ * already been tested above, the current segment is
+ * an insert or current mark from a peer of textPtr,
+ * which we don't want to return.
+ */
+ continue;
+ } else {
+ Tcl_SetResult(interp,
+ Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable,
+ segPtr->body.mark.hPtr), TCL_STATIC);
+ }
return TCL_OK;
}
}
- index.linePtr = TkBTreeNextLine(index.linePtr);
- if (index.linePtr == (TkTextLine *) NULL) {
+ index.linePtr = TkBTreeNextLine(textPtr, index.linePtr);
+ if (index.linePtr == NULL) {
return TCL_OK;
}
index.byteIndex = 0;
@@ -704,7 +856,7 @@ MarkFindNext(interp, textPtr, string)
*
* MarkFindPrev --
*
- * This procedure searches backwards for the previous mark.
+ * This function searches backwards for the previous mark.
*
* Results:
* A standard Tcl result, which is a mark name or an empty string.
@@ -716,62 +868,111 @@ MarkFindNext(interp, textPtr, string)
*/
static int
-MarkFindPrev(interp, textPtr, string)
- Tcl_Interp *interp; /* For error reporting */
- TkText *textPtr; /* The widget */
- CONST char *string; /* The starting index or mark name */
+MarkFindPrev(
+ Tcl_Interp *interp, /* For error reporting */
+ TkText *textPtr, /* The widget */
+ const char *string) /* The starting index or mark name */
{
TkTextIndex index;
Tcl_HashEntry *hPtr;
register TkTextSegment *segPtr, *seg2Ptr, *prevPtr;
int offset;
-
- hPtr = Tcl_FindHashEntry(&textPtr->markTable, string);
- if (hPtr != NULL) {
- /*
- * If given a mark name, return the previous mark in the list of
- * segments, even if it happens to be at the same character position.
- */
- segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+ if (!strcmp(string, "insert")) {
+ segPtr = textPtr->insertMarkPtr;
+ TkTextMarkSegToIndex(textPtr, segPtr, &index);
+ } else if (!strcmp(string, "current")) {
+ segPtr = textPtr->currentMarkPtr;
TkTextMarkSegToIndex(textPtr, segPtr, &index);
} else {
- /*
- * For non-mark name indices we do not return any marks that
- * are right at the index.
- */
- if (TkTextGetIndex(interp, textPtr, string, &index) != TCL_OK) {
- return TCL_ERROR;
- }
- for (offset = 0, segPtr = index.linePtr->segPtr;
- segPtr != NULL && offset < index.byteIndex;
- offset += segPtr->size, segPtr = segPtr->nextPtr) {
- /* Empty loop body */ ;
+ hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, string);
+ if (hPtr != NULL) {
+ /*
+ * If given a mark name, return the previous mark in the list of
+ * segments, even if it happens to be at the same character
+ * position.
+ */
+
+ segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+ TkTextMarkSegToIndex(textPtr, segPtr, &index);
+ } else {
+ /*
+ * For non-mark name indices we do not return any marks that are
+ * right at the index.
+ */
+
+ if (TkTextGetIndex(interp, textPtr, string, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ for (offset = 0, segPtr = index.linePtr->segPtr;
+ segPtr != NULL && offset < index.byteIndex;
+ offset += segPtr->size, segPtr = segPtr->nextPtr) {
+ /* Empty loop body */
+ }
}
}
+
while (1) {
/*
- * segPtr points just past the first possible candidate,
- * or at the begining of the line.
+ * segPtr points just past the first possible candidate, or at the
+ * beginning of the line.
*/
- for (prevPtr = NULL, seg2Ptr = index.linePtr->segPtr;
+
+ for (prevPtr = NULL, seg2Ptr = index.linePtr->segPtr;
seg2Ptr != NULL && seg2Ptr != segPtr;
seg2Ptr = seg2Ptr->nextPtr) {
if (seg2Ptr->typePtr == &tkTextRightMarkType ||
seg2Ptr->typePtr == &tkTextLeftMarkType) {
+ if (seg2Ptr->body.mark.hPtr == NULL) {
+ if (seg2Ptr != textPtr->currentMarkPtr &&
+ seg2Ptr != textPtr->insertMarkPtr) {
+ /*
+ * This is an insert or current mark from a
+ * peer of textPtr.
+ */
+ continue;
+ }
+ }
prevPtr = seg2Ptr;
}
}
if (prevPtr != NULL) {
- Tcl_SetResult(interp,
- Tcl_GetHashKey(&textPtr->markTable, prevPtr->body.mark.hPtr),
- TCL_STATIC);
- return TCL_OK;
+ if (prevPtr == textPtr->currentMarkPtr) {
+ Tcl_SetResult(interp, "current", TCL_STATIC);
+ return TCL_OK;
+ } else if (prevPtr == textPtr->insertMarkPtr) {
+ Tcl_SetResult(interp, "insert", TCL_STATIC);
+ return TCL_OK;
+ } else if (prevPtr->body.mark.hPtr == NULL) {
+ /*
+ * Ignore widget-specific marks for the other widgets.
+ * This is either an insert or a current mark
+ * (markPtr->body.mark.hPtr actually receives NULL
+ * for these marks in TkTextSetMark).
+ * The insert and current marks for textPtr having
+ * already been tested above, the current segment is
+ * an insert or current mark from a peer of textPtr,
+ * which we don't want to return.
+ */
+ } else {
+ Tcl_SetResult(interp,
+ Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable,
+ prevPtr->body.mark.hPtr), TCL_STATIC);
+ return TCL_OK;
+ }
}
- index.linePtr = TkBTreePreviousLine(index.linePtr);
- if (index.linePtr == (TkTextLine *) NULL) {
+ index.linePtr = TkBTreePreviousLine(textPtr, index.linePtr);
+ if (index.linePtr == NULL) {
return TCL_OK;
}
segPtr = NULL;
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c
index b05eb8f..5162e16 100644
--- a/generic/tkTextTag.c
+++ b/generic/tkTextTag.c
@@ -1,93 +1,116 @@
-/*
+/*
* tkTextTag.c --
*
- * This module implements the "tag" subcommand of the widget command
- * for text widgets, plus most of the other high-level functions
- * related to tags.
+ * This module implements the "tag" subcommand of the widget command for
+ * text widgets, plus most of the other high-level functions related to
+ * tags.
*
* Copyright (c) 1992-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "default.h"
-#include "tkPort.h"
#include "tkInt.h"
#include "tkText.h"
-static Tk_ConfigSpec tagConfigSpecs[] = {
- {TK_CONFIG_BORDER, "-background", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, border), TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-bgstipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, bgStipple), TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-borderwidth", (char *) NULL, (char *) NULL,
- "0", Tk_Offset(TkTextTag, bdString),
- TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-elide", (char *) NULL, (char *) NULL,
- "0", Tk_Offset(TkTextTag, elideString),
- TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK},
- {TK_CONFIG_BITMAP, "-fgstipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, fgStipple), TK_CONFIG_NULL_OK},
- {TK_CONFIG_FONT, "-font", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, tkfont), TK_CONFIG_NULL_OK},
- {TK_CONFIG_COLOR, "-foreground", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, fgColor), TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-justify", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, justifyString), TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-lmargin1", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, lMargin1String), TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-lmargin2", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, lMargin2String), TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-offset", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, offsetString), TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-overstrike", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, overstrikeString),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-relief", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, reliefString), TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-rmargin", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, rMarginString), TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-spacing1", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, spacing1String), TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-spacing2", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, spacing2String), TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-spacing3", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, spacing3String), TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-tabs", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, tabString), TK_CONFIG_NULL_OK},
- {TK_CONFIG_STRING, "-underline", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, underlineString),
- TK_CONFIG_NULL_OK},
- {TK_CONFIG_CUSTOM, "-wrap", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextTag, wrapMode),
- TK_CONFIG_NULL_OK, &TkTextWrapModeOption},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+/*
+ * The 'TkWrapMode' enum in tkText.h is used to define a type for the -wrap
+ * option of tags in a Text widget. These values are used as indices into the
+ * string table below. Tags are allowed an empty wrap value, but the widget as
+ * a whole is not.
+ */
+
+static const char *wrapStrings[] = {
+ "char", "none", "word", "", NULL
};
/*
- * Forward declarations for procedures defined later in this file:
+ * The 'TkTextTabStyle' enum in tkText.h is used to define a type for the
+ * -tabstyle option of the Text widget. These values are used as indices into
+ * the string table below. Tags are allowed an empty wrap value, but the
+ * widget as a whole is not.
*/
-static void ChangeTagPriority _ANSI_ARGS_((TkText *textPtr,
- TkTextTag *tagPtr, int prio));
-static TkTextTag * FindTag _ANSI_ARGS_((Tcl_Interp *interp,
- TkText *textPtr, CONST char *tagName));
-static void SortTags _ANSI_ARGS_((int numTags,
- TkTextTag **tagArrayPtr));
-static int TagSortProc _ANSI_ARGS_((CONST VOID *first,
- CONST VOID *second));
+static const char *tabStyleStrings[] = {
+ "tabular", "wordprocessor", "", NULL
+};
+
+static const Tk_OptionSpec tagOptionSpecs[] = {
+ {TK_OPTION_BORDER, "-background", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, border), TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_BITMAP, "-bgstipple", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, bgStipple), TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_PIXELS, "-borderwidth", NULL, NULL,
+ "0", Tk_Offset(TkTextTag, borderWidthPtr), Tk_Offset(TkTextTag, borderWidth),
+ TK_OPTION_DONT_SET_DEFAULT|TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-elide", NULL, NULL,
+ "0", -1, Tk_Offset(TkTextTag, elideString),
+ TK_OPTION_DONT_SET_DEFAULT|TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_BITMAP, "-fgstipple", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, fgStipple), TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_FONT, "-font", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, tkfont), TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_COLOR, "-foreground", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, fgColor), TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-justify", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, justifyString), TK_OPTION_NULL_OK, 0,0},
+ {TK_OPTION_STRING, "-lmargin1", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, lMargin1String), TK_OPTION_NULL_OK,0,0},
+ {TK_OPTION_STRING, "-lmargin2", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, lMargin2String), TK_OPTION_NULL_OK,0,0},
+ {TK_OPTION_STRING, "-offset", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, offsetString), TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-overstrike", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, overstrikeString),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-relief", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, reliefString), TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-rmargin", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, rMarginString), TK_OPTION_NULL_OK, 0,0},
+ {TK_OPTION_STRING, "-spacing1", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, spacing1String), TK_OPTION_NULL_OK,0,0},
+ {TK_OPTION_STRING, "-spacing2", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, spacing2String), TK_OPTION_NULL_OK,0,0},
+ {TK_OPTION_STRING, "-spacing3", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, spacing3String), TK_OPTION_NULL_OK,0,0},
+ {TK_OPTION_STRING, "-tabs", NULL, NULL,
+ NULL, Tk_Offset(TkTextTag, tabStringPtr), -1, TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING_TABLE, "-tabstyle", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, tabStyle),
+ TK_OPTION_NULL_OK, (ClientData) tabStyleStrings, 0},
+ {TK_OPTION_STRING, "-underline", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, underlineString),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING_TABLE, "-wrap", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, wrapMode),
+ TK_OPTION_NULL_OK, (ClientData) wrapStrings, 0},
+ {TK_OPTION_END}
+};
+
+/*
+ * Forward declarations for functions defined later in this file:
+ */
+
+static void ChangeTagPriority(TkText *textPtr, TkTextTag *tagPtr,
+ int prio);
+static TkTextTag * FindTag(Tcl_Interp *interp, TkText *textPtr,
+ Tcl_Obj *tagName);
+static void SortTags(int numTags, TkTextTag **tagArrayPtr);
+static int TagSortProc(CONST VOID *first, CONST VOID *second);
+static void TagBindEvent(TkText *textPtr, XEvent *eventPtr,
+ int numTags, TkTextTag **tagArrayPtr);
/*
*--------------------------------------------------------------
*
* TkTextTagCmd --
*
- * This procedure is invoked to process the "tag" options of
- * the widget command for text widgets. See the user documentation
- * for details on what it does.
+ * This function is invoked to process the "tag" options of the widget
+ * command for text widgets. See the user documentation for details on
+ * what it does.
*
* Results:
* A standard Tcl result.
@@ -99,47 +122,61 @@ static int TagSortProc _ANSI_ARGS_((CONST VOID *first,
*/
int
-TkTextTagCmd(textPtr, interp, argc, argv)
- register TkText *textPtr; /* Information about text widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. Someone else has already
+TkTextTagCmd(
+ register TkText *textPtr, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. Someone else has already
* parsed this command enough to know that
- * argv[1] is "tag". */
+ * objv[1] is "tag". */
{
- int c, i, addTag;
- size_t length;
- char *fullOption;
+ static CONST char *tagOptionStrings[] = {
+ "add", "bind", "cget", "configure", "delete", "lower", "names",
+ "nextrange", "prevrange", "raise", "ranges", "remove", NULL
+ };
+ enum tagOptions {
+ TAG_ADD, TAG_BIND, TAG_CGET, TAG_CONFIGURE, TAG_DELETE, TAG_LOWER,
+ TAG_NAMES, TAG_NEXTRANGE, TAG_PREVRANGE, TAG_RAISE, TAG_RANGES,
+ TAG_REMOVE
+ };
+ int optionIndex, i;
register TkTextTag *tagPtr;
- TkTextIndex first, last, index1, index2;
+ TkTextIndex index1, index2;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?");
+ return TCL_ERROR;
+ }
- if (argc < 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " tag option ?arg arg ...?\"", (char *) NULL);
+ if (Tcl_GetIndexFromObj(interp, objv[2], tagOptionStrings,
+ "tag option", 0, &optionIndex) != TCL_OK) {
return TCL_ERROR;
}
- c = argv[2][0];
- length = strlen(argv[2]);
- if ((c == 'a') && (strncmp(argv[2], "add", length) == 0)) {
- fullOption = "add";
- addTag = 1;
-
- addAndRemove:
- if (argc < 5) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " tag ", fullOption,
- " tagName index1 ?index2 index1 index2 ...?\"",
- (char *) NULL);
+
+ switch ((enum tagOptions)optionIndex) {
+ case TAG_ADD:
+ case TAG_REMOVE: {
+ int addTag;
+
+ if (((enum tagOptions)optionIndex) == TAG_ADD) {
+ addTag = 1;
+ } else {
+ addTag = 0;
+ }
+ if (objc < 5) {
+ Tcl_WrongNumArgs(interp, 3, objv,
+ "tagName index1 ?index2 index1 index2 ...?");
return TCL_ERROR;
}
- tagPtr = TkTextCreateTag(textPtr, argv[3]);
- for (i = 4; i < argc; i += 2) {
- if (TkTextGetIndex(interp, textPtr, argv[i], &index1) != TCL_OK) {
+ tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL);
+ for (i = 4; i < objc; i += 2) {
+ if (TkTextGetObjIndex(interp, textPtr, objv[i],
+ &index1) != TCL_OK) {
return TCL_ERROR;
}
- if (argc > (i+1)) {
- if (TkTextGetIndex(interp, textPtr, argv[i+1], &index2)
- != TCL_OK) {
+ if (objc > (i+1)) {
+ if (TkTextGetObjIndex(interp, textPtr, objv[i+1],
+ &index2) != TCL_OK) {
return TCL_ERROR;
}
if (TkTextIndexCmp(&index1, &index2) >= 0) {
@@ -147,85 +184,88 @@ TkTextTagCmd(textPtr, interp, argc, argv)
}
} else {
index2 = index1;
- TkTextIndexForwChars(&index2, 1, &index2);
+ TkTextIndexForwChars(NULL,&index2, 1, &index2, COUNT_INDICES);
}
if (tagPtr->affectsDisplay) {
- TkTextRedrawTag(textPtr, &index1, &index2, tagPtr, !addTag);
+ TkTextRedrawTag(textPtr->sharedTextPtr, NULL, &index1, &index2,
+ tagPtr, !addTag);
} else {
/*
- * Still need to trigger enter/leave events on tags that
- * have changed.
+ * Still need to trigger enter/leave events on tags that have
+ * changed.
*/
TkTextEventuallyRepick(textPtr);
}
- TkBTreeTag(&index1, &index2, tagPtr, addTag);
-
- /*
- * If the tag is "sel" then grab the selection if we're supposed
- * to export it and don't already have it. Also, invalidate
- * partially-completed selection retrievals.
- */
-
- if (tagPtr == textPtr->selTagPtr) {
- XEvent event;
+ if (TkBTreeTag(&index1, &index2, tagPtr, addTag)) {
/*
- * Send an event that the selection changed.
- * This is equivalent to
- * "event generate $textWidget <<Selection>>"
+ * If the tag is "sel", and we actually adjusted something
+ * then grab the selection if we're supposed to export it and
+ * don't already have it.
+ *
+ * Also, invalidate partially-completed selection retrievals.
+ * We only need to check whether the tag is "sel" for this
+ * textPtr (not for other peer widget's "sel" tags) because we
+ * cannot reach this code path with a different widget's "sel"
+ * tag.
*/
- memset((VOID *) &event, 0, sizeof(event));
- event.xany.type = VirtualEvent;
- event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin));
- event.xany.send_event = False;
- event.xany.window = Tk_WindowId(textPtr->tkwin);
- event.xany.display = Tk_Display(textPtr->tkwin);
- ((XVirtualEvent *) &event)->name = Tk_GetUid("Selection");
- Tk_HandleEvent(&event);
-
- if (addTag && textPtr->exportSelection
- && !(textPtr->flags & GOT_SELECTION)) {
- Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY,
- TkTextLostSelection, (ClientData) textPtr);
- textPtr->flags |= GOT_SELECTION;
+ if (tagPtr == textPtr->selTagPtr) {
+ /*
+ * Send an event that the selection changed. This is
+ * equivalent to:
+ * event generate $textWidget <<Selection>>
+ */
+
+ TkTextSelectionEvent(textPtr);
+
+ if (addTag && textPtr->exportSelection
+ && !(textPtr->flags & GOT_SELECTION)) {
+ Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY,
+ TkTextLostSelection, (ClientData) textPtr);
+ textPtr->flags |= GOT_SELECTION;
+ }
+ textPtr->abortSelections = 1;
}
- textPtr->abortSelections = 1;
}
}
- } else if ((c == 'b') && (strncmp(argv[2], "bind", length) == 0)) {
- if ((argc < 4) || (argc > 6)) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " tag bind tagName ?sequence? ?command?\"",
- (char *) NULL);
+ break;
+ }
+ case TAG_BIND:
+ if ((objc < 4) || (objc > 6)) {
+ Tcl_WrongNumArgs(interp, 3, objv, "tagName ?sequence? ?command?");
return TCL_ERROR;
}
- tagPtr = TkTextCreateTag(textPtr, argv[3]);
+ tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL);
/*
- * Make a binding table if the widget doesn't already have
- * one.
+ * Make a binding table if the widget doesn't already have one.
*/
- if (textPtr->bindingTable == NULL) {
- textPtr->bindingTable = Tk_CreateBindingTable(interp);
+ if (textPtr->sharedTextPtr->bindingTable == NULL) {
+ textPtr->sharedTextPtr->bindingTable =
+ Tk_CreateBindingTable(interp);
}
- if (argc == 6) {
+ if (objc == 6) {
int append = 0;
unsigned long mask;
+ char *fifth = Tcl_GetString(objv[5]);
- if (argv[5][0] == 0) {
- return Tk_DeleteBinding(interp, textPtr->bindingTable,
- (ClientData) tagPtr, argv[4]);
+ if (fifth[0] == 0) {
+ return Tk_DeleteBinding(interp,
+ textPtr->sharedTextPtr->bindingTable,
+ (ClientData) tagPtr->name, Tcl_GetString(objv[4]));
}
- if (argv[5][0] == '+') {
- argv[5]++;
+ if (fifth[0] == '+') {
+ fifth++;
append = 1;
}
- mask = Tk_CreateBinding(interp, textPtr->bindingTable,
- (ClientData) tagPtr, argv[4], argv[5], append);
+ mask = Tk_CreateBinding(interp,
+ textPtr->sharedTextPtr->bindingTable,
+ (ClientData) tagPtr->name, Tcl_GetString(objv[4]), fifth,
+ append);
if (mask == 0) {
return TCL_ERROR;
}
@@ -234,89 +274,97 @@ TkTextTagCmd(textPtr, interp, argc, argv)
|Button5MotionMask|ButtonPressMask|ButtonReleaseMask
|EnterWindowMask|LeaveWindowMask|KeyPressMask
|KeyReleaseMask|PointerMotionMask|VirtualEventMask)) {
- Tk_DeleteBinding(interp, textPtr->bindingTable,
- (ClientData) tagPtr, argv[4]);
+ Tk_DeleteBinding(interp, textPtr->sharedTextPtr->bindingTable,
+ (ClientData) tagPtr->name, Tcl_GetString(objv[4]));
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "requested illegal events; ",
"only key, button, motion, enter, leave, and virtual ",
- "events may be used", (char *) NULL);
+ "events may be used", NULL);
return TCL_ERROR;
}
- } else if (argc == 5) {
+ } else if (objc == 5) {
CONST char *command;
-
- command = Tk_GetBinding(interp, textPtr->bindingTable,
- (ClientData) tagPtr, argv[4]);
+
+ command = Tk_GetBinding(interp,
+ textPtr->sharedTextPtr->bindingTable,
+ (ClientData) tagPtr->name, Tcl_GetString(objv[4]));
if (command == NULL) {
- CONST char *string = Tcl_GetStringResult(interp);
+ CONST 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.
+ * 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);
}
+ Tcl_ResetResult(interp);
} else {
Tcl_SetResult(interp, (char *) command, TCL_STATIC);
}
} else {
- Tk_GetAllBindings(interp, textPtr->bindingTable,
- (ClientData) tagPtr);
- }
- } else if ((c == 'c') && (strncmp(argv[2], "cget", length) == 0)
- && (length >= 2)) {
- if (argc != 5) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " tag cget tagName option\"",
- (char *) NULL);
- return TCL_ERROR;
+ Tk_GetAllBindings(interp, textPtr->sharedTextPtr->bindingTable,
+ (ClientData) tagPtr->name);
}
- tagPtr = FindTag(interp, textPtr, argv[3]);
- if (tagPtr == NULL) {
+ break;
+ case TAG_CGET:
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 1, objv, "tag cget tagName option");
return TCL_ERROR;
+ } else {
+ Tcl_Obj *objPtr;
+
+ tagPtr = FindTag(interp, textPtr, objv[3]);
+ if (tagPtr == NULL) {
+ return TCL_ERROR;
+ }
+ objPtr = Tk_GetOptionValue(interp, (char *) tagPtr,
+ tagPtr->optionTable, objv[4], textPtr->tkwin);
+ if (objPtr == NULL) {
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
}
- return Tk_ConfigureValue(interp, textPtr->tkwin, tagConfigSpecs,
- (char *) tagPtr, argv[4], 0);
- } else if ((c == 'c') && (strncmp(argv[2], "configure", length) == 0)
- && (length >= 2)) {
- if (argc < 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " tag configure tagName ?option? ?value? ",
- "?option value ...?\"", (char *) NULL);
+ break;
+ case TAG_CONFIGURE: {
+ int newTag;
+
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 3, objv,
+ "tagName ?option? ?value? ?option value ...?");
return TCL_ERROR;
}
- tagPtr = TkTextCreateTag(textPtr, argv[3]);
- if (argc == 4) {
- return Tk_ConfigureInfo(interp, textPtr->tkwin, tagConfigSpecs,
- (char *) tagPtr, (char *) NULL, 0);
- } else if (argc == 5) {
- return Tk_ConfigureInfo(interp, textPtr->tkwin, tagConfigSpecs,
- (char *) tagPtr, argv[4], 0);
+ tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), &newTag);
+ if (objc <= 5) {
+ Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, (char *) tagPtr,
+ tagPtr->optionTable,
+ (objc == 5) ? objv[4] : NULL, textPtr->tkwin);
+
+ if (objPtr == NULL) {
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
} else {
- int result;
+ int result = TCL_OK;
+
+ if (Tk_SetOptions(interp, (char*)tagPtr, tagPtr->optionTable,
+ objc-4, objv+4, textPtr->tkwin, NULL, NULL) != TCL_OK) {
+ return TCL_ERROR;
+ }
- result = Tk_ConfigureWidget(interp, textPtr->tkwin, tagConfigSpecs,
- argc-4, argv+4, (char *) tagPtr, 0);
/*
- * Some of the configuration options, like -underline
- * and -justify, require additional translation (this is
- * needed because we need to distinguish a particular value
- * of an option from "unspecified").
+ * Some of the configuration options, like -underline and
+ * -justify, require additional translation (this is needed
+ * because we need to distinguish a particular value of an option
+ * from "unspecified").
*/
- if (tagPtr->bdString != NULL) {
- if (Tk_GetPixels(interp, textPtr->tkwin, tagPtr->bdString,
- &tagPtr->borderWidth) != TCL_OK) {
- return TCL_ERROR;
- }
- if (tagPtr->borderWidth < 0) {
- tagPtr->borderWidth = 0;
- }
+ if (tagPtr->borderWidth < 0) {
+ tagPtr->borderWidth = 0;
}
if (tagPtr->reliefString != NULL) {
if (Tk_GetRelief(interp, tagPtr->reliefString,
@@ -391,9 +439,9 @@ TkTextTagCmd(textPtr, interp, argc, argv)
ckfree((char *) tagPtr->tabArrayPtr);
tagPtr->tabArrayPtr = NULL;
}
- if (tagPtr->tabString != NULL) {
- tagPtr->tabArrayPtr = TkTextGetTabs(interp, textPtr->tkwin,
- tagPtr->tabString);
+ if (tagPtr->tabStringPtr != NULL) {
+ tagPtr->tabArrayPtr =
+ TkTextGetTabs(interp, textPtr, tagPtr->tabStringPtr);
if (tagPtr->tabArrayPtr == NULL) {
return TCL_ERROR;
}
@@ -409,59 +457,91 @@ TkTextTagCmd(textPtr, interp, argc, argv)
&tagPtr->elide) != TCL_OK) {
return TCL_ERROR;
}
+ /* Indices are potentially obsolete after changing -elide,
+ * especially those computed with "display" or "any"
+ * submodifier, therefore increase the epoch.
+ */
+ textPtr->sharedTextPtr->stateEpoch++;
}
/*
* If the "sel" tag was changed, be sure to mirror information
- * from the tag back into the text widget record. NOTE: we
- * don't have to free up information in the widget record
- * before overwriting it, because it was mirrored in the tag
- * and hence freed when the tag field was overwritten.
+ * from the tag back into the text widget record. NOTE: we don't
+ * have to free up information in the widget record before
+ * overwriting it, because it was mirrored in the tag and hence
+ * freed when the tag field was overwritten.
*/
if (tagPtr == textPtr->selTagPtr) {
textPtr->selBorder = tagPtr->border;
- textPtr->selBdString = tagPtr->bdString;
+ textPtr->selBorderWidth = tagPtr->borderWidth;
+ textPtr->selBorderWidthPtr = tagPtr->borderWidthPtr;
textPtr->selFgColorPtr = tagPtr->fgColor;
}
+
tagPtr->affectsDisplay = 0;
- if ((tagPtr->border != NULL)
- || (tagPtr->bdString != NULL)
- || (tagPtr->reliefString != NULL)
- || (tagPtr->bgStipple != None)
- || (tagPtr->fgColor != NULL) || (tagPtr->tkfont != None)
- || (tagPtr->fgStipple != None)
+ tagPtr->affectsDisplayGeometry = 0;
+ if ((tagPtr->elideString != NULL)
+ || (tagPtr->tkfont != None)
|| (tagPtr->justifyString != NULL)
|| (tagPtr->lMargin1String != NULL)
|| (tagPtr->lMargin2String != NULL)
|| (tagPtr->offsetString != NULL)
- || (tagPtr->overstrikeString != NULL)
|| (tagPtr->rMarginString != NULL)
|| (tagPtr->spacing1String != NULL)
|| (tagPtr->spacing2String != NULL)
|| (tagPtr->spacing3String != NULL)
- || (tagPtr->tabString != NULL)
- || (tagPtr->underlineString != NULL)
- || (tagPtr->elideString != NULL)
+ || (tagPtr->tabStringPtr != NULL)
+ || (tagPtr->tabStyle != TK_TEXT_TABSTYLE_NONE)
|| (tagPtr->wrapMode != TEXT_WRAPMODE_NULL)) {
tagPtr->affectsDisplay = 1;
+ tagPtr->affectsDisplayGeometry = 1;
+ }
+ if ((tagPtr->border != NULL)
+ || (tagPtr->reliefString != NULL)
+ || (tagPtr->bgStipple != None)
+ || (tagPtr->fgColor != NULL)
+ || (tagPtr->fgStipple != None)
+ || (tagPtr->overstrikeString != NULL)
+ || (tagPtr->underlineString != NULL)) {
+ tagPtr->affectsDisplay = 1;
+ }
+ if (!newTag) {
+ /*
+ * This line is not necessary if this is a new tag, since it
+ * can't possibly have been applied to anything yet.
+ */
+
+ /*
+ * VMD: If this is the 'sel' tag, then we don't need to call
+ * this for all peers, unless we actually want to synchronize
+ * sel-style changes across the peers.
+ */
+
+ TkTextRedrawTag(textPtr->sharedTextPtr, NULL,
+ NULL, NULL, tagPtr, 1);
}
- TkTextRedrawTag(textPtr, (TkTextIndex *) NULL,
- (TkTextIndex *) NULL, tagPtr, 1);
return result;
}
- } else if ((c == 'd') && (strncmp(argv[2], "delete", length) == 0)) {
+ break;
+ }
+ case TAG_DELETE: {
Tcl_HashEntry *hPtr;
- if (argc < 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " tag delete tagName tagName ...\"",
- (char *) NULL);
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "tagName ?tagName ...?");
return TCL_ERROR;
}
- for (i = 3; i < argc; i++) {
- hPtr = Tcl_FindHashEntry(&textPtr->tagTable, argv[i]);
+ for (i = 3; i < objc; i++) {
+ hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->tagTable,
+ Tcl_GetString(objv[i]));
if (hPtr == NULL) {
+ /*
+ * Either this tag doesn't exist or it's the 'sel' tag (which
+ * is not in the hash table). Either way we don't want to
+ * delete it.
+ */
+
continue;
}
tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr);
@@ -469,62 +549,28 @@ TkTextTagCmd(textPtr, interp, argc, argv)
continue;
}
if (tagPtr->affectsDisplay) {
- TkTextRedrawTag(textPtr, (TkTextIndex *) NULL,
- (TkTextIndex *) NULL, tagPtr, 1);
+ TkTextRedrawTag(textPtr->sharedTextPtr, NULL,
+ NULL, NULL, tagPtr, 1);
}
- TkTextMakeByteIndex(textPtr->tree, 0, 0, &first);
- TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree),
- 0, &last),
- TkBTreeTag(&first, &last, tagPtr, 0);
-
- if (tagPtr == textPtr->selTagPtr) {
- XEvent event;
- /*
- * Send an event that the selection changed.
- * This is equivalent to
- * "event generate $textWidget <<Selection>>"
- */
-
- memset((VOID *) &event, 0, sizeof(event));
- event.xany.type = VirtualEvent;
- event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin));
- event.xany.send_event = False;
- event.xany.window = Tk_WindowId(textPtr->tkwin);
- event.xany.display = Tk_Display(textPtr->tkwin);
- ((XVirtualEvent *) &event)->name = Tk_GetUid("Selection");
- Tk_HandleEvent(&event);
- }
-
+ TkTextDeleteTag(textPtr, tagPtr);
Tcl_DeleteHashEntry(hPtr);
- if (textPtr->bindingTable != NULL) {
- Tk_DeleteAllBindings(textPtr->bindingTable,
- (ClientData) tagPtr);
- }
-
- /*
- * Update the tag priorities to reflect the deletion of this tag.
- */
-
- ChangeTagPriority(textPtr, tagPtr, textPtr->numTags-1);
- textPtr->numTags -= 1;
- TkTextFreeTag(textPtr, tagPtr);
}
- } else if ((c == 'l') && (strncmp(argv[2], "lower", length) == 0)) {
+ break;
+ }
+ case TAG_LOWER: {
TkTextTag *tagPtr2;
int prio;
- if ((argc != 4) && (argc != 5)) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " tag lower tagName ?belowThis?\"",
- (char *) NULL);
+ if ((objc != 4) && (objc != 5)) {
+ Tcl_WrongNumArgs(interp, 3, objv, "tagName ?belowThis?");
return TCL_ERROR;
}
- tagPtr = FindTag(interp, textPtr, argv[3]);
+ tagPtr = FindTag(interp, textPtr, objv[3]);
if (tagPtr == NULL) {
return TCL_ERROR;
}
- if (argc == 5) {
- tagPtr2 = FindTag(interp, textPtr, argv[4]);
+ if (objc == 5) {
+ tagPtr2 = FindTag(interp, textPtr, objv[4]);
if (tagPtr2 == NULL) {
return TCL_ERROR;
}
@@ -537,81 +583,99 @@ TkTextTagCmd(textPtr, interp, argc, argv)
prio = 0;
}
ChangeTagPriority(textPtr, tagPtr, prio);
- TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, (TkTextIndex *) NULL,
- tagPtr, 1);
- } else if ((c == 'n') && (strncmp(argv[2], "names", length) == 0)
- && (length >= 2)) {
+
+ /*
+ * If this is the 'sel' tag, then we don't actually need to call this
+ * for all peers.
+ */
+
+ TkTextRedrawTag(textPtr->sharedTextPtr, NULL, NULL, NULL, tagPtr, 1);
+ break;
+ }
+ case TAG_NAMES: {
TkTextTag **arrayPtr;
int arraySize;
+ Tcl_Obj *listObj;
- if ((argc != 3) && (argc != 4)) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " tag names ?index?\"",
- (char *) NULL);
+ if ((objc != 3) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 3, objv, "?index?");
return TCL_ERROR;
}
- if (argc == 3) {
+ if (objc == 3) {
Tcl_HashSearch search;
Tcl_HashEntry *hPtr;
arrayPtr = (TkTextTag **) ckalloc((unsigned)
- (textPtr->numTags * sizeof(TkTextTag *)));
- for (i = 0, hPtr = Tcl_FirstHashEntry(&textPtr->tagTable, &search);
+ (textPtr->sharedTextPtr->numTags * sizeof(TkTextTag *)));
+ for (i=0, hPtr = Tcl_FirstHashEntry(
+ &textPtr->sharedTextPtr->tagTable, &search);
hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) {
arrayPtr[i] = (TkTextTag *) Tcl_GetHashValue(hPtr);
}
- arraySize = textPtr->numTags;
+
+ /*
+ * The 'sel' tag is not in the hash table.
+ */
+
+ arrayPtr[i] = textPtr->selTagPtr;
+ arraySize = ++i;
} else {
- if (TkTextGetIndex(interp, textPtr, argv[3], &index1)
- != TCL_OK) {
+ if (TkTextGetObjIndex(interp, textPtr, objv[3],
+ &index1) != TCL_OK) {
return TCL_ERROR;
}
- arrayPtr = TkBTreeGetTags(&index1, &arraySize);
+ arrayPtr = TkBTreeGetTags(&index1, textPtr, &arraySize);
if (arrayPtr == NULL) {
return TCL_OK;
}
}
+
SortTags(arraySize, arrayPtr);
+ listObj = Tcl_NewListObj(0, NULL);
+
for (i = 0; i < arraySize; i++) {
tagPtr = arrayPtr[i];
- Tcl_AppendElement(interp, tagPtr->name);
+ Tcl_ListObjAppendElement(interp, listObj,
+ Tcl_NewStringObj(tagPtr->name,-1));
}
+ Tcl_SetObjResult(interp, listObj);
ckfree((char *) arrayPtr);
- } else if ((c == 'n') && (strncmp(argv[2], "nextrange", length) == 0)
- && (length >= 2)) {
+ break;
+ }
+ case TAG_NEXTRANGE: {
+ TkTextIndex last;
TkTextSearch tSearch;
char position[TK_POS_CHARS];
- if ((argc != 5) && (argc != 6)) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " tag nextrange tagName index1 ?index2?\"",
- (char *) NULL);
+ if ((objc != 5) && (objc != 6)) {
+ Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?");
return TCL_ERROR;
}
- tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, argv[3]);
+ tagPtr = FindTag(NULL, textPtr, objv[3]);
if (tagPtr == NULL) {
return TCL_OK;
}
- if (TkTextGetIndex(interp, textPtr, argv[4], &index1) != TCL_OK) {
+ if (TkTextGetObjIndex(interp, textPtr, objv[4], &index1) != TCL_OK) {
return TCL_ERROR;
}
- TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree),
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr),
0, &last);
- if (argc == 5) {
+ if (objc == 5) {
index2 = last;
- } else if (TkTextGetIndex(interp, textPtr, argv[5], &index2)
- != TCL_OK) {
+ } else if (TkTextGetObjIndex(interp, textPtr, objv[5],
+ &index2) != TCL_OK) {
return TCL_ERROR;
}
/*
- * The search below is a bit tricky. Rather than use the B-tree
- * facilities to stop the search at index2, let it search up
- * until the end of the file but check for a position past index2
- * ourselves. The reason for doing it this way is that we only
- * care whether the *start* of the range is before index2; once
- * we find the start, we don't want TkBTreeNextTag to abort the
- * search because the end of the range is after index2.
+ * The search below is a bit tricky. Rather than use the B-tree
+ * facilities to stop the search at index2, let it search up until the
+ * end of the file but check for a position past index2 ourselves.
+ * The reason for doing it this way is that we only care whether the
+ * *start* of the range is before index2; once we find the start, we
+ * don't want TkBTreeNextTag to abort the search because the end of
+ * the range is after index2.
*/
TkBTreeStartSearch(&index1, &last, tagPtr, &tSearch);
@@ -620,12 +684,12 @@ TkTextTagCmd(textPtr, interp, argc, argv)
int offset;
/*
- * The first character is tagged. See if there is an
- * on-toggle just before the character. If not, then
- * skip to the end of this tagged range.
+ * The first character is tagged. See if there is an on-toggle
+ * just before the character. If not, then skip to the end of this
+ * tagged range.
*/
- for (segPtr = index1.linePtr->segPtr, offset = index1.byteIndex;
+ for (segPtr = index1.linePtr->segPtr, offset = index1.byteIndex;
offset >= 0;
offset -= segPtr->size, segPtr = segPtr->nextPtr) {
if ((offset == 0) && (segPtr->typePtr == &tkTextToggleOnType)
@@ -634,7 +698,7 @@ TkTextTagCmd(textPtr, interp, argc, argv)
}
}
if (!TkBTreeNextTag(&tSearch)) {
- return TCL_OK;
+ return TCL_OK;
}
}
@@ -645,87 +709,139 @@ TkTextTagCmd(textPtr, interp, argc, argv)
if (!TkBTreeNextTag(&tSearch)) {
return TCL_OK;
}
- gotStart:
+
+ gotStart:
if (TkTextIndexCmp(&tSearch.curIndex, &index2) >= 0) {
return TCL_OK;
}
- TkTextPrintIndex(&tSearch.curIndex, position);
+ TkTextPrintIndex(textPtr, &tSearch.curIndex, position);
Tcl_AppendElement(interp, position);
TkBTreeNextTag(&tSearch);
- TkTextPrintIndex(&tSearch.curIndex, position);
+ TkTextPrintIndex(textPtr, &tSearch.curIndex, position);
Tcl_AppendElement(interp, position);
- } else if ((c == 'p') && (strncmp(argv[2], "prevrange", length) == 0)
- && (length >= 2)) {
+ break;
+ }
+ case TAG_PREVRANGE: {
+ TkTextIndex last;
TkTextSearch tSearch;
char position1[TK_POS_CHARS];
char position2[TK_POS_CHARS];
- if ((argc != 5) && (argc != 6)) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " tag prevrange tagName index1 ?index2?\"",
- (char *) NULL);
+ if ((objc != 5) && (objc != 6)) {
+ Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?");
return TCL_ERROR;
}
- tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, argv[3]);
+ tagPtr = FindTag(NULL, textPtr, objv[3]);
if (tagPtr == NULL) {
return TCL_OK;
}
- if (TkTextGetIndex(interp, textPtr, argv[4], &index1) != TCL_OK) {
+ if (TkTextGetObjIndex(interp, textPtr, objv[4], &index1) != TCL_OK) {
return TCL_ERROR;
}
- if (argc == 5) {
- TkTextMakeByteIndex(textPtr->tree, 0, 0, &index2);
- } else if (TkTextGetIndex(interp, textPtr, argv[5], &index2)
- != TCL_OK) {
+ if (objc == 5) {
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0,
+ &index2);
+ } else if (TkTextGetObjIndex(interp, textPtr, objv[5],
+ &index2) != TCL_OK) {
return TCL_ERROR;
}
/*
- * The search below is a bit weird. The previous toggle can be
- * either an on or off toggle. If it is an on toggle, then we
- * need to turn around and search forward for the end toggle.
- * Otherwise we keep searching backwards.
+ * The search below is a bit weird. The previous toggle can be either
+ * an on or off toggle. If it is an on toggle, then we need to turn
+ * around and search forward for the end toggle. Otherwise we keep
+ * searching backwards.
*/
TkBTreeStartSearchBack(&index1, &index2, tagPtr, &tSearch);
if (!TkBTreePrevTag(&tSearch)) {
+ /*
+ * Special case, there may be a tag off toggle at index1, and a
+ * tag on toggle before the start of a partial peer widget. In
+ * this case we missed it.
+ */
+
+ if (textPtr->start != NULL && (textPtr->start == index2.linePtr)
+ && (index2.byteIndex == 0)
+ && TkBTreeCharTagged(&index2, tagPtr)
+ && (TkTextIndexCmp(&index2, &index1) < 0)) {
+ /*
+ * The first character is tagged, so just add the range from
+ * the first char to the start of the range.
+ */
+
+ TkTextPrintIndex(textPtr, &index2, position1);
+ TkTextPrintIndex(textPtr, &index1, position2);
+ Tcl_AppendElement(interp, position1);
+ Tcl_AppendElement(interp, position2);
+ }
return TCL_OK;
}
+
if (tSearch.segPtr->typePtr == &tkTextToggleOnType) {
- TkTextPrintIndex(&tSearch.curIndex, position1);
- TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree),
+ TkTextPrintIndex(textPtr, &tSearch.curIndex, position1);
+ if (textPtr->start != NULL) {
+ /*
+ * Make sure the first index is not before the first allowed
+ * text index in this widget.
+ */
+
+ TkTextIndex firstIndex;
+
+ firstIndex.linePtr = textPtr->start;
+ firstIndex.byteIndex = 0;
+ firstIndex.textPtr = NULL;
+ if (TkTextIndexCmp(&tSearch.curIndex, &firstIndex) < 0) {
+ if (TkTextIndexCmp(&firstIndex, &index1) >= 0) {
+ /*
+ * But now the new first index is actually too far
+ * along in the text, so nothing is returned.
+ */
+
+ return TCL_OK;
+ }
+ TkTextPrintIndex(textPtr, &firstIndex, position1);
+ }
+ }
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr),
0, &last);
TkBTreeStartSearch(&tSearch.curIndex, &last, tagPtr, &tSearch);
TkBTreeNextTag(&tSearch);
- TkTextPrintIndex(&tSearch.curIndex, position2);
+ TkTextPrintIndex(textPtr, &tSearch.curIndex, position2);
} else {
- TkTextPrintIndex(&tSearch.curIndex, position2);
+ TkTextPrintIndex(textPtr, &tSearch.curIndex, position2);
TkBTreePrevTag(&tSearch);
+ TkTextPrintIndex(textPtr, &tSearch.curIndex, position1);
if (TkTextIndexCmp(&tSearch.curIndex, &index2) < 0) {
- return TCL_OK;
+ if (textPtr->start != NULL && index2.linePtr == textPtr->start
+ && index2.byteIndex == 0) {
+ /* It's ok */
+ TkTextPrintIndex(textPtr, &index2, position1);
+ } else {
+ return TCL_OK;
+ }
}
- TkTextPrintIndex(&tSearch.curIndex, position1);
}
Tcl_AppendElement(interp, position1);
Tcl_AppendElement(interp, position2);
- } else if ((c == 'r') && (strncmp(argv[2], "raise", length) == 0)
- && (length >= 3)) {
+ break;
+ }
+ case TAG_RAISE: {
TkTextTag *tagPtr2;
int prio;
- if ((argc != 4) && (argc != 5)) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " tag raise tagName ?aboveThis?\"",
- (char *) NULL);
+ if ((objc != 4) && (objc != 5)) {
+ Tcl_WrongNumArgs(interp, 3, objv, "tagName ?aboveThis?");
return TCL_ERROR;
}
- tagPtr = FindTag(interp, textPtr, argv[3]);
+ tagPtr = FindTag(interp, textPtr, objv[3]);
if (tagPtr == NULL) {
return TCL_ERROR;
}
- if (argc == 5) {
- tagPtr2 = FindTag(interp, textPtr, argv[4]);
+ if (objc == 5) {
+ tagPtr2 = FindTag(interp, textPtr, objv[4]);
if (tagPtr2 == NULL) {
return TCL_ERROR;
}
@@ -735,48 +851,61 @@ TkTextTagCmd(textPtr, interp, argc, argv)
prio = tagPtr2->priority + 1;
}
} else {
- prio = textPtr->numTags-1;
+ prio = textPtr->sharedTextPtr->numTags-1;
}
ChangeTagPriority(textPtr, tagPtr, prio);
- TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, (TkTextIndex *) NULL,
- tagPtr, 1);
- } else if ((c == 'r') && (strncmp(argv[2], "ranges", length) == 0)
- && (length >= 3)) {
+
+ /*
+ * If this is the 'sel' tag, then we don't actually need to call this
+ * for all peers.
+ */
+
+ TkTextRedrawTag(textPtr->sharedTextPtr, NULL, NULL, NULL, tagPtr, 1);
+ break;
+ }
+ case TAG_RANGES: {
+ TkTextIndex first, last;
TkTextSearch tSearch;
- char position[TK_POS_CHARS];
+ Tcl_Obj *listObj = Tcl_NewListObj(0, NULL);
+ int count = 0;
- if (argc != 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " tag ranges tagName\"", (char *) NULL);
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "tagName");
return TCL_ERROR;
}
- tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, argv[3]);
+ tagPtr = FindTag(NULL, textPtr, objv[3]);
if (tagPtr == NULL) {
return TCL_OK;
}
- TkTextMakeByteIndex(textPtr->tree, 0, 0, &first);
- TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree),
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0,
+ &first);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr),
0, &last);
TkBTreeStartSearch(&first, &last, tagPtr, &tSearch);
if (TkBTreeCharTagged(&first, tagPtr)) {
- TkTextPrintIndex(&first, position);
- Tcl_AppendElement(interp, position);
+ Tcl_ListObjAppendElement(interp, listObj,
+ TkTextNewIndexObj(textPtr, &first));
+ count++;
}
while (TkBTreeNextTag(&tSearch)) {
- TkTextPrintIndex(&tSearch.curIndex, position);
- Tcl_AppendElement(interp, position);
+ Tcl_ListObjAppendElement(interp, listObj,
+ TkTextNewIndexObj(textPtr, &tSearch.curIndex));
+ count++;
}
- } else if ((c == 'r') && (strncmp(argv[2], "remove", length) == 0)
- && (length >= 2)) {
- fullOption = "remove";
- addTag = 0;
- goto addAndRemove;
- } else {
- Tcl_AppendResult(interp, "bad tag option \"", argv[2],
- "\": must be add, bind, cget, configure, delete, lower, ",
- "names, nextrange, raise, ranges, or remove",
- (char *) NULL);
- return TCL_ERROR;
+ if (count % 2 == 1) {
+ /*
+ * If a text widget uses '-end', it won't necessarily run to the
+ * end of the B-tree, and therefore the tag range might not be
+ * closed. In this case we add the end of the range.
+ */
+
+ Tcl_ListObjAppendElement(interp, listObj,
+ TkTextNewIndexObj(textPtr, &last));
+ }
+ Tcl_SetObjResult(interp, listObj);
+ break;
+ }
}
return TCL_OK;
}
@@ -786,46 +915,68 @@ TkTextTagCmd(textPtr, interp, argc, argv)
*
* TkTextCreateTag --
*
- * Find the record describing a tag within a given text widget,
- * creating a new record if one doesn't already exist.
+ * Find the record describing a tag within a given text widget, creating
+ * a new record if one doesn't already exist.
*
* Results:
* The return value is a pointer to the TkTextTag record for tagName.
*
* Side effects:
- * A new tag record is created if there isn't one already defined
- * for tagName.
+ * A new tag record is created if there isn't one already defined for
+ * tagName.
*
*----------------------------------------------------------------------
*/
TkTextTag *
-TkTextCreateTag(textPtr, tagName)
- TkText *textPtr; /* Widget in which tag is being used. */
- CONST char *tagName; /* Name of desired tag. */
+TkTextCreateTag(
+ TkText *textPtr, /* Widget in which tag is being used. */
+ CONST char *tagName, /* Name of desired tag. */
+ int *newTag) /* If non-NULL, then return 1 if new, or 0 if
+ * already exists. */
{
register TkTextTag *tagPtr;
- Tcl_HashEntry *hPtr;
- int new;
-
- hPtr = Tcl_CreateHashEntry(&textPtr->tagTable, tagName, &new);
- if (!new) {
- return (TkTextTag *) Tcl_GetHashValue(hPtr);
+ Tcl_HashEntry *hPtr = NULL;
+ int isNew;
+ CONST char *name;
+
+ if (!strcmp(tagName, "sel")) {
+ if (textPtr->selTagPtr != NULL) {
+ if (newTag != NULL) {
+ *newTag = 0;
+ }
+ return textPtr->selTagPtr;
+ }
+ if (newTag != NULL) {
+ *newTag = 1;
+ }
+ name = "sel";
+ } else {
+ hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->tagTable,
+ tagName, &isNew);
+ if (newTag != NULL) {
+ *newTag = isNew;
+ }
+ if (!isNew) {
+ return (TkTextTag *) Tcl_GetHashValue(hPtr);
+ }
+ name = Tcl_GetHashKey(&textPtr->sharedTextPtr->tagTable, hPtr);
}
/*
- * No existing entry. Create a new one, initialize it, and add a
- * pointer to it to the hash table entry.
+ * No existing entry. Create a new one, initialize it, and add a pointer
+ * to it to the hash table entry.
*/
tagPtr = (TkTextTag *) ckalloc(sizeof(TkTextTag));
- tagPtr->name = Tcl_GetHashKey(&textPtr->tagTable, hPtr);
+ tagPtr->name = name;
+ tagPtr->textPtr = NULL;
tagPtr->toggleCount = 0;
tagPtr->tagRootPtr = NULL;
- tagPtr->priority = textPtr->numTags;
+ tagPtr->priority = textPtr->sharedTextPtr->numTags;
tagPtr->border = NULL;
- tagPtr->bdString = NULL;
tagPtr->borderWidth = 0;
+ tagPtr->borderWidthPtr = NULL;
tagPtr->reliefString = NULL;
tagPtr->relief = TK_RELIEF_FLAT;
tagPtr->bgStipple = None;
@@ -850,16 +1001,25 @@ TkTextCreateTag(textPtr, tagName)
tagPtr->spacing2 = 0;
tagPtr->spacing3String = NULL;
tagPtr->spacing3 = 0;
- tagPtr->tabString = NULL;
+ tagPtr->tabStringPtr = NULL;
tagPtr->tabArrayPtr = NULL;
+ tagPtr->tabStyle = TK_TEXT_TABSTYLE_NONE;
tagPtr->underlineString = NULL;
tagPtr->underline = 0;
tagPtr->elideString = NULL;
tagPtr->elide = 0;
tagPtr->wrapMode = TEXT_WRAPMODE_NULL;
tagPtr->affectsDisplay = 0;
- textPtr->numTags++;
- Tcl_SetHashValue(hPtr, tagPtr);
+ tagPtr->affectsDisplayGeometry = 0;
+ textPtr->sharedTextPtr->numTags++;
+ if (!strcmp(tagName, "sel")) {
+ tagPtr->textPtr = textPtr;
+ textPtr->refCount++;
+ } else {
+ Tcl_SetHashValue(hPtr, tagPtr);
+ }
+ tagPtr->optionTable =
+ Tk_CreateOptionTable(textPtr->interp, tagOptionSpecs);
return tagPtr;
}
@@ -871,10 +1031,9 @@ TkTextCreateTag(textPtr, tagName)
* See if tag is defined for a given widget.
*
* 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 the interp's result unless interp
- * is NULL.
+ * 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 the interp's result unless interp is NULL.
*
* Side effects:
* None.
@@ -883,22 +1042,29 @@ TkTextCreateTag(textPtr, tagName)
*/
static TkTextTag *
-FindTag(interp, textPtr, tagName)
- Tcl_Interp *interp; /* Interpreter to use for error message;
- * if NULL, then don't record an error
+FindTag(
+ Tcl_Interp *interp, /* Interpreter to use for error message; if
+ * NULL, then don't record an error
* message. */
- TkText *textPtr; /* Widget in which tag is being used. */
- CONST char *tagName; /* Name of desired tag. */
+ TkText *textPtr, /* Widget in which tag is being used. */
+ Tcl_Obj *tagName) /* Name of desired tag. */
{
Tcl_HashEntry *hPtr;
+ int len;
+ CONST char *str;
- hPtr = Tcl_FindHashEntry(&textPtr->tagTable, tagName);
+ str = Tcl_GetStringFromObj(tagName, &len);
+ if (len == 3 && !strcmp(str,"sel")) {
+ return textPtr->selTagPtr;
+ }
+ hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->tagTable,
+ Tcl_GetString(tagName));
if (hPtr != NULL) {
return (TkTextTag *) Tcl_GetHashValue(hPtr);
}
if (interp != NULL) {
- Tcl_AppendResult(interp, "tag \"", tagName,
- "\" isn't defined in text widget", (char *) NULL);
+ Tcl_AppendResult(interp, "tag \"", Tcl_GetString(tagName),
+ "\" isn't defined in text widget", NULL);
}
return NULL;
}
@@ -906,10 +1072,76 @@ FindTag(interp, textPtr, tagName)
/*
*----------------------------------------------------------------------
*
+ * TkTextDeleteTag --
+ *
+ * This function is called to carry out most actions associated with the
+ * 'tag delete' sub-command. It will remove all evidence of the tag from
+ * the B-tree, and then call TkTextFreeTag to clean up the tag structure
+ * itself.
+ *
+ * The only actions this doesn't carry out it to check if the deletion of
+ * the tag requires something to be re-displayed, and to remove the tag
+ * from the tagTable (hash table) if that is necessary (i.e. if it's not
+ * the 'sel' tag). It is expected that the caller carry out both of these
+ * actions.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Memory and other resources are freed, the B-tree is manipulated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkTextDeleteTag(
+ TkText *textPtr, /* Info about overall widget. */
+ register TkTextTag *tagPtr) /* Tag being deleted. */
+{
+ TkTextIndex first, last;
+
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0, &first);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), 0, &last),
+ TkBTreeTag(&first, &last, tagPtr, 0);
+
+ if (tagPtr == textPtr->selTagPtr) {
+ /*
+ * Send an event that the selection changed. This is equivalent to:
+ * event generate $textWidget <<Selection>>
+ */
+
+ TkTextSelectionEvent(textPtr);
+ } else {
+ /*
+ * Since all peer widgets have an independent "sel" tag, we
+ * don't want removal of one sel tag to remove bindings which
+ * are still valid in other peer widgets.
+ */
+
+ if (textPtr->sharedTextPtr->bindingTable != NULL) {
+ Tk_DeleteAllBindings(textPtr->sharedTextPtr->bindingTable,
+ (ClientData) tagPtr->name);
+ }
+ }
+
+ /*
+ * Update the tag priorities to reflect the deletion of this tag.
+ */
+
+ ChangeTagPriority(textPtr, tagPtr, textPtr->sharedTextPtr->numTags-1);
+ textPtr->sharedTextPtr->numTags -= 1;
+ TkTextFreeTag(textPtr, tagPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkTextFreeTag --
*
- * This procedure is called when a tag is deleted to free up the
- * memory and other resources associated with the tag.
+ * This function is called when a tag is deleted to free up the memory
+ * and other resources associated with the tag.
*
* Results:
* None.
@@ -921,65 +1153,62 @@ FindTag(interp, textPtr, tagName)
*/
void
-TkTextFreeTag(textPtr, tagPtr)
- TkText *textPtr; /* Info about overall widget. */
- register TkTextTag *tagPtr; /* Tag being deleted. */
+TkTextFreeTag(
+ TkText *textPtr, /* Info about overall widget. */
+ register TkTextTag *tagPtr) /* Tag being deleted. */
{
- if (tagPtr->border != None) {
- Tk_Free3DBorder(tagPtr->border);
- }
- if (tagPtr->bdString != NULL) {
- ckfree(tagPtr->bdString);
- }
- if (tagPtr->reliefString != NULL) {
- ckfree(tagPtr->reliefString);
- }
- if (tagPtr->bgStipple != None) {
- Tk_FreeBitmap(textPtr->display, tagPtr->bgStipple);
- }
- if (tagPtr->fgColor != None) {
- Tk_FreeColor(tagPtr->fgColor);
- }
- Tk_FreeFont(tagPtr->tkfont);
- if (tagPtr->fgStipple != None) {
- Tk_FreeBitmap(textPtr->display, tagPtr->fgStipple);
- }
- if (tagPtr->justifyString != NULL) {
- ckfree(tagPtr->justifyString);
- }
- if (tagPtr->lMargin1String != NULL) {
- ckfree(tagPtr->lMargin1String);
- }
- if (tagPtr->lMargin2String != NULL) {
- ckfree(tagPtr->lMargin2String);
- }
- if (tagPtr->offsetString != NULL) {
- ckfree(tagPtr->offsetString);
- }
- if (tagPtr->overstrikeString != NULL) {
- ckfree(tagPtr->overstrikeString);
- }
- if (tagPtr->rMarginString != NULL) {
- ckfree(tagPtr->rMarginString);
- }
- if (tagPtr->spacing1String != NULL) {
- ckfree(tagPtr->spacing1String);
- }
- if (tagPtr->spacing2String != NULL) {
- ckfree(tagPtr->spacing2String);
- }
- if (tagPtr->spacing3String != NULL) {
- ckfree(tagPtr->spacing3String);
- }
- if (tagPtr->tabString != NULL) {
- ckfree(tagPtr->tabString);
- }
+ int i;
+
+ /*
+ * Let Tk do most of the hard work for us.
+ */
+
+ Tk_FreeConfigOptions((char *) tagPtr, tagPtr->optionTable,
+ textPtr->tkwin);
+
+ /*
+ * This associated information is managed by us.
+ */
+
if (tagPtr->tabArrayPtr != NULL) {
ckfree((char *) tagPtr->tabArrayPtr);
}
- if (tagPtr->underlineString != NULL) {
- ckfree(tagPtr->underlineString);
+
+ /*
+ * Make sure this tag isn't referenced from the 'current' tag array.
+ */
+
+ for (i = 0; i < textPtr->numCurTags; i++) {
+ if (textPtr->curTagArrayPtr[i] == tagPtr) {
+ for (; i < textPtr->numCurTags-1; i++) {
+ textPtr->curTagArrayPtr[i] = textPtr->curTagArrayPtr[i+1];
+ }
+ textPtr->curTagArrayPtr[textPtr->numCurTags-1] = NULL;
+ textPtr->numCurTags--;
+ break;
+ }
+ }
+
+ /*
+ * If this tag is widget-specific (peer widgets) then clean up the
+ * refCount it holds.
+ */
+
+ if (tagPtr->textPtr != NULL) {
+ if (textPtr != tagPtr->textPtr) {
+ Tcl_Panic("Tag being deleted from wrong widget");
+ }
+ textPtr->refCount--;
+ if (textPtr->refCount == 0) {
+ ckfree((char *) textPtr);
+ }
+ tagPtr->textPtr = NULL;
}
+
+ /*
+ * Finally free the tag's memory.
+ */
+
ckfree((char *) tagPtr);
}
@@ -988,9 +1217,8 @@ TkTextFreeTag(textPtr, tagPtr)
*
* SortTags --
*
- * This procedure sorts an array of tag pointers in increasing
- * order of priority, optimizing for the common case where the
- * array is small.
+ * This function sorts an array of tag pointers in increasing order of
+ * priority, optimizing for the common case where the array is small.
*
* Results:
* None.
@@ -1002,9 +1230,9 @@ TkTextFreeTag(textPtr, tagPtr)
*/
static void
-SortTags(numTags, tagArrayPtr)
- int numTags; /* Number of tag pointers at *tagArrayPtr. */
- TkTextTag **tagArrayPtr; /* Pointer to array of pointers. */
+SortTags(
+ int numTags, /* Number of tag pointers at *tagArrayPtr. */
+ TkTextTag **tagArrayPtr) /* Pointer to array of pointers. */
{
int i, j, prio;
register TkTextTag **tagPtrPtr;
@@ -1028,8 +1256,7 @@ SortTags(numTags, tagArrayPtr)
*tagArrayPtr = tmp;
}
} else {
- qsort((VOID *) tagArrayPtr, (unsigned) numTags, sizeof (TkTextTag *),
- TagSortProc);
+ qsort(tagArrayPtr,(unsigned)numTags,sizeof(TkTextTag *),TagSortProc);
}
}
@@ -1038,14 +1265,14 @@ SortTags(numTags, tagArrayPtr)
*
* TagSortProc --
*
- * This procedure is called by qsort when sorting an array of
- * tags in priority order.
+ * This function is called by qsort() when sorting an array of tags in
+ * priority order.
*
* Results:
- * The return value is -1 if the first argument should be before
- * the second element (i.e. it has lower priority), 0 if it's
- * equivalent (this should never happen!), and 1 if it should be
- * after the second element.
+ * The return value is -1 if the first argument should be before the
+ * second element (i.e. it has lower priority), 0 if it's equivalent
+ * (this should never happen!), and 1 if it should be after the second
+ * element.
*
* Side effects:
* None.
@@ -1054,8 +1281,9 @@ SortTags(numTags, tagArrayPtr)
*/
static int
-TagSortProc(first, second)
- CONST VOID *first, *second; /* Elements to be compared. */
+TagSortProc(
+ CONST void *first,
+ CONST void *second) /* Elements to be compared. */
{
TkTextTag *tagPtr1, *tagPtr2;
@@ -1069,28 +1297,26 @@ TagSortProc(first, second)
*
* ChangeTagPriority --
*
- * This procedure changes the priority of a tag by modifying
- * its priority and the priorities of other tags that are affected
- * by the change.
+ * This function changes the priority of a tag by modifying its priority
+ * and the priorities of other tags that are affected by the change.
*
* Results:
* None.
*
* Side effects:
- * Priorities may be changed for some or all of the tags in
- * textPtr. The tags will be arranged so that there is exactly
- * one tag at each priority level between 0 and textPtr->numTags-1,
- * with tagPtr at priority "prio".
+ * Priorities may be changed for some or all of the tags in textPtr. The
+ * tags will be arranged so that there is exactly one tag at each
+ * priority level between 0 and textPtr->sharedTextPtr->numTags-1, with
+ * tagPtr at priority "prio".
*
*----------------------------------------------------------------------
*/
static void
-ChangeTagPriority(textPtr, tagPtr, prio)
- TkText *textPtr; /* Information about text widget. */
- TkTextTag *tagPtr; /* Tag whose priority is to be
- * changed. */
- int prio; /* New priority for tag. */
+ChangeTagPriority(
+ TkText *textPtr, /* Information about text widget. */
+ TkTextTag *tagPtr, /* Tag whose priority is to be changed. */
+ int prio) /* New priority for tag. */
{
int low, high, delta;
register TkTextTag *tagPtr2;
@@ -1100,12 +1326,13 @@ ChangeTagPriority(textPtr, tagPtr, prio)
if (prio < 0) {
prio = 0;
}
- if (prio >= textPtr->numTags) {
- prio = textPtr->numTags-1;
+ if (prio >= textPtr->sharedTextPtr->numTags) {
+ prio = textPtr->sharedTextPtr->numTags-1;
}
if (prio == tagPtr->priority) {
return;
- } else if (prio < tagPtr->priority) {
+ }
+ if (prio < tagPtr->priority) {
low = prio;
high = tagPtr->priority-1;
delta = 1;
@@ -1114,7 +1341,16 @@ ChangeTagPriority(textPtr, tagPtr, prio)
high = prio;
delta = -1;
}
- for (hPtr = Tcl_FirstHashEntry(&textPtr->tagTable, &search);
+
+ /*
+ * Adjust first the 'sel' tag, then all others from the hash table
+ */
+
+ if ((textPtr->selTagPtr->priority >= low)
+ && (textPtr->selTagPtr->priority <= high)) {
+ textPtr->selTagPtr->priority += delta;
+ }
+ for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->tagTable, &search);
hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
tagPtr2 = (TkTextTag *) Tcl_GetHashValue(hPtr);
if ((tagPtr2->priority >= low) && (tagPtr2->priority <= high)) {
@@ -1129,37 +1365,36 @@ ChangeTagPriority(textPtr, tagPtr, prio)
*
* TkTextBindProc --
*
- * This procedure is invoked by the Tk dispatcher to handle
- * events associated with bindings on items.
+ * This function is invoked by the Tk dispatcher to handle events
+ * associated with bindings on items.
*
* Results:
* None.
*
* Side effects:
- * Depends on the command invoked as part of the binding
- * (if there was any).
+ * Depends on the command invoked as part of the binding (if there was
+ * any).
*
*--------------------------------------------------------------
*/
void
-TkTextBindProc(clientData, eventPtr)
- ClientData clientData; /* Pointer to canvas structure. */
- XEvent *eventPtr; /* Pointer to X event that just
- * happened. */
+TkTextBindProc(
+ ClientData clientData, /* Pointer to canvas structure. */
+ XEvent *eventPtr) /* Pointer to X event that just happened. */
{
TkText *textPtr = (TkText *) clientData;
int repick = 0;
-# define AnyButtonMask (Button1Mask|Button2Mask|Button3Mask\
- |Button4Mask|Button5Mask)
+# define AnyButtonMask \
+ (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask)
- Tcl_Preserve((ClientData) textPtr);
+ textPtr->refCount++;
/*
- * This code simulates grabs for mouse buttons by keeping track
- * of whether a button is pressed and refusing to pick a new current
- * character while a button is pressed.
+ * This code simulates grabs for mouse buttons by keeping track of whether
+ * a button is pressed and refusing to pick a new current character while
+ * a button is pressed.
*/
if (eventPtr->type == ButtonPress) {
@@ -1168,24 +1403,24 @@ TkTextBindProc(clientData, eventPtr)
int mask;
switch (eventPtr->xbutton.button) {
- case Button1:
- mask = Button1Mask;
- break;
- case Button2:
- mask = Button2Mask;
- break;
- case Button3:
- mask = Button3Mask;
- break;
- case Button4:
- mask = Button4Mask;
- break;
- case Button5:
- mask = Button5Mask;
- break;
- default:
- mask = 0;
- break;
+ case Button1:
+ mask = Button1Mask;
+ break;
+ case Button2:
+ mask = Button2Mask;
+ break;
+ case Button3:
+ mask = Button3Mask;
+ break;
+ case Button4:
+ mask = Button4Mask;
+ break;
+ case Button5:
+ mask = Button5Mask;
+ break;
+ default:
+ mask = 0;
+ break;
}
if ((eventPtr->xbutton.state & AnyButtonMask) == (unsigned) mask) {
textPtr->flags &= ~BUTTON_DOWN;
@@ -1208,10 +1443,11 @@ TkTextBindProc(clientData, eventPtr)
}
TkTextPickCurrent(textPtr, eventPtr);
}
- if ((textPtr->numCurTags > 0) && (textPtr->bindingTable != NULL)
- && (textPtr->tkwin != NULL)) {
- Tk_BindEvent(textPtr->bindingTable, eventPtr, textPtr->tkwin,
- textPtr->numCurTags, (ClientData *) textPtr->curTagArrayPtr);
+ if ((textPtr->numCurTags > 0)
+ && (textPtr->sharedTextPtr->bindingTable != NULL)
+ && (textPtr->tkwin != NULL) && !(textPtr->flags & DESTROYED)) {
+ TagBindEvent(textPtr, eventPtr, textPtr->numCurTags,
+ textPtr->curTagArrayPtr);
}
if (repick) {
unsigned int oldState;
@@ -1219,12 +1455,16 @@ TkTextBindProc(clientData, eventPtr)
oldState = eventPtr->xbutton.state;
eventPtr->xbutton.state &= ~(Button1Mask|Button2Mask
|Button3Mask|Button4Mask|Button5Mask);
- TkTextPickCurrent(textPtr, eventPtr);
+ if (!(textPtr->flags & DESTROYED)) {
+ TkTextPickCurrent(textPtr, eventPtr);
+ }
eventPtr->xbutton.state = oldState;
}
- done:
- Tcl_Release((ClientData) textPtr);
+ done:
+ if (--textPtr->refCount == 0) {
+ ckfree((char *) textPtr);
+ }
}
/*
@@ -1232,57 +1472,55 @@ TkTextBindProc(clientData, eventPtr)
*
* TkTextPickCurrent --
*
- * Find the character containing the coordinates in an event
- * and place the "current" mark on that character. If the
- * "current" mark has moved then generate a fake leave event
- * on the old current character and a fake enter event on the new
- * current character.
+ * Find the character containing the coordinates in an event and place
+ * the "current" mark on that character. If the "current" mark has moved
+ * then generate a fake leave event on the old current character and a
+ * fake enter event on the new current character.
*
* Results:
* None.
*
* Side effects:
- * The current mark for textPtr may change. If it does,
- * then the commands associated with character entry and leave
- * could do just about anything. For example, the text widget
- * might be deleted. It is up to the caller to protect itself
- * with calls to Tcl_Preserve and Tcl_Release.
+ * The current mark for textPtr may change. If it does, then the commands
+ * associated with character entry and leave could do just about
+ * anything. For example, the text widget might be deleted. It is up to
+ * the caller to protect itself by incrementing the refCount of the text
+ * widget.
*
*--------------------------------------------------------------
*/
void
-TkTextPickCurrent(textPtr, eventPtr)
- register TkText *textPtr; /* Text widget in which to select
- * current character. */
- XEvent *eventPtr; /* Event describing location of
- * mouse cursor. Must be EnterWindow,
- * LeaveWindow, ButtonRelease, or
- * MotionNotify. */
+TkTextPickCurrent(
+ register TkText *textPtr, /* Text widget in which to select current
+ * character. */
+ XEvent *eventPtr) /* Event describing location of mouse cursor.
+ * Must be EnterWindow, LeaveWindow,
+ * ButtonRelease, or MotionNotify. */
{
TkTextIndex index;
TkTextTag **oldArrayPtr, **newArrayPtr;
- TkTextTag **copyArrayPtr = NULL; /* Initialization needed to prevent
- * compiler warning. */
-
- int numOldTags, numNewTags, i, j, size;
+ TkTextTag **copyArrayPtr = NULL;
+ /* Initialization needed to prevent compiler
+ * warning. */
+ int numOldTags, numNewTags, i, j, size, nearby;
XEvent event;
/*
- * If a button is down, then don't do anything at all; we'll be
- * called again when all buttons are up, and we can repick then.
- * This implements a form of mouse grabbing.
+ * If a button is down, then don't do anything at all; we'll be called
+ * again when all buttons are up, and we can repick then. This implements
+ * a form of mouse grabbing.
*/
if (textPtr->flags & BUTTON_DOWN) {
- if (((eventPtr->type == EnterNotify) || (eventPtr->type == LeaveNotify))
+ if (((eventPtr->type == EnterNotify)
+ || (eventPtr->type == LeaveNotify))
&& ((eventPtr->xcrossing.mode == NotifyGrab)
|| (eventPtr->xcrossing.mode == NotifyUngrab))) {
/*
- * Special case: the window is being entered or left because
- * of a grab or ungrab. In this case, repick after all.
- * Furthermore, clear BUTTON_DOWN to release the simulated
- * grab.
+ * Special case: the window is being entered or left because of a
+ * grab or ungrab. In this case, repick after all. Furthermore,
+ * clear BUTTON_DOWN to release the simulated grab.
*/
textPtr->flags &= ~BUTTON_DOWN;
@@ -1292,12 +1530,12 @@ TkTextPickCurrent(textPtr, eventPtr)
}
/*
- * Save information about this event in the widget in case we have
- * to synthesize more enter and leave events later (e.g. because a
- * character was deleted, causing a new character to be underneath
- * the mouse cursor). Also translate MotionNotify events into
- * EnterNotify events, since that's what gets reported to event
- * handlers when the current character changes.
+ * Save information about this event in the widget in case we have to
+ * synthesize more enter and leave events later (e.g. because a character
+ * was deleted, causing a new character to be underneath the mouse
+ * cursor). Also translate MotionNotify events into EnterNotify events,
+ * since that's what gets reported to event handlers when the current
+ * character changes.
*/
if (eventPtr != &textPtr->pickEvent) {
@@ -1328,33 +1566,37 @@ TkTextPickCurrent(textPtr, eventPtr)
}
/*
- * Find the new current character, then find and sort all of the
- * tags associated with it.
+ * Find the new current character, then find and sort all of the tags
+ * associated with it.
*/
if (textPtr->pickEvent.type != LeaveNotify) {
TkTextPixelIndex(textPtr, textPtr->pickEvent.xcrossing.x,
- textPtr->pickEvent.xcrossing.y, &index);
- newArrayPtr = TkBTreeGetTags(&index, &numNewTags);
- SortTags(numNewTags, newArrayPtr);
+ textPtr->pickEvent.xcrossing.y, &index, &nearby);
+ if (nearby) {
+ newArrayPtr = NULL;
+ numNewTags = 0;
+ } else {
+ newArrayPtr = TkBTreeGetTags(&index, textPtr, &numNewTags);
+ SortTags(numNewTags, newArrayPtr);
+ }
} else {
newArrayPtr = NULL;
numNewTags = 0;
}
/*
- * Resort the tags associated with the previous marked character
- * (the priorities might have changed), then make a copy of the
- * new tags, and compare the old tags to the copy, nullifying
- * any tags that are present in both groups (i.e. the tags that
- * haven't changed).
+ * Resort the tags associated with the previous marked character (the
+ * priorities might have changed), then make a copy of the new tags, and
+ * compare the old tags to the copy, nullifying any tags that are present
+ * in both groups (i.e. the tags that haven't changed).
*/
SortTags(textPtr->numCurTags, textPtr->curTagArrayPtr);
if (numNewTags > 0) {
size = numNewTags * sizeof(TkTextTag *);
copyArrayPtr = (TkTextTag **) ckalloc((unsigned) size);
- memcpy((VOID *) copyArrayPtr, (VOID *) newArrayPtr, (size_t) size);
+ memcpy(copyArrayPtr, newArrayPtr, (size_t) size);
for (i = 0; i < textPtr->numCurTags; i++) {
for (j = 0; j < numNewTags; j++) {
if (textPtr->curTagArrayPtr[i] == copyArrayPtr[j]) {
@@ -1367,13 +1609,12 @@ TkTextPickCurrent(textPtr, eventPtr)
}
/*
- * Invoke the binding system with a LeaveNotify event for all of
- * the tags that have gone away. We have to be careful here,
- * because it's possible that the binding could do something
- * (like calling tkwait) that eventually modifies
- * textPtr->curTagArrayPtr. To avoid problems in situations like
- * this, update curTagArrayPtr to its new value before invoking
- * any bindings, and don't use it any more here.
+ * Invoke the binding system with a LeaveNotify event for all of the tags
+ * that have gone away. We have to be careful here, because it's possible
+ * that the binding could do something (like calling tkwait) that
+ * eventually modifies textPtr->curTagArrayPtr. To avoid problems in
+ * situations like this, update curTagArrayPtr to its new value before
+ * invoking any bindings, and don't use it any more here.
*/
numOldTags = textPtr->numCurTags;
@@ -1381,41 +1622,120 @@ TkTextPickCurrent(textPtr, eventPtr)
oldArrayPtr = textPtr->curTagArrayPtr;
textPtr->curTagArrayPtr = newArrayPtr;
if (numOldTags != 0) {
- if ((textPtr->bindingTable != NULL) && (textPtr->tkwin != NULL)) {
+ if ((textPtr->sharedTextPtr->bindingTable != NULL)
+ && (textPtr->tkwin != NULL)
+ && !(textPtr->flags & DESTROYED)) {
event = textPtr->pickEvent;
event.type = LeaveNotify;
/*
- * Always use a detail of NotifyAncestor. Besides being
- * consistent, this avoids problems where the binding code
- * will discard NotifyInferior events.
+ * Always use a detail of NotifyAncestor. Besides being
+ * consistent, this avoids problems where the binding code will
+ * discard NotifyInferior events.
*/
event.xcrossing.detail = NotifyAncestor;
- Tk_BindEvent(textPtr->bindingTable, &event, textPtr->tkwin,
- numOldTags, (ClientData *) oldArrayPtr);
+ TagBindEvent(textPtr, &event, numOldTags, oldArrayPtr);
}
ckfree((char *) oldArrayPtr);
}
/*
- * Reset the "current" mark (be careful to recompute its location,
- * since it might have changed during an event binding). Then
- * invoke the binding system with an EnterNotify event for all of
- * the tags that have just appeared.
+ * Reset the "current" mark (be careful to recompute its location, since
+ * it might have changed during an event binding). Then invoke the binding
+ * system with an EnterNotify event for all of the tags that have just
+ * appeared.
*/
TkTextPixelIndex(textPtr, textPtr->pickEvent.xcrossing.x,
- textPtr->pickEvent.xcrossing.y, &index);
+ textPtr->pickEvent.xcrossing.y, &index, &nearby);
TkTextSetMark(textPtr, "current", &index);
if (numNewTags != 0) {
- if ((textPtr->bindingTable != NULL) && (textPtr->tkwin != NULL)) {
+ if ((textPtr->sharedTextPtr->bindingTable != NULL)
+ && (textPtr->tkwin != NULL)
+ && !(textPtr->flags & DESTROYED) && !nearby) {
event = textPtr->pickEvent;
event.type = EnterNotify;
event.xcrossing.detail = NotifyAncestor;
- Tk_BindEvent(textPtr->bindingTable, &event, textPtr->tkwin,
- numNewTags, (ClientData *) copyArrayPtr);
+ TagBindEvent(textPtr, &event, numNewTags, copyArrayPtr);
}
ckfree((char *) copyArrayPtr);
}
}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TagBindEvent --
+ *
+ * Trigger given events for all tags that match the relevant bindings.
+ * To handle the "sel" tag correctly in all peer widgets, we must use the
+ * name of the tags as the binding table element.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Almost anything can be triggered by tag bindings, including deletion
+ * of the text widget.
+ *
+ *--------------------------------------------------------------
+ */
+
+static void
+TagBindEvent(
+ TkText *textPtr, /* Text widget to fire bindings in. */
+ XEvent *eventPtr, /* What actually happened. */
+ int numTags, /* Number of relevant tags. */
+ TkTextTag **tagArrayPtr) /* Array of relevant tags. */
+{
+ #define NUM_BIND_TAGS 10
+ CONST char *nameArray[NUM_BIND_TAGS];
+ CONST char **nameArrPtr;
+ int i;
+
+ /*
+ * Try to avoid allocation unless there are lots of tags.
+ */
+
+ if (numTags > NUM_BIND_TAGS) {
+ nameArrPtr = (CONST char **) ckalloc(numTags * sizeof(CONST char *));
+ } else {
+ nameArrPtr = nameArray;
+ }
+
+ /*
+ * We use tag names as keys in the hash table. We do this instead of using
+ * the actual tagPtr objects because we want one "sel" tag binding for all
+ * peer widgets, despite the fact that each has its own tagPtr object.
+ */
+
+ for (i = 0; i < numTags; i++) {
+ TkTextTag *tagPtr = tagArrayPtr[i];
+ if (tagPtr != NULL) {
+ nameArrPtr[i] = tagPtr->name;
+ } else {
+ /*
+ * Tag has been deleted elsewhere, and therefore nulled out in
+ * this array. Tk_BindEvent is clever enough to cope with NULLs
+ * being thrown at it.
+ */
+
+ nameArrPtr[i] = NULL;
+ }
+ }
+ Tk_BindEvent(textPtr->sharedTextPtr->bindingTable, eventPtr,
+ textPtr->tkwin, numTags, (ClientData *) nameArrPtr);
+
+ if (numTags > NUM_BIND_TAGS) {
+ ckfree((char *) nameArrPtr);
+ }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkTextWind.c b/generic/tkTextWind.c
index 999febe..8d1f850 100644
--- a/generic/tkTextWind.c
+++ b/generic/tkTextWind.c
@@ -1,47 +1,37 @@
-/*
+/*
* tkTextWind.c --
*
- * This file contains code that allows arbitrary windows to be
- * nested inside text widgets. It also implements the "window"
- * widget command for texts.
+ * This file contains code that allows arbitrary windows to be nested
+ * inside text widgets. It also implements the "window" widget command
+ * for texts.
*
* Copyright (c) 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tk.h"
-#include "tkText.h"
#include "tkPort.h"
+#include "tkText.h"
/*
- * The following structure is the official type record for the
- * embedded window geometry manager:
+ * The following structure is the official type record for the embedded window
+ * geometry manager:
*/
-static void EmbWinRequestProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin));
-static void EmbWinLostSlaveProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin));
+static void EmbWinRequestProc(ClientData clientData,
+ Tk_Window tkwin);
+static void EmbWinLostSlaveProc(ClientData clientData,
+ Tk_Window tkwin);
-static Tk_GeomMgr textGeomType = {
+static const Tk_GeomMgr textGeomType = {
"text", /* name */
EmbWinRequestProc, /* requestProc */
EmbWinLostSlaveProc, /* lostSlaveProc */
};
/*
- * Definitions for alignment values:
- */
-
-#define ALIGN_BOTTOM 0
-#define ALIGN_CENTER 1
-#define ALIGN_TOP 2
-#define ALIGN_BASELINE 3
-
-/*
* Macro that determines the size of an embedded window segment:
*/
@@ -49,85 +39,79 @@ static Tk_GeomMgr textGeomType = {
+ sizeof(TkTextEmbWindow)))
/*
- * Prototypes for procedures defined in this file:
+ * Prototypes for functions defined in this file:
*/
-static int AlignParseProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, Tk_Window tkwin,
- CONST char *value, char *widgRec, int offset));
-static char * AlignPrintProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin, char *widgRec, int offset,
- Tcl_FreeProc **freeProcPtr));
-static TkTextSegment * EmbWinCleanupProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr));
-static void EmbWinCheckProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr));
-static void EmbWinBboxProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr,
- int index, int y, int lineHeight, int baseline,
- int *xPtr, int *yPtr, int *widthPtr,
- int *heightPtr));
-static int EmbWinConfigure _ANSI_ARGS_((TkText *textPtr,
- TkTextSegment *ewPtr, int argc, CONST char **argv));
-static void EmbWinDelayedUnmap _ANSI_ARGS_((
- ClientData clientData));
-static int EmbWinDeleteProc _ANSI_ARGS_((TkTextSegment *segPtr,
- TkTextLine *linePtr, int treeGone));
-static void EmbWinDisplayProc _ANSI_ARGS_((
- TkTextDispChunk *chunkPtr, int x, int y,
- int lineHeight, int baseline, Display *display,
- Drawable dst, int screenY));
-static int EmbWinLayoutProc _ANSI_ARGS_((TkText *textPtr,
+static TkTextSegment * EmbWinCleanupProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr);
+static void EmbWinCheckProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr);
+static void EmbWinBboxProc(TkText *textPtr,
+ TkTextDispChunk *chunkPtr, int index, int y,
+ int lineHeight, int baseline, int *xPtr,int *yPtr,
+ int *widthPtr, int *heightPtr);
+static int EmbWinConfigure(TkText *textPtr, TkTextSegment *ewPtr,
+ int objc, Tcl_Obj *const objv[]);
+static void EmbWinDelayedUnmap(ClientData clientData);
+static int EmbWinDeleteProc(TkTextSegment *segPtr,
+ TkTextLine *linePtr, int treeGone);
+static int EmbWinLayoutProc(TkText *textPtr,
TkTextIndex *indexPtr, TkTextSegment *segPtr,
- int offset, int maxX, int maxChars,
- int noCharsYet, TkWrapMode wrapMode,
- TkTextDispChunk *chunkPtr));
-static void EmbWinStructureProc _ANSI_ARGS_((ClientData clientData,
- XEvent *eventPtr));
-static void EmbWinUndisplayProc _ANSI_ARGS_((TkText *textPtr,
- TkTextDispChunk *chunkPtr));
+ int offset, int maxX, int maxChars,int noCharsYet,
+ TkWrapMode wrapMode, TkTextDispChunk *chunkPtr);
+static void EmbWinStructureProc(ClientData clientData,
+ XEvent *eventPtr);
+static void EmbWinUndisplayProc(TkText *textPtr,
+ TkTextDispChunk *chunkPtr);
+static TkTextEmbWindowClient* EmbWinGetClient(const TkText *textPtr,
+ TkTextSegment *ewPtr);
/*
* The following structure declares the "embedded window" segment type.
*/
-static Tk_SegType tkTextEmbWindowType = {
- "window", /* name */
- 0, /* leftGravity */
- (Tk_SegSplitProc *) NULL, /* splitProc */
- EmbWinDeleteProc, /* deleteProc */
- EmbWinCleanupProc, /* cleanupProc */
- (Tk_SegLineChangeProc *) NULL, /* lineChangeProc */
- EmbWinLayoutProc, /* layoutProc */
- EmbWinCheckProc /* checkProc */
+static const Tk_SegType tkTextEmbWindowType = {
+ "window", /* name */
+ 0, /* leftGravity */
+ NULL, /* splitProc */
+ EmbWinDeleteProc, /* deleteProc */
+ EmbWinCleanupProc, /* cleanupProc */
+ NULL, /* lineChangeProc */
+ EmbWinLayoutProc, /* layoutProc */
+ EmbWinCheckProc /* checkProc */
+};
+
+/*
+ * Definitions for alignment values:
+ */
+
+static const char *alignStrings[] = {
+ "baseline", "bottom", "center", "top", NULL
};
+typedef enum {
+ ALIGN_BASELINE, ALIGN_BOTTOM, ALIGN_CENTER, ALIGN_TOP
+} alignMode;
+
/*
* Information used for parsing window configuration options:
*/
-static Tk_CustomOption alignOption = {AlignParseProc, AlignPrintProc,
- (ClientData) NULL};
-
-static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_CUSTOM, "-align", (char *) NULL, (char *) NULL,
- "center", 0, TK_CONFIG_DONT_SET_DEFAULT, &alignOption},
- {TK_CONFIG_STRING, "-create", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextEmbWindow, create),
- TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK},
- {TK_CONFIG_INT, "-padx", (char *) NULL, (char *) NULL,
- "0", Tk_Offset(TkTextEmbWindow, padX),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_INT, "-pady", (char *) NULL, (char *) NULL,
- "0", Tk_Offset(TkTextEmbWindow, padY),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_BOOLEAN, "-stretch", (char *) NULL, (char *) NULL,
- "0", Tk_Offset(TkTextEmbWindow, stretch),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_WINDOW, "-window", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextEmbWindow, tkwin),
- TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+static const Tk_OptionSpec optionSpecs[] = {
+ {TK_OPTION_STRING_TABLE, "-align", NULL, NULL,
+ "center", -1, Tk_Offset(TkTextEmbWindow, align),
+ 0, (ClientData) alignStrings, 0},
+ {TK_OPTION_STRING, "-create", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextEmbWindow, create), TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_PIXELS, "-padx", NULL, NULL,
+ "0", -1, Tk_Offset(TkTextEmbWindow, padX), 0, 0, 0},
+ {TK_OPTION_PIXELS, "-pady", NULL, NULL,
+ "0", -1, Tk_Offset(TkTextEmbWindow, padY), 0, 0, 0},
+ {TK_OPTION_BOOLEAN, "-stretch", NULL, NULL,
+ "0", -1, Tk_Offset(TkTextEmbWindow, stretch), 0, 0, 0},
+ {TK_OPTION_WINDOW, "-window", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextEmbWindow, tkwin), TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_END}
};
/*
@@ -135,9 +119,8 @@ static Tk_ConfigSpec configSpecs[] = {
*
* TkTextWindowCmd --
*
- * This procedure implements the "window" widget command
- * for text widgets. See the user documentation for details
- * on what it does.
+ * This function implements the "window" widget command for text widgets.
+ * See the user documentation for details on what it does.
*
* Results:
* A standard Tcl result or error.
@@ -149,100 +132,154 @@ static Tk_ConfigSpec configSpecs[] = {
*/
int
-TkTextWindowCmd(textPtr, interp, argc, argv)
- register TkText *textPtr; /* Information about text widget. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. Someone else has already
+TkTextWindowCmd(
+ register TkText *textPtr, /* Information about text widget. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. Someone else has already
* parsed this command enough to know that
- * argv[1] is "window". */
+ * objv[1] is "window". */
{
- size_t length;
+ int optionIndex;
+ static const char *windOptionStrings[] = {
+ "cget", "configure", "create", "names", NULL
+ };
+ enum windOptions {
+ WIND_CGET, WIND_CONFIGURE, WIND_CREATE, WIND_NAMES
+ };
register TkTextSegment *ewPtr;
- if (argc < 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " window option ?arg arg ...?\"", (char *) NULL);
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], windOptionStrings,
+ "window option", 0, &optionIndex) != TCL_OK) {
return TCL_ERROR;
}
- length = strlen(argv[2]);
- if ((strncmp(argv[2], "cget", length) == 0) && (length >= 2)) {
+ switch ((enum windOptions) optionIndex) {
+ case WIND_CGET: {
TkTextIndex index;
TkTextSegment *ewPtr;
+ Tcl_Obj *objPtr;
+ TkTextEmbWindowClient *client;
- if (argc != 5) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " window cget index option\"",
- (char *) NULL);
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index option");
return TCL_ERROR;
}
- if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {
+ if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
return TCL_ERROR;
}
- ewPtr = TkTextIndexToSeg(&index, (int *) NULL);
+ ewPtr = TkTextIndexToSeg(&index, NULL);
if (ewPtr->typePtr != &tkTextEmbWindowType) {
Tcl_AppendResult(interp, "no embedded window at index \"",
- argv[3], "\"", (char *) NULL);
+ Tcl_GetString(objv[3]), "\"", NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Copy over client specific value before querying.
+ */
+
+ client = EmbWinGetClient(textPtr, ewPtr);
+ if (client != NULL) {
+ ewPtr->body.ew.tkwin = client->tkwin;
+ } else {
+ ewPtr->body.ew.tkwin = NULL;
+ }
+
+ objPtr = Tk_GetOptionValue(interp, (char *) &ewPtr->body.ew,
+ ewPtr->body.ew.optionTable, objv[4], textPtr->tkwin);
+ if (objPtr == NULL) {
return TCL_ERROR;
}
- return Tk_ConfigureValue(interp, textPtr->tkwin, configSpecs,
- (char *) &ewPtr->body.ew, argv[4], 0);
- } else if ((strncmp(argv[2], "configure", length) == 0) && (length >= 2)) {
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
+ }
+ case WIND_CONFIGURE: {
TkTextIndex index;
TkTextSegment *ewPtr;
- if (argc < 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " window configure index ?option value ...?\"",
- (char *) NULL);
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?");
return TCL_ERROR;
}
- if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {
+ if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
return TCL_ERROR;
}
- ewPtr = TkTextIndexToSeg(&index, (int *) NULL);
+ ewPtr = TkTextIndexToSeg(&index, NULL);
if (ewPtr->typePtr != &tkTextEmbWindowType) {
Tcl_AppendResult(interp, "no embedded window at index \"",
- argv[3], "\"", (char *) NULL);
+ Tcl_GetString(objv[3]), "\"", NULL);
return TCL_ERROR;
}
- if (argc == 4) {
- return Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs,
- (char *) &ewPtr->body.ew, (char *) NULL, 0);
- } else if (argc == 5) {
- return Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs,
- (char *) &ewPtr->body.ew, argv[4], 0);
+ if (objc <= 5) {
+ TkTextEmbWindowClient *client;
+ Tcl_Obj* objPtr;
+
+ /*
+ * Copy over client specific value before querying.
+ */
+
+ client = EmbWinGetClient(textPtr, ewPtr);
+ if (client != NULL) {
+ ewPtr->body.ew.tkwin = client->tkwin;
+ } else {
+ ewPtr->body.ew.tkwin = NULL;
+ }
+
+ objPtr = Tk_GetOptionInfo(interp, (char *) &ewPtr->body.ew,
+ ewPtr->body.ew.optionTable, (objc == 5) ? objv[4] : NULL,
+ textPtr->tkwin);
+ if (objPtr == NULL) {
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
} else {
- TkTextChanged(textPtr, &index, &index);
- return EmbWinConfigure(textPtr, ewPtr, argc-4, argv+4);
+ TkTextChanged(textPtr->sharedTextPtr, NULL, &index, &index);
+
+ /*
+ * It's probably not true that all window configuration can change
+ * the line height, so we could be more efficient here and only
+ * call this when necessary.
+ */
+
+ TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL,
+ index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
+ return EmbWinConfigure(textPtr, ewPtr, objc-4, objv+4);
}
- } else if ((strncmp(argv[2], "create", length) == 0) && (length >= 2)) {
+ }
+ case WIND_CREATE: {
TkTextIndex index;
int lineIndex;
+ TkTextEmbWindowClient *client;
+ int res;
/*
- * Add a new window. Find where to put the new window, and
- * mark that position for redisplay.
+ * Add a new window. Find where to put the new window, and mark that
+ * position for redisplay.
*/
- if (argc < 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " window create index ?option value ...?\"",
- (char *) NULL);
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?");
return TCL_ERROR;
}
- if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {
+ if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
return TCL_ERROR;
}
/*
* Don't allow insertions on the last (dummy) line of the text.
*/
-
- lineIndex = TkBTreeLineIndex(index.linePtr);
- if (lineIndex == TkBTreeNumLines(textPtr->tree)) {
+
+ lineIndex = TkBTreeLinesTo(textPtr, index.linePtr);
+ if (lineIndex == TkBTreeNumLines(textPtr->sharedTextPtr->tree,
+ textPtr)) {
lineIndex--;
- TkTextMakeByteIndex(textPtr->tree, lineIndex, 1000000, &index);
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
+ lineIndex, 1000000, &index);
}
/*
@@ -252,49 +289,61 @@ TkTextWindowCmd(textPtr, interp, argc, argv)
ewPtr = (TkTextSegment *) ckalloc(EW_SEG_SIZE);
ewPtr->typePtr = &tkTextEmbWindowType;
ewPtr->size = 1;
- ewPtr->body.ew.textPtr = textPtr;
+ ewPtr->body.ew.sharedTextPtr = textPtr->sharedTextPtr;
ewPtr->body.ew.linePtr = NULL;
ewPtr->body.ew.tkwin = NULL;
ewPtr->body.ew.create = NULL;
ewPtr->body.ew.align = ALIGN_CENTER;
ewPtr->body.ew.padX = ewPtr->body.ew.padY = 0;
ewPtr->body.ew.stretch = 0;
- ewPtr->body.ew.chunkCount = 0;
- ewPtr->body.ew.displayed = 0;
+ ewPtr->body.ew.optionTable = Tk_CreateOptionTable(interp, optionSpecs);
+
+ client = (TkTextEmbWindowClient *)
+ ckalloc(sizeof(TkTextEmbWindowClient));
+ client->next = NULL;
+ client->textPtr = textPtr;
+ client->tkwin = NULL;
+ client->chunkCount = 0;
+ client->displayed = 0;
+ client->parent = ewPtr;
+ ewPtr->body.ew.clients = client;
/*
- * Link the segment into the text widget, then configure it (delete
- * it again if the configuration fails).
+ * Link the segment into the text widget, then configure it (delete it
+ * again if the configuration fails).
*/
- TkTextChanged(textPtr, &index, &index);
+ TkTextChanged(textPtr->sharedTextPtr, NULL, &index, &index);
TkBTreeLinkSegment(ewPtr, &index);
- if (EmbWinConfigure(textPtr, ewPtr, argc-4, argv+4) != TCL_OK) {
+ res = EmbWinConfigure(textPtr, ewPtr, objc-4, objv+4);
+ client->tkwin = ewPtr->body.ew.tkwin;
+ if (res != TCL_OK) {
TkTextIndex index2;
- TkTextIndexForwChars(&index, 1, &index2);
- TkBTreeDeleteChars(&index, &index2);
+ TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES);
+ TkBTreeDeleteIndexRange(textPtr->sharedTextPtr->tree, &index,
+ &index2);
return TCL_ERROR;
}
- } else if (strncmp(argv[2], "names", length) == 0) {
+ TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL,
+ index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
+ break;
+ }
+ case WIND_NAMES: {
Tcl_HashSearch search;
Tcl_HashEntry *hPtr;
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " window names\"", (char *) NULL);
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
- for (hPtr = Tcl_FirstHashEntry(&textPtr->windowTable, &search);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+ for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->windowTable,
+ &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
Tcl_AppendElement(interp,
- Tcl_GetHashKey(&textPtr->markTable, hPtr));
+ Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr));
}
- } else {
- Tcl_AppendResult(interp, "bad window option \"", argv[2],
- "\": must be cget, configure, create, or names",
- (char *) NULL);
- return TCL_ERROR;
+ break;
+ }
}
return TCL_OK;
}
@@ -304,76 +353,97 @@ TkTextWindowCmd(textPtr, interp, argc, argv)
*
* EmbWinConfigure --
*
- * This procedure is called to handle configuration options
- * for an embedded window, using an argc/argv list.
+ * This function is called to handle configuration options for an
+ * embedded window, using an objc/objv list.
*
* Results:
- * The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then the interp's result contains an error message..
+ * 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 for the embedded window changes,
- * such as alignment, stretching, or name of the embedded
- * window.
+ * Configuration information for the embedded window changes, such as
+ * alignment, stretching, or name of the embedded window.
+ *
+ * Note that this function may leave widget specific client information
+ * with a NULL tkwin attached to ewPtr. While we could choose to clean up
+ * the client data structure here, there is no need to do so, and it is
+ * likely that the user is going to adjust the tkwin again soon.
*
*--------------------------------------------------------------
*/
static int
-EmbWinConfigure(textPtr, ewPtr, argc, argv)
- TkText *textPtr; /* Information about text widget that
- * contains embedded window. */
- TkTextSegment *ewPtr; /* Embedded window to be configured. */
- int argc; /* Number of strings in argv. */
- CONST char **argv; /* Array of strings describing configuration
+EmbWinConfigure(
+ TkText *textPtr, /* Information about text widget that contains
+ * embedded window. */
+ TkTextSegment *ewPtr, /* Embedded window to be configured. */
+ int objc, /* Number of strings in objv. */
+ Tcl_Obj *const objv[]) /* Array of objects describing configuration
* options. */
{
Tk_Window oldWindow;
- Tcl_HashEntry *hPtr;
- int new;
+ TkTextEmbWindowClient *client;
+
+ /*
+ * Copy over client specific value before querying or setting.
+ */
+
+ client = EmbWinGetClient(textPtr, ewPtr);
+ if (client != NULL) {
+ ewPtr->body.ew.tkwin = client->tkwin;
+ } else {
+ ewPtr->body.ew.tkwin = NULL;
+ }
oldWindow = ewPtr->body.ew.tkwin;
- if (Tk_ConfigureWidget(textPtr->interp, textPtr->tkwin, configSpecs,
- argc, argv, (char *) &ewPtr->body.ew, TK_CONFIG_ARGV_ONLY)
- != TCL_OK) {
+ if (Tk_SetOptions(textPtr->interp, (char *) &ewPtr->body.ew,
+ ewPtr->body.ew.optionTable, objc, objv, textPtr->tkwin, NULL,
+ NULL) != TCL_OK) {
return TCL_ERROR;
}
+
if (oldWindow != ewPtr->body.ew.tkwin) {
if (oldWindow != NULL) {
- Tcl_DeleteHashEntry(Tcl_FindHashEntry(&textPtr->windowTable,
+ Tcl_DeleteHashEntry(Tcl_FindHashEntry(
+ &textPtr->sharedTextPtr->windowTable,
Tk_PathName(oldWindow)));
Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
- EmbWinStructureProc, (ClientData) ewPtr);
- Tk_ManageGeometry(oldWindow, (Tk_GeomMgr *) NULL,
- (ClientData) NULL);
+ EmbWinStructureProc, (ClientData) client);
+ Tk_ManageGeometry(oldWindow, NULL, (ClientData) NULL);
if (textPtr->tkwin != Tk_Parent(oldWindow)) {
Tk_UnmaintainGeometry(oldWindow, textPtr->tkwin);
} else {
Tk_UnmapWindow(oldWindow);
}
}
+ if (client != NULL) {
+ client->tkwin = NULL;
+ }
if (ewPtr->body.ew.tkwin != NULL) {
Tk_Window ancestor, parent;
+ Tcl_HashEntry *hPtr;
+ int isNew;
/*
- * Make sure that the text is either the parent of the
- * embedded window or a descendant of that parent. Also,
- * don't allow a top-level window to be managed inside
- * a text.
+ * Make sure that the text is either the parent of the embedded
+ * window or a descendant of that parent. Also, don't allow a
+ * top-level window to be managed inside a text.
*/
parent = Tk_Parent(ewPtr->body.ew.tkwin);
- for (ancestor = textPtr->tkwin; ;
- ancestor = Tk_Parent(ancestor)) {
+ for (ancestor = textPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
if (ancestor == parent) {
break;
}
if (Tk_TopWinHierarchy(ancestor)) {
- badMaster:
+ badMaster:
Tcl_AppendResult(textPtr->interp, "can't embed ",
Tk_PathName(ewPtr->body.ew.tkwin), " in ",
- Tk_PathName(textPtr->tkwin), (char *) NULL);
+ Tk_PathName(textPtr->tkwin), NULL);
ewPtr->body.ew.tkwin = NULL;
+ if (client != NULL) {
+ client->tkwin = NULL;
+ }
return TCL_ERROR;
}
}
@@ -382,28 +452,43 @@ EmbWinConfigure(textPtr, ewPtr, argc, argv)
goto badMaster;
}
+ if (client == NULL) {
+ /*
+ * Have to make the new client.
+ */
+
+ client = (TkTextEmbWindowClient *)
+ ckalloc(sizeof(TkTextEmbWindowClient));
+ client->next = ewPtr->body.ew.clients;
+ client->textPtr = textPtr;
+ client->tkwin = NULL;
+ client->chunkCount = 0;
+ client->displayed = 0;
+ client->parent = ewPtr;
+ ewPtr->body.ew.clients = client;
+ }
+ client->tkwin = ewPtr->body.ew.tkwin;
+
/*
- * Take over geometry management for the window, plus create
- * an event handler to find out when it is deleted.
+ * Take over geometry management for the window, plus create an
+ * event handler to find out when it is deleted.
*/
Tk_ManageGeometry(ewPtr->body.ew.tkwin, &textGeomType,
- (ClientData) ewPtr);
+ (ClientData) client);
Tk_CreateEventHandler(ewPtr->body.ew.tkwin, StructureNotifyMask,
- EmbWinStructureProc, (ClientData) ewPtr);
+ EmbWinStructureProc, (ClientData) client);
/*
- * Special trick! Must enter into the hash table *after*
- * calling Tk_ManageGeometry: if the window was already managed
- * elsewhere in this text, the Tk_ManageGeometry call will cause
- * the entry to be removed, which could potentially lose the new
- * entry.
+ * Special trick! Must enter into the hash table *after* calling
+ * Tk_ManageGeometry: if the window was already managed elsewhere
+ * in this text, the Tk_ManageGeometry call will cause the entry
+ * to be removed, which could potentially lose the new entry.
*/
- hPtr = Tcl_CreateHashEntry(&textPtr->windowTable,
- Tk_PathName(ewPtr->body.ew.tkwin), &new);
+ hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->windowTable,
+ Tk_PathName(ewPtr->body.ew.tkwin), &isNew);
Tcl_SetHashValue(hPtr, ewPtr);
-
}
}
return TCL_OK;
@@ -412,135 +497,54 @@ EmbWinConfigure(textPtr, ewPtr, argc, argv)
/*
*--------------------------------------------------------------
*
- * AlignParseProc --
- *
- * This procedure is invoked by Tk_ConfigureWidget during
- * option processing to handle "-align" options for embedded
- * windows.
- *
- * Results:
- * A standard Tcl return value.
- *
- * Side effects:
- * The alignment for the embedded window may change.
- *
- *--------------------------------------------------------------
- */
-
- /* ARGSUSED */
-static int
-AlignParseProc(clientData, interp, tkwin, value, widgRec, offset)
- ClientData clientData; /* Not used.*/
- Tcl_Interp *interp; /* Used for reporting errors. */
- Tk_Window tkwin; /* Window for text widget. */
- CONST char *value; /* Value of option. */
- char *widgRec; /* Pointer to TkTextEmbWindow
- * structure. */
- int offset; /* Offset into item (ignored). */
-{
- register TkTextEmbWindow *embPtr = (TkTextEmbWindow *) widgRec;
-
- if (strcmp(value, "baseline") == 0) {
- embPtr->align = ALIGN_BASELINE;
- } else if (strcmp(value, "bottom") == 0) {
- embPtr->align = ALIGN_BOTTOM;
- } else if (strcmp(value, "center") == 0) {
- embPtr->align = ALIGN_CENTER;
- } else if (strcmp(value, "top") == 0) {
- embPtr->align = ALIGN_TOP;
- } else {
- Tcl_AppendResult(interp, "bad alignment \"", value,
- "\": must be baseline, bottom, center, or top",
- (char *) NULL);
- return TCL_ERROR;
- }
- return TCL_OK;
-}
-
-/*
- *--------------------------------------------------------------
- *
- * AlignPrintProc --
- *
- * This procedure is invoked by the Tk configuration code
- * to produce a printable string for the "-align" configuration
- * option for embedded windows.
- *
- * Results:
- * The return value is a string describing the embedded
- * window's current alignment.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
- /* ARGSUSED */
-static char *
-AlignPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
- ClientData clientData; /* Ignored. */
- Tk_Window tkwin; /* Window for text widget. */
- char *widgRec; /* Pointer to TkTextEmbWindow
- * structure. */
- int offset; /* Ignored. */
- Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
- * information about how to reclaim
- * storage for return string. */
-{
- switch (((TkTextEmbWindow *) widgRec)->align) {
- case ALIGN_BASELINE:
- return "baseline";
- case ALIGN_BOTTOM:
- return "bottom";
- case ALIGN_CENTER:
- return "center";
- case ALIGN_TOP:
- return "top";
- default:
- return "??";
- }
-}
-
-/*
- *--------------------------------------------------------------
- *
* EmbWinStructureProc --
*
- * This procedure is invoked by the Tk event loop whenever
- * StructureNotify events occur for a window that's embedded
- * in a text widget. This procedure's only purpose is to
- * clean up when windows are deleted.
+ * This function is invoked by the Tk event loop whenever StructureNotify
+ * events occur for a window that's embedded in a text widget. This
+ * function's only purpose is to clean up when windows are deleted.
*
* Results:
* None.
*
* Side effects:
- * The window is disassociated from the window segment, and
- * the portion of the text is redisplayed.
+ * The window is disassociated from the window segment, and the portion
+ * of the text is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-EmbWinStructureProc(clientData, eventPtr)
- ClientData clientData; /* Pointer to record describing window item. */
- XEvent *eventPtr; /* Describes what just happened. */
+EmbWinStructureProc(
+ ClientData clientData, /* Pointer to record describing window item. */
+ XEvent *eventPtr) /* Describes what just happened. */
{
- register TkTextSegment *ewPtr = (TkTextSegment *) clientData;
+ TkTextEmbWindowClient *client = (TkTextEmbWindowClient*)clientData;
+ TkTextSegment *ewPtr = client->parent;
TkTextIndex index;
+ Tcl_HashEntry *hPtr;
if (eventPtr->type != DestroyNotify) {
return;
}
- Tcl_DeleteHashEntry(Tcl_FindHashEntry(&ewPtr->body.ew.textPtr->windowTable,
- Tk_PathName(ewPtr->body.ew.tkwin)));
+ hPtr = Tcl_FindHashEntry(&ewPtr->body.ew.sharedTextPtr->windowTable,
+ Tk_PathName(client->tkwin));
+ if (hPtr != NULL) {
+ /*
+ * This may not exist if the entire widget is being deleted.
+ */
+
+ Tcl_DeleteHashEntry(hPtr);
+ }
+
ewPtr->body.ew.tkwin = NULL;
- index.tree = ewPtr->body.ew.textPtr->tree;
+ client->tkwin = NULL;
+ index.tree = ewPtr->body.ew.sharedTextPtr->tree;
index.linePtr = ewPtr->body.ew.linePtr;
index.byteIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr);
- TkTextChanged(ewPtr->body.ew.textPtr, &index, &index);
+ TkTextChanged(ewPtr->body.ew.sharedTextPtr, NULL, &index, &index);
+ TkTextInvalidateLineMetrics(ewPtr->body.ew.sharedTextPtr, NULL,
+ index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
}
/*
@@ -548,8 +552,8 @@ EmbWinStructureProc(clientData, eventPtr)
*
* EmbWinRequestProc --
*
- * This procedure is invoked whenever a window that's associated
- * with a window canvas item changes its requested dimensions.
+ * This function is invoked whenever a window that's associated with a
+ * window canvas item changes its requested dimensions.
*
* Results:
* None.
@@ -563,18 +567,20 @@ EmbWinStructureProc(clientData, eventPtr)
/* ARGSUSED */
static void
-EmbWinRequestProc(clientData, tkwin)
- ClientData clientData; /* Pointer to record for window item. */
- Tk_Window tkwin; /* Window that changed its desired
- * size. */
+EmbWinRequestProc(
+ ClientData clientData, /* Pointer to record for window item. */
+ Tk_Window tkwin) /* Window that changed its desired size. */
{
- TkTextSegment *ewPtr = (TkTextSegment *) clientData;
+ TkTextEmbWindowClient *client = (TkTextEmbWindowClient*)clientData;
+ TkTextSegment *ewPtr = client->parent;
TkTextIndex index;
- index.tree = ewPtr->body.ew.textPtr->tree;
+ index.tree = ewPtr->body.ew.sharedTextPtr->tree;
index.linePtr = ewPtr->body.ew.linePtr;
index.byteIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr);
- TkTextChanged(ewPtr->body.ew.textPtr, &index, &index);
+ TkTextChanged(ewPtr->body.ew.sharedTextPtr, NULL, &index, &index);
+ TkTextInvalidateLineMetrics(ewPtr->body.ew.sharedTextPtr, NULL,
+ index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
}
/*
@@ -582,44 +588,126 @@ EmbWinRequestProc(clientData, tkwin)
*
* EmbWinLostSlaveProc --
*
- * This procedure is invoked by the Tk geometry manager when
- * a slave window managed by a text widget is claimed away
- * by another geometry manager.
+ * This function is invoked by the Tk geometry manager when a slave
+ * window managed by a text widget is claimed away by another geometry
+ * manager.
*
* Results:
* None.
*
* Side effects:
- * The window is disassociated from the window segment, and
- * the portion of the text is redisplayed.
+ * The window is disassociated from the window segment, and the portion
+ * of the text is redisplayed.
*
*--------------------------------------------------------------
*/
static void
-EmbWinLostSlaveProc(clientData, tkwin)
- ClientData clientData; /* Pointer to record describing window item. */
- Tk_Window tkwin; /* Window that was claimed away by another
+EmbWinLostSlaveProc(
+ ClientData clientData, /* Pointer to record describing window item. */
+ Tk_Window tkwin) /* Window that was claimed away by another
* geometry manager. */
{
- register TkTextSegment *ewPtr = (TkTextSegment *) clientData;
+ TkTextEmbWindowClient *client = (TkTextEmbWindowClient*)clientData;
+ TkTextSegment *ewPtr = client->parent;
TkTextIndex index;
+ Tcl_HashEntry *hPtr;
+ TkTextEmbWindowClient *loop;
- Tk_DeleteEventHandler(ewPtr->body.ew.tkwin, StructureNotifyMask,
- EmbWinStructureProc, (ClientData) ewPtr);
- Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) ewPtr);
- if (ewPtr->body.ew.textPtr->tkwin != Tk_Parent(tkwin)) {
- Tk_UnmaintainGeometry(tkwin, ewPtr->body.ew.textPtr->tkwin);
+ Tk_DeleteEventHandler(client->tkwin, StructureNotifyMask,
+ EmbWinStructureProc, (ClientData) client);
+ Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) client);
+ if (client->textPtr->tkwin != Tk_Parent(tkwin)) {
+ Tk_UnmaintainGeometry(tkwin, client->textPtr->tkwin);
} else {
Tk_UnmapWindow(tkwin);
}
- Tcl_DeleteHashEntry(Tcl_FindHashEntry(&ewPtr->body.ew.textPtr->windowTable,
- Tk_PathName(ewPtr->body.ew.tkwin)));
+ hPtr = Tcl_FindHashEntry(&ewPtr->body.ew.sharedTextPtr->windowTable,
+ Tk_PathName(client->tkwin));
+ Tcl_DeleteHashEntry(hPtr);
+ client->tkwin = NULL;
ewPtr->body.ew.tkwin = NULL;
- index.tree = ewPtr->body.ew.textPtr->tree;
+
+ /*
+ * Free up the memory allocation for this client.
+ */
+
+ loop = ewPtr->body.ew.clients;
+ if (loop == client) {
+ ewPtr->body.ew.clients = client->next;
+ } else {
+ while (loop->next != client) {
+ loop = loop->next;
+ }
+ loop->next = client->next;
+ }
+ ckfree((char *) client);
+
+ index.tree = ewPtr->body.ew.sharedTextPtr->tree;
index.linePtr = ewPtr->body.ew.linePtr;
index.byteIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr);
- TkTextChanged(ewPtr->body.ew.textPtr, &index, &index);
+ TkTextChanged(ewPtr->body.ew.sharedTextPtr, NULL, &index, &index);
+ TkTextInvalidateLineMetrics(ewPtr->body.ew.sharedTextPtr, NULL,
+ index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TkTextWinFreeClient --
+ *
+ * Free up the hash entry and client information for a given embedded
+ * window.
+ *
+ * It is assumed the caller will manage the linked list of clients
+ * associated with the relevant TkTextSegment.
+ *
+ * Results:
+ * Nothing.
+ *
+ * Side effects:
+ * The embedded window information for a single client is deleted, if it
+ * exists, and any resources associated with it are released.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+TkTextWinFreeClient(
+ Tcl_HashEntry *hPtr, /* Hash entry corresponding to this client, or
+ * NULL */
+ TkTextEmbWindowClient *client)
+ /* Client data structure, with the 'tkwin'
+ * field to be cleaned up. */
+{
+ if (hPtr != NULL) {
+ /*
+ * (It's possible for there to be no hash table entry for this window,
+ * if an error occurred while creating the window segment but before
+ * the window got added to the table)
+ */
+
+ Tcl_DeleteHashEntry(hPtr);
+ }
+
+ /*
+ * Delete the event handler for the window before destroying the window,
+ * so that EmbWinStructureProc doesn't get called (we'll already do
+ * everything that it would have done, and it will just get confused).
+ */
+
+ if (client->tkwin != NULL) {
+ Tk_DeleteEventHandler(client->tkwin, StructureNotifyMask,
+ EmbWinStructureProc, (ClientData) client);
+ Tk_DestroyWindow(client->tkwin);
+ }
+ Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) client);
+
+ /*
+ * Free up this client.
+ */
+
+ ckfree((char *) client);
}
/*
@@ -627,8 +715,8 @@ EmbWinLostSlaveProc(clientData, tkwin)
*
* EmbWinDeleteProc --
*
- * This procedure is invoked by the text B-tree code whenever
- * an embedded window lies in a range of characters being deleted.
+ * This function is invoked by the text B-tree code whenever an embedded
+ * window lies in a range of characters being deleted.
*
* Results:
* Returns 0 to indicate that the deletion has been accepted.
@@ -642,42 +730,37 @@ EmbWinLostSlaveProc(clientData, tkwin)
/* ARGSUSED */
static int
-EmbWinDeleteProc(ewPtr, linePtr, treeGone)
- TkTextSegment *ewPtr; /* Segment being deleted. */
- TkTextLine *linePtr; /* Line containing segment. */
- int treeGone; /* Non-zero means the entire tree is
- * being deleted, so everything must
- * get cleaned up. */
+EmbWinDeleteProc(
+ TkTextSegment *ewPtr, /* Segment being deleted. */
+ TkTextLine *linePtr, /* Line containing segment. */
+ int treeGone) /* Non-zero means the entire tree is being
+ * deleted, so everything must get cleaned
+ * up. */
{
- Tcl_HashEntry *hPtr;
+ TkTextEmbWindowClient *client;
+ client = ewPtr->body.ew.clients;
- if (ewPtr->body.ew.tkwin != NULL) {
- hPtr = Tcl_FindHashEntry(&ewPtr->body.ew.textPtr->windowTable,
- Tk_PathName(ewPtr->body.ew.tkwin));
- if (hPtr != NULL) {
- /*
- * (It's possible for there to be no hash table entry for this
- * window, if an error occurred while creating the window segment
- * but before the window got added to the table)
- */
+ while (client != NULL) {
+ TkTextEmbWindowClient *next = client->next;
+ Tcl_HashEntry *hPtr = NULL;
- Tcl_DeleteHashEntry(hPtr);
+ if (client->tkwin != NULL) {
+ hPtr = Tcl_FindHashEntry(
+ &ewPtr->body.ew.sharedTextPtr->windowTable,
+ Tk_PathName(client->tkwin));
}
+ TkTextWinFreeClient(hPtr, client);
+ client = next;
+ }
+ ewPtr->body.ew.clients = NULL;
- /*
- * Delete the event handler for the window before destroying
- * the window, so that EmbWinStructureProc doesn't get called
- * (we'll already do everything that it would have done, and
- * it will just get confused).
- */
+ Tk_FreeConfigOptions((char *) &ewPtr->body.ew, ewPtr->body.ew.optionTable,
+ NULL);
+
+ /*
+ * Free up all memory allocated.
+ */
- Tk_DeleteEventHandler(ewPtr->body.ew.tkwin, StructureNotifyMask,
- EmbWinStructureProc, (ClientData) ewPtr);
- Tk_DestroyWindow(ewPtr->body.ew.tkwin);
- }
- Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) ewPtr);
- Tk_FreeOptions(configSpecs, (char *) &ewPtr->body.ew,
- ewPtr->body.ew.textPtr->display, 0);
ckfree((char *) ewPtr);
return 0;
}
@@ -687,9 +770,8 @@ EmbWinDeleteProc(ewPtr, linePtr, treeGone)
*
* EmbWinCleanupProc --
*
- * This procedure is invoked by the B-tree code whenever a
- * segment containing an embedded window is moved from one
- * line to another.
+ * This function is invoked by the B-tree code whenever a segment
+ * containing an embedded window is moved from one line to another.
*
* Results:
* None.
@@ -701,9 +783,9 @@ EmbWinDeleteProc(ewPtr, linePtr, treeGone)
*/
static TkTextSegment *
-EmbWinCleanupProc(ewPtr, linePtr)
- TkTextSegment *ewPtr; /* Mark segment that's being moved. */
- TkTextLine *linePtr; /* Line that now contains segment. */
+EmbWinCleanupProc(
+ TkTextSegment *ewPtr, /* Mark segment that's being moved. */
+ TkTextLine *linePtr) /* Line that now contains segment. */
{
ewPtr->body.ew.linePtr = linePtr;
return ewPtr;
@@ -714,12 +796,11 @@ EmbWinCleanupProc(ewPtr, linePtr)
*
* EmbWinLayoutProc --
*
- * This procedure is the "layoutProc" for embedded window
- * segments.
+ * This function is the "layoutProc" for embedded window segments.
*
* Results:
- * 1 is returned to indicate that the segment should be
- * displayed. The chunkPtr structure is filled in.
+ * 1 is returned to indicate that the segment should be displayed. The
+ * chunkPtr structure is filled in.
*
* Side effects:
* None, except for filling in chunkPtr.
@@ -729,49 +810,105 @@ EmbWinCleanupProc(ewPtr, linePtr)
/*ARGSUSED*/
static int
-EmbWinLayoutProc(textPtr, indexPtr, ewPtr, offset, maxX, maxChars,
- noCharsYet, wrapMode, chunkPtr)
- TkText *textPtr; /* Text widget being layed out. */
- TkTextIndex *indexPtr; /* Identifies first character in chunk. */
- TkTextSegment *ewPtr; /* Segment corresponding to indexPtr. */
- int offset; /* Offset within segPtr corresponding to
+EmbWinLayoutProc(
+ TkText *textPtr, /* Text widget being layed out. */
+ TkTextIndex *indexPtr, /* Identifies first character in chunk. */
+ TkTextSegment *ewPtr, /* Segment corresponding to indexPtr. */
+ int offset, /* Offset within segPtr corresponding to
* indexPtr (always 0). */
- int maxX; /* Chunk must not occupy pixels at this
+ int maxX, /* Chunk must not occupy pixels at this
* position or higher. */
- int maxChars; /* Chunk must not include more than this
- * many characters. */
- int noCharsYet; /* Non-zero means no characters have been
+ int maxChars, /* Chunk must not include more than this many
+ * characters. */
+ int noCharsYet, /* Non-zero means no characters have been
* assigned to this line yet. */
- TkWrapMode wrapMode; /* Wrap mode to use for line: TEXT_WRAPMODE_CHAR,
- * TEXT_WRAPMODE_NONE, or TEXT_WRAPMODE_WORD. */
- register TkTextDispChunk *chunkPtr;
- /* Structure to fill in with information
- * about this chunk. The x field has already
- * been set by the caller. */
+ TkWrapMode wrapMode, /* Wrap mode to use for line:
+ * TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, or
+ * TEXT_WRAPMODE_WORD. */
+ register TkTextDispChunk *chunkPtr)
+ /* Structure to fill in with information about
+ * this chunk. The x field has already been
+ * set by the caller. */
{
int width, height;
+ TkTextEmbWindowClient *client;
if (offset != 0) {
- panic("Non-zero offset in EmbWinLayoutProc");
+ Tcl_Panic("Non-zero offset in EmbWinLayoutProc");
+ }
+
+ client = EmbWinGetClient(textPtr, ewPtr);
+ if (client == NULL) {
+ ewPtr->body.ew.tkwin = NULL;
+ } else {
+ ewPtr->body.ew.tkwin = client->tkwin;
}
if ((ewPtr->body.ew.tkwin == NULL) && (ewPtr->body.ew.create != NULL)) {
- int code, new;
- Tcl_DString name;
+ int code, isNew;
Tk_Window ancestor;
Tcl_HashEntry *hPtr;
+ const char *before, *string;
+ Tcl_DString name, buf, *dsPtr = NULL;
+
+ before = ewPtr->body.ew.create;
/*
- * The window doesn't currently exist. Create it by evaluating
- * the creation script. The script must return the window's
- * path name: look up that name to get back to the window
- * token. Then register ourselves as the geometry manager for
- * the window.
+ * Find everything up to the next % character and append it to the
+ * result string.
*/
- code = Tcl_EvalEx(textPtr->interp, ewPtr->body.ew.create, -1, TCL_EVAL_GLOBAL);
+ string = before;
+ while (*string != 0) {
+ if ((*string == '%') && (string[1] == '%' || string[1] == 'W')) {
+ if (dsPtr == NULL) {
+ Tcl_DStringInit(&buf);
+ dsPtr = &buf;
+ }
+ if (string != before) {
+ Tcl_DStringAppend(dsPtr, before, (int) (string-before));
+ before = string;
+ }
+ if (string[1] == '%') {
+ Tcl_DStringAppend(dsPtr, "%", 1);
+ } else {
+ /*
+ * Substitute string as proper Tcl list element.
+ */
+
+ int spaceNeeded, cvtFlags, length;
+ const char *str = Tk_PathName(textPtr->tkwin);
+
+ spaceNeeded = Tcl_ScanElement(str, &cvtFlags);
+ length = Tcl_DStringLength(dsPtr);
+ Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
+ spaceNeeded = Tcl_ConvertElement(str,
+ Tcl_DStringValue(dsPtr) + length,
+ cvtFlags | TCL_DONT_USE_BRACES);
+ Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
+ }
+ before += 2;
+ string++;
+ }
+ string++;
+ }
+
+ /*
+ * The window doesn't currently exist. Create it by evaluating the
+ * creation script. The script must return the window's path name:
+ * look up that name to get back to the window token. Then register
+ * ourselves as the geometry manager for the window.
+ */
+
+ if (dsPtr != NULL) {
+ Tcl_DStringAppend(dsPtr, before, (int) (string-before));
+ code = Tcl_EvalEx(textPtr->interp, Tcl_DStringValue(dsPtr), -1, TCL_EVAL_GLOBAL);
+ Tcl_DStringFree(dsPtr);
+ } else {
+ code = Tcl_EvalEx(textPtr->interp, ewPtr->body.ew.create, -1, TCL_EVAL_GLOBAL);
+ }
if (code != TCL_OK) {
- createError:
+ createError:
Tcl_BackgroundError(textPtr->interp);
goto gotWindow;
}
@@ -780,19 +917,19 @@ EmbWinLayoutProc(textPtr, indexPtr, ewPtr, offset, maxX, maxChars,
Tcl_ResetResult(textPtr->interp);
ewPtr->body.ew.tkwin = Tk_NameToWindow(textPtr->interp,
Tcl_DStringValue(&name), textPtr->tkwin);
+ Tcl_DStringFree(&name);
if (ewPtr->body.ew.tkwin == NULL) {
goto createError;
}
- for (ancestor = textPtr->tkwin; ;
- ancestor = Tk_Parent(ancestor)) {
+ for (ancestor = textPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
if (ancestor == Tk_Parent(ewPtr->body.ew.tkwin)) {
break;
}
if (Tk_TopWinHierarchy(ancestor)) {
- badMaster:
+ badMaster:
Tcl_AppendResult(textPtr->interp, "can't embed ",
Tk_PathName(ewPtr->body.ew.tkwin), " relative to ",
- Tk_PathName(textPtr->tkwin), (char *) NULL);
+ Tk_PathName(textPtr->tkwin), NULL);
Tcl_BackgroundError(textPtr->interp);
ewPtr->body.ew.tkwin = NULL;
goto gotWindow;
@@ -802,21 +939,39 @@ EmbWinLayoutProc(textPtr, indexPtr, ewPtr, offset, maxX, maxChars,
|| (textPtr->tkwin == ewPtr->body.ew.tkwin)) {
goto badMaster;
}
- Tk_ManageGeometry(ewPtr->body.ew.tkwin, &textGeomType,
- (ClientData) ewPtr);
- Tk_CreateEventHandler(ewPtr->body.ew.tkwin, StructureNotifyMask,
- EmbWinStructureProc, (ClientData) ewPtr);
+
+ if (client == NULL) {
+ /*
+ * We just used a '-create' script to make a new window, which we
+ * now need to add to our client list.
+ */
+
+ client = (TkTextEmbWindowClient *)
+ ckalloc(sizeof(TkTextEmbWindowClient));
+ client->next = ewPtr->body.ew.clients;
+ client->textPtr = textPtr;
+ client->tkwin = NULL;
+ client->chunkCount = 0;
+ client->displayed = 0;
+ client->parent = ewPtr;
+ ewPtr->body.ew.clients = client;
+ }
+
+ client->tkwin = ewPtr->body.ew.tkwin;
+ Tk_ManageGeometry(client->tkwin, &textGeomType,
+ (ClientData) client);
+ Tk_CreateEventHandler(client->tkwin, StructureNotifyMask,
+ EmbWinStructureProc, (ClientData) client);
/*
- * Special trick! Must enter into the hash table *after*
- * calling Tk_ManageGeometry: if the window was already managed
- * elsewhere in this text, the Tk_ManageGeometry call will cause
- * the entry to be removed, which could potentially lose the new
- * entry.
+ * Special trick! Must enter into the hash table *after* calling
+ * Tk_ManageGeometry: if the window was already managed elsewhere in
+ * this text, the Tk_ManageGeometry call will cause the entry to be
+ * removed, which could potentially lose the new entry.
*/
- hPtr = Tcl_CreateHashEntry(&textPtr->windowTable,
- Tk_PathName(ewPtr->body.ew.tkwin), &new);
+ hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->windowTable,
+ Tk_PathName(client->tkwin), &isNew);
Tcl_SetHashValue(hPtr, ewPtr);
}
@@ -824,7 +979,7 @@ EmbWinLayoutProc(textPtr, indexPtr, ewPtr, offset, maxX, maxChars,
* See if there's room for this window on this line.
*/
- gotWindow:
+ gotWindow:
if (ewPtr->body.ew.tkwin == NULL) {
width = 0;
height = 0;
@@ -841,9 +996,9 @@ EmbWinLayoutProc(textPtr, indexPtr, ewPtr, offset, maxX, maxChars,
* Fill in the chunk structure.
*/
- chunkPtr->displayProc = EmbWinDisplayProc;
+ chunkPtr->displayProc = TkTextEmbWinDisplayProc;
chunkPtr->undisplayProc = EmbWinUndisplayProc;
- chunkPtr->measureProc = (Tk_ChunkMeasureProc *) NULL;
+ chunkPtr->measureProc = NULL;
chunkPtr->bboxProc = EmbWinBboxProc;
chunkPtr->numBytes = 1;
if (ewPtr->body.ew.align == ALIGN_BASELINE) {
@@ -859,7 +1014,9 @@ EmbWinLayoutProc(textPtr, indexPtr, ewPtr, offset, maxX, maxChars,
chunkPtr->breakIndex = -1;
chunkPtr->breakIndex = 1;
chunkPtr->clientData = (ClientData) ewPtr;
- ewPtr->body.ew.chunkCount += 1;
+ if (client != NULL) {
+ client->chunkCount += 1;
+ }
return 1;
}
@@ -868,84 +1025,89 @@ EmbWinLayoutProc(textPtr, indexPtr, ewPtr, offset, maxX, maxChars,
*
* EmbWinCheckProc --
*
- * This procedure is invoked by the B-tree code to perform
- * consistency checks on embedded windows.
+ * This function is invoked by the B-tree code to perform consistency
+ * checks on embedded windows.
*
* Results:
* None.
*
* Side effects:
- * The procedure panics if it detects anything wrong with
- * the embedded window.
+ * The function panics if it detects anything wrong with the embedded
+ * window.
*
*--------------------------------------------------------------
*/
static void
-EmbWinCheckProc(ewPtr, linePtr)
- TkTextSegment *ewPtr; /* Segment to check. */
- TkTextLine *linePtr; /* Line containing segment. */
+EmbWinCheckProc(
+ TkTextSegment *ewPtr, /* Segment to check. */
+ TkTextLine *linePtr) /* Line containing segment. */
{
if (ewPtr->nextPtr == NULL) {
- panic("EmbWinCheckProc: embedded window is last segment in line");
+ Tcl_Panic("EmbWinCheckProc: embedded window is last segment in line");
}
if (ewPtr->size != 1) {
- panic("EmbWinCheckProc: embedded window has size %d", ewPtr->size);
+ Tcl_Panic("EmbWinCheckProc: embedded window has size %d", ewPtr->size);
}
}
/*
*--------------------------------------------------------------
*
- * EmbWinDisplayProc --
+ * TkTextEmbWinDisplayProc --
*
- * This procedure is invoked by the text displaying code
- * when it is time to actually draw an embedded window
- * chunk on the screen.
+ * This function is invoked by the text displaying code when it is time
+ * to actually draw an embedded window chunk on the screen.
*
* Results:
* None.
*
* Side effects:
- * The embedded window gets moved to the correct location
- * and mapped onto the screen.
+ * The embedded window gets moved to the correct location and mapped onto
+ * the screen.
*
*--------------------------------------------------------------
*/
-static void
-EmbWinDisplayProc(chunkPtr, x, y, lineHeight, baseline, display, dst, screenY)
- TkTextDispChunk *chunkPtr; /* Chunk that is to be drawn. */
- int x; /* X-position in dst at which to
- * draw this chunk (differs from
- * the x-position in the chunk because
- * of scrolling). */
- int y; /* Top of rectangular bounding box
- * for line: tells where to draw this
- * chunk in dst (x-position is in
- * the chunk itself). */
- int lineHeight; /* Total height of line. */
- int baseline; /* Offset of baseline from y. */
- Display *display; /* Display to use for drawing. */
- Drawable dst; /* Pixmap or window in which to draw */
- int screenY; /* Y-coordinate in text window that
- * corresponds to y. */
+void
+TkTextEmbWinDisplayProc(
+ TkText *textPtr, /* Information about text widget. */
+ TkTextDispChunk *chunkPtr, /* Chunk that is to be drawn. */
+ int x, /* X-position in dst at which to draw this
+ * chunk (differs from the x-position in the
+ * chunk because of scrolling). */
+ int y, /* Top of rectangular bounding box for line:
+ * tells where to draw this chunk in dst
+ * (x-position is in the chunk itself). */
+ int lineHeight, /* Total height of line. */
+ int baseline, /* Offset of baseline from y. */
+ Display *display, /* Display to use for drawing (unused). */
+ Drawable dst, /* Pixmap or window in which to draw
+ * (unused). */
+ int screenY) /* Y-coordinate in text window that
+ * corresponds to y. */
{
- TkTextSegment *ewPtr = (TkTextSegment *) chunkPtr->clientData;
int lineX, windowX, windowY, width, height;
Tk_Window tkwin;
+ TkTextSegment *ewPtr = (TkTextSegment*) chunkPtr->clientData;
+ TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);
- tkwin = ewPtr->body.ew.tkwin;
+ if (client == NULL) {
+ return;
+ }
+
+ tkwin = client->tkwin;
if (tkwin == NULL) {
return;
}
+
if ((x + chunkPtr->width) <= 0) {
/*
- * The window is off-screen; just unmap it.
+ * The window is off-screen; just unmap it.
*/
- if (ewPtr->body.ew.textPtr->tkwin != Tk_Parent(tkwin)) {
- Tk_UnmaintainGeometry(tkwin, ewPtr->body.ew.textPtr->tkwin);
+ if (textPtr->tkwin != Tk_Parent(tkwin)) {
+ Tk_UnmaintainGeometry(tkwin, textPtr->tkwin);
} else {
Tk_UnmapWindow(tkwin);
}
@@ -953,15 +1115,15 @@ EmbWinDisplayProc(chunkPtr, x, y, lineHeight, baseline, display, dst, screenY)
}
/*
- * Compute the window's location and size in the text widget, taking
- * into account the align and stretch values for the window.
+ * Compute the window's location and size in the text widget, taking into
+ * account the align and stretch values for the window.
*/
- EmbWinBboxProc(chunkPtr, 0, screenY, lineHeight, baseline, &lineX,
- &windowY, &width, &height);
+ EmbWinBboxProc(textPtr, chunkPtr, 0, screenY, lineHeight, baseline,
+ &lineX, &windowY, &width, &height);
windowX = lineX - chunkPtr->x + x;
- if (ewPtr->body.ew.textPtr->tkwin == Tk_Parent(tkwin)) {
+ if (textPtr->tkwin == Tk_Parent(tkwin)) {
if ((windowX != Tk_X(tkwin)) || (windowY != Tk_Y(tkwin))
|| (Tk_ReqWidth(tkwin) != Tk_Width(tkwin))
|| (height != Tk_Height(tkwin))) {
@@ -969,15 +1131,15 @@ EmbWinDisplayProc(chunkPtr, x, y, lineHeight, baseline, display, dst, screenY)
}
Tk_MapWindow(tkwin);
} else {
- Tk_MaintainGeometry(tkwin, ewPtr->body.ew.textPtr->tkwin,
- windowX, windowY, width, height);
+ Tk_MaintainGeometry(tkwin, textPtr->tkwin, windowX, windowY,
+ width, height);
}
/*
* Mark the window as displayed so that it won't get unmapped.
*/
- ewPtr->body.ew.displayed = 1;
+ client->displayed = 1;
}
/*
@@ -985,9 +1147,9 @@ EmbWinDisplayProc(chunkPtr, x, y, lineHeight, baseline, display, dst, screenY)
*
* EmbWinUndisplayProc --
*
- * This procedure is called when the chunk for an embedded
- * window is no longer going to be displayed. It arranges
- * for the window associated with the chunk to be unmapped.
+ * This function is called when the chunk for an embedded window is no
+ * longer going to be displayed. It arranges for the window associated
+ * with the chunk to be unmapped.
*
* Results:
* None.
@@ -999,25 +1161,29 @@ EmbWinDisplayProc(chunkPtr, x, y, lineHeight, baseline, display, dst, screenY)
*/
static void
-EmbWinUndisplayProc(textPtr, chunkPtr)
- TkText *textPtr; /* Overall information about text
- * widget. */
- TkTextDispChunk *chunkPtr; /* Chunk that is about to be freed. */
+EmbWinUndisplayProc(
+ TkText *textPtr, /* Overall information about text widget. */
+ TkTextDispChunk *chunkPtr) /* Chunk that is about to be freed. */
{
- TkTextSegment *ewPtr = (TkTextSegment *) chunkPtr->clientData;
+ TkTextSegment *ewPtr = (TkTextSegment*) chunkPtr->clientData;
+ TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);
- ewPtr->body.ew.chunkCount--;
- if (ewPtr->body.ew.chunkCount == 0) {
+ if (client == NULL) {
+ return;
+ }
+
+ client->chunkCount--;
+ if (client->chunkCount == 0) {
/*
* Don't unmap the window immediately, since there's a good chance
- * that it will immediately be redisplayed, perhaps even in the
- * same place. Instead, schedule the window to be unmapped later;
- * the call to EmbWinDelayedUnmap will be cancelled in the likely
- * event that the unmap becomes unnecessary.
+ * that it will immediately be redisplayed, perhaps even in the same
+ * place. Instead, schedule the window to be unmapped later; the call
+ * to EmbWinDelayedUnmap will be cancelled in the likely event that
+ * the unmap becomes unnecessary.
*/
- ewPtr->body.ew.displayed = 0;
- Tcl_DoWhenIdle(EmbWinDelayedUnmap, (ClientData) ewPtr);
+ client->displayed = 0;
+ Tcl_DoWhenIdle(EmbWinDelayedUnmap, (ClientData) client);
}
}
@@ -1026,17 +1192,16 @@ EmbWinUndisplayProc(textPtr, chunkPtr)
*
* EmbWinBboxProc --
*
- * This procedure is called to compute the bounding box of
- * the area occupied by an embedded window.
+ * This function is called to compute the bounding box of the area
+ * occupied by an embedded window.
*
* Results:
- * There is no return value. *xPtr and *yPtr are filled in
- * with the coordinates of the upper left corner of the
- * window, and *widthPtr and *heightPtr are filled in with
- * the dimensions of the window in pixels. Note: not all
- * of the returned bbox is necessarily visible on the screen
- * (the rightmost part might be off-screen to the right,
- * and the bottommost part might be off-screen to the bottom).
+ * There is no return value. *xPtr and *yPtr are filled in with the
+ * coordinates of the upper left corner of the window, and *widthPtr and
+ * *heightPtr are filled in with the dimensions of the window in pixels.
+ * Note: not all of the returned bbox is necessarily visible on the
+ * screen (the rightmost part might be off-screen to the right, and the
+ * bottommost part might be off-screen to the bottom).
*
* Side effects:
* None.
@@ -1045,27 +1210,32 @@ EmbWinUndisplayProc(textPtr, chunkPtr)
*/
static void
-EmbWinBboxProc(chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr,
- widthPtr, heightPtr)
- TkTextDispChunk *chunkPtr; /* Chunk containing desired char. */
- int index; /* Index of desired character within
- * the chunk. */
- int y; /* Topmost pixel in area allocated
- * for this line. */
- int lineHeight; /* Total height of line. */
- int baseline; /* Location of line's baseline, in
- * pixels measured down from y. */
- int *xPtr, *yPtr; /* Gets filled in with coords of
- * character's upper-left pixel. */
- int *widthPtr; /* Gets filled in with width of
- * character, in pixels. */
- int *heightPtr; /* Gets filled in with height of
- * character, in pixels. */
+EmbWinBboxProc(
+ TkText *textPtr, /* Information about text widget. */
+ TkTextDispChunk *chunkPtr, /* Chunk containing desired char. */
+ int index, /* Index of desired character within the
+ * chunk. */
+ int y, /* Topmost pixel in area allocated for this
+ * line. */
+ int lineHeight, /* Total height of line. */
+ int baseline, /* Location of line's baseline, in pixels
+ * measured down from y. */
+ int *xPtr, int *yPtr, /* Gets filled in with coords of character's
+ * upper-left pixel. */
+ int *widthPtr, /* Gets filled in with width of window, in
+ * pixels. */
+ int *heightPtr) /* Gets filled in with height of window, in
+ * pixels. */
{
- TkTextSegment *ewPtr = (TkTextSegment *) chunkPtr->clientData;
Tk_Window tkwin;
+ TkTextSegment *ewPtr = (TkTextSegment *) chunkPtr->clientData;
+ TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);
- tkwin = ewPtr->body.ew.tkwin;
+ if (client == NULL) {
+ tkwin = NULL;
+ } else {
+ tkwin = client->tkwin;
+ }
if (tkwin != NULL) {
*widthPtr = Tk_ReqWidth(tkwin);
*heightPtr = Tk_ReqHeight(tkwin);
@@ -1082,18 +1252,18 @@ EmbWinBboxProc(chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr,
}
}
switch (ewPtr->body.ew.align) {
- case ALIGN_BOTTOM:
- *yPtr = y + (lineHeight - *heightPtr - ewPtr->body.ew.padY);
- break;
- case ALIGN_CENTER:
- *yPtr = y + (lineHeight - *heightPtr)/2;
- break;
- case ALIGN_TOP:
- *yPtr = y + ewPtr->body.ew.padY;
- break;
- case ALIGN_BASELINE:
- *yPtr = y + (baseline - *heightPtr);
- break;
+ case ALIGN_BOTTOM:
+ *yPtr = y + (lineHeight - *heightPtr - ewPtr->body.ew.padY);
+ break;
+ case ALIGN_CENTER:
+ *yPtr = y + (lineHeight - *heightPtr)/2;
+ break;
+ case ALIGN_TOP:
+ *yPtr = y + ewPtr->body.ew.padY;
+ break;
+ case ALIGN_BASELINE:
+ *yPtr = y + (baseline - *heightPtr);
+ break;
}
}
@@ -1102,33 +1272,31 @@ EmbWinBboxProc(chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr,
*
* EmbWinDelayedUnmap --
*
- * This procedure is an idle handler that does the actual
- * work of unmapping an embedded window. See the comment
- * in EmbWinUndisplayProc for details.
+ * This function is an idle handler that does the actual work of
+ * unmapping an embedded window. See the comment in EmbWinUndisplayProc
+ * for details.
*
* Results:
* None.
*
* Side effects:
- * The window gets unmapped, unless its chunk reference count
- * has become non-zero again.
+ * The window gets unmapped, unless its chunk reference count has become
+ * non-zero again.
*
*--------------------------------------------------------------
*/
static void
-EmbWinDelayedUnmap(clientData)
- ClientData clientData; /* Token for the window to
- * be unmapped. */
+EmbWinDelayedUnmap(
+ ClientData clientData) /* Token for the window to be unmapped. */
{
- TkTextSegment *ewPtr = (TkTextSegment *) clientData;
+ TkTextEmbWindowClient *client = (TkTextEmbWindowClient*) clientData;
- if (!ewPtr->body.ew.displayed && (ewPtr->body.ew.tkwin != NULL)) {
- if (ewPtr->body.ew.textPtr->tkwin != Tk_Parent(ewPtr->body.ew.tkwin)) {
- Tk_UnmaintainGeometry(ewPtr->body.ew.tkwin,
- ewPtr->body.ew.textPtr->tkwin);
+ if (!client->displayed && (client->tkwin != NULL)) {
+ if (client->textPtr->tkwin != Tk_Parent(client->tkwin)) {
+ Tk_UnmaintainGeometry(client->tkwin, client->textPtr->tkwin);
} else {
- Tk_UnmapWindow(ewPtr->body.ew.tkwin);
+ Tk_UnmapWindow(client->tkwin);
}
}
}
@@ -1138,14 +1306,13 @@ EmbWinDelayedUnmap(clientData)
*
* TkTextWindowIndex --
*
- * Given the name of an embedded window within a text widget,
- * returns an index corresponding to the window's position
- * in the text.
+ * Given the name of an embedded window within a text widget, returns an
+ * index corresponding to the window's position in the text.
*
* Results:
- * The return value is 1 if there is an embedded window by
- * the given name in the text widget, 0 otherwise. If the
- * window exists, *indexPtr is filled in with its index.
+ * The return value is 1 if there is an embedded window by the given name
+ * in the text widget, 0 otherwise. If the window exists, *indexPtr is
+ * filled in with its index.
*
* Side effects:
* None.
@@ -1154,21 +1321,74 @@ EmbWinDelayedUnmap(clientData)
*/
int
-TkTextWindowIndex(textPtr, name, indexPtr)
- TkText *textPtr; /* Text widget containing window. */
- CONST char *name; /* Name of window. */
- TkTextIndex *indexPtr; /* Index information gets stored here. */
+TkTextWindowIndex(
+ TkText *textPtr, /* Text widget containing window. */
+ const char *name, /* Name of window. */
+ TkTextIndex *indexPtr) /* Index information gets stored here. */
{
Tcl_HashEntry *hPtr;
TkTextSegment *ewPtr;
- hPtr = Tcl_FindHashEntry(&textPtr->windowTable, name);
+ if (textPtr == NULL) {
+ return 0;
+ }
+
+ hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->windowTable, name);
if (hPtr == NULL) {
return 0;
}
+
ewPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
- indexPtr->tree = textPtr->tree;
+ indexPtr->tree = textPtr->sharedTextPtr->tree;
indexPtr->linePtr = ewPtr->body.ew.linePtr;
indexPtr->byteIndex = TkTextSegToOffset(ewPtr, indexPtr->linePtr);
return 1;
}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * EmbWinGetClient --
+ *
+ * Given a text widget and a segment which contains an embedded window,
+ * find the text-widget specific information about the embedded window,
+ * if any.
+ *
+ * This function performs a completely linear lookup for a matching data
+ * structure. If we envisage using this code with dozens of peer widgets,
+ * then performance could become an issue and a more sophisticated lookup
+ * mechanism might be desirable.
+ *
+ * Results:
+ * NULL if no widget-specific info exists, otherwise the structure is
+ * returned.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+static TkTextEmbWindowClient*
+EmbWinGetClient(
+ const TkText *textPtr, /* Information about text widget. */
+ TkTextSegment *ewPtr) /* Segment containing embedded window. */
+{
+ TkTextEmbWindowClient *client = ewPtr->body.ew.clients;
+
+ while (client != NULL) {
+ if (client->textPtr == textPtr) {
+ return client;
+ }
+ client = client->next;
+ }
+ return NULL;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkTrig.c b/generic/tkTrig.c
index 1e90cf3..d7439b3 100644
--- a/generic/tkTrig.c
+++ b/generic/tkTrig.c
@@ -1,21 +1,19 @@
-/*
+/*
* tkTrig.c --
*
- * This file contains a collection of trigonometry utility
- * routines that are used by Tk and in particular by the
- * canvas code. It also has miscellaneous geometry functions
- * used by canvases.
+ * This file contains a collection of trigonometry utility routines that
+ * are used by Tk and in particular by the canvas code. It also has
+ * miscellaneous geometry functions used by canvases.
*
* Copyright (c) 1992-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <stdio.h>
#include "tkInt.h"
-#include "tkPort.h"
#include "tkCanvas.h"
#undef MIN
@@ -34,9 +32,8 @@
* Compute the distance from a point to a finite line segment.
*
* Results:
- * The return value is the distance from the line segment
- * whose end-points are *end1Ptr and *end2Ptr to the point
- * given by *pointPtr.
+ * The return value is the distance from the line segment whose
+ * end-points are *end1Ptr and *end2Ptr to the point given by *pointPtr.
*
* Side effects:
* None.
@@ -45,17 +42,17 @@
*/
double
-TkLineToPoint(end1Ptr, end2Ptr, pointPtr)
- double end1Ptr[2]; /* Coordinates of first end-point of line. */
- double end2Ptr[2]; /* Coordinates of second end-point of line. */
- double pointPtr[2]; /* Points to coords for point. */
+TkLineToPoint(
+ double end1Ptr[2], /* Coordinates of first end-point of line. */
+ double end2Ptr[2], /* Coordinates of second end-point of line. */
+ double pointPtr[2]) /* Points to coords for point. */
{
double x, y;
/*
- * Compute the point on the line that is closest to the
- * point. This must be done separately for vertical edges,
- * horizontal edges, and other edges.
+ * Compute the point on the line that is closest to the point. This must
+ * be done separately for vertical edges, horizontal edges, and other
+ * edges.
*/
if (end1Ptr[0] == end2Ptr[0]) {
@@ -90,10 +87,10 @@ TkLineToPoint(end1Ptr, end2Ptr, pointPtr)
double m1, b1, m2, b2;
/*
- * The edge is neither horizontal nor vertical. Convert the
- * edge to a line equation of the form y = m1*x + b1. Then
- * compute a line perpendicular to this edge but passing
- * through the point, also in the form y = m2*x + b2.
+ * The edge is neither horizontal nor vertical. Convert the edge to a
+ * line equation of the form y = m1*x + b1. Then compute a line
+ * perpendicular to this edge but passing through the point, also in
+ * the form y = m2*x + b2.
*/
m1 = (end2Ptr[1] - end1Ptr[1])/(end2Ptr[0] - end1Ptr[0]);
@@ -133,14 +130,14 @@ TkLineToPoint(end1Ptr, end2Ptr, pointPtr)
*
* TkLineToArea --
*
- * Determine whether a line lies entirely inside, entirely
- * outside, or overlapping a given rectangular area.
+ * Determine whether a line lies entirely inside, entirely outside, or
+ * overlapping a given rectangular area.
*
* Results:
- * -1 is returned if the line given by end1Ptr and end2Ptr
- * is entirely outside the rectangle given by rectPtr. 0 is
- * returned if the polygon overlaps the rectangle, and 1 is
- * returned if the polygon is entirely inside the rectangle.
+ * -1 is returned if the line given by end1Ptr and end2Ptr is entirely
+ * outside the rectangle given by rectPtr. 0 is returned if the polygon
+ * overlaps the rectangle, and 1 is returned if the polygon is entirely
+ * inside the rectangle.
*
* Side effects:
* None.
@@ -149,20 +146,20 @@ TkLineToPoint(end1Ptr, end2Ptr, pointPtr)
*/
int
-TkLineToArea(end1Ptr, end2Ptr, rectPtr)
- double end1Ptr[2]; /* X and y coordinates for one endpoint
- * of line. */
- double end2Ptr[2]; /* X and y coordinates for other endpoint
- * of line. */
- double rectPtr[4]; /* Points to coords for rectangle, in the
- * order x1, y1, x2, y2. X1 must be no
- * larger than x2, and y1 no larger than y2. */
+TkLineToArea(
+ double end1Ptr[2], /* X and y coordinates for one endpoint of
+ * line. */
+ double end2Ptr[2], /* X and y coordinates for other endpoint of
+ * line. */
+ double rectPtr[4]) /* Points to coords for rectangle, in the
+ * order x1, y1, x2, y2. X1 must be no larger
+ * than x2, and y1 no larger than y2. */
{
int inside1, inside2;
/*
- * First check the two points individually to see whether they
- * are inside the rectangle or not.
+ * First check the two points individually to see whether they are inside
+ * the rectangle or not.
*/
inside1 = (end1Ptr[0] >= rectPtr[0]) && (end1Ptr[0] <= rectPtr[2])
@@ -177,17 +174,16 @@ TkLineToArea(end1Ptr, end2Ptr, rectPtr)
}
/*
- * Both points are outside the rectangle, but still need to check
- * for intersections between the line and the rectangle. Horizontal
- * and vertical lines are particularly easy, so handle them
- * separately.
+ * Both points are outside the rectangle, but still need to check for
+ * intersections between the line and the rectangle. Horizontal and
+ * vertical lines are particularly easy, so handle them separately.
*/
if (end1Ptr[0] == end2Ptr[0]) {
/*
* Vertical line.
*/
-
+
if (((end1Ptr[1] >= rectPtr[1]) ^ (end2Ptr[1] >= rectPtr[1]))
&& (end1Ptr[0] >= rectPtr[0])
&& (end1Ptr[0] <= rectPtr[2])) {
@@ -197,7 +193,7 @@ TkLineToArea(end1Ptr, end2Ptr, rectPtr)
/*
* Horizontal line.
*/
-
+
if (((end1Ptr[0] >= rectPtr[0]) ^ (end2Ptr[0] >= rectPtr[0]))
&& (end1Ptr[1] >= rectPtr[1])
&& (end1Ptr[1] <= rectPtr[3])) {
@@ -205,59 +201,63 @@ TkLineToArea(end1Ptr, end2Ptr, rectPtr)
}
} else {
double m, x, y, low, high;
-
+
/*
- * Diagonal line. Compute slope of line and use
- * for intersection checks against each of the
- * sides of the rectangle: left, right, bottom, top.
+ * Diagonal line. Compute slope of line and use for intersection
+ * checks against each of the sides of the rectangle: left, right,
+ * bottom, top.
*/
-
+
m = (end2Ptr[1] - end1Ptr[1])/(end2Ptr[0] - end1Ptr[0]);
if (end1Ptr[0] < end2Ptr[0]) {
- low = end1Ptr[0]; high = end2Ptr[0];
+ low = end1Ptr[0];
+ high = end2Ptr[0];
} else {
- low = end2Ptr[0]; high = end1Ptr[0];
+ low = end2Ptr[0];
+ high = end1Ptr[0];
}
-
+
/*
* Left edge.
*/
-
+
y = end1Ptr[1] + (rectPtr[0] - end1Ptr[0])*m;
if ((rectPtr[0] >= low) && (rectPtr[0] <= high)
&& (y >= rectPtr[1]) && (y <= rectPtr[3])) {
return 0;
}
-
+
/*
* Right edge.
*/
-
+
y += (rectPtr[2] - rectPtr[0])*m;
if ((y >= rectPtr[1]) && (y <= rectPtr[3])
&& (rectPtr[2] >= low) && (rectPtr[2] <= high)) {
return 0;
}
-
+
/*
* Bottom edge.
*/
-
+
if (end1Ptr[1] < end2Ptr[1]) {
- low = end1Ptr[1]; high = end2Ptr[1];
+ low = end1Ptr[1];
+ high = end2Ptr[1];
} else {
- low = end2Ptr[1]; high = end1Ptr[1];
+ low = end2Ptr[1];
+ high = end1Ptr[1];
}
x = end1Ptr[0] + (rectPtr[1] - end1Ptr[1])/m;
if ((x >= rectPtr[0]) && (x <= rectPtr[2])
&& (rectPtr[1] >= low) && (rectPtr[1] <= high)) {
return 0;
}
-
+
/*
* Top edge.
*/
-
+
x += (rectPtr[3] - rectPtr[1])/m;
if ((x >= rectPtr[0]) && (x <= rectPtr[2])
&& (rectPtr[3] >= low) && (rectPtr[3] <= high)) {
@@ -272,14 +272,13 @@ TkLineToArea(end1Ptr, end2Ptr, rectPtr)
*
* TkThickPolyLineToArea --
*
- * This procedure is called to determine whether a connected
- * series of line segments lies entirely inside, entirely
- * outside, or overlapping a given rectangular area.
+ * This function is called to determine whether a connected series of
+ * line segments lies entirely inside, entirely outside, or overlapping a
+ * given rectangular area.
*
* Results:
- * -1 is returned if the lines are entirely outside the area,
- * 0 if they overlap, and 1 if they are entirely inside the
- * given area.
+ * -1 is returned if the lines are entirely outside the area, 0 if they
+ * overlap, and 1 if they are entirely inside the given area.
*
* Side effects:
* None.
@@ -289,28 +288,27 @@ TkLineToArea(end1Ptr, end2Ptr, rectPtr)
/* ARGSUSED */
int
-TkThickPolyLineToArea(coordPtr, numPoints, width, capStyle, joinStyle, rectPtr)
- double *coordPtr; /* Points to an array of coordinates for
- * the polyline: x0, y0, x1, y1, ... */
- int numPoints; /* Total number of points at *coordPtr. */
- double width; /* Width of each line segment. */
- int capStyle; /* How are end-points of polyline drawn?
+TkThickPolyLineToArea(
+ double *coordPtr, /* Points to an array of coordinates for the
+ * polyline: x0, y0, x1, y1, ... */
+ int numPoints, /* Total number of points at *coordPtr. */
+ double width, /* Width of each line segment. */
+ int capStyle, /* How are end-points of polyline drawn?
* CapRound, CapButt, or CapProjecting. */
- int joinStyle; /* How are joints in polyline drawn?
+ int joinStyle, /* How are joints in polyline drawn?
* JoinMiter, JoinRound, or JoinBevel. */
- double *rectPtr; /* Rectangular area to check against. */
+ double *rectPtr) /* Rectangular area to check against. */
{
double radius, poly[10];
int count;
- int changedMiterToBevel; /* Non-zero means that a mitered corner
- * had to be treated as beveled after all
- * because the angle was < 11 degrees. */
- int inside; /* Tentative guess about what to return,
- * based on all points seen so far: one
- * means everything seen so far was
- * inside the area; -1 means everything
- * was outside the area. 0 means overlap
- * has been found. */
+ int changedMiterToBevel; /* Non-zero means that a mitered corner had to
+ * be treated as beveled after all because the
+ * angle was < 11 degrees. */
+ int inside; /* Tentative guess about what to return, based
+ * on all points seen so far: one means
+ * everything seen so far was inside the area;
+ * -1 means everything was outside the area.
+ * 0 means overlap has been found. */
radius = width/2.0;
inside = -1;
@@ -321,19 +319,16 @@ TkThickPolyLineToArea(coordPtr, numPoints, width, capStyle, joinStyle, rectPtr)
}
/*
- * Iterate through all of the edges of the line, computing a polygon
- * for each edge and testing the area against that polygon. In
- * addition, there are additional tests to deal with rounded joints
- * and caps.
+ * Iterate through all of the edges of the line, computing a polygon for
+ * each edge and testing the area against that polygon. In addition, there
+ * are additional tests to deal with rounded joints and caps.
*/
changedMiterToBevel = 0;
for (count = numPoints; count >= 2; count--, coordPtr += 2) {
-
/*
- * If rounding is done around the first point of the edge
- * then test a circular region around the point with the
- * area.
+ * If rounding is done around the first point of the edge then test a
+ * circular region around the point with the area.
*/
if (((capStyle == CapRound) && (count == numPoints))
@@ -348,9 +343,9 @@ TkThickPolyLineToArea(coordPtr, numPoints, width, capStyle, joinStyle, rectPtr)
}
/*
- * Compute the polygonal shape corresponding to this edge,
- * consisting of two points for the first point of the edge
- * and two points for the last point of the edge.
+ * Compute the polygonal shape corresponding to this edge, consisting
+ * of two points for the first point of the edge and two points for
+ * the last point of the edge.
*/
if (count == numPoints) {
@@ -365,10 +360,10 @@ TkThickPolyLineToArea(coordPtr, numPoints, width, capStyle, joinStyle, rectPtr)
TkGetButtPoints(coordPtr+2, coordPtr, width, 0, poly, poly+2);
/*
- * If the last joint was beveled, then also check a
- * polygon comprising the last two points of the previous
- * polygon and the first two from this polygon; this checks
- * the wedges that fill the beveled joint.
+ * If the last joint was beveled, then also check a polygon
+ * comprising the last two points of the previous polygon and the
+ * first two from this polygon; this checks the wedges that fill
+ * the beveled joint.
*/
if ((joinStyle == JoinBevel) || changedMiterToBevel) {
@@ -401,8 +396,7 @@ TkThickPolyLineToArea(coordPtr, numPoints, width, capStyle, joinStyle, rectPtr)
}
/*
- * If caps are rounded, check the cap around the final point
- * of the line.
+ * If caps are rounded, check the cap around the final point of the line.
*/
if (capStyle == CapRound) {
@@ -426,10 +420,9 @@ TkThickPolyLineToArea(coordPtr, numPoints, width, capStyle, joinStyle, rectPtr)
* Compute the distance from a point to a polygon.
*
* Results:
- * The return value is 0.0 if the point referred to by
- * pointPtr is within the polygon referred to by polyPtr
- * and numPoints. Otherwise the return value is the
- * distance of the point from the polygon.
+ * The return value is 0.0 if the point referred to by pointPtr is within
+ * the polygon referred to by polyPtr and numPoints. Otherwise the return
+ * value is the distance of the point from the polygon.
*
* Side effects:
* None.
@@ -438,15 +431,15 @@ TkThickPolyLineToArea(coordPtr, numPoints, width, capStyle, joinStyle, rectPtr)
*/
double
-TkPolygonToPoint(polyPtr, numPoints, pointPtr)
- double *polyPtr; /* Points to an array coordinates for
- * closed polygon: x0, y0, x1, y1, ...
- * The polygon may be self-intersecting. */
- int numPoints; /* Total number of points at *polyPtr. */
- double *pointPtr; /* Points to coords for point. */
+TkPolygonToPoint(
+ double *polyPtr, /* Points to an array coordinates for closed
+ * polygon: x0, y0, x1, y1, ... The polygon
+ * may be self-intersecting. */
+ int numPoints, /* Total number of points at *polyPtr. */
+ double *pointPtr) /* Points to coords for point. */
{
- double bestDist; /* Closest distance between point and
- * any edge in polygon. */
+ double bestDist; /* Closest distance between point and any edge
+ * in polygon. */
int intersections; /* Number of edges in the polygon that
* intersect a ray extending vertically
* upwards from the point to infinity. */
@@ -454,13 +447,12 @@ TkPolygonToPoint(polyPtr, numPoints, pointPtr)
register double *pPtr;
/*
- * Iterate through all of the edges in the polygon, updating
- * bestDist and intersections.
+ * Iterate through all of the edges in the polygon, updating bestDist and
+ * intersections.
*
- * TRICKY POINT: when computing intersections, include left
- * x-coordinate of line within its range, but not y-coordinate.
- * Otherwise if the point lies exactly below a vertex we'll
- * count it as two intersections.
+ * TRICKY POINT: when computing intersections, include left x-coordinate
+ * of line within its range, but not y-coordinate. Otherwise if the point
+ * lies exactly below a vertex we'll count it as two intersections.
*/
bestDist = 1.0e36;
@@ -470,10 +462,9 @@ TkPolygonToPoint(polyPtr, numPoints, pointPtr)
double x, y, dist;
/*
- * Compute the point on the current edge closest to the point
- * and update the intersection count. This must be done
- * separately for vertical edges, horizontal edges, and
- * other edges.
+ * Compute the point on the current edge closest to the point and
+ * update the intersection count. This must be done separately for
+ * vertical edges, horizontal edges, and other edges.
*/
if (pPtr[2] == pPtr[0]) {
@@ -514,13 +505,13 @@ TkPolygonToPoint(polyPtr, numPoints, pointPtr)
}
} else {
double m1, b1, m2, b2;
- int lower; /* Non-zero means point below line. */
+ int lower; /* Non-zero means point below line. */
/*
- * The edge is neither horizontal nor vertical. Convert the
- * edge to a line equation of the form y = m1*x + b1. Then
- * compute a line perpendicular to this edge but passing
- * through the point, also in the form y = m2*x + b2.
+ * The edge is neither horizontal nor vertical. Convert the edge
+ * to a line equation of the form y = m1*x + b1. Then compute a
+ * line perpendicular to this edge but passing through the point,
+ * also in the form y = m2*x + b2.
*/
m1 = (pPtr[3] - pPtr[1])/(pPtr[2] - pPtr[0]);
@@ -554,8 +545,8 @@ TkPolygonToPoint(polyPtr, numPoints, pointPtr)
}
/*
- * Compute the distance to the closest point, and see if that
- * is the best distance seen so far.
+ * Compute the distance to the closest point, and see if that is the
+ * best distance seen so far.
*/
dist = hypot(pointPtr[0] - x, pointPtr[1] - y);
@@ -565,8 +556,8 @@ TkPolygonToPoint(polyPtr, numPoints, pointPtr)
}
/*
- * We've processed all of the points. If the number of intersections
- * is odd, the point is inside the polygon.
+ * We've processed all of the points. If the number of intersections is
+ * odd, the point is inside the polygon.
*/
if (intersections & 0x1) {
@@ -580,14 +571,14 @@ TkPolygonToPoint(polyPtr, numPoints, pointPtr)
*
* TkPolygonToArea --
*
- * Determine whether a polygon lies entirely inside, entirely
- * outside, or overlapping a given rectangular area.
+ * Determine whether a polygon lies entirely inside, entirely outside, or
+ * overlapping a given rectangular area.
*
* Results:
- * -1 is returned if the polygon given by polyPtr and numPoints
- * is entirely outside the rectangle given by rectPtr. 0 is
- * returned if the polygon overlaps the rectangle, and 1 is
- * returned if the polygon is entirely inside the rectangle.
+ * -1 is returned if the polygon given by polyPtr and numPoints is
+ * entirely outside the rectangle given by rectPtr. 0 is returned if the
+ * polygon overlaps the rectangle, and 1 is returned if the polygon is
+ * entirely inside the rectangle.
*
* Side effects:
* None.
@@ -596,14 +587,14 @@ TkPolygonToPoint(polyPtr, numPoints, pointPtr)
*/
int
-TkPolygonToArea(polyPtr, numPoints, rectPtr)
- double *polyPtr; /* Points to an array coordinates for
- * closed polygon: x0, y0, x1, y1, ...
- * The polygon may be self-intersecting. */
- int numPoints; /* Total number of points at *polyPtr. */
- register double *rectPtr; /* Points to coords for rectangle, in the
- * order x1, y1, x2, y2. X1 and y1 must
- * be lower-left corner. */
+TkPolygonToArea(
+ double *polyPtr, /* Points to an array coordinates for closed
+ * polygon: x0, y0, x1, y1, ... The polygon
+ * may be self-intersecting. */
+ int numPoints, /* Total number of points at *polyPtr. */
+ register double *rectPtr) /* Points to coords for rectangle, in the
+ * order x1, y1, x2, y2. X1 and y1 must be
+ * lower-left corner. */
{
int state; /* State of all edges seen so far (-1 means
* outside, 1 means inside, won't ever be
@@ -612,9 +603,8 @@ TkPolygonToArea(polyPtr, numPoints, rectPtr)
register double *pPtr;
/*
- * Iterate over all of the edges of the polygon and test them
- * against the rectangle. Can quit as soon as the state becomes
- * "intersecting".
+ * Iterate over all of the edges of the polygon and test them against the
+ * rectangle. Can quit as soon as the state becomes "intersecting".
*/
state = TkLineToArea(polyPtr, polyPtr+2, rectPtr);
@@ -629,10 +619,10 @@ TkPolygonToArea(polyPtr, numPoints, rectPtr)
}
/*
- * If all of the edges were inside the rectangle we're done.
- * If all of the edges were outside, then the rectangle could
- * still intersect the polygon (if it's entirely enclosed).
- * Call TkPolygonToPoint to figure this out.
+ * If all of the edges were inside the rectangle we're done. If all of the
+ * edges were outside, then the rectangle could still intersect the
+ * polygon (if it's entirely enclosed). Call TkPolygonToPoint to figure
+ * this out.
*/
if (state == 1) {
@@ -649,17 +639,16 @@ TkPolygonToArea(polyPtr, numPoints, rectPtr)
*
* TkOvalToPoint --
*
- * Computes the distance from a given point to a given
- * oval, in canvas units.
+ * Computes the distance from a given point to a given oval, in canvas
+ * units.
*
* Results:
- * The return value is 0 if the point given by *pointPtr is
- * inside the oval. If the point isn't inside the
- * oval then the return value is approximately the distance
- * from the point to the oval. If the oval is filled, then
- * anywhere in the interior is considered "inside"; if
- * the oval isn't filled, then "inside" means only the area
- * occupied by the outline.
+ * The return value is 0 if the point given by *pointPtr is inside the
+ * oval. If the point isn't inside the oval then the return value is
+ * approximately the distance from the point to the oval. If the oval is
+ * filled, then anywhere in the interior is considered "inside"; if the
+ * oval isn't filled, then "inside" means only the area occupied by the
+ * outline.
*
* Side effects:
* None.
@@ -669,22 +658,23 @@ TkPolygonToArea(polyPtr, numPoints, rectPtr)
/* ARGSUSED */
double
-TkOvalToPoint(ovalPtr, width, filled, pointPtr)
- double ovalPtr[4]; /* Pointer to array of four coordinates
- * (x1, y1, x2, y2) defining oval's bounding
+TkOvalToPoint(
+ double ovalPtr[4], /* Pointer to array of four coordinates (x1,
+ * y1, x2, y2) defining oval's bounding
* box. */
- double width; /* Width of outline for oval. */
- int filled; /* Non-zero means oval should be treated as
- * filled; zero means only consider outline. */
- double pointPtr[2]; /* Coordinates of point. */
+ double width, /* Width of outline for oval. */
+ int filled, /* Non-zero means oval should be treated as
+ * filled; zero means only consider
+ * outline. */
+ double pointPtr[2]) /* Coordinates of point. */
{
double xDelta, yDelta, scaledDistance, distToOutline, distToCenter;
double xDiam, yDiam;
/*
- * Compute the distance between the center of the oval and the
- * point in question, using a coordinate system where the oval
- * has been transformed to a circle with unit radius.
+ * Compute the distance between the center of the oval and the point in
+ * question, using a coordinate system where the oval has been transformed
+ * to a circle with unit radius.
*/
xDelta = (pointPtr[0] - (ovalPtr[0] + ovalPtr[2])/2.0);
@@ -693,16 +683,14 @@ TkOvalToPoint(ovalPtr, width, filled, pointPtr)
scaledDistance = hypot(xDelta / ((ovalPtr[2] + width - ovalPtr[0])/2.0),
yDelta / ((ovalPtr[3] + width - ovalPtr[1])/2.0));
-
/*
- * If the scaled distance is greater than 1 then it means no
- * hit. Compute the distance from the point to the edge of
- * the circle, then scale this distance back to the original
- * coordinate system.
+ * If the scaled distance is greater than 1 then it means no hit. Compute
+ * the distance from the point to the edge of the circle, then scale this
+ * distance back to the original coordinate system.
*
- * Note: this distance isn't completely accurate. It's only
- * an approximation, and it can overestimate the correct
- * distance when the oval is eccentric.
+ * Note: this distance isn't completely accurate. It's only an
+ * approximation, and it can overestimate the correct distance when the
+ * oval is eccentric.
*/
if (scaledDistance > 1.0) {
@@ -710,11 +698,11 @@ TkOvalToPoint(ovalPtr, width, filled, pointPtr)
}
/*
- * Scaled distance less than 1 means the point is inside the
- * outer edge of the oval. If this is a filled oval, then we
- * have a hit. Otherwise, do the same computation as above
- * (scale back to original coordinate system), but also check
- * to see if the point is within the width of the outline.
+ * Scaled distance less than 1 means the point is inside the outer edge of
+ * the oval. If this is a filled oval, then we have a hit. Otherwise, do
+ * the same computation as above (scale back to original coordinate
+ * system), but also check to see if the point is within the width of the
+ * outline.
*/
if (filled) {
@@ -725,9 +713,9 @@ TkOvalToPoint(ovalPtr, width, filled, pointPtr)
- width;
} else {
/*
- * Avoid dividing by a very small number (it could cause an
- * arithmetic overflow). This problem occurs if the point is
- * very close to the center of the oval.
+ * Avoid dividing by a very small number (it could cause an arithmetic
+ * overflow). This problem occurs if the point is very close to the
+ * center of the oval.
*/
xDiam = ovalPtr[2] - ovalPtr[0];
@@ -750,14 +738,14 @@ TkOvalToPoint(ovalPtr, width, filled, pointPtr)
*
* TkOvalToArea --
*
- * Determine whether an oval lies entirely inside, entirely
- * outside, or overlapping a given rectangular area.
+ * Determine whether an oval lies entirely inside, entirely outside, or
+ * overlapping a given rectangular area.
*
* Results:
- * -1 is returned if the oval described by ovalPtr is entirely
- * outside the rectangle given by rectPtr. 0 is returned if the
- * oval overlaps the rectangle, and 1 is returned if the oval
- * is entirely inside the rectangle.
+ * -1 is returned if the oval described by ovalPtr is entirely outside
+ * the rectangle given by rectPtr. 0 is returned if the oval overlaps the
+ * rectangle, and 1 is returned if the oval is entirely inside the
+ * rectangle.
*
* Side effects:
* None.
@@ -766,20 +754,20 @@ TkOvalToPoint(ovalPtr, width, filled, pointPtr)
*/
int
-TkOvalToArea(ovalPtr, rectPtr)
- register double *ovalPtr; /* Points to coordinates definining the
+TkOvalToArea(
+ register double *ovalPtr, /* Points to coordinates definining the
* bounding rectangle for the oval: x1, y1,
- * x2, y2. X1 must be less than x2 and y1
- * less than y2. */
- register double *rectPtr; /* Points to coords for rectangle, in the
- * order x1, y1, x2, y2. X1 and y1 must
- * be lower-left corner. */
+ * x2, y2. X1 must be less than x2 and y1 less
+ * than y2. */
+ register double *rectPtr) /* Points to coords for rectangle, in the
+ * order x1, y1, x2, y2. X1 and y1 must be
+ * lower-left corner. */
{
double centerX, centerY, radX, radY, deltaX, deltaY;
/*
- * First, see if oval is entirely inside rectangle or entirely
- * outside rectangle.
+ * First, see if oval is entirely inside rectangle or entirely outside
+ * rectangle.
*/
if ((rectPtr[0] <= ovalPtr[0]) && (rectPtr[2] >= ovalPtr[2])
@@ -792,11 +780,10 @@ TkOvalToArea(ovalPtr, rectPtr)
}
/*
- * Next, go through the rectangle side by side. For each side
- * of the rectangle, find the point on the side that is closest
- * to the oval's center, and see if that point is inside the
- * oval. If at least one such point is inside the oval, then
- * the rectangle intersects the oval.
+ * Next, go through the rectangle side by side. For each side of the
+ * rectangle, find the point on the side that is closest to the oval's
+ * center, and see if that point is inside the oval. If at least one such
+ * point is inside the oval, then the rectangle intersects the oval.
*/
centerX = (ovalPtr[0] + ovalPtr[2])/2;
@@ -872,8 +859,8 @@ TkOvalToArea(ovalPtr, rectPtr)
*
* TkIncludePoint --
*
- * Given a point and a generic canvas item header, expand
- * the item's bounding box if needed to include the point.
+ * Given a point and a generic canvas item header, expand the item's
+ * bounding box if needed to include the point.
*
* Results:
* None.
@@ -886,11 +873,11 @@ TkOvalToArea(ovalPtr, rectPtr)
/* ARGSUSED */
void
-TkIncludePoint(itemPtr, pointPtr)
- register Tk_Item *itemPtr; /* Item whose bounding box is
- * being calculated. */
- double *pointPtr; /* Address of two doubles giving
- * x and y coordinates of point. */
+TkIncludePoint(
+ register Tk_Item *itemPtr, /* Item whose bounding box is being
+ * calculated. */
+ double *pointPtr) /* Address of two doubles giving x and y
+ * coordinates of point. */
{
int tmp;
@@ -915,15 +902,14 @@ TkIncludePoint(itemPtr, pointPtr)
*
* TkBezierScreenPoints --
*
- * Given four control points, create a larger set of XPoints
- * for a Bezier spline based on the points.
+ * Given four control points, create a larger set of XPoints for a Bezier
+ * curve based on the points.
*
* Results:
* The array at *xPointPtr gets filled in with numSteps XPoints
- * corresponding to the Bezier spline defined by the four
- * control points. Note: no output point is generated for the
- * first input point, but an output point *is* generated for
- * the last input point.
+ * corresponding to the Bezier spline defined by the four control points.
+ * Note: no output point is generated for the first input point, but an
+ * output point *is* generated for the last input point.
*
* Side effects:
* None.
@@ -932,15 +918,12 @@ TkIncludePoint(itemPtr, pointPtr)
*/
void
-TkBezierScreenPoints(canvas, control, numSteps, xPointPtr)
- Tk_Canvas canvas; /* Canvas in which curve is to be
- * drawn. */
- double control[]; /* Array of coordinates for four
- * control points: x0, y0, x1, y1,
- * ... x3 y3. */
- int numSteps; /* Number of curve points to
- * generate. */
- register XPoint *xPointPtr; /* Where to put new points. */
+TkBezierScreenPoints(
+ Tk_Canvas canvas, /* Canvas in which curve is to be drawn. */
+ double control[], /* Array of coordinates for four control
+ * points: x0, y0, x1, y1, ... x3 y3. */
+ int numSteps, /* Number of curve points to generate. */
+ register XPoint *xPointPtr) /* Where to put new points. */
{
int i;
double u, u2, u3, t, t2, t3;
@@ -966,15 +949,14 @@ TkBezierScreenPoints(canvas, control, numSteps, xPointPtr)
*
* TkBezierPoints --
*
- * Given four control points, create a larger set of points
- * for a Bezier spline based on the points.
+ * Given four control points, create a larger set of points for a Bezier
+ * curve based on the points.
*
* Results:
- * The array at *coordPtr gets filled in with 2*numSteps
- * coordinates, which correspond to the Bezier spline defined
- * by the four control points. Note: no output point is
- * generated for the first input point, but an output point
- * *is* generated for the last input point.
+ * The array at *coordPtr gets filled in with 2*numSteps coordinates,
+ * which correspond to the Bezier spline defined by the four control
+ * points. Note: no output point is generated for the first input point,
+ * but an output point *is* generated for the last input point.
*
* Side effects:
* None.
@@ -983,13 +965,11 @@ TkBezierScreenPoints(canvas, control, numSteps, xPointPtr)
*/
void
-TkBezierPoints(control, numSteps, coordPtr)
- double control[]; /* Array of coordinates for four
- * control points: x0, y0, x1, y1,
- * ... x3 y3. */
- int numSteps; /* Number of curve points to
- * generate. */
- register double *coordPtr; /* Where to put new points. */
+TkBezierPoints(
+ double control[], /* Array of coordinates for four control
+ * points: x0, y0, x1, y1, ... x3 y3. */
+ int numSteps, /* Number of curve points to generate. */
+ register double *coordPtr) /* Where to put new points. */
{
int i;
double u, u2, u3, t, t2, t3;
@@ -1013,20 +993,21 @@ TkBezierPoints(control, numSteps, coordPtr)
*
* TkMakeBezierCurve --
*
- * Given a set of points, create a new set of points that fit
- * parabolic splines to the line segments connecting the original
- * points. Produces output points in either of two forms.
+ * Given a set of points, create a new set of points that fit parabolic
+ * splines to the line segments connecting the original points. Produces
+ * output points in either of two forms.
*
- * Note: in spite of this procedure's name, it does *not* generate
- * Bezier curves. Since only three control points are used for
- * each curve segment, not four, the curves are actually just
- * parabolic.
+ * Note: the name of this function should *not* be taken to mean that it
+ * interprets the input points as directly defining Bezier curves.
+ * Rather, it internally computes a Bezier curve representation of each
+ * parabolic spline segment. (These Bezier curves are then flattened to
+ * produce the points filled into the output arrays.)
*
* Results:
- * Either or both of the xPoints or dblPoints arrays are filled
- * in. The return value is the number of points placed in the
- * arrays. Note: if the first and last points are the same, then
- * a closed curve is generated.
+ * Either or both of the xPoints or dblPoints arrays are filled in. The
+ * return value is the number of points placed in the arrays. Note: if
+ * the first and last points are the same, then a closed curve is
+ * generated.
*
* Side effects:
* None.
@@ -1035,40 +1016,40 @@ TkBezierPoints(control, numSteps, coordPtr)
*/
int
-TkMakeBezierCurve(canvas, pointPtr, numPoints, numSteps, xPoints, dblPoints)
- Tk_Canvas canvas; /* Canvas in which curve is to be
- * drawn. */
- double *pointPtr; /* Array of input coordinates: x0,
- * y0, x1, y1, etc.. */
- int numPoints; /* Number of points at pointPtr. */
- int numSteps; /* Number of steps to use for each
- * spline segments (determines
- * smoothness of curve). */
- XPoint xPoints[]; /* Array of XPoints to fill in (e.g.
- * for display. NULL means don't
- * fill in any XPoints. */
- double dblPoints[]; /* Array of points to fill in as
- * doubles, in the form x0, y0,
- * x1, y1, .... NULL means don't
- * fill in anything in this form.
- * Caller must make sure that this
- * array has enough space. */
+TkMakeBezierCurve(
+ Tk_Canvas canvas, /* Canvas in which curve is to be drawn. */
+ double *pointPtr, /* Array of input coordinates: x0, y0, x1, y1,
+ * etc.. */
+ int numPoints, /* Number of points at pointPtr. */
+ int numSteps, /* Number of steps to use for each spline
+ * segments (determines smoothness of
+ * curve). */
+ XPoint xPoints[], /* Array of XPoints to fill in (e.g. for
+ * display). NULL means don't fill in any
+ * XPoints. */
+ double dblPoints[]) /* Array of points to fill in as doubles, in
+ * the form x0, y0, x1, y1, .... NULL means
+ * don't fill in anything in this form. Caller
+ * must make sure that this array has enough
+ * space. */
{
int closed, outputPoints, i;
int numCoords = numPoints*2;
double control[8];
/*
- * If the curve is a closed one then generate a special spline
- * that spans the last points and the first ones. Otherwise
- * just put the first point into the output.
+ * If the curve is a closed one then generate a special spline that spans
+ * the last points and the first ones. Otherwise just put the first point
+ * into the output.
*/
if (!pointPtr) {
- /* Of pointPtr == NULL, this function returns an upper limit.
- * of the array size to store the coordinates. This can be
- * used to allocate storage, before the actual coordinates
- * are calculated. */
+ /*
+ * Of pointPtr == NULL, this function returns an upper limit of the
+ * array size to store the coordinates. This can be used to allocate
+ * storage, before the actual coordinates are calculated.
+ */
+
return 1 + numPoints * numSteps;
}
@@ -1114,9 +1095,8 @@ TkMakeBezierCurve(canvas, pointPtr, numPoints, numSteps, xPoints, dblPoints)
for (i = 2; i < numPoints; i++, pointPtr += 2) {
/*
- * Set up the first two control points. This is done
- * differently for the first spline of an open curve
- * than for other cases.
+ * Set up the first two control points. This is done differently for
+ * the first spline of an open curve than for other cases.
*/
if ((i == 2) && !closed) {
@@ -1132,9 +1112,8 @@ TkMakeBezierCurve(canvas, pointPtr, numPoints, numSteps, xPoints, dblPoints)
}
/*
- * Set up the last two control points. This is done
- * differently for the last spline of an open curve
- * than for other cases.
+ * Set up the last two control points. This is done differently for
+ * the last spline of an open curve than for other cases.
*/
if ((i == (numPoints-1)) && !closed) {
@@ -1150,10 +1129,9 @@ TkMakeBezierCurve(canvas, pointPtr, numPoints, numSteps, xPoints, dblPoints)
}
/*
- * If the first two points coincide, or if the last
- * two points coincide, then generate a single
- * straight-line segment by outputting the last control
- * point.
+ * If the first two points coincide, or if the last two points
+ * coincide, then generate a single straight-line segment by
+ * outputting the last control point.
*/
if (((pointPtr[0] == pointPtr[2]) && (pointPtr[1] == pointPtr[3]))
@@ -1194,14 +1172,193 @@ TkMakeBezierCurve(canvas, pointPtr, numPoints, numSteps, xPoints, dblPoints)
/*
*--------------------------------------------------------------
*
+ * TkMakeRawCurve --
+ *
+ * Interpret the given set of points as the raw knots and control points
+ * defining a sequence of cubic Bezier curves. Create a new set of points
+ * that fit these Bezier curves. Output points are produced in either of
+ * two forms.
+ *
+ * Results:
+ * Either or both of the xPoints or dblPoints arrays are filled in. The
+ * return value is the number of points placed in the arrays.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+int
+TkMakeRawCurve(
+ Tk_Canvas canvas, /* Canvas in which curve is to be drawn. */
+ double *pointPtr, /* Array of input coordinates: x0, y0, x1, y1,
+ * etc.. */
+ int numPoints, /* Number of points at pointPtr. */
+ int numSteps, /* Number of steps to use for each curve
+ * segment (determines smoothness of
+ * curve). */
+ XPoint xPoints[], /* Array of XPoints to fill in (e.g. for
+ * display). NULL means don't fill in any
+ * XPoints. */
+ double dblPoints[]) /* Array of points to fill in as doubles, in
+ * the form x0, y0, x1, y1, .... NULL means
+ * don't fill in anything in this form.
+ * Caller must make sure that this array has
+ * enough space. */
+{
+ int outputPoints, i;
+ int numSegments = (numPoints+1)/3;
+ double *segPtr;
+
+ /*
+ * The input describes a curve with s Bezier curve segments if there are
+ * 3s+1, 3s, or 3s-1 input points. In the last two cases, 1 or 2 initial
+ * points from the first curve segment are reused as defining points also
+ * for the last curve segment. In the case of 3s input points, this will
+ * automatically close the curve.
+ */
+
+ if (!pointPtr) {
+ /*
+ * If pointPtr == NULL, this function returns an upper limit of the
+ * array size to store the coordinates. This can be used to allocate
+ * storage, before the actual coordinates are calculated.
+ */
+
+ return 1 + numSegments * numSteps;
+ }
+
+ outputPoints = 0;
+ if (xPoints != NULL) {
+ Tk_CanvasDrawableCoords(canvas, pointPtr[0], pointPtr[1],
+ &xPoints->x, &xPoints->y);
+ xPoints += 1;
+ }
+ if (dblPoints != NULL) {
+ dblPoints[0] = pointPtr[0];
+ dblPoints[1] = pointPtr[1];
+ dblPoints += 2;
+ }
+ outputPoints += 1;
+
+ /*
+ * The next loop handles all curve segments except one that overlaps the
+ * end of the list of coordinates.
+ */
+
+ for (i=numPoints,segPtr=pointPtr ; i>=4 ; i-=3,segPtr+=6) {
+ if (segPtr[0]==segPtr[2] && segPtr[1]==segPtr[3] &&
+ segPtr[4]==segPtr[6] && segPtr[5]==segPtr[7]) {
+ /*
+ * The control points on this segment are equal to their
+ * neighbouring knots, so this segment is just a straight line. A
+ * single point is sufficient.
+ */
+
+ if (xPoints != NULL) {
+ Tk_CanvasDrawableCoords(canvas, segPtr[6], segPtr[7],
+ &xPoints->x, &xPoints->y);
+ xPoints += 1;
+ }
+ if (dblPoints != NULL) {
+ dblPoints[0] = segPtr[6];
+ dblPoints[1] = segPtr[7];
+ dblPoints += 2;
+ }
+ outputPoints += 1;
+ } else {
+ /*
+ * This is a generic Bezier curve segment.
+ */
+
+ if (xPoints != NULL) {
+ TkBezierScreenPoints(canvas, segPtr, numSteps, xPoints);
+ xPoints += numSteps;
+ }
+ if (dblPoints != NULL) {
+ TkBezierPoints(segPtr, numSteps, dblPoints);
+ dblPoints += 2*numSteps;
+ }
+ outputPoints += numSteps;
+ }
+ }
+
+ /*
+ * If at this point i>1, then there is some point which has not yet been
+ * used. Make another curve segment.
+ */
+
+ if (i > 1) {
+ int j;
+ double control[8];
+
+ /*
+ * Copy the relevant coordinates to control[], so that it can be
+ * passed as a unit to e.g. TkBezierPoints.
+ */
+
+ for (j=0; j<2*i; j++) {
+ control[j] = segPtr[j];
+ }
+ for (; j<8; j++) {
+ control[j] = pointPtr[j-2*i];
+ }
+
+ /*
+ * Then we just do the same things as above.
+ */
+
+ if (control[0]==control[2] && control[1]==control[3] &&
+ control[4]==control[6] && control[5]==control[7]) {
+ /*
+ * The control points on this segment are equal to their
+ * neighbouring knots, so this segment is just a straight line. A
+ * single point is sufficient.
+ */
+
+ if (xPoints != NULL) {
+ Tk_CanvasDrawableCoords(canvas, control[6], control[7],
+ &xPoints->x, &xPoints->y);
+ xPoints += 1;
+ }
+ if (dblPoints != NULL) {
+ dblPoints[0] = control[6];
+ dblPoints[1] = control[7];
+ dblPoints += 2;
+ }
+ outputPoints += 1;
+ } else {
+ /*
+ * This is a generic Bezier curve segment.
+ */
+
+ if (xPoints != NULL) {
+ TkBezierScreenPoints(canvas, control, numSteps, xPoints);
+ xPoints += numSteps;
+ }
+ if (dblPoints != NULL) {
+ TkBezierPoints(control, numSteps, dblPoints);
+ dblPoints += 2*numSteps;
+ }
+ outputPoints += numSteps;
+ }
+ }
+
+ return outputPoints;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
* TkMakeBezierPostscript --
*
- * This procedure generates Postscript commands that create
- * a path corresponding to a given Bezier curve.
+ * This function generates Postscript commands that create a path
+ * corresponding to a given Bezier curve.
*
* Results:
- * None. Postscript commands to generate the path are appended
- * to the interp's result.
+ * None. Postscript commands to generate the path are appended to the
+ * interp's result.
*
* Side effects:
* None.
@@ -1210,14 +1367,14 @@ TkMakeBezierCurve(canvas, pointPtr, numPoints, numSteps, xPoints, dblPoints)
*/
void
-TkMakeBezierPostscript(interp, canvas, pointPtr, numPoints)
- Tcl_Interp *interp; /* Interpreter in whose result the
- * Postscript is to be stored. */
- Tk_Canvas canvas; /* Canvas widget for which the
- * Postscript is being generated. */
- double *pointPtr; /* Array of input coordinates: x0,
- * y0, x1, y1, etc.. */
- int numPoints; /* Number of points at pointPtr. */
+TkMakeBezierPostscript(
+ Tcl_Interp *interp, /* Interpreter in whose result the Postscript
+ * is to be stored. */
+ Tk_Canvas canvas, /* Canvas widget for which the Postscript is
+ * being generated. */
+ double *pointPtr, /* Array of input coordinates: x0, y0, x1, y1,
+ * etc.. */
+ int numPoints) /* Number of points at pointPtr. */
{
int closed, i;
int numCoords = numPoints*2;
@@ -1225,9 +1382,9 @@ TkMakeBezierPostscript(interp, canvas, pointPtr, numPoints)
char buffer[200];
/*
- * If the curve is a closed one then generate a special spline
- * that spans the last points and the first ones. Otherwise
- * just put the first point into the path.
+ * If the curve is a closed one then generate a special spline that spans
+ * the last points and the first ones. Otherwise just put the first point
+ * into the path.
*/
if ((pointPtr[0] == pointPtr[numCoords-2])
@@ -1253,11 +1410,11 @@ TkMakeBezierPostscript(interp, canvas, pointPtr, numPoints)
sprintf(buffer, "%.15g %.15g moveto\n",
control[6], Tk_CanvasPsY(canvas, control[7]));
}
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
/*
- * Cycle through all the remaining points in the curve, generating
- * a curve section for each vertex in the linear path.
+ * Cycle through all the remaining points in the curve, generating a curve
+ * section for each vertex in the linear path.
*/
for (i = numPoints-2, pointPtr += 2; i > 0; i--, pointPtr += 2) {
@@ -1265,9 +1422,8 @@ TkMakeBezierPostscript(interp, canvas, pointPtr, numPoints)
control[3] = 0.333*control[7] + 0.667*pointPtr[1];
/*
- * Set up the last two control points. This is done
- * differently for the last spline of an open curve
- * than for other cases.
+ * Set up the last two control points. This is done differently for
+ * the last spline of an open curve than for other cases.
*/
if ((i == 1) && !closed) {
@@ -1284,7 +1440,115 @@ TkMakeBezierPostscript(interp, canvas, pointPtr, numPoints)
control[2], Tk_CanvasPsY(canvas, control[3]),
control[4], Tk_CanvasPsY(canvas, control[5]),
control[6], Tk_CanvasPsY(canvas, control[7]));
- Tcl_AppendResult(interp, buffer, (char *) NULL);
+ Tcl_AppendResult(interp, buffer, NULL);
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TkMakeRawCurvePostscript --
+ *
+ * This function interprets the input points as the raw knot and control
+ * points for a curve composed of Bezier curve segments, just like
+ * TkMakeRawCurve. It generates Postscript commands that create a path
+ * corresponding to this given curve.
+ *
+ * Results:
+ * None. Postscript commands to generate the path are appended to the
+ * interp's result.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+TkMakeRawCurvePostscript(
+ Tcl_Interp *interp, /* Interpreter in whose result the Postscript
+ * is to be stored. */
+ Tk_Canvas canvas, /* Canvas widget for which the Postscript is
+ * being generated. */
+ double *pointPtr, /* Array of input coordinates: x0, y0, x1, y1,
+ * etc.. */
+ int numPoints) /* Number of points at pointPtr. */
+{
+ int i;
+ double *segPtr;
+ char buffer[200];
+
+ /*
+ * Put the first point into the path.
+ */
+
+ sprintf(buffer, "%.15g %.15g moveto\n",
+ pointPtr[0], Tk_CanvasPsY(canvas, pointPtr[1]));
+ Tcl_AppendResult(interp, buffer, NULL);
+
+ /*
+ * Loop through all the remaining points in the curve, generating a
+ * straight line or curve section for every three of them.
+ */
+
+ for (i=numPoints-1,segPtr=pointPtr ; i>=3 ; i-=3,segPtr+=6) {
+ if (segPtr[0]==segPtr[2] && segPtr[1]==segPtr[3] &&
+ segPtr[4]==segPtr[6] && segPtr[5]==segPtr[7]) {
+ /*
+ * The control points on this segment are equal to their
+ * neighbouring knots, so this segment is just a straight line.
+ */
+
+ sprintf(buffer, "%.15g %.15g lineto\n",
+ segPtr[6], Tk_CanvasPsY(canvas, segPtr[7]));
+ } else {
+ /*
+ * This is a generic Bezier curve segment.
+ */
+
+ sprintf(buffer, "%.15g %.15g %.15g %.15g %.15g %.15g curveto\n",
+ segPtr[2], Tk_CanvasPsY(canvas, segPtr[3]),
+ segPtr[4], Tk_CanvasPsY(canvas, segPtr[5]),
+ segPtr[6], Tk_CanvasPsY(canvas, segPtr[7]));
+ }
+ Tcl_AppendResult(interp, buffer, NULL);
+ }
+
+ /*
+ * If there are any points left that haven't been used, then build the
+ * last segment and generate Postscript in the same way for that.
+ */
+
+ if (i > 0) {
+ int j;
+ double control[8];
+
+ for (j=0; j<2*i+2; j++) {
+ control[j] = segPtr[j];
+ }
+ for (; j<8; j++) {
+ control[j] = pointPtr[j-2*i-2];
+ }
+
+ if (control[0]==control[2] && control[1]==control[3] &&
+ control[4]==control[6] && control[5]==control[7]) {
+ /*
+ * Straight line.
+ */
+
+ sprintf(buffer, "%.15g %.15g lineto\n",
+ control[6], Tk_CanvasPsY(canvas, control[7]));
+ } else {
+ /*
+ * Bezier curve segment.
+ */
+
+ sprintf(buffer, "%.15g %.15g %.15g %.15g %.15g %.15g curveto\n",
+ control[2], Tk_CanvasPsY(canvas, control[3]),
+ control[4], Tk_CanvasPsY(canvas, control[5]),
+ control[6], Tk_CanvasPsY(canvas, control[7]));
+ }
+ Tcl_AppendResult(interp, buffer, NULL);
}
}
@@ -1293,16 +1557,14 @@ TkMakeBezierPostscript(interp, canvas, pointPtr, numPoints)
*
* TkGetMiterPoints --
*
- * Given three points forming an angle, compute the
- * coordinates of the inside and outside points of
- * the mitered corner formed by a line of a given
- * width at that angle.
+ * Given three points forming an angle, compute the coordinates of the
+ * inside and outside points of the mitered corner formed by a line of a
+ * given width at that angle.
*
* Results:
- * If the angle formed by the three points is less than
- * 11 degrees then 0 is returned and m1 and m2 aren't
- * modified. Otherwise 1 is returned and the points at
- * m1 and m2 are filled in with the positions of the points
+ * If the angle formed by the three points is less than 11 degrees then 0
+ * is returned and m1 and m2 aren't modified. Otherwise 1 is returned and
+ * the points at m1 and m2 are filled in with the positions of the points
* of the mitered corner.
*
* Side effects:
@@ -1312,36 +1574,39 @@ TkMakeBezierPostscript(interp, canvas, pointPtr, numPoints)
*/
int
-TkGetMiterPoints(p1, p2, p3, width, m1, m2)
- double p1[]; /* Points to x- and y-coordinates of point
+TkGetMiterPoints(
+ double p1[], /* Points to x- and y-coordinates of point
* before vertex. */
- double p2[]; /* Points to x- and y-coordinates of vertex
+ double p2[], /* Points to x- and y-coordinates of vertex
* for mitered joint. */
- double p3[]; /* Points to x- and y-coordinates of point
+ double p3[], /* Points to x- and y-coordinates of point
* after vertex. */
- double width; /* Width of line. */
- double m1[]; /* Points to place to put "left" vertex
- * point (see as you face from p1 to p2). */
- double m2[]; /* Points to place to put "right" vertex
+ double width, /* Width of line. */
+ double m1[], /* Points to place to put "left" vertex point
+ * (see as you face from p1 to p2). */
+ double m2[]) /* Points to place to put "right" vertex
* point. */
{
double theta1; /* Angle of segment p2-p1. */
double theta2; /* Angle of segment p2-p3. */
- double theta; /* Angle between line segments (angle
- * of joint). */
- double theta3; /* Angle that bisects theta1 and
- * theta2 and points to m1. */
+ double theta; /* Angle between line segments (angle of
+ * joint). */
+ double theta3; /* Angle that bisects theta1 and theta2 and
+ * points to m1. */
double dist; /* Distance of miter points from p2. */
- double deltaX, deltaY; /* X and y offsets cooresponding to
- * dist (fudge factors for bounding
- * box). */
+ double deltaX, deltaY; /* X and y offsets cooresponding to dist
+ * (fudge factors for bounding box). */
double p1x, p1y, p2x, p2y, p3x, p3y;
- static double elevenDegrees = (11.0*2.0*PI)/360.0;
+#ifndef _MSC_VER
+ static const double elevenDegrees = (11.0*2.0*PI)/360.0;
+#else /* msvc8 with -fp:strict requires it this way */
+ static const double elevenDegrees = 0.19198621771937624;
+#endif
/*
- * Round the coordinates to integers to mimic what happens when the
- * line segments are displayed; without this code, the bounding box
- * of a mitered line can be miscomputed greatly.
+ * Round the coordinates to integers to mimic what happens when the line
+ * segments are displayed; without this code, the bounding box of a
+ * mitered line can be miscomputed greatly.
*/
p1x = floor(p1[0]+0.5);
@@ -1358,6 +1623,7 @@ TkGetMiterPoints(p1, p2, p3, width, m1, m2)
} else {
theta1 = atan2(p1y - p2y, p1x - p2x);
}
+
if (p3y == p2y) {
theta2 = (p3x > p2x) ? 0 : PI;
} else if (p3x == p2x) {
@@ -1365,23 +1631,26 @@ TkGetMiterPoints(p1, p2, p3, width, m1, m2)
} else {
theta2 = atan2(p3y - p2y, p3x - p2x);
}
+
theta = theta1 - theta2;
if (theta > PI) {
theta -= 2*PI;
} else if (theta < -PI) {
theta += 2*PI;
}
+
if ((theta < elevenDegrees) && (theta > -elevenDegrees)) {
return 0;
}
+
dist = 0.5*width/sin(0.5*theta);
if (dist < 0.0) {
dist = -dist;
}
/*
- * Compute theta3 (make sure that it points to the left when
- * looking from p1 to p2).
+ * Compute theta3 (make sure that it points to the left when looking from
+ * p1 to p2).
*/
theta3 = (theta1 + theta2)/2.0;
@@ -1394,6 +1663,7 @@ TkGetMiterPoints(p1, p2, p3, width, m1, m2)
deltaY = dist*sin(theta3);
m1[1] = p2y + deltaY;
m2[1] = p2y - deltaY;
+
return 1;
}
@@ -1402,13 +1672,13 @@ TkGetMiterPoints(p1, p2, p3, width, m1, m2)
*
* TkGetButtPoints --
*
- * Given two points forming a line segment, compute the
- * coordinates of two endpoints of a rectangle formed by
- * bloating the line segment until it is width units wide.
+ * Given two points forming a line segment, compute the coordinates of
+ * two endpoints of a rectangle formed by bloating the line segment until
+ * it is width units wide.
*
* Results:
- * There is no return value. M1 and m2 are filled in to
- * correspond to m1 and m2 in the diagram below:
+ * There is no return value. M1 and m2 are filled in to correspond to m1
+ * and m2 in the diagram below:
*
* ----------------* m1
* |
@@ -1416,9 +1686,9 @@ TkGetMiterPoints(p1, p2, p3, width, m1, m2)
* |
* ----------------* m2
*
- * M1 and m2 will be W units apart, with p2 centered between
- * them and m1-m2 perpendicular to p1-p2. However, if
- * "project" is true then m1 and m2 will be as follows:
+ * M1 and m2 will be W units apart, with p2 centered between them and
+ * m1-m2 perpendicular to p1-p2. However, if "project" is true then m1
+ * and m2 will be as follows:
*
* -------------------* m1
* p2 |
@@ -1435,17 +1705,17 @@ TkGetMiterPoints(p1, p2, p3, width, m1, m2)
*/
void
-TkGetButtPoints(p1, p2, width, project, m1, m2)
- double p1[]; /* Points to x- and y-coordinates of point
+TkGetButtPoints(
+ double p1[], /* Points to x- and y-coordinates of point
* before vertex. */
- double p2[]; /* Points to x- and y-coordinates of vertex
+ double p2[], /* Points to x- and y-coordinates of vertex
* for mitered joint. */
- double width; /* Width of line. */
- int project; /* Non-zero means project p2 by an additional
+ double width, /* Width of line. */
+ int project, /* Non-zero means project p2 by an additional
* width/2 before computing m1 and m2. */
- double m1[]; /* Points to place to put "left" result
- * point, as you face from p1 to p2. */
- double m2[]; /* Points to place to put "right" result
+ double m1[], /* Points to place to put "left" result point,
+ * as you face from p1 to p2. */
+ double m2[]) /* Points to place to put "right" result
* point. */
{
double length; /* Length of p1-p2 segment. */
@@ -1471,3 +1741,11 @@ TkGetButtPoints(p1, p2, width, project, m1, m2)
}
}
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkUndo.c b/generic/tkUndo.c
index 81c8648..bf2ed7c 100644
--- a/generic/tkUndo.c
+++ b/generic/tkUndo.c
@@ -1,378 +1,689 @@
-/*
+/*
* tkUndo.c --
*
* This module provides the implementation of an undo stack.
*
* Copyright (c) 2002 by Ludwig Callewaert.
+ * Copyright (c) 2003-2004 by Vincent Darley.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
+#include "tkInt.h"
#include "tkUndo.h"
+static int EvaluateActionList(Tcl_Interp *interp,
+ TkUndoSubAtom *action);
/*
- * TkUndoPushStack
- * Push elem on the stack identified by stack.
+ *----------------------------------------------------------------------
+ *
+ * TkUndoPushStack --
+ *
+ * Push elem on the stack identified by stack.
*
* Results:
- * None
+ * None.
*
* Side effects:
- * None.
+ * None.
+ *
+ *----------------------------------------------------------------------
*/
-
-void TkUndoPushStack ( stack, elem )
- TkUndoAtom ** stack;
- TkUndoAtom * elem;
-{
+
+void
+TkUndoPushStack(
+ TkUndoAtom **stack,
+ TkUndoAtom *elem)
+{
elem->next = *stack;
*stack = elem;
}
/*
+ *----------------------------------------------------------------------
+ *
* TkUndoPopStack --
- * Remove and return the top element from the stack identified by
- * stack.
+ *
+ * Remove and return the top element from the stack identified by stack.
*
* Results:
- * None
+ * None.
*
* Side effects:
- * None.
+ * None.
+ *
+ *----------------------------------------------------------------------
*/
-
-TkUndoAtom * TkUndoPopStack ( stack )
- TkUndoAtom ** stack ;
-{
- TkUndoAtom * elem = NULL;
- if (*stack != NULL ) {
- elem = *stack;
- *stack = elem->next;
+
+TkUndoAtom *
+TkUndoPopStack(
+ TkUndoAtom **stack)
+{
+ TkUndoAtom *elem = NULL;
+
+ if (*stack != NULL) {
+ elem = *stack;
+ *stack = elem->next;
}
return elem;
}
/*
+ *----------------------------------------------------------------------
+ *
* TkUndoInsertSeparator --
- * insert a separator on the stack, indicating a border for
- * an undo/redo chunk.
+ *
+ * Insert a separator on the stack, indicating a border for an undo/redo
+ * chunk.
*
* Results:
- * None
+ * None.
*
* Side effects:
- * None.
+ * None.
+ *
+ *----------------------------------------------------------------------
*/
-
-int TkUndoInsertSeparator ( stack )
- TkUndoAtom ** stack;
+
+int
+TkUndoInsertSeparator(
+ TkUndoAtom **stack)
{
- TkUndoAtom * separator;
-
- if ( *stack != NULL && (*stack)->type != TK_UNDO_SEPARATOR ) {
- separator = (TkUndoAtom *) ckalloc(sizeof(TkUndoAtom));
- separator->type = TK_UNDO_SEPARATOR;
- TkUndoPushStack(stack,separator);
- return 1;
- } else {
- return 0;
+ TkUndoAtom *separator;
+
+ if (*stack!=NULL && (*stack)->type!=TK_UNDO_SEPARATOR) {
+ separator = (TkUndoAtom *) ckalloc(sizeof(TkUndoAtom));
+ separator->type = TK_UNDO_SEPARATOR;
+ TkUndoPushStack(stack,separator);
+ return 1;
}
+ return 0;
}
/*
+ *----------------------------------------------------------------------
+ *
* TkUndoClearStack --
- * Clear an entire undo or redo stack and destroy all elements in it.
+ *
+ * Clear an entire undo or redo stack and destroy all elements in it.
*
* Results:
- * None
+ * None.
*
* Side effects:
- * None.
+ * None.
+ *
+ *----------------------------------------------------------------------
*/
-void TkUndoClearStack ( stack )
- TkUndoAtom ** stack; /* An Undo or Redo stack */
+void
+TkUndoClearStack(
+ TkUndoAtom **stack) /* An Undo or Redo stack */
{
- TkUndoAtom * elem;
-
- while ( (elem = TkUndoPopStack(stack)) ) {
- if ( elem->type != TK_UNDO_SEPARATOR ) {
- Tcl_DecrRefCount(elem->apply);
- Tcl_DecrRefCount(elem->revert);
- }
- ckfree((char *)elem);
+ TkUndoAtom *elem;
+
+ while ((elem = TkUndoPopStack(stack)) != NULL) {
+ if (elem->type != TK_UNDO_SEPARATOR) {
+ TkUndoSubAtom *sub;
+
+ sub = elem->apply;
+ while (sub != NULL) {
+ TkUndoSubAtom *next = sub->next;
+
+ if (sub->action != NULL) {
+ Tcl_DecrRefCount(sub->action);
+ }
+ ckfree((char *)sub);
+ sub = next;
+ }
+
+ sub = elem->revert;
+ while (sub != NULL) {
+ TkUndoSubAtom *next = sub->next;
+
+ if (sub->action != NULL) {
+ Tcl_DecrRefCount(sub->action);
+ }
+ ckfree((char *)sub);
+ sub = next;
+ }
+ }
+ ckfree((char *)elem);
}
*stack = NULL;
}
/*
- * TkUndoPushAction
- * Push a new elem on the stack identified by stack.
- * action and revert are given through Tcl_DStrings
+ *----------------------------------------------------------------------
+ *
+ * TkUndoPushAction --
+ *
+ * Push a new elem on the stack identified by stack. Action and revert
+ * are given through Tcl_Obj's to which we will retain a reference. (So
+ * they can be passed in with a zero refCount if desired).
*
* Results:
- * None
+ * None.
*
* Side effects:
- * None.
+ * None.
+ *
+ *----------------------------------------------------------------------
*/
-
-void TkUndoPushAction ( stack, actionScript, revertScript )
- TkUndoRedoStack * stack; /* An Undo or Redo stack */
- Tcl_DString * actionScript; /* The script to get the action (redo) */
- Tcl_DString * revertScript; /* The script to revert the action (undo) */
-{
- TkUndoAtom * atom;
+
+void
+TkUndoPushAction(
+ TkUndoRedoStack *stack, /* An Undo or Redo stack */
+ TkUndoSubAtom *apply,
+ TkUndoSubAtom *revert)
+{
+ TkUndoAtom *atom;
atom = (TkUndoAtom *) ckalloc(sizeof(TkUndoAtom));
atom->type = TK_UNDO_ACTION;
+ atom->apply = apply;
+ atom->revert = revert;
- atom->apply = Tcl_NewStringObj(Tcl_DStringValue(actionScript),Tcl_DStringLength(actionScript));
- Tcl_IncrRefCount(atom->apply);
+ TkUndoPushStack(&stack->undoStack, atom);
+ TkUndoClearStack(&stack->redoStack);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkUndoMakeCmdSubAtom --
+ *
+ * Create a new undo/redo step which must later be place into an undo
+ * stack with TkUndoPushAction. This sub-atom, if evaluated, will take
+ * the given command (if non-NULL), find its full Tcl command string, and
+ * then evaluate that command with the list elements of 'actionScript'
+ * appended.
+ *
+ * If 'subAtomList' is non-NULL, the newly created sub-atom is added onto
+ * the end of the linked list of which 'subAtomList' is a part. This
+ * makes it easy to build up a sequence of actions which will be pushed
+ * in one step.
+ *
+ * Note: if the undo stack can persist for longer than the Tcl_Command
+ * provided, the stack will cause crashes when actions are evaluated. In
+ * this case the 'command' argument should not be used. This is the case
+ * with peer text widgets, for example.
+ *
+ * Results:
+ * The newly created subAtom is returned. It must be passed to
+ * TkUndoPushAction otherwise a memory leak will result.
+ *
+ * Side effects:
+ * A refCount is retained on 'actionScript'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkUndoSubAtom *
+TkUndoMakeCmdSubAtom(
+ Tcl_Command command, /* Tcl command token for actions, may be NULL
+ * if not needed. */
+ Tcl_Obj *actionScript, /* The script to append to the command to
+ * perform the action (may be NULL if the
+ * command is not-null). */
+ TkUndoSubAtom *subAtomList) /* Add to the end of this list of actions if
+ * non-NULL */
+{
+ TkUndoSubAtom *atom;
- atom->revert = Tcl_NewStringObj(Tcl_DStringValue(revertScript),Tcl_DStringLength(revertScript));
- Tcl_IncrRefCount(atom->revert);
+ if (command == NULL && actionScript == NULL) {
+ Tcl_Panic("NULL command and actionScript in TkUndoMakeCmdSubAtom");
+ }
- TkUndoPushStack(&(stack->undoStack), atom);
- TkUndoClearStack(&(stack->redoStack));
+ atom = (TkUndoSubAtom *) ckalloc(sizeof(TkUndoSubAtom));
+ atom->command = command;
+ atom->funcPtr = NULL;
+ atom->clientData = NULL;
+ atom->next = NULL;
+ atom->action = actionScript;
+ if (atom->action != NULL) {
+ Tcl_IncrRefCount(atom->action);
+ }
+
+ if (subAtomList != NULL) {
+ while (subAtomList->next != NULL) {
+ subAtomList = subAtomList->next;
+ }
+ subAtomList->next = atom;
+ }
+ return atom;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkUndoMakeSubAtom --
+ *
+ * Create a new undo/redo step which must later be place into an undo
+ * stack with TkUndoPushAction. This sub-atom, if evaluated, will take
+ * the given C-funcPtr (which must be non-NULL), and call it with three
+ * arguments: the undo stack's 'interp', the 'clientData' given and the
+ * 'actionScript'. The callback should return a standard Tcl return code
+ * (TCL_OK on success).
+ *
+ * If 'subAtomList' is non-NULL, the newly created sub-atom is added onto
+ * the end of the linked list of which 'subAtomList' is a part. This
+ * makes it easy to build up a sequence of actions which will be pushed
+ * in one step.
+ *
+ * Results:
+ * The newly created subAtom is returned. It must be passed to
+ * TkUndoPushAction otherwise a memory leak will result.
+ *
+ * Side effects:
+ * A refCount is retained on 'actionScript'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkUndoSubAtom *
+TkUndoMakeSubAtom(
+ TkUndoProc *funcPtr, /* Callback function to perform the
+ * undo/redo. */
+ ClientData clientData, /* Data to pass to the callback function. */
+ Tcl_Obj *actionScript, /* Additional Tcl data to pass to the callback
+ * function (may be NULL). */
+ TkUndoSubAtom *subAtomList) /* Add to the end of this list of actions if
+ * non-NULL */
+{
+ TkUndoSubAtom *atom;
+ if (funcPtr == NULL) {
+ Tcl_Panic("NULL funcPtr in TkUndoMakeSubAtom");
+ }
+
+ atom = (TkUndoSubAtom *) ckalloc(sizeof(TkUndoSubAtom));
+ atom->command = NULL;
+ atom->funcPtr = funcPtr;
+ atom->clientData = clientData;
+ atom->next = NULL;
+ atom->action = actionScript;
+ if (atom->action != NULL) {
+ Tcl_IncrRefCount(atom->action);
+ }
+
+ if (subAtomList != NULL) {
+ while (subAtomList->next != NULL) {
+ subAtomList = subAtomList->next;
+ }
+ subAtomList->next = atom;
+ }
+ return atom;
+}
/*
- * TkUndoInitStack
- * Initialize a new undo/redo stack
+ *----------------------------------------------------------------------
+ *
+ * TkUndoInitStack --
+ *
+ * Initialize a new undo/redo stack.
*
* Results:
- * un Undo/Redo stack pointer
+ * An Undo/Redo stack pointer.
*
* Side effects:
- * None.
+ * None.
+ *
+ *----------------------------------------------------------------------
*/
-
-TkUndoRedoStack * TkUndoInitStack ( interp, maxdepth )
- Tcl_Interp * interp; /* The interpreter */
- int maxdepth; /* The maximum stack depth */
-{
- TkUndoRedoStack * stack; /* An Undo/Redo stack */
+
+TkUndoRedoStack *
+TkUndoInitStack(
+ Tcl_Interp *interp, /* The interpreter */
+ int maxdepth) /* The maximum stack depth */
+{
+ TkUndoRedoStack *stack; /* An Undo/Redo stack */
+
stack = (TkUndoRedoStack *) ckalloc(sizeof(TkUndoRedoStack));
stack->undoStack = NULL;
stack->redoStack = NULL;
- stack->interp = interp;
- stack->maxdepth = maxdepth;
- stack->depth = 0;
+ stack->interp = interp;
+ stack->maxdepth = maxdepth;
+ stack->depth = 0;
return stack;
}
-
/*
- * TkUndoInitStack
- * Initialize a new undo/redo stack
+ *----------------------------------------------------------------------
+ *
+ * TkUndoSetDepth --
+ *
+ * Set the maximum depth of stack.
*
* Results:
- * un Undo/Redo stack pointer
+ * None.
*
* Side effects:
- * None.
+ * May delete elements from the stack if the new maximum depth is smaller
+ * than the number of elements previously in the stack.
+ *
+ *----------------------------------------------------------------------
*/
-
-void TkUndoSetDepth ( stack, maxdepth )
- TkUndoRedoStack * stack; /* An Undo/Redo stack */
- int maxdepth; /* The maximum stack depth */
+
+void
+TkUndoSetDepth(
+ TkUndoRedoStack *stack, /* An Undo/Redo stack */
+ int maxdepth) /* The maximum stack depth */
{
- TkUndoAtom * elem;
- TkUndoAtom * prevelem;
- int sepNumber = 0;
-
stack->maxdepth = maxdepth;
- if ((stack->maxdepth > 0) && (stack->depth > stack->maxdepth)) {
- /*
+ if (stack->maxdepth>0 && stack->depth>stack->maxdepth) {
+ TkUndoAtom *elem, *prevelem;
+ int sepNumber = 0;
+
+ /*
* Maximum stack depth exceeded. We have to remove the last compound
* elements on the stack.
*/
- elem = stack->undoStack;
- prevelem = NULL;
- while (elem && (sepNumber <= stack->maxdepth)) {
- if (elem->type == TK_UNDO_SEPARATOR) {
- sepNumber++;
- }
- prevelem = elem;
- elem = elem->next;
- }
- prevelem->next = NULL;
- while ( elem ) {
- prevelem = elem;
- elem = elem->next;
- ckfree((char *) prevelem);
- }
- stack->depth = stack->maxdepth;
+ elem = stack->undoStack;
+ prevelem = NULL;
+ while ((elem != NULL) && (sepNumber <= stack->maxdepth)) {
+ if (elem->type == TK_UNDO_SEPARATOR) {
+ sepNumber++;
+ }
+ prevelem = elem;
+ elem = elem->next;
+ }
+ prevelem->next = NULL;
+ while (elem != NULL) {
+ prevelem = elem;
+ if (elem->type != TK_UNDO_SEPARATOR) {
+ TkUndoSubAtom *sub = elem->apply;
+ while (sub != NULL) {
+ TkUndoSubAtom *next = sub->next;
+
+ if (sub->action != NULL) {
+ Tcl_DecrRefCount(sub->action);
+ }
+ ckfree((char *)sub);
+ sub = next;
+ }
+ sub = elem->revert;
+ while (sub != NULL) {
+ TkUndoSubAtom *next = sub->next;
+
+ if (sub->action != NULL) {
+ Tcl_DecrRefCount(sub->action);
+ }
+ ckfree((char *)sub);
+ sub = next;
+ }
+ }
+ elem = elem->next;
+ ckfree((char *) prevelem);
+ }
+ stack->depth = stack->maxdepth;
}
}
-
/*
- * TkUndoClearStacks
- * Clear both the undo and redo stack
+ *----------------------------------------------------------------------
+ *
+ * TkUndoClearStacks --
+ *
+ * Clear both the undo and redo stack.
*
* Results:
- * None
+ * None.
*
* Side effects:
- * None.
+ * None.
+ *
+ *----------------------------------------------------------------------
*/
-
-void TkUndoClearStacks ( stack )
- TkUndoRedoStack * stack; /* An Undo/Redo stack */
-{
- TkUndoClearStack(&(stack->undoStack));
- TkUndoClearStack(&(stack->redoStack));
+
+void
+TkUndoClearStacks(
+ TkUndoRedoStack *stack) /* An Undo/Redo stack */
+{
+ TkUndoClearStack(&stack->undoStack);
+ TkUndoClearStack(&stack->redoStack);
stack->depth = 0;
}
-
/*
+ *----------------------------------------------------------------------
+ *
* TkUndoFreeStack
- * Clear both the undo and redo stack
- * also free the memory allocated to the u/r stack pointer
+ *
+ * Clear both the undo and redo stack and free the memory allocated to
+ * the u/r stack pointer.
*
* Results:
- * None
+ * None.
*
* Side effects:
- * None.
+ * None.
+ *
+ *----------------------------------------------------------------------
*/
-
-void TkUndoFreeStack ( stack )
- TkUndoRedoStack * stack; /* An Undo/Redo stack */
-{
- TkUndoClearStacks(stack);
-/* ckfree((TkUndoRedoStack *) stack); */
- ckfree((char *) stack);
-}
+void
+TkUndoFreeStack(
+ TkUndoRedoStack *stack) /* An Undo/Redo stack */
+{
+ TkUndoClearStacks(stack);
+ ckfree((char *) stack);
+}
/*
+ *----------------------------------------------------------------------
+ *
* TkUndoInsertUndoSeparator --
- * insert a separator on the undo stack, indicating a border for
- * an undo/redo chunk.
+ *
+ * Insert a separator on the undo stack, indicating a border for an
+ * undo/redo chunk.
*
* Results:
- * None
+ * None.
*
* Side effects:
- * None.
+ * None.
+ *
+ *----------------------------------------------------------------------
*/
-
-void TkUndoInsertUndoSeparator ( stack )
- TkUndoRedoStack * stack;
+
+void
+TkUndoInsertUndoSeparator(
+ TkUndoRedoStack *stack)
{
- if ( TkUndoInsertSeparator(&(stack->undoStack)) ) {
- ++(stack->depth);
- TkUndoSetDepth(stack,stack->maxdepth);
+ if (TkUndoInsertSeparator(&stack->undoStack)) {
+ stack->depth++;
+ TkUndoSetDepth(stack, stack->maxdepth);
}
}
-
/*
+ *----------------------------------------------------------------------
+ *
* TkUndoRevert --
- * Undo a compound action on the stack.
+ *
+ * Undo a compound action on the stack.
*
* Results:
- * A TCL status code
+ * A Tcl status code
*
* Side effects:
- * None.
+ * None.
+ *
+ *----------------------------------------------------------------------
*/
-
-int TkUndoRevert ( stack )
- TkUndoRedoStack * stack;
+
+int
+TkUndoRevert(
+ TkUndoRedoStack *stack)
{
- TkUndoAtom * elem;
+ TkUndoAtom *elem;
- /* insert a separator on the undo and the redo stack */
+ /*
+ * Insert a separator on the undo and the redo stack.
+ */
TkUndoInsertUndoSeparator(stack);
- TkUndoInsertSeparator(&(stack->redoStack));
-
- /* Pop and skip the first separator if there is one*/
+ TkUndoInsertSeparator(&stack->redoStack);
- elem = TkUndoPopStack(&(stack->undoStack));
+ /*
+ * Pop and skip the first separator if there is one.
+ */
- if ( elem == NULL ) {
- return TCL_ERROR;
+ elem = TkUndoPopStack(&stack->undoStack);
+ if (elem == NULL) {
+ return TCL_ERROR;
}
- if ( ( elem != NULL ) && ( elem->type == TK_UNDO_SEPARATOR ) ) {
- ckfree((char *) elem);
- elem = TkUndoPopStack(&(stack->undoStack));
+ if (elem->type == TK_UNDO_SEPARATOR) {
+ ckfree((char *) elem);
+ elem = TkUndoPopStack(&stack->undoStack);
}
-
- while ( elem && (elem->type != TK_UNDO_SEPARATOR) ) {
- Tcl_EvalObjEx(stack->interp,elem->revert,TCL_EVAL_GLOBAL);
-
- TkUndoPushStack(&(stack->redoStack),elem);
- elem = TkUndoPopStack(&(stack->undoStack));
+
+ while (elem != NULL && elem->type != TK_UNDO_SEPARATOR) {
+ /*
+ * Note that we currently ignore errors thrown here.
+ */
+
+ EvaluateActionList(stack->interp, elem->revert);
+
+ TkUndoPushStack(&stack->redoStack, elem);
+ elem = TkUndoPopStack(&stack->undoStack);
}
-
- /* insert a separator on the redo stack */
-
- TkUndoInsertSeparator(&(stack->redoStack));
-
- --(stack->depth);
-
+
+ /*
+ * Insert a separator on the redo stack.
+ */
+
+ TkUndoInsertSeparator(&stack->redoStack);
+ stack->depth--;
return TCL_OK;
}
-
/*
+ *----------------------------------------------------------------------
+ *
* TkUndoApply --
- * Redo a compound action on the stack.
+ *
+ * Redo a compound action on the stack.
*
* Results:
- * A TCL status code
+ * A Tcl status code
*
* Side effects:
- * None.
+ * None.
+ *
+ *----------------------------------------------------------------------
*/
-
-int TkUndoApply ( stack )
- TkUndoRedoStack * stack;
+
+int
+TkUndoApply(
+ TkUndoRedoStack *stack)
{
TkUndoAtom *elem;
- /* insert a separator on the undo stack */
+ /*
+ * Insert a separator on the undo stack.
+ */
- TkUndoInsertSeparator(&(stack->undoStack));
+ TkUndoInsertSeparator(&stack->undoStack);
- /* Pop and skip the first separator if there is one*/
+ /*
+ * Pop and skip the first separator if there is one.
+ */
- elem = TkUndoPopStack(&(stack->redoStack));
-
- if ( elem == NULL ) {
- return TCL_ERROR;
+ elem = TkUndoPopStack(&stack->redoStack);
+ if (elem == NULL) {
+ return TCL_ERROR;
}
- if ( ( elem != NULL ) && ( elem->type == TK_UNDO_SEPARATOR ) ) {
- ckfree((char *) elem);
- elem = TkUndoPopStack(&(stack->redoStack));
+ if (elem->type == TK_UNDO_SEPARATOR) {
+ ckfree((char *) elem);
+ elem = TkUndoPopStack(&stack->redoStack);
}
- while ( elem && (elem->type != TK_UNDO_SEPARATOR) ) {
- Tcl_EvalObjEx(stack->interp,elem->apply,TCL_EVAL_GLOBAL);
-
- TkUndoPushStack(&(stack->undoStack), elem);
- elem = TkUndoPopStack(&(stack->redoStack));
+ while (elem != NULL && elem->type != TK_UNDO_SEPARATOR) {
+ /*
+ * Note that we currently ignore errors thrown here.
+ */
+
+ EvaluateActionList(stack->interp, elem->apply);
+
+ TkUndoPushStack(&stack->undoStack, elem);
+ elem = TkUndoPopStack(&stack->redoStack);
}
- /* insert a separator on the undo stack */
-
- TkUndoInsertSeparator(&(stack->undoStack));
+ /*
+ * Insert a separator on the undo stack.
+ */
- ++(stack->depth);
-
+ TkUndoInsertSeparator(&stack->undoStack);
+ stack->depth++;
return TCL_OK;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * EvaluateActionList --
+ *
+ * Execute a linked list of undo/redo sub-atoms. If any sub-atom returns
+ * a non TCL_OK value, execution of subsequent sub-atoms is cancelled and
+ * the error returned immediately.
+ *
+ * Results:
+ * A Tcl status code
+ *
+ * Side effects:
+ * The undo/redo subAtoms can perform arbitrary actions.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+EvaluateActionList(
+ Tcl_Interp *interp, /* Interpreter to evaluate the action in. */
+ TkUndoSubAtom *action) /* Head of linked list of action steps to
+ * perform. */
+{
+ int result = TCL_OK;
+
+ while (action != NULL) {
+ if (action->funcPtr != NULL) {
+ result = (*action->funcPtr)(interp, action->clientData,
+ action->action);
+ } else if (action->command != NULL) {
+ Tcl_Obj *cmdNameObj, *evalObj;
+
+ cmdNameObj = Tcl_NewObj();
+ evalObj = Tcl_NewObj();
+ Tcl_IncrRefCount(evalObj);
+ Tcl_GetCommandFullName(interp, action->command, cmdNameObj);
+ Tcl_ListObjAppendElement(NULL, evalObj, cmdNameObj);
+ if (action->action != NULL) {
+ Tcl_ListObjAppendList(NULL, evalObj, action->action);
+ }
+ result = Tcl_EvalObjEx(interp, evalObj, TCL_EVAL_GLOBAL);
+ Tcl_DecrRefCount(evalObj);
+ } else {
+ result = Tcl_EvalObjEx(interp, action->action, TCL_EVAL_GLOBAL);
+ }
+ if (result != TCL_OK) {
+ return result;
+ }
+ action = action->next;
+ }
+ return result;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkUndo.h b/generic/tkUndo.h
index 8f0411c..b0e2db0 100644
--- a/generic/tkUndo.h
+++ b/generic/tkUndo.h
@@ -1,20 +1,19 @@
/*
* tkUndo.h --
*
- * Declarations shared among the files that implement an undo
- * stack.
+ * Declarations shared among the files that implement an undo stack.
*
* Copyright (c) 2002 Ludwig Callewaert.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TKUNDO
#define _TKUNDO
-#ifndef _TK
-#include "tk.h"
+#ifndef _TKINT
+#include "tkInt.h"
#endif
#ifdef BUILD_tk
@@ -22,65 +21,99 @@
# define TCL_STORAGE_CLASS DLLEXPORT
#endif
-/* enum definining the types used in an undo stack */
+/*
+ * Enum definining the types used in an undo stack.
+ */
typedef enum {
- TK_UNDO_SEPARATOR, /* Marker */
- TK_UNDO_ACTION /* Command */
+ TK_UNDO_SEPARATOR, /* Marker */
+ TK_UNDO_ACTION /* Command */
} TkUndoAtomType;
-/* struct defining the basic undo/redo stack element */
-
-typedef struct TkUndoAtom {
- TkUndoAtomType type; /* The type that will trigger the
- * required action*/
- Tcl_Obj * apply; /* Command to apply the action that was taken */
- Tcl_Obj * revert; /* The command to undo the action */
- struct TkUndoAtom * next; /* Pointer to the next element in the
- * stack */
-} TkUndoAtom;
-
-/* struct defining the basic undo/redo stack element */
-
-typedef struct TkUndoRedoStack {
- TkUndoAtom * undoStack; /* The undo stack */
- TkUndoAtom * redoStack; /* The redo stack */
- Tcl_Interp * interp ; /* The interpreter in which to execute the revert and apply scripts */
- int maxdepth;
- int depth;
-} TkUndoRedoStack;
-
-/* basic functions */
+/*
+ * Callback proc type to carry out an undo or redo action via C code. (Actions
+ * can also be defined by Tcl scripts).
+ */
-EXTERN void TkUndoPushStack _ANSI_ARGS_((TkUndoAtom ** stack,
- TkUndoAtom * elem));
+typedef int (TkUndoProc)(Tcl_Interp *interp, ClientData clientData,
+ Tcl_Obj *objPtr);
-EXTERN TkUndoAtom * TkUndoPopStack _ANSI_ARGS_((TkUndoAtom ** stack));
-
-EXTERN int TkUndoInsertSeparator _ANSI_ARGS_((TkUndoAtom ** stack));
+/*
+ * Struct defining a single action, one or more of which may be defined (and
+ * stored in a linked list) separately for each undo and redo action of an
+ * undo atom.
+ */
-EXTERN void TkUndoClearStack _ANSI_ARGS_((TkUndoAtom ** stack));
+typedef struct TkUndoSubAtom {
+ Tcl_Command command; /* Tcl token used to get the current Tcl
+ * command name which will be used to execute
+ * apply/revert scripts. If NULL then it is
+ * assumed the apply/revert scripts already
+ * contain everything. */
+ TkUndoProc *funcPtr; /* Function pointer for callback to perform
+ * undo/redo actions. */
+ ClientData clientData; /* Data for 'funcPtr'. */
+ Tcl_Obj *action; /* Command to apply the action that was
+ * taken. */
+ struct TkUndoSubAtom *next; /* Pointer to the next element in the linked
+ * list. */
+} TkUndoSubAtom;
-/* functions working on an undo/redo stack */
+/*
+ * Struct representing a single undo+redo atom to be placed in the stack.
+ */
-EXTERN TkUndoRedoStack * TkUndoInitStack _ANSI_ARGS_((Tcl_Interp * interp,
- int maxdepth));
+typedef struct TkUndoAtom {
+ TkUndoAtomType type; /* The type that will trigger the required
+ * action. */
+ TkUndoSubAtom *apply; /* Linked list of 'apply' actions to perform
+ * for this operation. */
+ TkUndoSubAtom *revert; /* Linked list of 'revert' actions to perform
+ * for this operation. */
+ struct TkUndoAtom *next; /* Pointer to the next element in the
+ * stack. */
+} TkUndoAtom;
-EXTERN void TkUndoSetDepth _ANSI_ARGS_((TkUndoRedoStack * stack,
- int maxdepth));
+/*
+ * Struct defining a single undo+redo stack.
+ */
-EXTERN void TkUndoClearStacks _ANSI_ARGS_((TkUndoRedoStack * stack));
+typedef struct TkUndoRedoStack {
+ TkUndoAtom *undoStack; /* The undo stack. */
+ TkUndoAtom *redoStack; /* The redo stack. */
+ Tcl_Interp *interp; /* The interpreter in which to execute the
+ * revert and apply scripts. */
+ int maxdepth;
+ int depth;
+} TkUndoRedoStack;
-EXTERN void TkUndoFreeStack _ANSI_ARGS_((TkUndoRedoStack * stack));
+/*
+ * Basic functions.
+ */
-EXTERN void TkUndoInsertUndoSeparator _ANSI_ARGS_((TkUndoRedoStack * stack));
+MODULE_SCOPE void TkUndoPushStack(TkUndoAtom **stack, TkUndoAtom *elem);
+MODULE_SCOPE TkUndoAtom *TkUndoPopStack(TkUndoAtom **stack);
+MODULE_SCOPE int TkUndoInsertSeparator(TkUndoAtom **stack);
+MODULE_SCOPE void TkUndoClearStack(TkUndoAtom **stack);
-EXTERN void TkUndoPushAction _ANSI_ARGS_((TkUndoRedoStack * stack,
- Tcl_DString * actionScript, Tcl_DString * revertScript));
+/*
+ * Functions for working on an undo/redo stack.
+ */
-EXTERN int TkUndoRevert _ANSI_ARGS_((TkUndoRedoStack * stack));
-
-EXTERN int TkUndoApply _ANSI_ARGS_((TkUndoRedoStack * stack));
+MODULE_SCOPE TkUndoRedoStack *TkUndoInitStack(Tcl_Interp *interp, int maxdepth);
+MODULE_SCOPE void TkUndoSetDepth(TkUndoRedoStack *stack, int maxdepth);
+MODULE_SCOPE void TkUndoClearStacks(TkUndoRedoStack *stack);
+MODULE_SCOPE void TkUndoFreeStack(TkUndoRedoStack *stack);
+MODULE_SCOPE void TkUndoInsertUndoSeparator(TkUndoRedoStack *stack);
+MODULE_SCOPE TkUndoSubAtom *TkUndoMakeCmdSubAtom(Tcl_Command command,
+ Tcl_Obj *actionScript, TkUndoSubAtom *subAtomList);
+MODULE_SCOPE TkUndoSubAtom *TkUndoMakeSubAtom(TkUndoProc *funcPtr,
+ ClientData clientData, Tcl_Obj *actionScript,
+ TkUndoSubAtom *subAtomList);
+MODULE_SCOPE void TkUndoPushAction(TkUndoRedoStack *stack,
+ TkUndoSubAtom *apply, TkUndoSubAtom *revert);
+MODULE_SCOPE int TkUndoRevert(TkUndoRedoStack *stack);
+MODULE_SCOPE int TkUndoApply(TkUndoRedoStack *stack);
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLIMPORT
diff --git a/generic/tkUtil.c b/generic/tkUtil.c
index 3d04657..2a8240b 100644
--- a/generic/tkUtil.c
+++ b/generic/tkUtil.c
@@ -1,63 +1,60 @@
-/*
+/*
* tkUtil.c --
*
- * This file contains miscellaneous utility procedures that
- * are used by the rest of Tk, such as a procedure for drawing
- * a focus highlight.
+ * This file contains miscellaneous utility functions that are used by
+ * the rest of Tk, such as a function for drawing a focus highlight.
*
* Copyright (c) 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#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.
+ * The structure below defines the implementation of the "statekey" Tcl
+ * object, used for quickly finding a mapping in a TkStateMap.
*/
Tcl_ObjType tkStateKeyObjType = {
- "statekey", /* name */
- (Tcl_FreeInternalRepProc *) NULL, /* freeIntRepProc */
- (Tcl_DupInternalRepProc *) NULL, /* dupIntRepProc */
- (Tcl_UpdateStringProc *) NULL, /* updateStringProc */
- (Tcl_SetFromAnyProc *) NULL /* setFromAnyProc */
+ "statekey", /* name */
+ NULL, /* freeIntRepProc */
+ NULL, /* dupIntRepProc */
+ NULL, /* updateStringProc */
+ NULL /* setFromAnyProc */
};
-
/*
*--------------------------------------------------------------
*
* TkStateParseProc --
*
- * This procedure is invoked during option processing to handle
- * the "-state" and "-default" options.
+ * This function is invoked during option processing to handle the
+ * "-state" and "-default" options.
*
* Results:
* A standard Tcl return value.
*
* Side effects:
- * The state for a given item gets replaced by the state
- * indicated in the value argument.
+ * The state for a given item gets replaced by the state indicated in the
+ * value argument.
*
*--------------------------------------------------------------
*/
int
-TkStateParseProc(clientData, interp, tkwin, value, widgRec, offset)
- ClientData clientData; /* some flags.*/
- Tcl_Interp *interp; /* Used for reporting errors. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- CONST char *value; /* Value of option. */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Offset into item. */
+TkStateParseProc(
+ ClientData clientData, /* some flags.*/
+ Tcl_Interp *interp, /* Used for reporting errors. */
+ Tk_Window tkwin, /* Window containing canvas widget. */
+ const char *value, /* Value of option. */
+ char *widgRec, /* Pointer to record for item. */
+ int offset) /* Offset into item. */
{
int c;
- int flags = (int)clientData;
+ int flags = PTR2INT(clientData);
size_t length;
register Tk_State *statePtr = (Tk_State *) (widgRec + offset);
@@ -88,18 +85,17 @@ TkStateParseProc(clientData, interp, tkwin, value, widgRec, offset)
}
Tcl_AppendResult(interp, "bad ", (flags&4)?"-default" : "state",
- " value \"", value, "\": must be normal",
- (char *) NULL);
+ " value \"", value, "\": must be normal", NULL);
if (flags&1) {
- Tcl_AppendResult(interp, ", active",(char *) NULL);
+ Tcl_AppendResult(interp, ", active", NULL);
}
if (flags&2) {
- Tcl_AppendResult(interp, ", hidden",(char *) NULL);
+ Tcl_AppendResult(interp, ", hidden", NULL);
}
if (flags&3) {
- Tcl_AppendResult(interp, ",",(char *) NULL);
+ Tcl_AppendResult(interp, ",", NULL);
}
- Tcl_AppendResult(interp, " or disabled",(char *) NULL);
+ Tcl_AppendResult(interp, " or disabled", NULL);
*statePtr = TK_STATE_NORMAL;
return TCL_ERROR;
}
@@ -109,16 +105,15 @@ TkStateParseProc(clientData, interp, tkwin, value, widgRec, offset)
*
* TkStatePrintProc --
*
- * This procedure is invoked by the Tk configuration code
- * to produce a printable string for the "-state"
- * configuration option.
+ * This function is invoked by the Tk configuration code to produce a
+ * printable string for the "-state" configuration option.
*
* Results:
- * The return value is a string describing the state for
- * the item referred to by "widgRec". In addition, *freeProcPtr
- * is filled in with the address of a procedure to call to free
- * the result string when it's no longer needed (or NULL to
- * indicate that the string doesn't need to be freed).
+ * The return value is a string describing the state for the item
+ * referred to by "widgRec". In addition, *freeProcPtr is filled in with
+ * the address of a function to call to free the result string when it's
+ * no longer needed (or NULL to indicate that the string doesn't need to
+ * be freed).
*
* Side effects:
* None.
@@ -127,26 +122,27 @@ TkStateParseProc(clientData, interp, tkwin, value, widgRec, offset)
*/
char *
-TkStatePrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
- ClientData clientData; /* Ignored. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Offset into item. */
- Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
- * information about how to reclaim
- * storage for return string. */
+TkStatePrintProc(
+ ClientData clientData, /* Ignored. */
+ Tk_Window tkwin, /* Window containing canvas widget. */
+ char *widgRec, /* Pointer to record for item. */
+ int offset, /* Offset into item. */
+ Tcl_FreeProc **freeProcPtr) /* Pointer to variable to fill in with
+ * information about how to reclaim storage
+ * for return string. */
{
register Tk_State *statePtr = (Tk_State *) (widgRec + offset);
- if (*statePtr==TK_STATE_NORMAL) {
+ switch (*statePtr) {
+ case TK_STATE_NORMAL:
return "normal";
- } else if (*statePtr==TK_STATE_DISABLED) {
+ case TK_STATE_DISABLED:
return "disabled";
- } else if (*statePtr==TK_STATE_HIDDEN) {
+ case TK_STATE_HIDDEN:
return "hidden";
- } else if (*statePtr==TK_STATE_ACTIVE) {
+ case TK_STATE_ACTIVE:
return "active";
- } else {
+ default:
return "";
}
}
@@ -156,8 +152,8 @@ TkStatePrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
*
* TkOrientParseProc --
*
- * This procedure is invoked during option processing to handle
- * the "-orient" option.
+ * This function is invoked during option processing to handle the
+ * "-orient" option.
*
* Results:
* A standard Tcl return value.
@@ -170,13 +166,13 @@ TkStatePrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
*/
int
-TkOrientParseProc(clientData, interp, tkwin, value, widgRec, offset)
- ClientData clientData; /* some flags.*/
- Tcl_Interp *interp; /* Used for reporting errors. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- CONST char *value; /* Value of option. */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Offset into item. */
+TkOrientParseProc(
+ ClientData clientData, /* some flags.*/
+ Tcl_Interp *interp, /* Used for reporting errors. */
+ Tk_Window tkwin, /* Window containing canvas widget. */
+ const char *value, /* Value of option. */
+ char *widgRec, /* Pointer to record for item. */
+ int offset) /* Offset into item. */
{
int c;
size_t length;
@@ -200,8 +196,7 @@ TkOrientParseProc(clientData, interp, tkwin, value, widgRec, offset)
return TCL_OK;
}
Tcl_AppendResult(interp, "bad orientation \"", value,
- "\": must be vertical or horizontal",
- (char *) NULL);
+ "\": must be vertical or horizontal", NULL);
*orientPtr = 0;
return TCL_ERROR;
}
@@ -211,16 +206,15 @@ TkOrientParseProc(clientData, interp, tkwin, value, widgRec, offset)
*
* TkOrientPrintProc --
*
- * This procedure is invoked by the Tk configuration code
- * to produce a printable string for the "-orient"
- * configuration option.
+ * This function is invoked by the Tk configuration code to produce a
+ * printable string for the "-orient" configuration option.
*
* Results:
- * The return value is a string describing the orientation for
- * the item referred to by "widgRec". In addition, *freeProcPtr
- * is filled in with the address of a procedure to call to free
- * the result string when it's no longer needed (or NULL to
- * indicate that the string doesn't need to be freed).
+ * The return value is a string describing the orientation for the item
+ * referred to by "widgRec". In addition, *freeProcPtr is filled in with
+ * the address of a function to call to free the result string when it's
+ * no longer needed (or NULL to indicate that the string doesn't need to
+ * be freed).
*
* Side effects:
* None.
@@ -229,14 +223,14 @@ TkOrientParseProc(clientData, interp, tkwin, value, widgRec, offset)
*/
char *
-TkOrientPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
- ClientData clientData; /* Ignored. */
- Tk_Window tkwin; /* Window containing canvas widget. */
- char *widgRec; /* Pointer to record for item. */
- int offset; /* Offset into item. */
- Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
- * information about how to reclaim
- * storage for return string. */
+TkOrientPrintProc(
+ ClientData clientData, /* Ignored. */
+ Tk_Window tkwin, /* Window containing canvas widget. */
+ char *widgRec, /* Pointer to record for item. */
+ int offset, /* Offset into item. */
+ Tcl_FreeProc **freeProcPtr) /* Pointer to variable to fill in with
+ * information about how to reclaim storage
+ * for return string. */
{
register int *statePtr = (int *) (widgRec + offset);
@@ -252,23 +246,24 @@ TkOrientPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
*
* TkOffsetParseProc --
*
- * Converts the offset of a stipple or tile into the Tk_TSOffset structure.
+ * Converts the offset of a stipple or tile into the Tk_TSOffset
+ * structure.
*
*----------------------------------------------------------------------
*/
int
-TkOffsetParseProc(clientData, interp, tkwin, value, widgRec, offset)
- ClientData clientData; /* not used */
- Tcl_Interp *interp; /* Interpreter to send results back to */
- Tk_Window tkwin; /* Window on same display as tile */
- CONST char *value; /* Name of image */
- char *widgRec; /* Widget structure record */
- int offset; /* Offset of tile in record */
+TkOffsetParseProc(
+ ClientData clientData, /* not used */
+ Tcl_Interp *interp, /* Interpreter to send results back to */
+ Tk_Window tkwin, /* Window on same display as tile */
+ const char *value, /* Name of image */
+ char *widgRec, /* Widget structure record */
+ int offset) /* Offset of tile in record */
{
- Tk_TSOffset *offsetPtr = (Tk_TSOffset *)(widgRec + offset);
+ Tk_TSOffset *offsetPtr = (Tk_TSOffset *) (widgRec + offset);
Tk_TSOffset tsoffset;
- CONST char *q, *p;
+ const char *q, *p;
int result;
if ((value == NULL) || (*value == 0)) {
@@ -279,61 +274,70 @@ TkOffsetParseProc(clientData, interp, tkwin, value, widgRec, offset)
p = value;
switch(value[0]) {
- case '#':
- if (((int)clientData) & TK_OFFSET_RELATIVE) {
- tsoffset.flags = TK_OFFSET_RELATIVE;
- p++; break;
- }
- goto badTSOffset;
- case 'e':
- switch(value[1]) {
- case '\0':
- tsoffset.flags = TK_OFFSET_RIGHT|TK_OFFSET_MIDDLE;
- goto goodTSOffset;
- case 'n':
- if (value[2]!='d' || value[3]!='\0') {goto badTSOffset;}
- tsoffset.flags = INT_MAX;
- goto goodTSOffset;
- }
- case 'w':
- if (value[1] != '\0') {goto badTSOffset;}
- tsoffset.flags = TK_OFFSET_LEFT|TK_OFFSET_MIDDLE;
+ case '#':
+ if (PTR2INT(clientData) & TK_OFFSET_RELATIVE) {
+ tsoffset.flags = TK_OFFSET_RELATIVE;
+ p++;
+ break;
+ }
+ goto badTSOffset;
+ case 'e':
+ switch(value[1]) {
+ case '\0':
+ tsoffset.flags = TK_OFFSET_RIGHT|TK_OFFSET_MIDDLE;
goto goodTSOffset;
case 'n':
- if ((value[1] != '\0') && (value[2] != '\0')) {
+ if (value[2]!='d' || value[3]!='\0') {
goto badTSOffset;
}
- switch(value[1]) {
- case '\0': tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_TOP;
- goto goodTSOffset;
- case 'w': tsoffset.flags = TK_OFFSET_LEFT|TK_OFFSET_TOP;
- goto goodTSOffset;
- case 'e': tsoffset.flags = TK_OFFSET_RIGHT|TK_OFFSET_TOP;
- goto goodTSOffset;
- }
+ tsoffset.flags = INT_MAX;
+ goto goodTSOffset;
+ }
+ case 'w':
+ if (value[1] != '\0') {goto badTSOffset;}
+ tsoffset.flags = TK_OFFSET_LEFT|TK_OFFSET_MIDDLE;
+ goto goodTSOffset;
+ case 'n':
+ if ((value[1] != '\0') && (value[2] != '\0')) {
goto badTSOffset;
- case 's':
- if ((value[1] != '\0') && (value[2] != '\0')) {
- goto badTSOffset;
- }
- switch(value[1]) {
- case '\0': tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_BOTTOM;
- goto goodTSOffset;
- case 'w': tsoffset.flags = TK_OFFSET_LEFT|TK_OFFSET_BOTTOM;
- goto goodTSOffset;
- case 'e': tsoffset.flags = TK_OFFSET_RIGHT|TK_OFFSET_BOTTOM;
- goto goodTSOffset;
- }
+ }
+ switch(value[1]) {
+ case '\0':
+ tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_TOP;
+ goto goodTSOffset;
+ case 'w':
+ tsoffset.flags = TK_OFFSET_LEFT|TK_OFFSET_TOP;
+ goto goodTSOffset;
+ case 'e':
+ tsoffset.flags = TK_OFFSET_RIGHT|TK_OFFSET_TOP;
+ goto goodTSOffset;
+ }
+ goto badTSOffset;
+ case 's':
+ if ((value[1] != '\0') && (value[2] != '\0')) {
goto badTSOffset;
- case 'c':
- if (strncmp(value, "center", strlen(value)) != 0) {
- goto badTSOffset;
- }
- tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_MIDDLE;
+ }
+ switch(value[1]) {
+ case '\0':
+ tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_BOTTOM;
+ goto goodTSOffset;
+ case 'w':
+ tsoffset.flags = TK_OFFSET_LEFT|TK_OFFSET_BOTTOM;
+ goto goodTSOffset;
+ case 'e':
+ tsoffset.flags = TK_OFFSET_RIGHT|TK_OFFSET_BOTTOM;
goto goodTSOffset;
+ }
+ goto badTSOffset;
+ case 'c':
+ if (strncmp(value, "center", strlen(value)) != 0) {
+ goto badTSOffset;
+ }
+ tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_MIDDLE;
+ goto goodTSOffset;
}
if ((q = strchr(p,',')) == NULL) {
- if (((int)clientData) & TK_OFFSET_INDEX) {
+ if (PTR2INT(clientData) & TK_OFFSET_INDEX) {
if (Tcl_GetInt(interp, (char *) p, &tsoffset.flags) != TCL_OK) {
Tcl_ResetResult(interp);
goto badTSOffset;
@@ -349,33 +353,31 @@ TkOffsetParseProc(clientData, interp, tkwin, value, widgRec, offset)
if (result != TCL_OK) {
return TCL_ERROR;
}
- if (Tk_GetPixels(interp, tkwin, (char *) q+1, &tsoffset.yoffset) != TCL_OK) {
+ if (Tk_GetPixels(interp, tkwin, (char*)q+1, &tsoffset.yoffset) != TCL_OK) {
return TCL_ERROR;
}
-
-goodTSOffset:
- /* below is a hack to allow the stipple/tile offset to be stored
- * in the internal tile structure. Most of the times, offsetPtr
- * is a pointer to an already existing tile structure. However
- * if this structure is not already created, we must do it
- * with Tk_GetTile()!!!!;
+ goodTSOffset:
+ /*
+ * Below is a hack to allow the stipple/tile offset to be stored in the
+ * internal tile structure. Most of the times, offsetPtr is a pointer to
+ * an already existing tile structure. However if this structure is not
+ * already created, we must do it with Tk_GetTile()!!!!;
*/
- memcpy(offsetPtr,&tsoffset, sizeof(Tk_TSOffset));
+ memcpy(offsetPtr, &tsoffset, sizeof(Tk_TSOffset));
return TCL_OK;
-badTSOffset:
+ badTSOffset:
Tcl_AppendResult(interp, "bad offset \"", value,
- "\": expected \"x,y\"", (char *) NULL);
- if (((int) clientData) & TK_OFFSET_RELATIVE) {
- Tcl_AppendResult(interp, ", \"#x,y\"", (char *) NULL);
+ "\": expected \"x,y\"", NULL);
+ if (PTR2INT(clientData) & TK_OFFSET_RELATIVE) {
+ Tcl_AppendResult(interp, ", \"#x,y\"", NULL);
}
- if (((int) clientData) & TK_OFFSET_INDEX) {
- Tcl_AppendResult(interp, ", <index>", (char *) NULL);
+ if (PTR2INT(clientData) & TK_OFFSET_INDEX) {
+ Tcl_AppendResult(interp, ", <index>", NULL);
}
- Tcl_AppendResult(interp, ", n, ne, e, se, s, sw, w, nw, or center",
- (char *) NULL);
+ Tcl_AppendResult(interp, ", n, ne, e, se, s, sw, w, nw, or center", NULL);
return TCL_ERROR;
}
@@ -393,60 +395,59 @@ badTSOffset:
*/
char *
-TkOffsetPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
- ClientData clientData; /* not used */
- Tk_Window tkwin; /* not used */
- char *widgRec; /* Widget structure record */
- int offset; /* Offset of tile in record */
- Tcl_FreeProc **freeProcPtr; /* not used */
+TkOffsetPrintProc(
+ ClientData clientData, /* not used */
+ Tk_Window tkwin, /* not used */
+ char *widgRec, /* Widget structure record */
+ int offset, /* Offset of tile in record */
+ Tcl_FreeProc **freeProcPtr) /* not used */
{
- Tk_TSOffset *offsetPtr = (Tk_TSOffset *)(widgRec + offset);
+ Tk_TSOffset *offsetPtr = (Tk_TSOffset *) (widgRec + offset);
char *p, *q;
- if ((offsetPtr->flags) & TK_OFFSET_INDEX) {
- if ((offsetPtr->flags) >= INT_MAX) {
+ if (offsetPtr->flags & TK_OFFSET_INDEX) {
+ if (offsetPtr->flags >= INT_MAX) {
return "end";
}
p = (char *) ckalloc(32);
- sprintf(p, "%d",(offsetPtr->flags & (~TK_OFFSET_INDEX)));
+ sprintf(p, "%d", offsetPtr->flags & ~TK_OFFSET_INDEX);
*freeProcPtr = TCL_DYNAMIC;
return p;
}
- if ((offsetPtr->flags) & TK_OFFSET_TOP) {
- if ((offsetPtr->flags) & TK_OFFSET_LEFT) {
+ if (offsetPtr->flags & TK_OFFSET_TOP) {
+ if (offsetPtr->flags & TK_OFFSET_LEFT) {
return "nw";
- } else if ((offsetPtr->flags) & TK_OFFSET_CENTER) {
+ } else if (offsetPtr->flags & TK_OFFSET_CENTER) {
return "n";
- } else if ((offsetPtr->flags) & TK_OFFSET_RIGHT) {
+ } else if (offsetPtr->flags & TK_OFFSET_RIGHT) {
return "ne";
}
- } else if ((offsetPtr->flags) & TK_OFFSET_MIDDLE) {
- if ((offsetPtr->flags) & TK_OFFSET_LEFT) {
+ } else if (offsetPtr->flags & TK_OFFSET_MIDDLE) {
+ if (offsetPtr->flags & TK_OFFSET_LEFT) {
return "w";
- } else if ((offsetPtr->flags) & TK_OFFSET_CENTER) {
+ } else if (offsetPtr->flags & TK_OFFSET_CENTER) {
return "center";
- } else if ((offsetPtr->flags) & TK_OFFSET_RIGHT) {
+ } else if (offsetPtr->flags & TK_OFFSET_RIGHT) {
return "e";
}
- } else if ((offsetPtr->flags) & TK_OFFSET_BOTTOM) {
- if ((offsetPtr->flags) & TK_OFFSET_LEFT) {
+ } else if (offsetPtr->flags & TK_OFFSET_BOTTOM) {
+ if (offsetPtr->flags & TK_OFFSET_LEFT) {
return "sw";
- } else if ((offsetPtr->flags) & TK_OFFSET_CENTER) {
+ } else if (offsetPtr->flags & TK_OFFSET_CENTER) {
return "s";
- } else if ((offsetPtr->flags) & TK_OFFSET_RIGHT) {
+ } else if (offsetPtr->flags & TK_OFFSET_RIGHT) {
return "se";
}
- }
+ }
q = p = (char *) ckalloc(32);
- if ((offsetPtr->flags) & TK_OFFSET_RELATIVE) {
+ if (offsetPtr->flags & TK_OFFSET_RELATIVE) {
*q++ = '#';
}
- sprintf(q, "%d,%d",offsetPtr->xoffset, offsetPtr->yoffset);
+ sprintf(q, "%d,%d", offsetPtr->xoffset, offsetPtr->yoffset);
*freeProcPtr = TCL_DYNAMIC;
return p;
}
-
/*
*----------------------------------------------------------------------
*
@@ -458,23 +459,22 @@ TkOffsetPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
*/
int
-TkPixelParseProc(clientData, interp, tkwin, value, widgRec, offset)
- ClientData clientData; /* if non-NULL, negative values are
- * allowed as well */
- Tcl_Interp *interp; /* Interpreter to send results back to */
- Tk_Window tkwin; /* Window on same display as tile */
- CONST char *value; /* Name of image */
- char *widgRec; /* Widget structure record */
- int offset; /* Offset of tile in record */
+TkPixelParseProc(
+ ClientData clientData, /* If non-NULL, negative values are allowed as
+ * well */
+ Tcl_Interp *interp, /* Interpreter to send results back to */
+ Tk_Window tkwin, /* Window on same display as tile */
+ const char *value, /* Name of image */
+ char *widgRec, /* Widget structure record */
+ int offset) /* Offset of tile in record */
{
- double *doublePtr = (double *)(widgRec + offset);
+ double *doublePtr = (double *) (widgRec + offset);
int result;
result = TkGetDoublePixels(interp, tkwin, value, doublePtr);
if ((result == TCL_OK) && (clientData == NULL) && (*doublePtr < 0.0)) {
- Tcl_AppendResult(interp, "bad screen distance \"", value,
- "\"", (char *) NULL);
+ Tcl_AppendResult(interp, "bad screen distance \"", value, "\"", NULL);
return TCL_ERROR;
}
return result;
@@ -494,18 +494,17 @@ TkPixelParseProc(clientData, interp, tkwin, value, widgRec, offset)
*/
char *
-TkPixelPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
- ClientData clientData; /* not used */
- Tk_Window tkwin; /* not used */
- char *widgRec; /* Widget structure record */
- int offset; /* Offset of tile in record */
- Tcl_FreeProc **freeProcPtr; /* not used */
+TkPixelPrintProc(
+ ClientData clientData, /* not used */
+ Tk_Window tkwin, /* not used */
+ char *widgRec, /* Widget structure record */
+ int offset, /* Offset of tile in record */
+ Tcl_FreeProc **freeProcPtr) /* not used */
{
- double *doublePtr = (double *)(widgRec + offset);
- char *p;
+ double *doublePtr = (double *) (widgRec + offset);
+ char *p = (char *) ckalloc(24);
- p = (char *) ckalloc(24);
- Tcl_PrintDouble((Tcl_Interp *) NULL, *doublePtr, p);
+ Tcl_PrintDouble(NULL, *doublePtr, p);
*freeProcPtr = TCL_DYNAMIC;
return p;
}
@@ -515,31 +514,31 @@ TkPixelPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
*
* TkDrawInsetFocusHighlight --
*
- * This procedure draws a rectangular ring around the outside of
- * a widget to indicate that it has received the input focus. It
- * takes an additional padding argument that specifies how much
- * padding is present outside th widget.
+ * This function draws a rectangular ring around the outside of a widget
+ * to indicate that it has received the input focus. It takes an
+ * additional padding argument that specifies how much padding is present
+ * outside the widget.
*
* Results:
* None.
*
* Side effects:
- * A rectangle "width" pixels wide is drawn in "drawable",
- * corresponding to the outer area of "tkwin".
+ * A rectangle "width" pixels wide is drawn in "drawable", corresponding
+ * to the outer area of "tkwin".
*
*----------------------------------------------------------------------
*/
void
-TkDrawInsetFocusHighlight(tkwin, gc, width, drawable, padding)
- Tk_Window tkwin; /* Window whose focus highlight ring is
- * to be drawn. */
- GC gc; /* Graphics context to use for drawing
- * the highlight ring. */
- int width; /* Width of the highlight ring, in pixels. */
- Drawable drawable; /* Where to draw the ring (typically a
- * pixmap for double buffering). */
- int padding; /* Width of padding outside of widget. */
+TkDrawInsetFocusHighlight(
+ Tk_Window tkwin, /* Window whose focus highlight ring is to be
+ * drawn. */
+ GC gc, /* Graphics context to use for drawing the
+ * highlight ring. */
+ int width, /* Width of the highlight ring, in pixels. */
+ Drawable drawable, /* Where to draw the ring (typically a pixmap
+ * for double buffering). */
+ int padding) /* Width of padding outside of widget. */
{
XRectangle rects[4];
@@ -567,34 +566,34 @@ TkDrawInsetFocusHighlight(tkwin, gc, width, drawable, padding)
*
* Tk_DrawFocusHighlight --
*
- * This procedure draws a rectangular ring around the outside of
- * a widget to indicate that it has received the input focus.
+ * This function draws a rectangular ring around the outside of a widget
+ * to indicate that it has received the input focus.
*
- * This function is now deprecated. Use TkpDrawHighlightBorder instead,
- * since this function does not handle drawing the Focus ring properly
- * on the Macintosh - you need to know the background GC as well
- * as the foreground since the Mac focus ring separated from the widget
- * by a 1 pixel border.
+ * This function is now deprecated. Use TkpDrawHighlightBorder instead,
+ * since this function does not handle drawing the Focus ring properly on
+ * the Macintosh - you need to know the background GC as well as the
+ * foreground since the Mac focus ring separated from the widget by a 1
+ * pixel border.
*
* Results:
* None.
*
* Side effects:
- * A rectangle "width" pixels wide is drawn in "drawable",
- * corresponding to the outer area of "tkwin".
+ * A rectangle "width" pixels wide is drawn in "drawable", corresponding
+ * to the outer area of "tkwin".
*
*----------------------------------------------------------------------
*/
void
-Tk_DrawFocusHighlight(tkwin, gc, width, drawable)
- Tk_Window tkwin; /* Window whose focus highlight ring is
- * to be drawn. */
- GC gc; /* Graphics context to use for drawing
- * the highlight ring. */
- int width; /* Width of the highlight ring, in pixels. */
- Drawable drawable; /* Where to draw the ring (typically a
- * pixmap for double buffering). */
+Tk_DrawFocusHighlight(
+ Tk_Window tkwin, /* Window whose focus highlight ring is to be
+ * drawn. */
+ GC gc, /* Graphics context to use for drawing the
+ * highlight ring. */
+ int width, /* Width of the highlight ring, in pixels. */
+ Drawable drawable) /* Where to draw the ring (typically a pixmap
+ * for double buffering). */
{
TkDrawInsetFocusHighlight(tkwin, gc, width, drawable, 0);
}
@@ -604,19 +603,18 @@ Tk_DrawFocusHighlight(tkwin, gc, width, drawable)
*
* Tk_GetScrollInfo --
*
- * This procedure is invoked to parse "xview" and "yview"
- * scrolling commands for widgets using the new scrolling
- * command syntax ("moveto" or "scroll" options).
+ * This function 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.
+ * 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.
@@ -625,25 +623,22 @@ Tk_DrawFocusHighlight(tkwin, gc, width, drawable)
*/
int
-Tk_GetScrollInfo(interp, argc, argv, dblPtr, intPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- int argc; /* # arguments for command. */
- CONST char **argv; /* 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. */
+Tk_GetScrollInfo(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ int argc, /* # arguments for command. */
+ const char **argv, /* 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;
+ int c = argv[2][0];
+ size_t length = strlen(argv[2]);
- length = strlen(argv[2]);
- c = argv[2][0];
if ((c == 'm') && (strncmp(argv[2], "moveto", length) == 0)) {
if (argc != 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " ", argv[1], " moveto fraction\"",
- (char *) NULL);
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+ " ", argv[1], " moveto fraction\"", NULL);
return TK_SCROLL_ERROR;
}
if (Tcl_GetDouble(interp, argv[3], dblPtr) != TCL_OK) {
@@ -653,9 +648,8 @@ Tk_GetScrollInfo(interp, argc, argv, dblPtr, intPtr)
} else if ((c == 's')
&& (strncmp(argv[2], "scroll", length) == 0)) {
if (argc != 5) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " ", argv[1], " scroll number units|pages\"",
- (char *) NULL);
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+ " ", argv[1], " scroll number units|pages\"", NULL);
return TK_SCROLL_ERROR;
}
if (Tcl_GetInt(interp, argv[3], intPtr) != TCL_OK) {
@@ -665,17 +659,16 @@ Tk_GetScrollInfo(interp, argc, argv, dblPtr, intPtr)
c = argv[4][0];
if ((c == 'p') && (strncmp(argv[4], "pages", length) == 0)) {
return TK_SCROLL_PAGES;
- } else if ((c == 'u')
- && (strncmp(argv[4], "units", length) == 0)) {
+ } else if ((c == 'u') && (strncmp(argv[4], "units", length) == 0)) {
return TK_SCROLL_UNITS;
- } else {
- Tcl_AppendResult(interp, "bad argument \"", argv[4],
- "\": must be units or pages", (char *) NULL);
- return TK_SCROLL_ERROR;
}
+
+ Tcl_AppendResult(interp, "bad argument \"", argv[4],
+ "\": must be units or pages", NULL);
+ return TK_SCROLL_ERROR;
}
Tcl_AppendResult(interp, "unknown option \"", argv[2],
- "\": must be moveto or scroll", (char *) NULL);
+ "\": must be moveto or scroll", NULL);
return TK_SCROLL_ERROR;
}
@@ -684,19 +677,18 @@ 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).
+ * This function 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.
+ * 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.
@@ -705,23 +697,23 @@ Tk_GetScrollInfo(interp, argc, argv, dblPtr, intPtr)
*/
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. */
+Tk_GetScrollInfoObj(
+ 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;
+ int length;
+ const char *arg;
+
+ arg = Tcl_GetStringFromObj(objv[2], &length);
+
+#define ArgPfxEq(str) ((arg[0]==str[0])&&!strncmp(arg,str,(unsigned)length))
- arg2 = Tcl_GetString(objv[2]);
- length = strlen(arg2);
- c = arg2[0];
- if ((c == 'm') && (strncmp(arg2, "moveto", length) == 0)) {
+ if (ArgPfxEq("moveto")) {
if (objc != 4) {
Tcl_WrongNumArgs(interp, 2, objv, "moveto fraction");
return TK_SCROLL_ERROR;
@@ -730,8 +722,7 @@ Tk_GetScrollInfoObj(interp, objc, objv, dblPtr, intPtr)
return TK_SCROLL_ERROR;
}
return TK_SCROLL_MOVETO;
- } else if ((c == 's')
- && (strncmp(arg2, "scroll", length) == 0)) {
+ } else if (ArgPfxEq("scroll")) {
if (objc != 5) {
Tcl_WrongNumArgs(interp, 2, objv, "scroll number units|pages");
return TK_SCROLL_ERROR;
@@ -739,22 +730,20 @@ Tk_GetScrollInfoObj(interp, objc, objv, dblPtr, intPtr)
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)) {
+
+ arg = Tcl_GetStringFromObj(objv[4], &length);
+ if (ArgPfxEq("pages")) {
return TK_SCROLL_PAGES;
- } else if ((c == 'u')
- && (strncmp(arg4, "units", length) == 0)) {
+ } else if (ArgPfxEq("units")) {
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, "bad argument \"", arg,
+ "\": must be units or pages", NULL);
+ return TK_SCROLL_ERROR;
}
- Tcl_AppendResult(interp, "unknown option \"", arg2,
- "\": must be moveto or scroll", (char *) NULL);
+ Tcl_AppendResult(interp, "unknown option \"", arg,
+ "\": must be moveto or scroll", NULL);
return TK_SCROLL_ERROR;
}
@@ -764,66 +753,80 @@ Tk_GetScrollInfoObj(interp, objc, objv, dblPtr, intPtr)
* TkComputeAnchor --
*
* Determine where to place a rectangle so that it will be properly
- * anchored with respect to the given window. Used by widgets
- * to align a box of text inside a window. When anchoring with
- * respect to one of the sides, the rectangle be placed inside of
- * the internal border of the window.
+ * anchored with respect to the given window. Used by widgets to align a
+ * box of text inside a window. When anchoring with respect to one of the
+ * sides, the rectangle be placed inside of the internal border of the
+ * window.
*
* Results:
- * *xPtr and *yPtr set to the upper-left corner of the rectangle
- * anchored in the window.
+ * *xPtr and *yPtr set to the upper-left corner of the rectangle anchored
+ * in the window.
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
+
void
-TkComputeAnchor(anchor, tkwin, padX, padY, innerWidth, innerHeight, xPtr, yPtr)
- Tk_Anchor anchor; /* Desired anchor. */
- Tk_Window tkwin; /* Anchored with respect to this window. */
- int padX, padY; /* Use this extra padding inside window, in
+TkComputeAnchor(
+ Tk_Anchor anchor, /* Desired anchor. */
+ Tk_Window tkwin, /* Anchored with respect to this window. */
+ int padX, int padY, /* Use this extra padding inside window, in
* addition to the internal border. */
- int innerWidth, innerHeight;/* Size of rectangle to anchor in window. */
- int *xPtr, *yPtr; /* Returns upper-left corner of anchored
+ int innerWidth, int innerHeight,
+ /* Size of rectangle to anchor in window. */
+ int *xPtr, int *yPtr) /* Returns upper-left corner of anchored
* rectangle. */
{
- switch (anchor) {
- case TK_ANCHOR_NW:
- case TK_ANCHOR_W:
- case TK_ANCHOR_SW:
- *xPtr = Tk_InternalBorderLeft(tkwin) + padX;
- break;
-
- case TK_ANCHOR_N:
- case TK_ANCHOR_CENTER:
- case TK_ANCHOR_S:
- *xPtr = (Tk_Width(tkwin) - innerWidth) / 2;
- break;
-
- default:
- *xPtr = Tk_Width(tkwin) - (Tk_InternalBorderRight(tkwin) + padX)
- - innerWidth;
- break;
- }
+ /*
+ * Handle the horizontal parts.
+ */
switch (anchor) {
- case TK_ANCHOR_NW:
- case TK_ANCHOR_N:
- case TK_ANCHOR_NE:
- *yPtr = Tk_InternalBorderTop(tkwin) + padY;
- break;
+ case TK_ANCHOR_NW:
+ case TK_ANCHOR_W:
+ case TK_ANCHOR_SW:
+ *xPtr = Tk_InternalBorderLeft(tkwin) + padX;
+ break;
+
+ case TK_ANCHOR_N:
+ case TK_ANCHOR_CENTER:
+ case TK_ANCHOR_S:
+ *xPtr = (Tk_Width(tkwin) - innerWidth - Tk_InternalBorderLeft(tkwin) -
+ Tk_InternalBorderRight(tkwin)) / 2 +
+ Tk_InternalBorderLeft(tkwin);
+ break;
+
+ default:
+ *xPtr = Tk_Width(tkwin) - Tk_InternalBorderRight(tkwin) - padX
+ - innerWidth;
+ break;
+ }
- case TK_ANCHOR_W:
- case TK_ANCHOR_CENTER:
- case TK_ANCHOR_E:
- *yPtr = (Tk_Height(tkwin) - innerHeight) / 2;
- break;
+ /*
+ * Handle the vertical parts.
+ */
- default:
- *yPtr = Tk_Height(tkwin) - Tk_InternalBorderBottom(tkwin) - padY
- - innerHeight;
- break;
+ switch (anchor) {
+ case TK_ANCHOR_NW:
+ case TK_ANCHOR_N:
+ case TK_ANCHOR_NE:
+ *yPtr = Tk_InternalBorderTop(tkwin) + padY;
+ break;
+
+ case TK_ANCHOR_W:
+ case TK_ANCHOR_CENTER:
+ case TK_ANCHOR_E:
+ *yPtr = (Tk_Height(tkwin) - innerHeight- Tk_InternalBorderTop(tkwin) -
+ Tk_InternalBorderBottom(tkwin)) / 2 +
+ Tk_InternalBorderTop(tkwin);
+ break;
+
+ default:
+ *yPtr = Tk_Height(tkwin) - Tk_InternalBorderBottom(tkwin) - padY
+ - innerHeight;
+ break;
}
}
@@ -835,10 +838,9 @@ TkComputeAnchor(anchor, tkwin, padX, padY, innerWidth, innerHeight, xPtr, yPtr)
* Given a lookup table, map a number to a string in the table.
*
* Results:
- * If numKey was equal to the numeric key of one of the elements
- * in the table, returns the string key of that element.
- * Returns NULL if numKey was not equal to any of the numeric keys
- * in the table.
+ * If numKey was equal to the numeric key of one of the elements in the
+ * table, returns the string key of that element. Returns NULL if numKey
+ * was not equal to any of the numeric keys in the table.
*
* Side effects.
* None.
@@ -847,13 +849,13 @@ TkComputeAnchor(anchor, tkwin, padX, padY, innerWidth, innerHeight, xPtr, yPtr)
*/
char *
-TkFindStateString(mapPtr, numKey)
- CONST TkStateMap *mapPtr; /* The state table. */
- int numKey; /* The key to try to find in the table. */
+TkFindStateString(
+ const TkStateMap *mapPtr, /* The state table. */
+ int numKey) /* The key to try to find in the table. */
{
- for ( ; mapPtr->strKey != NULL; mapPtr++) {
+ for (; mapPtr->strKey!=NULL ; mapPtr++) {
if (numKey == mapPtr->numKey) {
- return mapPtr->strKey;
+ return (char *) mapPtr->strKey;
}
}
return NULL;
@@ -862,17 +864,17 @@ TkFindStateString(mapPtr, numKey)
/*
*---------------------------------------------------------------------------
*
- * TkFindStateNum --
+ * TkFindStateNum, TkFindStateNumObj --
*
* Given a lookup table, map a string to a number in the table.
*
* Results:
- * If strKey was equal to the string keys of one of the elements
- * in the table, returns the numeric key of that element.
- * 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 the interp's result (if interp is not NULL).
+ * If strKey was equal to the string keys of one of the elements in the
+ * table, returns the numeric key of that element. 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 the interp's result (if interp
+ * is not NULL).
*
* Side effects.
* None.
@@ -881,48 +883,66 @@ TkFindStateString(mapPtr, numKey)
*/
int
-TkFindStateNum(interp, option, mapPtr, strKey)
- Tcl_Interp *interp; /* Interp for error reporting. */
- 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. */
+TkFindStateNum(
+ Tcl_Interp *interp, /* Interp for error reporting. */
+ 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;
+ const TkStateMap *mPtr;
+
+ /*
+ * See if the value is in the state map.
+ */
for (mPtr = mapPtr; mPtr->strKey != NULL; mPtr++) {
if (strcmp(strKey, mPtr->strKey) == 0) {
return mPtr->numKey;
}
}
+
+ /*
+ * Not there. Generate an error message (if we can) and return the
+ * default.
+ */
+
if (interp != NULL) {
mPtr = mapPtr;
Tcl_AppendResult(interp, "bad ", option, " value \"", strKey,
- "\": must be ", mPtr->strKey, (char *) NULL);
+ "\": must be ", mPtr->strKey, NULL);
for (mPtr++; mPtr->strKey != NULL; mPtr++) {
- Tcl_AppendResult(interp,
- ((mPtr[1].strKey != NULL) ? ", " : ", or "),
- mPtr->strKey, (char *) NULL);
+ Tcl_AppendResult(interp,
+ ((mPtr[1].strKey != NULL) ? ", " : ", or "),
+ mPtr->strKey, 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. */
+TkFindStateNumObj(
+ 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;
+ const TkStateMap *mPtr;
+ const char *key;
+ const Tcl_ObjType *typePtr;
+
+ /*
+ * See if the value is in the object cache.
+ */
if ((keyPtr->typePtr == &tkStateKeyObjType)
- && (keyPtr->internalRep.twoPtrValue.ptr1 == (VOID *) mapPtr)) {
- return (int) keyPtr->internalRep.twoPtrValue.ptr2;
+ && (keyPtr->internalRep.twoPtrValue.ptr1 == mapPtr)) {
+ return PTR2INT(keyPtr->internalRep.twoPtrValue.ptr2);
}
+ /*
+ * Not there. Look in the state map.
+ */
+
key = Tcl_GetStringFromObj(keyPtr, NULL);
for (mPtr = mapPtr; mPtr->strKey != NULL; mPtr++) {
if (strcmp(key, mPtr->strKey) == 0) {
@@ -930,168 +950,118 @@ TkFindStateNumObj(interp, optionPtr, mapPtr, keyPtr)
if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
(*typePtr->freeIntRepProc)(keyPtr);
}
- keyPtr->internalRep.twoPtrValue.ptr1 = (VOID *) mapPtr;
- keyPtr->internalRep.twoPtrValue.ptr2 = (VOID *) mPtr->numKey;
- keyPtr->typePtr = &tkStateKeyObjType;
+ keyPtr->internalRep.twoPtrValue.ptr1 = (void *) mapPtr;
+ keyPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(mPtr->numKey);
+ keyPtr->typePtr = &tkStateKeyObjType;
return mPtr->numKey;
}
}
+
+ /*
+ * Not there either. Generate an error message (if we can) and return the
+ * default.
+ */
+
if (interp != NULL) {
mPtr = mapPtr;
- Tcl_AppendResult(interp, "bad ",
- Tcl_GetStringFromObj(optionPtr, NULL), " value \"", key,
- "\": must be ", mPtr->strKey, (char *) NULL);
+ Tcl_AppendResult(interp, "bad ", Tcl_GetString(optionPtr),
+ " value \"", key, "\": must be ", mPtr->strKey, NULL);
for (mPtr++; mPtr->strKey != NULL; mPtr++) {
- Tcl_AppendResult(interp,
- ((mPtr[1].strKey != NULL) ? ", " : ", or "),
- mPtr->strKey, (char *) NULL);
+ Tcl_AppendResult(interp,
+ ((mPtr[1].strKey != NULL) ? ", " : ", or "),
+ mPtr->strKey, NULL);
}
}
return mPtr->numKey;
}
-
-/*
- * For each exit handler created with a call to TkCreateExitHandler
- * there is a structure of the following type:
- */
-
-typedef struct ExitHandler {
- Tcl_ExitProc *proc; /* Procedure to call when process exits. */
- ClientData clientData; /* One word of information to pass to proc. */
- struct ExitHandler *nextPtr;/* Next in list of all exit handlers for
- * this application, or NULL for end of list. */
-} ExitHandler;
-
-/*
- * There is both per-process and per-thread exit handlers.
- * The first list is controlled by a mutex. The other is in
- * thread local storage.
- */
-
-static ExitHandler *firstExitPtr = NULL;
- /* First in list of all exit handlers for
- * application. */
-TCL_DECLARE_MUTEX(exitMutex)
-
+
/*
- *---------------------------------------------------------------------------
+ * ----------------------------------------------------------------------
*
- * TkCreateExitHandler --
+ * TkBackgroundEvalObjv --
*
- * Same as Tcl_CreateExitHandler, but private to Tk.
+ * Evaluate a command while ensuring that we do not affect the
+ * interpreters state. This is important when evaluating script
+ * during background tasks.
*
* Results:
- * None.
+ * A standard Tcl result code.
*
- * Side effects.
- * Sets a handler with Tcl_CreateExitHandler if this is the first call.
+ * Side Effects:
+ * The interpreters variables and code may be modified by the script
+ * but the result will not be modified.
*
- *---------------------------------------------------------------------------
+ * ----------------------------------------------------------------------
*/
-void
-TkCreateExitHandler (proc, clientData)
- Tcl_ExitProc *proc; /* Procedure to invoke. */
- ClientData clientData; /* Arbitrary value to pass to proc. */
+int
+TkBackgroundEvalObjv(
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const *objv,
+ int flags)
{
- ExitHandler *exitPtr;
-
- exitPtr = (ExitHandler *) ckalloc(sizeof(ExitHandler));
- exitPtr->proc = proc;
- exitPtr->clientData = clientData;
- Tcl_MutexLock(&exitMutex);
- if (firstExitPtr == NULL) {
- Tcl_CreateExitHandler(TkFinalize, NULL);
- }
- exitPtr->nextPtr = firstExitPtr;
- firstExitPtr = exitPtr;
- Tcl_MutexUnlock(&exitMutex);
-}
+ Tcl_DString errorInfo, errorCode;
+ Tcl_SavedResult state;
+ int n, r = TCL_OK;
-/*
- *---------------------------------------------------------------------------
- *
- * TkDeleteExitHandler --
- *
- * Same as Tcl_DeleteExitHandler, but private to Tk.
- *
- * Results:
- * None.
- *
- * Side effects.
- * None.
- *
- *---------------------------------------------------------------------------
- */
+ Tcl_DStringInit(&errorInfo);
+ Tcl_DStringInit(&errorCode);
-void
-TkDeleteExitHandler (proc, clientData)
- Tcl_ExitProc *proc; /* Procedure that was previously registered. */
- ClientData clientData; /* Arbitrary value to pass to proc. */
-{
- ExitHandler *exitPtr, *prevPtr;
-
- Tcl_MutexLock(&exitMutex);
- for (prevPtr = NULL, exitPtr = firstExitPtr; exitPtr != NULL;
- prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
- if ((exitPtr->proc == proc)
- && (exitPtr->clientData == clientData)) {
- if (prevPtr == NULL) {
- firstExitPtr = exitPtr->nextPtr;
- } else {
- prevPtr->nextPtr = exitPtr->nextPtr;
- }
- ckfree((char *) exitPtr);
- break;
- }
+ Tcl_Preserve(interp);
+
+ /*
+ * Record the state of the interpreter
+ */
+
+ Tcl_SaveResult(interp, &state);
+ Tcl_DStringAppend(&errorInfo,
+ Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY), -1);
+ Tcl_DStringAppend(&errorCode,
+ Tcl_GetVar(interp, "errorCode", TCL_GLOBAL_ONLY), -1);
+
+ /*
+ * Evaluate the command and handle any error.
+ */
+
+ for (n = 0; n < objc; ++n) {
+ Tcl_IncrRefCount(objv[n]);
+ }
+ r = Tcl_EvalObjv(interp, objc, objv, flags);
+ for (n = 0; n < objc; ++n) {
+ Tcl_DecrRefCount(objv[n]);
+ }
+ if (r == TCL_ERROR) {
+ Tcl_AddErrorInfo(interp, "\n (background event handler)");
+ Tcl_BackgroundError(interp);
}
- Tcl_MutexUnlock(&exitMutex);
- return;
-}
-/*
- *---------------------------------------------------------------------------
- *
- * TkFinalize --
- *
- * Runs our private exit handlers and removes itself from Tcl. This is
- * benificial should we want to protect from dangling pointers should
- * the Tk shared library be unloaded prior to Tcl which can happen on
- * windows should the process be forcefully exiting from an exception
- * handler.
- *
- * Results:
- * None.
- *
- * Side effects.
- * None.
- *
- *---------------------------------------------------------------------------
- */
+ Tcl_Release(interp);
-void
-TkFinalize (clientData)
- ClientData clientData; /* Arbitrary value to pass to proc. */
-{
- ExitHandler *exitPtr;
-
- Tcl_DeleteExitHandler(TkFinalize, NULL);
-
- Tcl_MutexLock(&exitMutex);
- for (exitPtr = firstExitPtr; exitPtr != NULL; exitPtr = firstExitPtr) {
- /*
- * Be careful to remove the handler from the list before
- * invoking its callback. This protects us against
- * double-freeing if the callback should call
- * Tcl_DeleteExitHandler on itself.
- */
-
- firstExitPtr = exitPtr->nextPtr;
- Tcl_MutexUnlock(&exitMutex);
- (*exitPtr->proc)(exitPtr->clientData);
- ckfree((char *) exitPtr);
- Tcl_MutexLock(&exitMutex);
- }
- firstExitPtr = NULL;
- Tcl_MutexUnlock(&exitMutex);
+ /*
+ * Restore the state of the interpreter
+ */
+
+ Tcl_SetVar(interp, "errorInfo",
+ Tcl_DStringValue(&errorInfo), TCL_GLOBAL_ONLY);
+ Tcl_SetVar(interp, "errorCode",
+ Tcl_DStringValue(&errorCode), TCL_GLOBAL_ONLY);
+ Tcl_RestoreResult(interp, &state);
+
+ /*
+ * Clean up references.
+ */
+
+ Tcl_DStringFree(&errorInfo);
+ Tcl_DStringFree(&errorCode);
+
+ return r;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkVisual.c b/generic/tkVisual.c
index 41d2060..ec8be11 100644
--- a/generic/tkVisual.c
+++ b/generic/tkVisual.c
@@ -1,29 +1,28 @@
-/*
+/*
* tkVisual.c --
*
- * This file contains library procedures for allocating and
- * freeing visuals and colormaps. This code is based on a
- * prototype implementation by Paul Mackerras.
+ * This file contains library procedures for allocating and freeing
+ * visuals and colormaps. This code is based on a prototype
+ * implementation by Paul Mackerras.
*
* Copyright (c) 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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tkInt.h"
-#include "tkPort.h"
/*
- * The table below maps from symbolic names for visual classes
- * to the associated X class symbols.
+ * The table below maps from symbolic names for visual classes to the
+ * associated X class symbols.
*/
typedef struct VisualDictionary {
char *name; /* Textual name of class. */
- int minLength; /* Minimum # characters that must be
- * specified for an unambiguous match. */
+ int minLength; /* Minimum # characters that must be specified
+ * for an unambiguous match. */
int class; /* X symbol for class. */
} VisualDictionary;
static VisualDictionary visualNames[] = {
@@ -46,17 +45,16 @@ static VisualDictionary visualNames[] = {
struct TkColormap {
Colormap colormap; /* X's identifier for the colormap. */
- Visual *visual; /* Visual for which colormap was
- * allocated. */
+ Visual *visual; /* Visual for which colormap was allocated. */
int refCount; /* How many uses of the colormap are still
- * outstanding (calls to Tk_GetColormap
- * minus calls to Tk_FreeColormap). */
- int shareable; /* 0 means this colormap was allocated by
- * a call to Tk_GetColormap with "new",
- * implying that the window wants it all
- * for itself. 1 means that the colormap
- * was allocated as a default for a particular
- * visual, so it can be shared. */
+ * outstanding (calls to Tk_GetColormap minus
+ * calls to Tk_FreeColormap). */
+ int shareable; /* 0 means this colormap was allocated by a
+ * call to Tk_GetColormap with "new", implying
+ * that the window wants it all for itself. 1
+ * means that the colormap was allocated as a
+ * default for a particular visual, so it can
+ * be shared. */
struct TkColormap *nextPtr; /* Next in list of colormaps for this display,
* or NULL for end of list. */
};
@@ -66,17 +64,17 @@ struct TkColormap {
*
* Tk_GetVisual --
*
- * Given a string identifying a particular kind of visual, this
- * procedure returns a visual and depth that matches the specification.
+ * Given a string identifying a particular kind of visual, this procedure
+ * returns a visual and depth that matches the specification.
*
* 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 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
- * returns that colormap in *colormapPtr unless an error occurs.
+ * 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 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 returns that colormap in *colormapPtr
+ * unless an error occurs.
*
* Side effects:
* A new colormap may be allocated.
@@ -85,42 +83,40 @@ struct TkColormap {
*/
Visual *
-Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr)
- Tcl_Interp *interp; /* Interpreter to use for error
- * reporting. */
- Tk_Window tkwin; /* Window in which visual will be
- * used. */
- CONST char *string; /* String describing visual. See
- * manual entry for details. */
- int *depthPtr; /* The depth of the returned visual
- * is stored here. */
- Colormap *colormapPtr; /* If non-NULL, then a suitable
- * colormap for visual is placed here.
- * This colormap must eventually be
- * freed by calling Tk_FreeColormap. */
+Tk_GetVisual(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ Tk_Window tkwin, /* Window in which visual will be used. */
+ CONST char *string, /* String describing visual. See manual entry
+ * for details. */
+ int *depthPtr, /* The depth of the returned visual is stored
+ * here. */
+ Colormap *colormapPtr) /* If non-NULL, then a suitable colormap for
+ * visual is placed here. This colormap must
+ * eventually be freed by calling
+ * Tk_FreeColormap. */
{
Tk_Window tkwin2;
XVisualInfo template, *visInfoList, *bestPtr;
long mask;
Visual *visual;
- int length, c, numVisuals, prio, bestPrio, i;
+ ptrdiff_t length;
+ int c, numVisuals, prio, bestPrio, i;
CONST char *p;
VisualDictionary *dictPtr;
TkColormap *cmapPtr;
TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
/*
- * Parse string and set up a template for use in searching for
- * an appropriate visual.
+ * Parse string and set up a template for use in searching for an
+ * appropriate visual.
*/
c = string[0];
if (c == '.') {
/*
- * The string must be a window name. If the window is on the
- * same screen as tkwin, then just use its visual. Otherwise
- * use the information about the visual as a template for the
- * search.
+ * The string must be a window name. If the window is on the same
+ * screen as tkwin, then just use its visual. Otherwise use the
+ * information about the visual as a template for the search.
*/
tkwin2 = Tk_NameToWindow(interp, string, tkwin);
@@ -132,8 +128,8 @@ Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr)
*depthPtr = Tk_Depth(tkwin2);
if (colormapPtr != NULL) {
/*
- * Use the colormap from the other window too (but be sure
- * to increment its reference count if it's one of the ones
+ * Use the colormap from the other window too (but be sure to
+ * increment its reference count if it's one of the ones
* allocated here).
*/
@@ -173,21 +169,21 @@ Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr)
int visualId;
/*
- * This is a visual ID.
- */
+ * This is a visual ID.
+ */
if (Tcl_GetInt(interp, string, &visualId) == TCL_ERROR) {
Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad X identifier for visual: ",
- string, "\"", (char *) NULL);
+ Tcl_AppendResult(interp, "bad X identifier for visual: \"",
+ string, "\"", NULL);
return NULL;
}
template.visualid = visualId;
mask = VisualIDMask;
} else {
/*
- * Parse the string into a class name (or "best") optionally
- * followed by whitespace and a depth.
+ * Parse the string into a class name (or "best") optionally followed
+ * by whitespace and a depth.
*/
for (p = string; *p != 0; p++) {
@@ -207,11 +203,11 @@ Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr)
}
if (template.class == -1) {
Tcl_AppendResult(interp, "unknown or ambiguous visual name \"",
- string, "\": class must be ", (char *) NULL);
+ string, "\": class must be ", NULL);
for (dictPtr = visualNames; dictPtr->name != NULL; dictPtr++) {
- Tcl_AppendResult(interp, dictPtr->name, ", ", (char *) NULL);
+ Tcl_AppendResult(interp, dictPtr->name, ", ", NULL);
}
- Tcl_AppendResult(interp, "or default", (char *) NULL);
+ Tcl_AppendResult(interp, "or default", NULL);
return NULL;
}
while (isspace(UCHAR(*p))) {
@@ -232,8 +228,8 @@ Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr)
}
/*
- * Find all visuals that match the template we've just created,
- * and return an error if there are none that match.
+ * Find all visuals that match the template we've just created, and return
+ * an error if there are none that match.
*/
template.screen = Tk_ScreenNumber(tkwin);
@@ -247,31 +243,37 @@ Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr)
}
/*
- * Search through the visuals that were returned to find the best
- * one. The choice is based on the following criteria, in decreasing
- * order of importance:
+ * Search through the visuals that were returned to find the best one.
+ * The choice is based on the following criteria, in decreasing order of
+ * importance:
*
- * 1. Depth: choose a visual with exactly the desired depth,
- * else one with more bits than requested but as few bits
- * as possible, else one with fewer bits but as many as
- * possible.
- * 2. Class: some visual classes are more desirable than others;
- * pick the visual with the most desirable class.
- * 3. Default: the default visual for the screen gets preference
- * over other visuals, all else being equal.
+ * 1. Depth: choose a visual with exactly the desired depth, else one with
+ * more bits than requested but as few bits as possible, else one with
+ * fewer bits but as many as possible.
+ * 2. Class: some visual classes are more desirable than others; pick the
+ * visual with the most desirable class.
+ * 3. Default: the default visual for the screen gets preference over
+ * other visuals, all else being equal.
*/
bestPrio = 0;
bestPtr = NULL;
for (i = 0; i < numVisuals; i++) {
switch (visInfoList[i].class) {
- case DirectColor: prio = 5; break;
- case GrayScale: prio = 1; break;
- case PseudoColor: prio = 7; break;
- case StaticColor: prio = 3; break;
- case StaticGray: prio = 1; break;
- case TrueColor: prio = 5; break;
- default: prio = 0; break;
+ case DirectColor:
+ prio = 5; break;
+ case GrayScale:
+ prio = 1; break;
+ case PseudoColor:
+ prio = 7; break;
+ case StaticColor:
+ prio = 3; break;
+ case StaticGray:
+ prio = 1; break;
+ case TrueColor:
+ prio = 5; break;
+ default:
+ prio = 0; break;
}
if (visInfoList[i].visual
== DefaultVisualOfScreen(Tk_Screen(tkwin))) {
@@ -295,7 +297,7 @@ Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr)
}
continue;
- newBest:
+ newBest:
bestPtr = &visInfoList[i];
bestPrio = prio;
}
@@ -304,11 +306,10 @@ Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr)
XFree((char *) visInfoList);
/*
- * If we need to find a colormap for this visual, do it now.
- * If the visual is the default visual for the screen, then
- * use the default colormap. Otherwise search for an existing
- * colormap that's shareable. If all else fails, create a new
- * colormap.
+ * If we need to find a colormap for this visual, do it now. If the visual
+ * is the default visual for the screen, then use the default colormap.
+ * Otherwise search for an existing colormap that's shareable. If all else
+ * fails, create a new colormap.
*/
if (colormapPtr != NULL) {
@@ -336,7 +337,7 @@ Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr)
}
}
- done:
+ done:
return visual;
}
@@ -345,31 +346,28 @@ Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr)
*
* Tk_GetColormap --
*
- * Given a string identifying a colormap, this procedure finds
- * an appropriate colormap.
+ * Given a string identifying a colormap, this procedure finds an
+ * appropriate colormap.
*
* 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 the interp's result.
+ * colormap. If an error occurs, None is returned and an error message is
+ * placed in the interp's result.
*
* Side effects:
- * A reference count is incremented for the colormap, so
- * Tk_FreeColormap must eventually be called exactly once for
- * each call to Tk_GetColormap.
+ * A reference count is incremented for the colormap, so Tk_FreeColormap
+ * must eventually be called exactly once for each call to
+ * Tk_GetColormap.
*
*----------------------------------------------------------------------
*/
Colormap
-Tk_GetColormap(interp, tkwin, string)
- Tcl_Interp *interp; /* Interpreter to use for error
- * reporting. */
- Tk_Window tkwin; /* Window where colormap will be
- * used. */
- CONST char *string; /* String that identifies colormap:
- * either "new" or the name of
- * another window. */
+Tk_GetColormap(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ Tk_Window tkwin, /* Window where colormap will be used. */
+ CONST char *string) /* String that identifies colormap: either
+ * "new" or the name of another window. */
{
Colormap colormap;
TkColormap *cmapPtr;
@@ -394,9 +392,9 @@ Tk_GetColormap(interp, tkwin, string)
}
/*
- * Use a colormap from an existing window. It must have the same
- * visual as tkwin (which means, among other things, that the
- * other window must be on the same screen).
+ * Use a colormap from an existing window. It must have the same visual as
+ * tkwin (which means, among other things, that the other window must be
+ * on the same screen).
*/
other = Tk_NameToWindow(interp, string, tkwin);
@@ -405,12 +403,12 @@ Tk_GetColormap(interp, tkwin, string)
}
if (Tk_Screen(other) != Tk_Screen(tkwin)) {
Tcl_AppendResult(interp, "can't use colormap for ", string,
- ": not on same screen", (char *) NULL);
+ ": not on same screen", NULL);
return None;
}
if (Tk_Visual(other) != Tk_Visual(tkwin)) {
Tcl_AppendResult(interp, "can't use colormap for ", string,
- ": incompatible visuals", (char *) NULL);
+ ": incompatible visuals", NULL);
return None;
}
colormap = Tk_Colormap(other);
@@ -434,41 +432,40 @@ Tk_GetColormap(interp, tkwin, string)
*
* Tk_FreeColormap --
*
- * This procedure is called to release a colormap that was
- * previously allocated by Tk_GetColormap.
+ * This procedure is called to release a colormap that was previously
+ * allocated by Tk_GetColormap.
*
* Results:
* None.
*
* Side effects:
- * The colormap's reference count is decremented. If this was the
- * last reference to the colormap, then the colormap is freed.
+ * The colormap's reference count is decremented. If this was the last
+ * reference to the colormap, then the colormap is freed.
*
*----------------------------------------------------------------------
*/
void
-Tk_FreeColormap(display, colormap)
- Display *display; /* Display for which colormap was
- * allocated. */
- Colormap colormap; /* Colormap that is no longer needed.
- * Must have been returned by previous
- * call to Tk_GetColormap, or
- * preserved by a previous call to
- * Tk_PreserveColormap. */
+Tk_FreeColormap(
+ Display *display, /* Display for which colormap was
+ * allocated. */
+ Colormap colormap) /* Colormap that is no longer needed. Must
+ * have been returned by previous call to
+ * Tk_GetColormap, or preserved by a previous
+ * call to Tk_PreserveColormap. */
{
TkDisplay *dispPtr;
TkColormap *cmapPtr, *prevPtr;
/*
- * Find Tk's information about the display, then see if this
- * colormap is a non-default one (if it's a default one, there
- * won't be an entry for it in the display's list).
+ * Find Tk's information about the display, then see if this colormap is a
+ * non-default one (if it's a default one, there won't be an entry for it
+ * in the display's list).
*/
dispPtr = TkGetDisplay(display);
if (dispPtr == NULL) {
- panic("unknown display passed to Tk_FreeColormap");
+ Tcl_Panic("unknown display passed to Tk_FreeColormap");
}
for (prevPtr = NULL, cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
prevPtr = cmapPtr, cmapPtr = cmapPtr->nextPtr) {
@@ -485,7 +482,7 @@ Tk_FreeColormap(display, colormap)
}
return;
}
- }
+ }
}
/*
@@ -493,41 +490,40 @@ Tk_FreeColormap(display, colormap)
*
* Tk_PreserveColormap --
*
- * This procedure is called to indicate to Tk that the specified
- * colormap is being referenced from another location and should
- * not be freed until all extra references are eliminated. The
- * colormap must have been returned by Tk_GetColormap.
+ * This procedure is called to indicate to Tk that the specified colormap
+ * is being referenced from another location and should not be freed
+ * until all extra references are eliminated. The colormap must have been
+ * returned by Tk_GetColormap.
*
* Results:
* None.
*
* Side effects:
- * The colormap's reference count is incremented, so
- * Tk_FreeColormap must eventually be called exactly once for
- * each call to Tk_PreserveColormap.
+ * The colormap's reference count is incremented, so Tk_FreeColormap must
+ * eventually be called exactly once for each call to
+ * Tk_PreserveColormap.
*
*----------------------------------------------------------------------
*/
void
-Tk_PreserveColormap(display, colormap)
- Display *display; /* Display for which colormap was
- * allocated. */
- Colormap colormap; /* Colormap that should be
- * preserved. */
+Tk_PreserveColormap(
+ Display *display, /* Display for which colormap was
+ * allocated. */
+ Colormap colormap) /* Colormap that should be preserved. */
{
TkDisplay *dispPtr;
TkColormap *cmapPtr;
/*
- * Find Tk's information about the display, then see if this
- * colormap is a non-default one (if it's a default one, there
- * won't be an entry for it in the display's list).
+ * Find Tk's information about the display, then see if this colormap is a
+ * non-default one (if it's a default one, there won't be an entry for it
+ * in the display's list).
*/
dispPtr = TkGetDisplay(display);
if (dispPtr == NULL) {
- panic("unknown display passed to Tk_PreserveColormap");
+ Tcl_Panic("unknown display passed to Tk_PreserveColormap");
}
for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
cmapPtr = cmapPtr->nextPtr) {
@@ -535,5 +531,13 @@ Tk_PreserveColormap(display, colormap)
cmapPtr->refCount += 1;
return;
}
- }
+ }
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tkWindow.c b/generic/tkWindow.c
index 40b2fed..ac69455 100644
--- a/generic/tkWindow.c
+++ b/generic/tkWindow.c
@@ -1,32 +1,28 @@
/*
* tkWindow.c --
*
- * This file provides basic window-manipulation procedures,
- * which are equivalent to procedures in Xlib (and even
- * invoke them) but also maintain the local Tk_Window
- * structure.
+ * This file provides basic window-manipulation functions, which are
+ * equivalent to functions in Xlib (and even invoke them) but also
+ * maintain the local Tk_Window structure.
*
* Copyright (c) 1989-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.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tkPort.h"
#include "tkInt.h"
#ifdef __WIN32__
#include "tkWinInt.h"
-#elif !(defined(MAC_OSX_TK))
+#elif !defined(MAC_OSX_TK)
#include "tkUnixInt.h"
#endif
-#include "tclInt.h" /* for Tcl_CreateNamespace() */
-
/*
- * Type used to keep track of Window objects that were
- * only partically deallocated by Tk_DestroyWindow.
+ * Type used to keep track of Window objects that were only partially
+ * deallocated by Tk_DestroyWindow.
*/
#define HD_CLEANUP 1
@@ -41,21 +37,19 @@ typedef struct TkHalfdeadWindow {
struct TkHalfdeadWindow *nextPtr;
} TkHalfdeadWindow;
-
typedef struct ThreadSpecificData {
- int numMainWindows; /* Count of numver of main windows currently
- * open in this thread. */
+ 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. */
+ /* First in list of all main windows managed
+ * by this thread. */
TkHalfdeadWindow *halfdeadWindowList;
- /* First in list of partially deallocated
- * windows. */
- TkDisplay *displayList;
- /* List of all displays currently in use by
- * the current thread. */
- int initialized; /* 0 means the structures above need
- * initializing. */
+ /* First in list of partially deallocated
+ * windows. */
+ 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;
@@ -66,19 +60,19 @@ static Tcl_ThreadDataKey dataKey;
TCL_DECLARE_MUTEX(windowMutex)
/*
- * Default values for "changes" and "atts" fields of TkWindows. Note
- * that Tk always requests all events for all windows, except StructureNotify
- * events on internal windows: these events are generated internally.
+ * Default values for "changes" and "atts" fields of TkWindows. Note that Tk
+ * always requests all events for all windows, except StructureNotify events
+ * on internal windows: these events are generated internally.
*/
-static CONST XWindowChanges defChanges = {
+static const XWindowChanges defChanges = {
0, 0, 1, 1, 0, 0, Above
};
#define ALL_EVENTS_MASK \
KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask| \
EnterWindowMask|LeaveWindowMask|PointerMotionMask|ExposureMask| \
VisibilityChangeMask|PropertyChangeMask|ColormapChangeMask
-static CONST XSetWindowAttributes defAtts= {
+static const XSetWindowAttributes defAtts= {
None, /* background_pixmap */
0, /* background_pixel */
CopyFromParent, /* border_pixmap */
@@ -97,8 +91,8 @@ static CONST XSetWindowAttributes defAtts= {
};
/*
- * The following structure defines all of the commands supported by
- * Tk, and the C procedures that execute them.
+ * The following structure defines all of the commands supported by Tk, and
+ * the C functions that execute them.
*/
#define ISSAFE 1
@@ -107,12 +101,12 @@ static CONST XSetWindowAttributes defAtts= {
#define WINMACONLY 8
typedef struct {
- CONST char *name; /* Name of command. */
- Tcl_ObjCmdProc *objProc; /* Command's object- (or string-) based procedure. */
+ const char *name; /* Name of command. */
+ Tcl_ObjCmdProc *objProc; /* Command's object- (or string-) based function. */
int flags;
} TkCmd;
-static CONST TkCmd commands[] = {
+static const TkCmd commands[] = {
/*
* Commands that are part of the intrinsics:
*/
@@ -136,21 +130,12 @@ static CONST TkCmd commands[] = {
{"selection", Tk_SelectionObjCmd, PASSMAINWINDOW},
{"tk", Tk_TkObjCmd, PASSMAINWINDOW|ISSAFE},
{"tkwait", Tk_TkwaitObjCmd, PASSMAINWINDOW|ISSAFE},
-#if defined(__WIN32__) || defined(MAC_OSX_TK)
- {"tk_chooseColor", Tk_ChooseColorObjCmd, PASSMAINWINDOW},
- {"tk_chooseDirectory", Tk_ChooseDirectoryObjCmd, WINMACONLY|PASSMAINWINDOW},
- {"tk_getOpenFile", Tk_GetOpenFileObjCmd, WINMACONLY|PASSMAINWINDOW},
- {"tk_getSaveFile", Tk_GetSaveFileObjCmd, WINMACONLY|PASSMAINWINDOW},
-#endif
-#if defined(__WIN32__) || defined(MAC_OSX_TK)
- {"tk_messageBox", Tk_MessageBoxObjCmd, PASSMAINWINDOW},
-#endif
{"update", Tk_UpdateObjCmd, PASSMAINWINDOW|ISSAFE},
{"winfo", Tk_WinfoObjCmd, PASSMAINWINDOW|ISSAFE},
{"wm", Tk_WmObjCmd, PASSMAINWINDOW},
/*
- * Widget class commands.
+ * Default widget class commands.
*/
{"button", Tk_ButtonObjCmd, ISSAFE},
@@ -168,23 +153,58 @@ static CONST TkCmd commands[] = {
{"scale", Tk_ScaleObjCmd, ISSAFE},
{"scrollbar", (Tcl_ObjCmdProc *) Tk_ScrollbarCmd, NOOBJPROC|PASSMAINWINDOW|ISSAFE},
{"spinbox", Tk_SpinboxObjCmd, ISSAFE},
- {"text", (Tcl_ObjCmdProc *) Tk_TextCmd, NOOBJPROC|PASSMAINWINDOW|ISSAFE},
+ {"text", Tk_TextObjCmd, PASSMAINWINDOW|ISSAFE},
{"toplevel", Tk_ToplevelObjCmd, 0},
/*
+ * Classic widget class commands.
+ */
+
+ {"::tk::button", Tk_ButtonObjCmd, ISSAFE},
+ {"::tk::canvas", Tk_CanvasObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"::tk::checkbutton",Tk_CheckbuttonObjCmd, ISSAFE},
+ {"::tk::entry", Tk_EntryObjCmd, ISSAFE},
+ {"::tk::frame", Tk_FrameObjCmd, ISSAFE},
+ {"::tk::label", Tk_LabelObjCmd, ISSAFE},
+ {"::tk::labelframe",Tk_LabelframeObjCmd, ISSAFE},
+ {"::tk::listbox", Tk_ListboxObjCmd, ISSAFE},
+ {"::tk::menubutton",Tk_MenubuttonObjCmd, ISSAFE},
+ {"::tk::message", Tk_MessageObjCmd, ISSAFE},
+ {"::tk::panedwindow",Tk_PanedWindowObjCmd, ISSAFE},
+ {"::tk::radiobutton",Tk_RadiobuttonObjCmd, ISSAFE},
+ {"::tk::scale", Tk_ScaleObjCmd, ISSAFE},
+ {"::tk::scrollbar", (Tcl_ObjCmdProc *) Tk_ScrollbarCmd, NOOBJPROC|PASSMAINWINDOW|ISSAFE},
+ {"::tk::spinbox", Tk_SpinboxObjCmd, ISSAFE},
+ {"::tk::text", Tk_TextObjCmd, PASSMAINWINDOW|ISSAFE},
+ {"::tk::toplevel", Tk_ToplevelObjCmd, 0},
+
+ /*
+ * Standard dialog support. Note that the Unix/X11 platform implements
+ * these commands differently (via the script library).
+ */
+
+#if defined(__WIN32__) || defined(MAC_OSX_TK)
+ {"tk_chooseColor", Tk_ChooseColorObjCmd, PASSMAINWINDOW},
+ {"tk_chooseDirectory", Tk_ChooseDirectoryObjCmd,WINMACONLY|PASSMAINWINDOW},
+ {"tk_getOpenFile", Tk_GetOpenFileObjCmd, WINMACONLY|PASSMAINWINDOW},
+ {"tk_getSaveFile", Tk_GetSaveFileObjCmd, WINMACONLY|PASSMAINWINDOW},
+ {"tk_messageBox", Tk_MessageBoxObjCmd, PASSMAINWINDOW},
+#endif
+
+ /*
* Misc.
*/
#if defined(MAC_OSX_TK)
{"::tk::unsupported::MacWindowStyle",
- TkUnsupported1ObjCmd, PASSMAINWINDOW|ISSAFE},
+ TkUnsupported1ObjCmd, PASSMAINWINDOW|ISSAFE},
#endif
- {NULL, NULL, 0}
+ {NULL, NULL, 0}
};
/*
- * The variables and table below are used to parse arguments from
- * the "argv" variable in Tk_Init.
+ * The variables and table below are used to parse arguments from the "argv"
+ * variable in Tk_Init.
*/
static int synchronize = 0;
@@ -197,62 +217,62 @@ static char *visual = NULL;
static int rest = 0;
static Tk_ArgvInfo argTable[] = {
- {"-colormap", TK_ARGV_STRING, (char *) NULL, (char *) &colormap,
+ {"-colormap", TK_ARGV_STRING, NULL, (char *) &colormap,
"Colormap for main window"},
- {"-display", TK_ARGV_STRING, (char *) NULL, (char *) &display,
+ {"-display", TK_ARGV_STRING, NULL, (char *) &display,
"Display to use"},
- {"-geometry", TK_ARGV_STRING, (char *) NULL, (char *) &geometry,
+ {"-geometry", TK_ARGV_STRING, NULL, (char *) &geometry,
"Initial geometry for window"},
- {"-name", TK_ARGV_STRING, (char *) NULL, (char *) &name,
+ {"-name", TK_ARGV_STRING, NULL, (char *) &name,
"Name to use for application"},
{"-sync", TK_ARGV_CONSTANT, (char *) 1, (char *) &synchronize,
"Use synchronous mode for display server"},
- {"-visual", TK_ARGV_STRING, (char *) NULL, (char *) &visual,
+ {"-visual", TK_ARGV_STRING, NULL, (char *) &visual,
"Visual for main window"},
- {"-use", TK_ARGV_STRING, (char *) NULL, (char *) &use,
+ {"-use", TK_ARGV_STRING, NULL, (char *) &use,
"Id of window in which to embed application"},
{"--", TK_ARGV_REST, (char *) 1, (char *) &rest,
"Pass all remaining arguments through to script"},
- {(char *) NULL, TK_ARGV_END, (char *) NULL, (char *) NULL,
- (char *) NULL}
+ {NULL, TK_ARGV_END, NULL, NULL, NULL}
};
/*
- * Forward declarations to procedures defined later in this file:
+ * Forward declarations to functions defined later in this file:
*/
-static Tk_Window CreateTopLevelWindow _ANSI_ARGS_((Tcl_Interp *interp,
+static Tk_Window CreateTopLevelWindow(Tcl_Interp *interp,
Tk_Window parent, CONST char *name,
- CONST char *screenName, unsigned int flags));
-static void DeleteWindowsExitProc _ANSI_ARGS_((
- ClientData clientData));
-static TkDisplay * GetScreen _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *screenName, int *screenPtr));
-static int Initialize _ANSI_ARGS_((Tcl_Interp *interp));
-static int NameWindow _ANSI_ARGS_((Tcl_Interp *interp,
- TkWindow *winPtr, TkWindow *parentPtr,
- CONST char *name));
-static void UnlinkWindow _ANSI_ARGS_((TkWindow *winPtr));
+ CONST char *screenName, unsigned int flags);
+static void DeleteWindowsExitProc(ClientData clientData);
+static TkDisplay * GetScreen(Tcl_Interp *interp, CONST char *screenName,
+ int *screenPtr);
+static int Initialize(Tcl_Interp *interp);
+static int NameWindow(Tcl_Interp *interp, TkWindow *winPtr,
+ TkWindow *parentPtr, CONST char *name);
+static void UnlinkWindow(TkWindow *winPtr);
/*
*----------------------------------------------------------------------
*
* TkCloseDisplay --
- * Closing the display can lead to order of deletion problems.
- * We defer it until exit handling for Mac/Win, but since Unix can
- * use many displays, try and clean it up as best as possible.
+ *
+ * Closing the display can lead to order of deletion problems. We defer
+ * it until exit handling for Mac/Win, but since Unix can use many
+ * displays, try and clean it up as best as possible.
*
* Results:
* None.
*
* Side effects:
- * Resources associated with the display will be free.
- * The display may not be referenced at all after this.
+ * Resources associated with the display will be free. The display may
+ * not be referenced at all after this.
+ *
*----------------------------------------------------------------------
*/
static void
-TkCloseDisplay(TkDisplay *dispPtr)
+TkCloseDisplay(
+ TkDisplay *dispPtr)
{
TkClipCleanup(dispPtr);
@@ -269,8 +289,8 @@ TkCloseDisplay(TkDisplay *dispPtr)
if (dispPtr->errorPtr != NULL) {
TkErrorHandler *errorPtr;
for (errorPtr = dispPtr->errorPtr;
- errorPtr != NULL;
- errorPtr = dispPtr->errorPtr) {
+ errorPtr != NULL;
+ errorPtr = dispPtr->errorPtr) {
dispPtr->errorPtr = errorPtr->nextPtr;
ckfree((char *) errorPtr);
}
@@ -281,8 +301,8 @@ TkCloseDisplay(TkDisplay *dispPtr)
TkpCloseDisplay(dispPtr);
/*
- * Delete winTable after TkpCloseDisplay since special windows
- * may need call Tk_DestroyWindow and it checks the winTable.
+ * Delete winTable after TkpCloseDisplay since special windows may need
+ * call Tk_DestroyWindow and it checks the winTable.
*/
Tcl_DeleteHashTable(&dispPtr->winTable);
@@ -299,44 +319,42 @@ TkCloseDisplay(TkDisplay *dispPtr)
*
* CreateTopLevelWindow --
*
- * Make a new window that will be at top-level (its parent will
- * be the root window of a screen).
+ * Make a new window that will be at top-level (its parent will be the
+ * root window of a screen).
*
* Results:
- * 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
- * the interp's result.
+ * 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 the interp's result.
*
* Side effects:
- * A new window structure is allocated locally. An X
- * window is NOT initially created, but will be created
- * the first time the window is mapped.
+ * A new window structure is allocated locally. An X window is NOT
+ * initially created, but will be created the first time the window is
+ * mapped.
*
*----------------------------------------------------------------------
*/
static Tk_Window
-CreateTopLevelWindow(interp, parent, name, screenName, flags)
- Tcl_Interp *interp; /* Interpreter to use for error reporting. */
- Tk_Window parent; /* Token for logical parent of new window
- * (used for naming, options, etc.). May
- * be NULL. */
- CONST char *name; /* Name for new window; if parent is
- * non-NULL, must be unique among parent's
- * children. */
- CONST char *screenName; /* Name of screen on which to create
- * window. NULL means use DISPLAY environment
- * variable to determine. Empty string means
- * use parent's screen, or DISPLAY if no
+CreateTopLevelWindow(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ Tk_Window parent, /* Token for logical parent of new window
+ * (used for naming, options, etc.). May be
+ * NULL. */
+ CONST char *name, /* Name for new window; if parent is non-NULL,
+ * must be unique among parent's children. */
+ CONST char *screenName, /* Name of screen on which to create window.
+ * NULL means use DISPLAY environment variable
+ * to determine. Empty string means use
+ * parent's screen, or DISPLAY if no
* parent. */
- unsigned int flags; /* Additional flags to set on the window. */
+ unsigned int flags) /* Additional flags to set on the window. */
{
register TkWindow *winPtr;
register TkDisplay *dispPtr;
int screenId;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (!tsdPtr->initialized) {
tsdPtr->initialized = 1;
@@ -354,16 +372,6 @@ CreateTopLevelWindow(interp, parent, name, screenName, flags)
Tk_CreatePhotoImageFormat(&tkImgFmtGIF);
Tk_CreatePhotoImageFormat(&tkImgFmtPPM);
-
- /*
- * Create exit handler to delete all windows when the application
- * exits. This must be a thread exit handler, but there may be
- * ordering issues with other exit handlers
- * (i.e. OptionThreadExitProc).
- */
-
- Tcl_CreateThreadExitHandler(DeleteWindowsExitProc,
- (ClientData) tsdPtr);
}
if ((parent != NULL) && (screenName != NULL) && (screenName[0] == '\0')) {
@@ -381,28 +389,29 @@ CreateTopLevelWindow(interp, parent, name, screenName, flags)
/*
* Set the flags specified in the call.
*/
+
winPtr->flags |= flags;
/*
- * Force the window to use a border pixel instead of border pixmap.
- * This is needed for the case where the window doesn't use the
- * default visual. In this case, the default border is a pixmap
- * inherited from the root window, which won't work because it will
- * have the wrong visual.
+ * Force the window to use a border pixel instead of border pixmap. This
+ * is needed for the case where the window doesn't use the default visual.
+ * In this case, the default border is a pixmap inherited from the root
+ * window, which won't work because it will have the wrong visual.
*/
winPtr->dirtyAtts |= CWBorderPixel;
/*
- * (Need to set the TK_TOP_HIERARCHY flag immediately here; otherwise
- * Tk_DestroyWindow will core dump if it is called before the flag
- * has been set.)
+ * (Need to set the TK_TOP_HIERARCHY flag immediately here; otherwise
+ * Tk_DestroyWindow will core dump if it is called before the flag has
+ * been set.)
*/
- winPtr->flags |= TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED;
+ winPtr->flags |=
+ TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED;
if (parent != NULL) {
- if (NameWindow(interp, winPtr, (TkWindow *) parent, name) != TCL_OK) {
+ if (NameWindow(interp, winPtr, (TkWindow *) parent, name) != TCL_OK) {
Tk_DestroyWindow((Tk_Window) winPtr);
return (Tk_Window) NULL;
}
@@ -417,44 +426,40 @@ CreateTopLevelWindow(interp, parent, name, screenName, flags)
*
* GetScreen --
*
- * Given a string name for a display-plus-screen, find the
- * TkDisplay structure for the display and return the screen
- * number too.
+ * Given a string name for a display-plus-screen, find the TkDisplay
+ * structure for the display and return the screen number too.
*
* 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 the interp's result. The location at
- * *screenPtr is overwritten with the screen number parsed from
- * screenName.
+ * 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 the interp's result. The location at *screenPtr is
+ * overwritten with the screen number parsed from screenName.
*
* Side effects:
- * A new connection is opened to the display if there is no
- * connection already. A new TkDisplay data structure is also
- * setup, if necessary.
+ * A new connection is opened to the display if there is no connection
+ * already. A new TkDisplay data structure is also setup, if necessary.
*
*----------------------------------------------------------------------
*/
static TkDisplay *
-GetScreen(interp, screenName, screenPtr)
- Tcl_Interp *interp; /* Place to leave error message. */
- CONST char *screenName; /* Name for screen. NULL or empty means
- * use DISPLAY envariable. */
- int *screenPtr; /* Where to store screen number. */
+GetScreen(
+ Tcl_Interp *interp, /* Place to leave error message. */
+ CONST char *screenName, /* Name for screen. NULL or empty means use
+ * DISPLAY envariable. */
+ int *screenPtr) /* Where to store screen number. */
{
register TkDisplay *dispPtr;
CONST char *p;
int screenId;
size_t length;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
- * Separate the screen number from the rest of the display
- * name. ScreenName is assumed to have the syntax
- * <display>.<screen> with the dot and the screen being
- * optional.
+ * Separate the screen number from the rest of the display name.
+ * ScreenName is assumed to have the syntax <display>.<screen> with the
+ * dot and the screen being optional.
*/
screenName = TkGetDefaultScreenName(interp, screenName);
@@ -462,7 +467,7 @@ GetScreen(interp, screenName, screenPtr)
Tcl_SetResult(interp,
"no display name and no $DISPLAY environment variable",
TCL_STATIC);
- return (TkDisplay *) NULL;
+ return NULL;
}
length = strlen(screenName);
screenId = 0;
@@ -472,26 +477,27 @@ GetScreen(interp, screenName, screenPtr)
}
if ((*p == '.') && (p[1] != '\0')) {
length = p - screenName;
- screenId = strtoul(p+1, (char **) NULL, 10);
+ screenId = strtoul(p+1, NULL, 10);
}
/*
- * See if we already have a connection to this display. If not,
- * then open a new connection.
+ * See if we already have a connection to this display. If not, then open
+ * a new connection.
*/
for (dispPtr = tsdPtr->displayList; ; dispPtr = dispPtr->nextPtr) {
if (dispPtr == NULL) {
/*
- * The private function zeros out dispPtr when it is created,
- * so we only need to initialize the non-zero items.
+ * The private function zeros out dispPtr when it is created, so
+ * we only need to initialize the non-zero items.
*/
+
dispPtr = TkpOpenDisplay(screenName);
if (dispPtr == NULL) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "couldn't connect to display \"",
- screenName, "\"", (char *) NULL);
- return (TkDisplay *) NULL;
+ screenName, "\"", NULL);
+ return NULL;
}
dispPtr->nextPtr = tsdPtr->displayList; /* TkGetDisplayList(); */
tsdPtr->displayList = dispPtr;
@@ -501,10 +507,12 @@ GetScreen(interp, screenName, screenPtr)
dispPtr->cursorFont = None;
dispPtr->warpWindow = None;
dispPtr->multipleAtom = None;
+
/*
* By default we do want to collapse motion events in
* Tk_QueueWindowEvent.
*/
+
dispPtr->flags |= TK_DISPLAY_COLLAPSE_MOTION_EVENTS;
Tcl_InitHashTable(&dispPtr->winTable, TCL_ONE_WORD_KEYS);
@@ -526,7 +534,7 @@ GetScreen(interp, screenName, screenPtr)
sprintf(buf, "bad screen number \"%d\"", screenId);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
- return (TkDisplay *) NULL;
+ return NULL;
}
*screenPtr = screenId;
return dispPtr;
@@ -537,26 +545,26 @@ GetScreen(interp, screenName, screenPtr)
*
* TkGetDisplay --
*
- * Given an X display, TkGetDisplay returns the TkDisplay
- * structure for the display.
+ * Given an X display, TkGetDisplay returns the TkDisplay structure for
+ * the display.
*
* Results:
- * The return value is a pointer to information about the display,
- * or NULL if the display did not have a TkDisplay structure.
+ * The return value is a pointer to information about the display, or
+ * NULL if the display did not have a TkDisplay structure.
*
* Side effects:
- * None.
+ * None.
*
*----------------------------------------------------------------------
*/
TkDisplay *
-TkGetDisplay(display)
- Display *display; /* X's display pointer */
+TkGetDisplay(
+ Display *display) /* X's display pointer */
{
TkDisplay *dispPtr;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
for (dispPtr = tsdPtr->displayList; dispPtr != NULL;
dispPtr = dispPtr->nextPtr) {
@@ -572,23 +580,24 @@ TkGetDisplay(display)
*
* TkGetDisplayList --
*
- * This procedure returns a pointer to the thread-local
- * list of TkDisplays corresponding to the open displays.
+ * This function 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.
+ * The return value is a pointer to the first TkDisplay structure in
+ * thread-local-storage.
*
* Side effects:
- * None.
+ * None.
*
*--------------------------------------------------------------
*/
+
TkDisplay *
-TkGetDisplayList()
+TkGetDisplayList(void)
{
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
return tsdPtr->displayList;
}
@@ -598,24 +607,24 @@ TkGetDisplayList()
*
* TkGetMainInfoList --
*
- * This procedure returns a pointer to the list of structures
- * containing information about all main windows for the
- * current thread.
+ * This function 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.
+ * The return value is a pointer to the first TkMainInfo structure in
+ * thread local storage.
*
* Side effects:
- * None.
+ * None.
*
*--------------------------------------------------------------
*/
+
TkMainInfo *
-TkGetMainInfoList()
+TkGetMainInfoList(void)
{
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
return tsdPtr->mainWindowList;
}
@@ -624,7 +633,7 @@ TkGetMainInfoList()
*
* TkAllocWindow --
*
- * This procedure creates and initializes a TkWindow structure.
+ * This function creates and initializes a TkWindow structure.
*
* Results:
* The return value is a pointer to the new window.
@@ -637,13 +646,12 @@ TkGetMainInfoList()
*/
TkWindow *
-TkAllocWindow(dispPtr, screenNum, parentPtr)
- TkDisplay *dispPtr; /* Display associated with new window. */
- int screenNum; /* Index of screen for new window. */
- TkWindow *parentPtr; /* Parent from which this window should
- * inherit visual information. NULL means
- * use screen defaults instead of
- * inheriting. */
+TkAllocWindow(
+ TkDisplay *dispPtr, /* Display associated with new window. */
+ int screenNum, /* Index of screen for new window. */
+ TkWindow *parentPtr) /* Parent from which this window should
+ * inherit visual information. NULL means use
+ * screen defaults instead of inheriting. */
{
register TkWindow *winPtr;
@@ -709,41 +717,41 @@ TkAllocWindow(dispPtr, screenNum, parentPtr)
*
* NameWindow --
*
- * This procedure is invoked to give a window a name and insert
- * the window into the hierarchy associated with a particular
- * application.
+ * This function is invoked to give a window a name and insert the window
+ * into the hierarchy associated with a particular application.
*
* Results:
* A standard Tcl return value.
*
* Side effects:
- * See above.
+ * See above.
*
*----------------------------------------------------------------------
*/
static int
-NameWindow(interp, winPtr, parentPtr, name)
- Tcl_Interp *interp; /* Interpreter to use for error reporting. */
- register TkWindow *winPtr; /* Window that is to be named and inserted. */
- TkWindow *parentPtr; /* Pointer to logical parent for winPtr
- * (used for naming, options, etc.). */
- CONST char *name; /* Name for winPtr; must be unique among
+NameWindow(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ register TkWindow *winPtr, /* Window that is to be named and inserted. */
+ TkWindow *parentPtr, /* Pointer to logical parent for winPtr (used
+ * for naming, options, etc.). */
+ CONST char *name) /* Name for winPtr; must be unique among
* parentPtr's children. */
{
#define FIXED_SIZE 200
char staticSpace[FIXED_SIZE];
char *pathName;
- int new;
+ int isNew;
Tcl_HashEntry *hPtr;
- int length1, length2;
+ size_t length1, length2;
/*
* Setup all the stuff except name right away, then do the name stuff
- * last. This is so that if the name stuff fails, everything else
- * will be properly initialized (needed to destroy the window cleanly
- * after the naming failure).
+ * last. This is so that if the name stuff fails, everything else will be
+ * properly initialized (needed to destroy the window cleanly after the
+ * naming failure).
*/
+
winPtr->parentPtr = parentPtr;
winPtr->nextPtr = NULL;
if (parentPtr->childList == NULL) {
@@ -759,6 +767,7 @@ NameWindow(interp, winPtr, parentPtr, name)
* If this is an anonymous window (ie, it has no name), just return OK
* now.
*/
+
if (winPtr->flags & TK_ANONYMOUS_WINDOW) {
return TCL_OK;
}
@@ -770,22 +779,21 @@ NameWindow(interp, winPtr, parentPtr, name)
winPtr->nameUid = Tk_GetUid(name);
/*
- * Don't permit names that start with an upper-case letter: this
- * will just cause confusion with class names in the option database.
+ * Don't permit names that start with an upper-case letter: this will just
+ * cause confusion with class names in the option database.
*/
if (isupper(UCHAR(name[0]))) {
Tcl_AppendResult(interp,
"window name starts with an upper-case letter: \"",
- name, "\"", (char *) NULL);
+ name, "\"", NULL);
return TCL_ERROR;
}
/*
- * To permit names of arbitrary length, must be prepared to malloc
- * a buffer to hold the new path name. To run fast in the common
- * case where names are short, use a fixed-size buffer on the
- * stack.
+ * To permit names of arbitrary length, must be prepared to malloc a
+ * buffer to hold the new path name. To run fast in the common case where
+ * names are short, use a fixed-size buffer on the stack.
*/
length1 = strlen(parentPtr->pathName);
@@ -803,13 +811,14 @@ NameWindow(interp, winPtr, parentPtr, name)
pathName[length1] = '.';
strcpy(pathName+length1+1, name);
}
- hPtr = Tcl_CreateHashEntry(&parentPtr->mainPtr->nameTable, pathName, &new);
+ hPtr = Tcl_CreateHashEntry(&parentPtr->mainPtr->nameTable, pathName,
+ &isNew);
if (pathName != staticSpace) {
ckfree(pathName);
}
- if (!new) {
+ if (!isNew) {
Tcl_AppendResult(interp, "window name \"", name,
- "\" already exists in parent", (char *) NULL);
+ "\" already exists in parent", NULL);
return TCL_ERROR;
}
Tcl_SetHashValue(hPtr, winPtr);
@@ -822,53 +831,50 @@ NameWindow(interp, winPtr, parentPtr, name)
*
* TkCreateMainWindow --
*
- * Make a new main window. A main window is a special kind of
- * top-level window used as the outermost window in an
- * application.
+ * Make a new main window. A main window is a special kind of top-level
+ * window used as the outermost window in an application.
*
* Results:
- * 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
- * the interp's result.
+ * 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 the interp's result.
*
* Side effects:
- * A new window structure is allocated locally; "interp" is
- * associated with the window and registered for "send" commands
- * under "baseName". BaseName may be extended with an instance
- * number in the form "#2" if necessary to make it globally
- * unique. Tk-related commands are bound into interp.
+ * A new window structure is allocated locally; "interp" is associated
+ * with the window and registered for "send" commands under "baseName".
+ * BaseName may be extended with an instance number in the form "#2" if
+ * necessary to make it globally unique. Tk-related commands are bound
+ * into interp.
*
*----------------------------------------------------------------------
*/
Tk_Window
-TkCreateMainWindow(interp, screenName, baseName)
- Tcl_Interp *interp; /* Interpreter to use for error reporting. */
- CONST char *screenName; /* Name of screen on which to create
- * window. Empty or NULL string means
- * use DISPLAY environment variable. */
- char *baseName; /* Base name for application; usually of the
+TkCreateMainWindow(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting. */
+ CONST char *screenName, /* Name of screen on which to create window.
+ * Empty or NULL string means use DISPLAY
+ * environment variable. */
+ char *baseName) /* Base name for application; usually of the
* form "prog instance". */
{
Tk_Window tkwin;
- int dummy;
- int isSafe;
+ int dummy, isSafe;
Tcl_HashEntry *hPtr;
register TkMainInfo *mainPtr;
register TkWindow *winPtr;
- register CONST TkCmd *cmdPtr;
+ register const TkCmd *cmdPtr;
ClientData clientData;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
- * Panic if someone updated the TkWindow structure without
- * also updating the Tk_FakeWin structure (or vice versa).
+ * Panic if someone updated the TkWindow structure without also updating
+ * the Tk_FakeWin structure (or vice versa).
*/
if (sizeof(TkWindow) != sizeof(Tk_FakeWin)) {
- panic("TkWindow and Tk_FakeWin are not the same size");
+ Tcl_Panic("TkWindow and Tk_FakeWin are not the same size");
}
/*
@@ -882,8 +888,8 @@ TkCreateMainWindow(interp, screenName, baseName)
}
/*
- * Create the TkMainInfo structure for this application, and set
- * up name-related information for the new window.
+ * Create the TkMainInfo structure for this application, and set up
+ * name-related information for the new window.
*/
winPtr = (TkWindow *) tkwin;
@@ -911,8 +917,8 @@ TkCreateMainWindow(interp, screenName, baseName)
Tcl_ResetResult(interp);
}
if (Tcl_LinkVar(interp, "::tk::AlwaysShowSelection",
- (char *) &mainPtr->alwaysShowSelection,
- TCL_LINK_BOOLEAN) != TCL_OK) {
+ (char *) &mainPtr->alwaysShowSelection,
+ TCL_LINK_BOOLEAN) != TCL_OK) {
Tcl_ResetResult(interp);
}
mainPtr->nextPtr = tsdPtr->mainWindowList;
@@ -923,8 +929,8 @@ TkCreateMainWindow(interp, screenName, baseName)
winPtr->pathName = Tcl_GetHashKey(&mainPtr->nameTable, hPtr);
/*
- * We have just created another Tk application; increment the refcount
- * on the display pointer.
+ * We have just created another Tk application; increment the refcount on
+ * the display pointer.
*/
winPtr->dispPtr->refCount++;
@@ -987,36 +993,35 @@ TkCreateMainWindow(interp, screenName, baseName)
*
* Tk_CreateWindow --
*
- * Create a new internal or top-level window as a child of an
- * existing window.
+ * Create a new internal or top-level window as a child of an existing
+ * window.
*
* Results:
- * 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 the interp's result and
- * NULL is returned.
+ * 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 the interp's result and NULL is returned.
*
* Side effects:
- * A new window structure is allocated locally. An X
- * window is not initially created, but will be created
- * the first time the window is mapped.
+ * A new window structure is allocated locally. An X window is not
+ * initially created, but will be created the first time the window is
+ * mapped.
*
*--------------------------------------------------------------
*/
Tk_Window
-Tk_CreateWindow(interp, parent, name, screenName)
- Tcl_Interp *interp; /* Interpreter to use for error reporting.
+Tk_CreateWindow(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting.
* the interp's result is assumed to be
* initialized by the caller. */
- Tk_Window parent; /* Token for parent of new window. */
- CONST char *name; /* Name for new window. Must be unique
- * among parent's children. */
- CONST char *screenName; /* If NULL, new window will be internal on
- * same screen as its parent. If non-NULL,
- * gives name of screen on which to create
- * new window; window will be a top-level
+ Tk_Window parent, /* Token for parent of new window. */
+ CONST char *name, /* Name for new window. Must be unique among
+ * parent's children. */
+ CONST char *screenName) /* If NULL, new window will be internal on
+ * same screen as its parent. If non-NULL,
+ * gives name of screen on which to create new
+ * window; window will be a top-level
* window. */
{
TkWindow *parentPtr = (TkWindow *) parent;
@@ -1024,29 +1029,26 @@ Tk_CreateWindow(interp, parent, name, screenName)
if ((parentPtr != NULL) && (parentPtr->flags & TK_ALREADY_DEAD)) {
Tcl_AppendResult(interp,
- "can't create window: parent has been destroyed",
- (char *) NULL);
+ "can't create window: parent has been destroyed", NULL);
return NULL;
} else if ((parentPtr != NULL) &&
(parentPtr->flags & TK_CONTAINER)) {
Tcl_AppendResult(interp,
- "can't create window: its parent has -container = yes",
- (char *) NULL);
+ "can't create window: its parent has -container = yes", NULL);
return NULL;
}
+
if (screenName == NULL) {
winPtr = TkAllocWindow(parentPtr->dispPtr, parentPtr->screenNum,
parentPtr);
if (NameWindow(interp, winPtr, parentPtr, name) != TCL_OK) {
Tk_DestroyWindow((Tk_Window) winPtr);
return NULL;
- } else {
- return (Tk_Window) winPtr;
}
- } else {
- return CreateTopLevelWindow(interp, parent, name, screenName,
- /* flags */ 0);
+ return (Tk_Window) winPtr;
}
+ return CreateTopLevelWindow(interp, parent, name, screenName,
+ /* flags */ 0);
}
/*
@@ -1054,35 +1056,34 @@ Tk_CreateWindow(interp, parent, name, screenName)
*
* Tk_CreateAnonymousWindow --
*
- * Create a new internal or top-level window as a child of an
- * existing window; this window will be anonymous (unnamed), so
- * it will not be visible at the Tcl level.
+ * Create a new internal or top-level window as a child of an existing
+ * window; this window will be anonymous (unnamed), so it will not be
+ * visible at the Tcl level.
*
* Results:
- * 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 the interp's result and
- * NULL is returned.
+ * 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 the interp's result and NULL is returned.
*
* Side effects:
- * A new window structure is allocated locally. An X
- * window is not initially created, but will be created
- * the first time the window is mapped.
+ * A new window structure is allocated locally. An X window is not
+ * initially created, but will be created the first time the window is
+ * mapped.
*
*--------------------------------------------------------------
*/
Tk_Window
-Tk_CreateAnonymousWindow(interp, parent, screenName)
- Tcl_Interp *interp; /* Interpreter to use for error reporting.
+Tk_CreateAnonymousWindow(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting.
* the interp's result is assumed to be
* initialized by the caller. */
- Tk_Window parent; /* Token for parent of new window. */
- CONST char *screenName; /* If NULL, new window will be internal on
- * same screen as its parent. If non-NULL,
- * gives name of screen on which to create
- * new window; window will be a top-level
+ Tk_Window parent, /* Token for parent of new window. */
+ CONST char *screenName) /* If NULL, new window will be internal on
+ * same screen as its parent. If non-NULL,
+ * gives name of screen on which to create new
+ * window; window will be a top-level
* window. */
{
TkWindow *parentPtr = (TkWindow *) parent;
@@ -1090,14 +1091,12 @@ Tk_CreateAnonymousWindow(interp, parent, screenName)
if ((parentPtr != NULL) && (parentPtr->flags & TK_ALREADY_DEAD)) {
Tcl_AppendResult(interp,
- "can't create window: parent has been destroyed",
- (char *) NULL);
+ "can't create window: parent has been destroyed", NULL);
return NULL;
} else if ((parentPtr != NULL) &&
(parentPtr->flags & TK_CONTAINER)) {
Tcl_AppendResult(interp,
- "can't create window: its parent has -container = yes",
- (char *) NULL);
+ "can't create window: its parent has -container = yes", NULL);
return NULL;
}
if (screenName == NULL) {
@@ -1109,15 +1108,14 @@ Tk_CreateAnonymousWindow(interp, parent, screenName)
*/
winPtr->flags |= TK_ANONYMOUS_WINDOW;
- if (NameWindow(interp, winPtr, parentPtr, (char *)NULL) != TCL_OK) {
+ if (NameWindow(interp, winPtr, parentPtr, NULL) != TCL_OK) {
Tk_DestroyWindow((Tk_Window) winPtr);
return NULL;
}
return (Tk_Window) winPtr;
- } else {
- return CreateTopLevelWindow(interp, parent, (char *)NULL, screenName,
- TK_ANONYMOUS_WINDOW);
}
+ return CreateTopLevelWindow(interp, parent, NULL, screenName,
+ TK_ANONYMOUS_WINDOW);
}
/*
@@ -1125,41 +1123,38 @@ Tk_CreateAnonymousWindow(interp, parent, screenName)
*
* Tk_CreateWindowFromPath --
*
- * This procedure is similar to Tk_CreateWindow except that
- * it uses a path name to create the window, rather than a
- * parent and a child name.
+ * This function is similar to Tk_CreateWindow except that it uses a path
+ * name to create the window, rather than a parent and a child name.
*
* Results:
- * 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 the interp's result and
- * NULL is returned.
+ * 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 the interp's result and NULL is returned.
*
* Side effects:
- * A new window structure is allocated locally. An X
- * window is not initially created, but will be created
- * the first time the window is mapped.
+ * A new window structure is allocated locally. An X window is not
+ * initially created, but will be created the first time the window is
+ * mapped.
*
*----------------------------------------------------------------------
*/
Tk_Window
-Tk_CreateWindowFromPath(interp, tkwin, pathName, screenName)
- Tcl_Interp *interp; /* Interpreter to use for error reporting.
+Tk_CreateWindowFromPath(
+ Tcl_Interp *interp, /* Interpreter to use for error reporting.
* 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. */
- CONST char *pathName; /* Path name for new window within the
- * application of tkwin. The parent of
- * this window must already exist, but
- * the window itself must not exist. */
- CONST char *screenName; /* If NULL, new window will be on same
- * screen as its parent. If non-NULL,
- * gives name of screen on which to create
- * new window; window will be a top-level
- * window. */
+ Tk_Window tkwin, /* Token for any window in application that is
+ * to contain new window. */
+ CONST char *pathName, /* Path name for new window within the
+ * application of tkwin. The parent of this
+ * window must already exist, but the window
+ * itself must not exist. */
+ CONST char *screenName) /* If NULL, new window will be on same screen
+ * as its parent. If non-NULL, gives name of
+ * screen on which to create new window;
+ * window will be a top-level window. */
{
#define FIXED_SPACE 5
char fixedSpace[FIXED_SPACE+1];
@@ -1168,18 +1163,17 @@ Tk_CreateWindowFromPath(interp, tkwin, pathName, screenName)
int numChars;
/*
- * Strip the parent's name out of pathName (it's everything up
- * to the last dot). There are two tricky parts: (a) must
- * copy the parent's name somewhere else to avoid modifying
- * the pathName string (for large names, space for the copy
- * will have to be malloc'ed); (b) must special-case the
- * situation where the parent is ".".
+ * Strip the parent's name out of pathName (it's everything up to the last
+ * dot). There are two tricky parts: (a) must copy the parent's name
+ * somewhere else to avoid modifying the pathName string (for large names,
+ * space for the copy will have to be malloc'ed); (b) must special-case
+ * the situation where the parent is ".".
*/
p = strrchr(pathName, '.');
if (p == NULL) {
Tcl_AppendResult(interp, "bad window path name \"", pathName,
- "\"", (char *) NULL);
+ "\"", NULL);
return NULL;
}
numChars = (int) (p-pathName);
@@ -1202,19 +1196,19 @@ Tk_CreateWindowFromPath(interp, tkwin, pathName, screenName)
parent = Tk_NameToWindow(interp, p, tkwin);
if (p != fixedSpace) {
- ckfree(p);
+ ckfree(p);
}
if (parent == NULL) {
return NULL;
}
if (((TkWindow *) parent)->flags & TK_ALREADY_DEAD) {
Tcl_AppendResult(interp,
- "can't create window: parent has been destroyed", (char *) NULL);
+ "can't create window: parent has been destroyed", NULL);
return NULL;
- } else if (((TkWindow *) parent)->flags & TK_CONTAINER) {
+ }
+ if (((TkWindow *) parent)->flags & TK_CONTAINER) {
Tcl_AppendResult(interp,
- "can't create window: its parent has -container = yes",
- (char *) NULL);
+ "can't create window: its parent has -container = yes", NULL);
return NULL;
}
@@ -1232,13 +1226,12 @@ Tk_CreateWindowFromPath(interp, tkwin, pathName, screenName)
!= TCL_OK) {
Tk_DestroyWindow((Tk_Window) winPtr);
return NULL;
- } else {
- return (Tk_Window) winPtr;
}
- } else {
- return CreateTopLevelWindow(interp, parent, pathName+numChars+1,
- screenName, /* flags */ 0);
+ return (Tk_Window) winPtr;
}
+
+ return CreateTopLevelWindow(interp, parent, pathName+numChars+1,
+ screenName, /* flags */ 0);
}
/*
@@ -1246,36 +1239,36 @@ Tk_CreateWindowFromPath(interp, tkwin, pathName, screenName)
*
* Tk_DestroyWindow --
*
- * Destroy an existing window. After this call, the caller
- * should never again use the token. Note that this function
- * can be reentered to destroy a window that was only
- * partially destroyed before a call to exit.
+ * Destroy an existing window. After this call, the caller should never
+ * again use the token. Note that this function can be reentered to
+ * destroy a window that was only partially destroyed before a call to
+ * exit.
*
* Results:
* None.
*
* Side effects:
- * The window is deleted, along with all of its children.
- * Relevant callback procedures are invoked.
+ * The window is deleted, along with all of its children. Relevant
+ * callback functions are invoked.
*
*--------------------------------------------------------------
*/
void
-Tk_DestroyWindow(tkwin)
- Tk_Window tkwin; /* Window to destroy. */
+Tk_DestroyWindow(
+ Tk_Window tkwin) /* Window to destroy. */
{
TkWindow *winPtr = (TkWindow *) tkwin;
TkDisplay *dispPtr = winPtr->dispPtr;
XEvent event;
TkHalfdeadWindow *halfdeadPtr, *prev_halfdeadPtr;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (winPtr->flags & TK_ALREADY_DEAD) {
/*
- * A destroy event binding caused the window to be destroyed
- * again. Ignore the request.
+ * A destroy event binding caused the window to be destroyed again.
+ * Ignore the request.
*/
return;
@@ -1283,9 +1276,8 @@ Tk_DestroyWindow(tkwin)
winPtr->flags |= TK_ALREADY_DEAD;
/*
- * Unless we are cleaning up a half dead
- * window from DeleteWindowsExitProc,
- * add this window to the half dead list.
+ * Unless we are cleaning up a half dead window from
+ * DeleteWindowsExitProc, add this window to the half dead list.
*/
if (tsdPtr->halfdeadWindowList &&
@@ -1301,12 +1293,12 @@ Tk_DestroyWindow(tkwin)
}
/*
- * Some cleanup needs to be done immediately, rather than later,
- * because it needs information that will be destoyed before we
- * get to the main cleanup point. For example, TkFocusDeadWindow
- * needs to access the parentPtr field from a window, but if
- * a Destroy event handler deletes the window's parent this
- * field will be NULL before the main cleanup point is reached.
+ * Some cleanup needs to be done immediately, rather than later, because
+ * it needs information that will be destoyed before we get to the main
+ * cleanup point. For example, TkFocusDeadWindow needs to access the
+ * parentPtr field from a window, but if a Destroy event handler deletes
+ * the window's parent this field will be NULL before the main cleanup
+ * point is reached.
*/
if (!(halfdeadPtr->flags & HD_FOCUS)) {
@@ -1315,23 +1307,23 @@ Tk_DestroyWindow(tkwin)
}
/*
- * If this is a main window, remove it from the list of main
- * windows. This needs to be done now (rather than later with
- * all the other main window cleanup) to handle situations where
- * a destroy binding for a window calls "exit". In this case
- * the child window cleanup isn't complete when exit is called.
- * This situation is dealt with using the half dead window
- * list. Windows that are half dead gets cleaned up during exit.
+ * If this is a main window, remove it from the list of main windows.
+ * This needs to be done now (rather than later with all the other main
+ * window cleanup) to handle situations where a destroy binding for a
+ * window calls "exit". In this case the child window cleanup isn't
+ * complete when exit is called. This situation is dealt with using the
+ * half dead window list. Windows that are half dead gets cleaned up
+ * during exit.
*
- * Also decrement the display refcount so that if this is the
- * last Tk application in this process on this display, the display
- * can be closed and its data structures deleted.
+ * Also decrement the display refcount so that if this is the last Tk
+ * application in this process on this display, the display can be closed
+ * and its data structures deleted.
*/
if (!(halfdeadPtr->flags & HD_MAIN_WIN) &&
winPtr->mainPtr != NULL && winPtr->mainPtr->winPtr == winPtr) {
halfdeadPtr->flags |= HD_MAIN_WIN;
- dispPtr->refCount--;
+ dispPtr->refCount--;
if (tsdPtr->mainWindowList == winPtr->mainPtr) {
tsdPtr->mainWindowList = winPtr->mainPtr->nextPtr;
} else {
@@ -1348,10 +1340,9 @@ Tk_DestroyWindow(tkwin)
}
/*
- * Recursively destroy children. Note that this child
- * window block may need to be run multiple times
- * in the case where a child window has a Destroy
- * binding that calls exit.
+ * Recursively destroy children. Note that this child window block may
+ * need to be run multiple times in the case where a child window has a
+ * Destroy binding that calls exit.
*/
if (!(halfdeadPtr->flags & HD_DESTROY_COUNT)) {
@@ -1366,10 +1357,10 @@ Tk_DestroyWindow(tkwin)
Tk_DestroyWindow((Tk_Window) childPtr);
if (winPtr->childList == childPtr) {
/*
- * The child didn't remove itself from the child list, so
- * let's remove it here. This can happen in some strange
- * conditions, such as when a Destroy event handler for a
- * window destroys the window's parent.
+ * The child didn't remove itself from the child list, so let's
+ * remove it here. This can happen in some strange conditions,
+ * such as when a Destroy event handler for a window destroys the
+ * window's parent.
*/
winPtr->childList = childPtr->nextPtr;
@@ -1379,14 +1370,13 @@ Tk_DestroyWindow(tkwin)
if ((winPtr->flags & (TK_CONTAINER|TK_BOTH_HALVES))
== (TK_CONTAINER|TK_BOTH_HALVES)) {
/*
- * This is the container for an embedded application, and
- * the embedded application is also in this process. Delete
- * the embedded window in-line here, for the same reasons we
- * delete children in-line (otherwise, for example, the Tk
- * window may appear to exist even though its X window is
- * gone; this could cause errors). Special note: it's possible
- * that the embedded window has already been deleted, in which
- * case TkpGetOtherWindow will return NULL.
+ * This is the container for an embedded application, and the embedded
+ * application is also in this process. Delete the embedded window
+ * in-line here, for the same reasons we delete children in-line
+ * (otherwise, for example, the Tk window may appear to exist even
+ * though its X window is gone; this could cause errors). Special
+ * note: it's possible that the embedded window has already been
+ * deleted, in which case TkpGetOtherWindow will return NULL.
*/
TkWindow *childPtr;
@@ -1398,11 +1388,10 @@ Tk_DestroyWindow(tkwin)
}
/*
- * Generate a DestroyNotify event. In order for the DestroyNotify
- * event to be processed correctly, need to make sure the window
- * exists. This is a bit of a kludge, and may be unnecessarily
- * expensive, but without it no event handlers will get called for
- * windows that don't exist yet.
+ * Generate a DestroyNotify event. In order for the DestroyNotify event to
+ * be processed correctly, need to make sure the window exists. This is a
+ * bit of a kludge, and may be unnecessarily expensive, but without it no
+ * event handlers will get called for windows that don't exist yet.
*
* Note: if the window's pathName is NULL and the window is not an
* anonymous window, it means that the window was not successfully
@@ -1428,28 +1417,28 @@ Tk_DestroyWindow(tkwin)
}
/*
- * No additional bindings that could call exit
- * should be invoked from this point on,
- * so it is safe to remove this window
- * from the half dead list.
+ * No additional bindings that could call exit should be invoked from this
+ * point on, so it is safe to remove this window from the half dead list.
*/
for (prev_halfdeadPtr = NULL,
halfdeadPtr = tsdPtr->halfdeadWindowList;
halfdeadPtr != NULL; ) {
if (halfdeadPtr->winPtr == winPtr) {
- if (prev_halfdeadPtr == NULL)
- tsdPtr->halfdeadWindowList = halfdeadPtr->nextPtr;
- else
- prev_halfdeadPtr->nextPtr = halfdeadPtr->nextPtr;
+ if (prev_halfdeadPtr == NULL) {
+ tsdPtr->halfdeadWindowList = halfdeadPtr->nextPtr;
+ } else {
+ prev_halfdeadPtr->nextPtr = halfdeadPtr->nextPtr;
+ }
ckfree((char *) halfdeadPtr);
break;
}
prev_halfdeadPtr = halfdeadPtr;
halfdeadPtr = halfdeadPtr->nextPtr;
}
- if (halfdeadPtr == NULL)
- panic("window not found on half dead list");
+ if (halfdeadPtr == NULL) {
+ Tcl_Panic("window not found on half dead list");
+ }
/*
* Cleanup the data structures associated with this window.
@@ -1467,11 +1456,10 @@ Tk_DestroyWindow(tkwin)
if ((winPtr->flags & TK_TOP_HIERARCHY)
|| !(winPtr->flags & TK_DONT_DESTROY_WINDOW)) {
/*
- * The parent has already been destroyed and this isn't
- * a top-level window, so this window will be destroyed
- * implicitly when the parent's X window is destroyed;
- * it's much faster not to do an explicit destroy of this
- * X window.
+ * The parent has already been destroyed and this isn't a
+ * top-level window, so this window will be destroyed implicitly
+ * when the parent's X window is destroyed; it's much faster not
+ * to do an explicit destroy of this X window.
*/
dispPtr->lastDestroyRequest = NextRequest(winPtr->display);
@@ -1505,47 +1493,49 @@ Tk_DestroyWindow(tkwin)
(ClientData) winPtr->pathName);
Tcl_DeleteHashEntry(Tcl_FindHashEntry(&winPtr->mainPtr->nameTable,
winPtr->pathName));
- /*
- * The memory pointed to by pathName has been deallocated.
- * Keep users from accessing it after the window has been
- * destroyed by setting it to NULL.
- */
- winPtr->pathName = NULL;
/*
- * Invalidate all objects referring to windows
- * with the same main window
+ * The memory pointed to by pathName has been deallocated. Keep
+ * users from accessing it after the window has been destroyed by
+ * setting it to NULL.
+ */
+
+ winPtr->pathName = NULL;
+
+ /*
+ * Invalidate all objects referring to windows with the same main
+ * window.
*/
+
winPtr->mainPtr->deletionEpoch++;
}
winPtr->mainPtr->refCount--;
if (winPtr->mainPtr->refCount == 0) {
- register CONST TkCmd *cmdPtr;
+ register const TkCmd *cmdPtr;
/*
- * We just deleted the last window in the application. Delete
- * the TkMainInfo structure too and replace all of Tk's commands
- * with dummy commands that return errors. Also delete the
- * "send" command to unregister the interpreter.
+ * We just deleted the last window in the application. Delete the
+ * TkMainInfo structure too and replace all of Tk's commands with
+ * dummy commands that return errors. Also delete the "send"
+ * command to unregister the interpreter.
*
- * NOTE: Only replace the commands it if the interpreter is
- * not being deleted. If it *is*, the interpreter cleanup will
- * do all the needed work.
+ * NOTE: Only replace the commands it if the interpreter is not
+ * being deleted. If it *is*, the interpreter cleanup will do all
+ * the needed work.
*/
- if ((winPtr->mainPtr->interp != NULL) &&
- (!Tcl_InterpDeleted(winPtr->mainPtr->interp))) {
- for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
- Tcl_CreateCommand(winPtr->mainPtr->interp, cmdPtr->name,
- TkDeadAppCmd, (ClientData) NULL,
- (void (*) _ANSI_ARGS_((ClientData))) NULL);
- }
- Tcl_CreateCommand(winPtr->mainPtr->interp, "send",
- TkDeadAppCmd, (ClientData) NULL,
- (void (*) _ANSI_ARGS_((ClientData))) NULL);
- Tcl_UnlinkVar(winPtr->mainPtr->interp, "tk_strictMotif");
- Tcl_UnlinkVar(winPtr->mainPtr->interp, "::tk::AlwaysShowSelection");
- }
+ if ((winPtr->mainPtr->interp != NULL) &&
+ (!Tcl_InterpDeleted(winPtr->mainPtr->interp))) {
+ for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
+ Tcl_CreateCommand(winPtr->mainPtr->interp, cmdPtr->name,
+ TkDeadAppCmd, NULL, NULL);
+ }
+ Tcl_CreateCommand(winPtr->mainPtr->interp, "send",
+ TkDeadAppCmd, NULL, NULL);
+ Tcl_UnlinkVar(winPtr->mainPtr->interp, "tk_strictMotif");
+ Tcl_UnlinkVar(winPtr->mainPtr->interp,
+ "::tk::AlwaysShowSelection");
+ }
Tcl_DeleteHashTable(&winPtr->mainPtr->nameTable);
TkBindFree(winPtr->mainPtr);
@@ -1554,72 +1544,71 @@ Tk_DestroyWindow(tkwin)
TkFocusFree(winPtr->mainPtr);
TkStylePkgFree(winPtr->mainPtr);
- /*
- * When embedding Tk into other applications, make sure
- * that all destroy events reach the server. Otherwise
- * the embedding application may also attempt to destroy
- * the windows, resulting in an X error
- */
+ /*
+ * When embedding Tk into other applications, make sure that all
+ * destroy events reach the server. Otherwise the embedding
+ * application may also attempt to destroy the windows, resulting
+ * in an X error
+ */
- if (winPtr->flags & TK_EMBEDDED) {
- XSync(winPtr->display, False);
- }
+ if (winPtr->flags & TK_EMBEDDED) {
+ XSync(winPtr->display, False);
+ }
ckfree((char *) winPtr->mainPtr);
- /*
- * If no other applications are using the display, close the
- * display now and relinquish its data structures.
- */
+ /*
+ * If no other applications are using the display, close the
+ * display now and relinquish its data structures.
+ */
#if !defined(WIN32) && defined(NOT_YET)
- if (dispPtr->refCount <= 0) {
- /*
- * I have disabled this code because on Windows there are
- * still order dependencies in close-down. All displays
- * and resources will get closed down properly anyway at
- * exit, through the exit handler. -- jyl
- */
+ if (dispPtr->refCount <= 0) {
/*
+ * I have disabled this code because on Windows there are
+ * still order dependencies in close-down. All displays and
+ * resources will get closed down properly anyway at exit,
+ * through the exit handler. -- jyl
+ *
* Ideally this should be enabled, as unix Tk can use multiple
- * displays. However, there are order issues still, as well
- * as the handling of queued events and such that must be
- * addressed before this can be enabled. The current cleanup
+ * displays. However, there are order issues still, as well as
+ * the handling of queued events and such that must be
+ * addressed before this can be enabled. The current cleanup
* works except for send event issues. -- hobbs 04/2002
*/
- TkDisplay *theDispPtr, *backDispPtr;
-
- /*
- * Splice this display out of the list of displays.
- */
-
- for (theDispPtr = tsdPtr->displayList, backDispPtr = NULL;
- (theDispPtr != winPtr->dispPtr) &&
- (theDispPtr != NULL);
- theDispPtr = theDispPtr->nextPtr) {
- backDispPtr = theDispPtr;
- }
- if (theDispPtr == NULL) {
- panic("could not find display to close!");
- }
- if (backDispPtr == NULL) {
- tsdPtr->displayList = theDispPtr->nextPtr;
- } else {
- backDispPtr->nextPtr = theDispPtr->nextPtr;
- }
-
- /*
+ TkDisplay *theDispPtr, *backDispPtr;
+
+ /*
+ * Splice this display out of the list of displays.
+ */
+
+ for (theDispPtr = tsdPtr->displayList, backDispPtr = NULL;
+ (theDispPtr!=winPtr->dispPtr) && (theDispPtr!=NULL);
+ theDispPtr = theDispPtr->nextPtr) {
+ backDispPtr = theDispPtr;
+ }
+ if (theDispPtr == NULL) {
+ Tcl_Panic("could not find display to close!");
+ }
+ if (backDispPtr == NULL) {
+ tsdPtr->displayList = theDispPtr->nextPtr;
+ } else {
+ backDispPtr->nextPtr = theDispPtr->nextPtr;
+ }
+
+ /*
* Calling XSync creates X server traffic, but addresses a
* focus issue on close (but not the send issue). -- hobbs
- XSync(dispPtr->display, True);
+ *
+ * XSync(dispPtr->display, True);
*/
- /*
- * Found and spliced it out, now actually do the cleanup.
- */
+ /*
+ * Found and spliced it out, now actually do the cleanup.
+ */
TkCloseDisplay(dispPtr);
- }
+ }
#endif
}
}
@@ -1631,22 +1620,21 @@ Tk_DestroyWindow(tkwin)
*
* Tk_MapWindow --
*
- * Map a window within its parent. This may require the
- * window and/or its parents to actually be created.
+ * Map a window within its parent. This may require the window and/or its
+ * parents to actually be created.
*
* Results:
* None.
*
* Side effects:
- * The given window will be mapped. Windows may also
- * be created.
+ * The given window will be mapped. Windows may also be created.
*
*--------------------------------------------------------------
*/
void
-Tk_MapWindow(tkwin)
- Tk_Window tkwin; /* Token for window to map. */
+Tk_MapWindow(
+ Tk_Window tkwin) /* Token for window to map. */
{
TkWindow *winPtr = (TkWindow *) tkwin;
XEvent event;
@@ -1666,8 +1654,8 @@ Tk_MapWindow(tkwin)
}
if (winPtr->flags & TK_WIN_MANAGED) {
/*
- * Lots of special processing has to be done for top-level
- * windows. Let tkWm.c handle everything itself.
+ * Lots of special processing has to be done for top-level windows.
+ * Let tkWm.c handle everything itself.
*/
TkWmMapWindow(winPtr);
@@ -1690,32 +1678,31 @@ Tk_MapWindow(tkwin)
*
* Tk_MakeWindowExist --
*
- * Ensure that a particular window actually exists. This
- * procedure shouldn't normally need to be invoked from
- * outside the Tk package, but may be needed if someone
- * wants to manipulate a window before mapping it.
+ * Ensure that a particular window actually exists. This function should
+ * not normally need to be invoked from outside the Tk package, but may
+ * be needed if someone wants to manipulate a window before mapping it.
*
* Results:
* None.
*
* Side effects:
- * When the procedure returns, the X window associated with
- * tkwin is guaranteed to exist. This may require the
- * window's ancestors to be created also.
+ * When the function returns, the X window associated with tkwin is
+ * guaranteed to exist. This may require the window's ancestors to be
+ * created also.
*
*--------------------------------------------------------------
*/
void
-Tk_MakeWindowExist(tkwin)
- Tk_Window tkwin; /* Token for window. */
+Tk_MakeWindowExist(
+ Tk_Window tkwin) /* Token for window. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
TkWindow *winPtr2;
Window parent;
Tcl_HashEntry *hPtr;
Tk_ClassCreateProc *createProc;
- int new;
+ int isNew;
if (winPtr->window != None) {
return;
@@ -1731,28 +1718,28 @@ Tk_MakeWindowExist(tkwin)
}
createProc = Tk_GetClassProc(winPtr->classProcsPtr, createProc);
- if (createProc != NULL) {
+ if (createProc != NULL && parent != None) {
winPtr->window = (*createProc)(tkwin, parent, winPtr->instanceData);
} else {
winPtr->window = TkpMakeWindow(winPtr, parent);
}
hPtr = Tcl_CreateHashEntry(&winPtr->dispPtr->winTable,
- (char *) winPtr->window, &new);
+ (char *) winPtr->window, &isNew);
Tcl_SetHashValue(hPtr, winPtr);
winPtr->dirtyAtts = 0;
winPtr->dirtyChanges = 0;
if (!(winPtr->flags & TK_TOP_HIERARCHY)) {
/*
- * If any siblings higher up in the stacking order have already
- * been created then move this window to its rightful position
- * in the stacking order.
+ * If any siblings higher up in the stacking order have already been
+ * created then move this window to its rightful position in the
+ * stacking order.
*
- * NOTE: this code ignores any changes anyone might have made
- * to the sibling and stack_mode field of the window's attributes,
- * so it really isn't safe for these to be manipulated except
- * by calling Tk_RestackWindow.
+ * NOTE: this code ignores any changes anyone might have made to the
+ * sibling and stack_mode field of the window's attributes, so it
+ * really isn't safe for these to be manipulated except by calling
+ * Tk_RestackWindow.
*/
for (winPtr2 = winPtr->nextPtr; winPtr2 != NULL;
@@ -1769,8 +1756,8 @@ Tk_MakeWindowExist(tkwin)
}
/*
- * If this window has a different colormap than its parent, add
- * the window to the WM_COLORMAP_WINDOWS property for its top-level.
+ * If this window has a different colormap than its parent, add the
+ * window to the WM_COLORMAP_WINDOWS property for its top-level.
*/
if ((winPtr->parentPtr != NULL) &&
@@ -1782,9 +1769,9 @@ Tk_MakeWindowExist(tkwin)
/*
* Issue a ConfigureNotify event if there were deferred configuration
- * changes (but skip it if the window is being deleted; the
- * ConfigureNotify event could cause problems if we're being called
- * from Tk_DestroyWindow under some conditions).
+ * changes (but skip it if the window is being deleted; the
+ * ConfigureNotify event could cause problems if we're being called from
+ * Tk_DestroyWindow under some conditions).
*/
if ((winPtr->flags & TK_NEED_CONFIG_NOTIFY)
@@ -1799,12 +1786,11 @@ Tk_MakeWindowExist(tkwin)
*
* Tk_UnmapWindow, etc. --
*
- * There are several procedures under here, each of which
- * mirrors an existing X procedure. In addition to performing
- * the functions of the corresponding procedure, each
- * procedure also updates the local window structure and
- * synthesizes an X event (if the window's structure is being
- * managed internally).
+ * There are several functions under here, each of which mirrors an
+ * existing X function. In addition to performing the functions of the
+ * corresponding function, each function also updates the local window
+ * structure and synthesizes an X event (if the window's structure is
+ * being managed internally).
*
* Results:
* See the manual entries.
@@ -1816,8 +1802,8 @@ Tk_MakeWindowExist(tkwin)
*/
void
-Tk_UnmapWindow(tkwin)
- Tk_Window tkwin; /* Token for window to unmap. */
+Tk_UnmapWindow(
+ Tk_Window tkwin) /* Token for window to unmap. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -1826,8 +1812,8 @@ Tk_UnmapWindow(tkwin)
}
if (winPtr->flags & TK_WIN_MANAGED) {
/*
- * Special processing has to be done for top-level windows. Let
- * tkWm.c handle everything itself.
+ * Special processing has to be done for top-level windows. Let tkWm.c
+ * handle everything itself.
*/
TkWmUnmapWindow(winPtr);
@@ -1850,11 +1836,11 @@ Tk_UnmapWindow(tkwin)
}
void
-Tk_ConfigureWindow(tkwin, valueMask, valuePtr)
- Tk_Window tkwin; /* Window to re-configure. */
- unsigned int valueMask; /* Mask indicating which parts of
- * *valuePtr are to be used. */
- XWindowChanges *valuePtr; /* New values. */
+Tk_ConfigureWindow(
+ Tk_Window tkwin, /* Window to re-configure. */
+ unsigned int valueMask, /* Mask indicating which parts of *valuePtr
+ * are to be used. */
+ XWindowChanges *valuePtr) /* New values. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -1874,13 +1860,13 @@ Tk_ConfigureWindow(tkwin, valueMask, valuePtr)
winPtr->changes.border_width = valuePtr->border_width;
}
if (valueMask & (CWSibling|CWStackMode)) {
- panic("Can't set sibling or stack mode from Tk_ConfigureWindow.");
+ Tcl_Panic("Can't set sibling or stack mode from Tk_ConfigureWindow.");
}
if (winPtr->window != None) {
XConfigureWindow(winPtr->display, winPtr->window,
valueMask, valuePtr);
- TkDoConfigureNotify(winPtr);
+ TkDoConfigureNotify(winPtr);
} else {
winPtr->dirtyChanges |= valueMask;
winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
@@ -1888,10 +1874,9 @@ Tk_ConfigureWindow(tkwin, valueMask, valuePtr)
}
void
-Tk_MoveWindow(tkwin, x, y)
- Tk_Window tkwin; /* Window to move. */
- int x, y; /* New location for window (within
- * parent). */
+Tk_MoveWindow(
+ Tk_Window tkwin, /* Window to move. */
+ int x, int y) /* New location for window (within parent). */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -1899,7 +1884,7 @@ Tk_MoveWindow(tkwin, x, y)
winPtr->changes.y = y;
if (winPtr->window != None) {
XMoveWindow(winPtr->display, winPtr->window, x, y);
- TkDoConfigureNotify(winPtr);
+ TkDoConfigureNotify(winPtr);
} else {
winPtr->dirtyChanges |= CWX|CWY;
winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
@@ -1907,9 +1892,9 @@ Tk_MoveWindow(tkwin, x, y)
}
void
-Tk_ResizeWindow(tkwin, width, height)
- Tk_Window tkwin; /* Window to resize. */
- int width, height; /* New dimensions for window. */
+Tk_ResizeWindow(
+ Tk_Window tkwin, /* Window to resize. */
+ int width, int height) /* New dimensions for window. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -1918,7 +1903,7 @@ Tk_ResizeWindow(tkwin, width, height)
if (winPtr->window != None) {
XResizeWindow(winPtr->display, winPtr->window, (unsigned) width,
(unsigned) height);
- TkDoConfigureNotify(winPtr);
+ TkDoConfigureNotify(winPtr);
} else {
winPtr->dirtyChanges |= CWWidth|CWHeight;
winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
@@ -1926,11 +1911,10 @@ Tk_ResizeWindow(tkwin, width, height)
}
void
-Tk_MoveResizeWindow(tkwin, x, y, width, height)
- Tk_Window tkwin; /* Window to move and resize. */
- int x, y; /* New location for window (within
- * parent). */
- int width, height; /* New dimensions for window. */
+Tk_MoveResizeWindow(
+ Tk_Window tkwin, /* Window to move and resize. */
+ int x, int y, /* New location for window (within parent). */
+ int width, int height) /* New dimensions for window. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -1941,7 +1925,7 @@ Tk_MoveResizeWindow(tkwin, x, y, width, height)
if (winPtr->window != None) {
XMoveResizeWindow(winPtr->display, winPtr->window, x, y,
(unsigned) width, (unsigned) height);
- TkDoConfigureNotify(winPtr);
+ TkDoConfigureNotify(winPtr);
} else {
winPtr->dirtyChanges |= CWX|CWY|CWWidth|CWHeight;
winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
@@ -1949,9 +1933,9 @@ Tk_MoveResizeWindow(tkwin, x, y, width, height)
}
void
-Tk_SetWindowBorderWidth(tkwin, width)
- Tk_Window tkwin; /* Window to modify. */
- int width; /* New border width for window. */
+Tk_SetWindowBorderWidth(
+ Tk_Window tkwin, /* Window to modify. */
+ int width) /* New border width for window. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -1959,7 +1943,7 @@ Tk_SetWindowBorderWidth(tkwin, width)
if (winPtr->window != None) {
XSetWindowBorderWidth(winPtr->display, winPtr->window,
(unsigned) width);
- TkDoConfigureNotify(winPtr);
+ TkDoConfigureNotify(winPtr);
} else {
winPtr->dirtyChanges |= CWBorderWidth;
winPtr->flags |= TK_NEED_CONFIG_NOTIFY;
@@ -1967,12 +1951,11 @@ Tk_SetWindowBorderWidth(tkwin, width)
}
void
-Tk_ChangeWindowAttributes(tkwin, valueMask, attsPtr)
- Tk_Window tkwin; /* Window to manipulate. */
- unsigned long valueMask; /* OR'ed combination of bits,
- * indicating which fields of
- * *attsPtr are to be used. */
- register XSetWindowAttributes *attsPtr;
+Tk_ChangeWindowAttributes(
+ Tk_Window tkwin, /* Window to manipulate. */
+ unsigned long valueMask, /* OR'ed combination of bits, indicating which
+ * fields of *attsPtr are to be used. */
+ register XSetWindowAttributes *attsPtr)
/* New values for some attributes. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -2033,10 +2016,10 @@ Tk_ChangeWindowAttributes(tkwin, valueMask, attsPtr)
}
void
-Tk_SetWindowBackground(tkwin, pixel)
- Tk_Window tkwin; /* Window to manipulate. */
- unsigned long pixel; /* Pixel value to use for
- * window's background. */
+Tk_SetWindowBackground(
+ Tk_Window tkwin, /* Window to manipulate. */
+ unsigned long pixel) /* Pixel value to use for window's
+ * background. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -2051,10 +2034,9 @@ Tk_SetWindowBackground(tkwin, pixel)
}
void
-Tk_SetWindowBackgroundPixmap(tkwin, pixmap)
- Tk_Window tkwin; /* Window to manipulate. */
- Pixmap pixmap; /* Pixmap to use for window's
- * background. */
+Tk_SetWindowBackgroundPixmap(
+ Tk_Window tkwin, /* Window to manipulate. */
+ Pixmap pixmap) /* Pixmap to use for window's background. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -2070,10 +2052,9 @@ Tk_SetWindowBackgroundPixmap(tkwin, pixmap)
}
void
-Tk_SetWindowBorder(tkwin, pixel)
- Tk_Window tkwin; /* Window to manipulate. */
- unsigned long pixel; /* Pixel value to use for
- * window's border. */
+Tk_SetWindowBorder(
+ Tk_Window tkwin, /* Window to manipulate. */
+ unsigned long pixel) /* Pixel value to use for window's border. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -2088,10 +2069,9 @@ Tk_SetWindowBorder(tkwin, pixel)
}
void
-Tk_SetWindowBorderPixmap(tkwin, pixmap)
- Tk_Window tkwin; /* Window to manipulate. */
- Pixmap pixmap; /* Pixmap to use for window's
- * border. */
+Tk_SetWindowBorderPixmap(
+ Tk_Window tkwin, /* Window to manipulate. */
+ Pixmap pixmap) /* Pixmap to use for window's border. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -2107,9 +2087,9 @@ Tk_SetWindowBorderPixmap(tkwin, pixmap)
}
void
-Tk_DefineCursor(tkwin, cursor)
- Tk_Window tkwin; /* Window to manipulate. */
- Tk_Cursor cursor; /* Cursor to use for window (may be None). */
+Tk_DefineCursor(
+ Tk_Window tkwin, /* Window to manipulate. */
+ Tk_Cursor cursor) /* Cursor to use for window (may be None). */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -2127,16 +2107,16 @@ Tk_DefineCursor(tkwin, cursor)
}
void
-Tk_UndefineCursor(tkwin)
- Tk_Window tkwin; /* Window to manipulate. */
+Tk_UndefineCursor(
+ Tk_Window tkwin) /* Window to manipulate. */
{
Tk_DefineCursor(tkwin, None);
}
void
-Tk_SetWindowColormap(tkwin, colormap)
- Tk_Window tkwin; /* Window to manipulate. */
- Colormap colormap; /* Colormap to use for window. */
+Tk_SetWindowColormap(
+ Tk_Window tkwin, /* Window to manipulate. */
+ Colormap colormap) /* Colormap to use for window. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -2158,14 +2138,14 @@ Tk_SetWindowColormap(tkwin, colormap)
*
* Tk_SetWindowVisual --
*
- * This procedure is called to specify a visual to be used
- * for a Tk window when it is created. This procedure, if
- * called at all, must be called before the X window is created
- * (i.e. before Tk_MakeWindowExist is called).
+ * This function is called to specify a visual to be used for a Tk window
+ * when it is created. This function, if called at all, must be called
+ * before the X window is created (i.e. before Tk_MakeWindowExist is
+ * called).
*
* Results:
- * The return value is 1 if successful, or 0 if the X window has
- * been already created.
+ * The return value is 1 if successful, or 0 if the X window has been
+ * already created.
*
* Side effects:
* The information given is stored for when the window is created.
@@ -2174,15 +2154,15 @@ Tk_SetWindowColormap(tkwin, colormap)
*/
int
-Tk_SetWindowVisual(tkwin, visual, depth, colormap)
- Tk_Window tkwin; /* Window to manipulate. */
- Visual *visual; /* New visual for window. */
- int depth; /* New depth for window. */
- Colormap colormap; /* An appropriate colormap for the visual. */
+Tk_SetWindowVisual(
+ Tk_Window tkwin, /* Window to manipulate. */
+ Visual *visual, /* New visual for window. */
+ int depth, /* New depth for window. */
+ Colormap colormap) /* An appropriate colormap for the visual. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
- if( winPtr->window != None ){
+ if (winPtr->window != None) {
/* Too late! */
return 0;
}
@@ -2209,8 +2189,8 @@ Tk_SetWindowVisual(tkwin, visual, depth, colormap)
*
* TkDoConfigureNotify --
*
- * Generate a ConfigureNotify event describing the current
- * configuration of a window.
+ * Generate a ConfigureNotify event describing the current configuration
+ * of a window.
*
* Results:
* None.
@@ -2222,9 +2202,9 @@ Tk_SetWindowVisual(tkwin, visual, depth, colormap)
*/
void
-TkDoConfigureNotify(winPtr)
- register TkWindow *winPtr; /* Window whose configuration
- * was just changed. */
+TkDoConfigureNotify(
+ register TkWindow *winPtr) /* Window whose configuration was just
+ * changed. */
{
XEvent event;
@@ -2253,22 +2233,21 @@ TkDoConfigureNotify(winPtr)
*
* Tk_SetClass --
*
- * This procedure is used to give a window a class.
+ * This function is used to give a window a class.
*
* Results:
* None.
*
* Side effects:
- * A new class is stored for tkwin, replacing any existing
- * class for it.
+ * A new class is stored for tkwin, replacing any existing class for it.
*
*----------------------------------------------------------------------
*/
void
-Tk_SetClass(tkwin, className)
- Tk_Window tkwin; /* Token for window to assign class. */
- CONST char *className; /* New class for tkwin. */
+Tk_SetClass(
+ Tk_Window tkwin, /* Token for window to assign class. */
+ CONST char *className) /* New class for tkwin. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -2284,24 +2263,24 @@ Tk_SetClass(tkwin, className)
*
* Tk_SetClassProcs --
*
- * This procedure is used to set the class procedures and
- * instance data for a window.
+ * This function is used to set the class functions and instance data for
+ * a window.
*
* Results:
* None.
*
* Side effects:
- * A new set of class procedures and instance data is stored
- * for tkwin, replacing any existing values.
+ * A new set of class functions and instance data is stored for tkwin,
+ * replacing any existing values.
*
*----------------------------------------------------------------------
*/
void
-Tk_SetClassProcs(tkwin, procs, instanceData)
- Tk_Window tkwin; /* Token for window to modify. */
- Tk_ClassProcs *procs; /* Class procs structure. */
- ClientData instanceData; /* Data to be passed to class procedures. */
+Tk_SetClassProcs(
+ Tk_Window tkwin, /* Token for window to modify. */
+ Tk_ClassProcs *procs, /* Class procs structure. */
+ ClientData instanceData) /* Data to be passed to class functions. */
{
register TkWindow *winPtr = (TkWindow *) tkwin;
@@ -2314,14 +2293,14 @@ Tk_SetClassProcs(tkwin, procs, instanceData)
*
* Tk_NameToWindow --
*
- * Given a string name for a window, this procedure
- * returns the token for the window, if there exists a
- * window corresponding to the given name.
+ * Given a string name for a window, this function returns the token for
+ * the window, if there exists a window corresponding to the given name.
*
* 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 the interp's result.
+ * 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 the interp's result, unless interp
+ * is NULL.
*
* Side effects:
* None.
@@ -2330,28 +2309,33 @@ Tk_SetClassProcs(tkwin, procs, instanceData)
*/
Tk_Window
-Tk_NameToWindow(interp, pathName, tkwin)
- Tcl_Interp *interp; /* Where to report errors. */
- CONST char *pathName; /* Path name of window. */
- Tk_Window tkwin; /* Token for window: name is assumed to
- * belong to the same main window as tkwin. */
+Tk_NameToWindow(
+ Tcl_Interp *interp, /* Where to report errors. */
+ CONST char *pathName, /* Path name of window. */
+ Tk_Window tkwin) /* Token for window: name is assumed to belong
+ * to the same main window as tkwin. */
{
Tcl_HashEntry *hPtr;
if (tkwin == NULL) {
/*
* Either we're not really in Tk, or the main window was destroyed and
- * we're on our way out of the application
+ * we're on our way out of the application.
*/
- Tcl_AppendResult(interp, "NULL main window", (char *)NULL);
+
+ if (interp != NULL) {
+ Tcl_AppendResult(interp, "NULL main window", NULL);
+ }
return NULL;
}
hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->nameTable,
pathName);
if (hPtr == NULL) {
- Tcl_AppendResult(interp, "bad window path name \"",
- pathName, "\"", (char *) NULL);
+ if (interp != NULL) {
+ Tcl_AppendResult(interp, "bad window path name \"",
+ pathName, "\"", NULL);
+ }
return NULL;
}
return (Tk_Window) Tcl_GetHashValue(hPtr);
@@ -2362,14 +2346,13 @@ Tk_NameToWindow(interp, pathName, tkwin)
*
* Tk_IdToWindow --
*
- * Given an X display and window ID, this procedure returns the
- * Tk token for the window, if there exists a Tk window corresponding
- * to the given ID.
+ * Given an X display and window ID, this function returns the Tk token
+ * for the window, if there exists a Tk window corresponding to the given
+ * ID.
*
* Results:
- * The return result is either a token for the window corresponding
- * to the given X id, or else NULL to indicate that there is no such
- * window.
+ * The return result is either a token for the window corresponding to
+ * the given X id, or else NULL to indicate that there is no such window.
*
* Side effects:
* None.
@@ -2378,9 +2361,9 @@ Tk_NameToWindow(interp, pathName, tkwin)
*/
Tk_Window
-Tk_IdToWindow(display, window)
- Display *display; /* X display containing the window. */
- Window window; /* X window window id. */
+Tk_IdToWindow(
+ Display *display, /* X display containing the window. */
+ Window window) /* X window window id. */
{
TkDisplay *dispPtr;
Tcl_HashEntry *hPtr;
@@ -2409,8 +2392,8 @@ Tk_IdToWindow(display, window)
* Return the textual name of a window's display.
*
* Results:
- * The return value is the string name of the display associated
- * with tkwin.
+ * The return value is the string name of the display associated with
+ * tkwin.
*
* Side effects:
* None.
@@ -2419,8 +2402,8 @@ Tk_IdToWindow(display, window)
*/
CONST char *
-Tk_DisplayName(tkwin)
- Tk_Window tkwin; /* Window whose display name is desired. */
+Tk_DisplayName(
+ Tk_Window tkwin) /* Window whose display name is desired. */
{
return ((TkWindow *) tkwin)->dispPtr->name;
}
@@ -2428,10 +2411,35 @@ Tk_DisplayName(tkwin)
/*
*----------------------------------------------------------------------
*
+ * Tk_Interp --
+ *
+ * Get the Tcl interpreter from a Tk window.
+ *
+ * Results:
+ * A pointer to the interpreter or NULL.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Interp *
+Tk_Interp(
+ Tk_Window tkwin)
+{
+ if (tkwin != NULL && ((TkWindow *)tkwin)->mainPtr != NULL) {
+ return ((TkWindow *)tkwin)->mainPtr->interp;
+ }
+ return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* UnlinkWindow --
*
- * This procedure removes a window from the childList of its
- * parent.
+ * This function removes a window from the childList of its parent.
*
* Results:
* None.
@@ -2443,8 +2451,8 @@ Tk_DisplayName(tkwin)
*/
static void
-UnlinkWindow(winPtr)
- TkWindow *winPtr; /* Child window to be unlinked. */
+UnlinkWindow(
+ TkWindow *winPtr) /* Child window to be unlinked. */
{
TkWindow *prevPtr;
@@ -2461,7 +2469,7 @@ UnlinkWindow(winPtr)
while (prevPtr->nextPtr != winPtr) {
prevPtr = prevPtr->nextPtr;
if (prevPtr == NULL) {
- panic("UnlinkWindow couldn't find child in parent");
+ Tcl_Panic("UnlinkWindow couldn't find child in parent");
}
}
prevPtr->nextPtr = winPtr->nextPtr;
@@ -2479,9 +2487,8 @@ UnlinkWindow(winPtr)
* Change a window's position in the stacking order.
*
* Results:
- * TCL_OK is normally returned. If other is not a descendant
- * of tkwin's parent then TCL_ERROR is returned and tkwin is
- * not repositioned.
+ * TCL_OK is normally returned. If other is not a descendant of tkwin's
+ * parent then TCL_ERROR is returned and tkwin is not repositioned.
*
* Side effects:
* Tkwin is repositioned in the stacking order.
@@ -2490,23 +2497,23 @@ UnlinkWindow(winPtr)
*/
int
-Tk_RestackWindow(tkwin, aboveBelow, other)
- Tk_Window tkwin; /* Token for window whose position in
- * the stacking order is to change. */
- int aboveBelow; /* Indicates new position of tkwin relative
- * to other; must be Above or Below. */
- Tk_Window other; /* Tkwin will be moved to a position that
- * puts it just above or below this window.
- * If NULL then tkwin goes above or below
- * all windows in the same parent. */
+Tk_RestackWindow(
+ Tk_Window tkwin, /* Token for window whose position in the
+ * stacking order is to change. */
+ int aboveBelow, /* Indicates new position of tkwin relative to
+ * other; must be Above or Below. */
+ Tk_Window other) /* Tkwin will be moved to a position that puts
+ * it just above or below this window. If NULL
+ * then tkwin goes above or below all windows
+ * in the same parent. */
{
TkWindow *winPtr = (TkWindow *) tkwin;
TkWindow *otherPtr = (TkWindow *) other;
/*
- * Special case: if winPtr is a top-level window then just find
- * the top-level ancestor of otherPtr and restack winPtr above
- * otherPtr without changing any of Tk's childLists.
+ * Special case: if winPtr is a top-level window then just find the
+ * top-level ancestor of otherPtr and restack winPtr above otherPtr
+ * without changing any of Tk's childLists.
*/
if (winPtr->flags & TK_WIN_MANAGED) {
@@ -2523,7 +2530,7 @@ Tk_RestackWindow(tkwin, aboveBelow, other)
if (winPtr->parentPtr == NULL) {
/*
- * Window is going to be deleted shortly; don't do anything.
+ * Window is going to be deleted shortly; don't do anything.
*/
return TCL_OK;
@@ -2573,10 +2580,9 @@ Tk_RestackWindow(tkwin, aboveBelow, other)
}
/*
- * Notify the X server of the change. If winPtr hasn't yet been
- * created then there's no need to tell the X server now, since
- * the stacking order will be handled properly when the window
- * is finally created.
+ * Notify the X server of the change. If winPtr hasn't yet been created
+ * then there's no need to tell the X server now, since the stacking order
+ * will be handled properly when the window is finally created.
*/
if (winPtr->window != None) {
@@ -2608,9 +2614,9 @@ Tk_RestackWindow(tkwin, aboveBelow, other)
* Returns the main window for an application.
*
* 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 the interp's result.
+ * 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 the interp's result.
*
* Side effects:
* None.
@@ -2619,10 +2625,9 @@ Tk_RestackWindow(tkwin, aboveBelow, other)
*/
Tk_Window
-Tk_MainWindow(interp)
- Tcl_Interp *interp; /* Interpreter that embodies the
- * application. Used for error
- * reporting also. */
+Tk_MainWindow(
+ Tcl_Interp *interp) /* Interpreter that embodies the application.
+ * Used for error reporting also. */
{
TkMainInfo *mainPtr;
ThreadSpecificData *tsdPtr;
@@ -2653,14 +2658,14 @@ Tk_MainWindow(interp)
*
* Tk_StrictMotif --
*
- * Indicates whether strict Motif compliance has been specified
- * for the given window.
+ * Indicates whether strict Motif compliance has been specified for the
+ * given window.
*
* Results:
- * The return value is 1 if strict Motif compliance has been
- * requested for tkwin's application by setting the tk_strictMotif
- * variable in its interpreter to a true value. 0 is returned
- * if tk_strictMotif has a false value.
+ * The return value is 1 if strict Motif compliance has been requested
+ * for tkwin's application by setting the tk_strictMotif variable in its
+ * interpreter to a true value. 0 is returned if tk_strictMotif has a
+ * false value.
*
* Side effects:
* None.
@@ -2669,9 +2674,9 @@ Tk_MainWindow(interp)
*/
int
-Tk_StrictMotif(tkwin)
- Tk_Window tkwin; /* Window whose application is
- * to be checked. */
+Tk_StrictMotif(
+ Tk_Window tkwin) /* Window whose application is to be
+ * checked. */
{
return ((TkWindow *) tkwin)->mainPtr->strictMotif;
}
@@ -2681,8 +2686,8 @@ Tk_StrictMotif(tkwin)
*
* Tk_GetNumMainWindows --
*
- * This procedure returns the number of main windows currently
- * open in this process.
+ * This function returns the number of main windows currently open in
+ * this process.
*
* Results:
* The number of main windows open in this process.
@@ -2694,7 +2699,7 @@ Tk_StrictMotif(tkwin)
*/
int
-Tk_GetNumMainWindows()
+Tk_GetNumMainWindows(void)
{
ThreadSpecificData *tsdPtr;
@@ -2705,7 +2710,7 @@ Tk_GetNumMainWindows()
#endif
tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
return tsdPtr->numMainWindows;
}
@@ -2731,9 +2736,9 @@ Tk_GetNumMainWindows()
*/
int
-TkpAlwaysShowSelection(tkwin)
- Tk_Window tkwin; /* Window whose application is
- * to be checked. */
+TkpAlwaysShowSelection(
+ Tk_Window tkwin) /* Window whose application is to be
+ * checked. */
{
return ((TkWindow *) tkwin)->mainPtr->alwaysShowSelection;
}
@@ -2743,11 +2748,10 @@ TkpAlwaysShowSelection(tkwin)
*
* DeleteWindowsExitProc --
*
- * This procedure is invoked as an exit handler. It deletes all
- * of the main windows in the current thread. We really should
- * be using a thread local exit handler to delete windows and a
- * process exit handler to close the display but Tcl does
- * not provide support for this usage.
+ * This function is invoked as an exit handler. It deletes all of the
+ * main windows in the current thread. We really should be using a thread
+ * local exit handler to delete windows and a process exit handler to
+ * close the display but Tcl does not provide support for this usage.
*
* Results:
* None.
@@ -2759,30 +2763,32 @@ TkpAlwaysShowSelection(tkwin)
*/
static void
-DeleteWindowsExitProc(clientData)
- ClientData clientData; /* tsdPtr when handler was created. */
+DeleteWindowsExitProc(
+ ClientData clientData) /* tsdPtr when handler was created. */
{
TkDisplay *dispPtr, *nextPtr;
Tcl_Interp *interp;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData;
+ if (tsdPtr == NULL) {
+ return;
+ }
+
/*
- * Finish destroying any windows that are in a
- * half-dead state. We must protect the interpreter
- * while destroying the window, because of <Destroy>
- * bindings which could destroy the interpreter
- * while the window is being deleted. This would
- * leave frames on the call stack pointing at
+ * Finish destroying any windows that are in a half-dead state. We must
+ * protect the interpreter while destroying the window, because of
+ * <Destroy> bindings which could destroy the interpreter while the window
+ * is being deleted. This would leave frames on the call stack pointing at
* deleted memory, causing core dumps.
*/
while (tsdPtr->halfdeadWindowList != NULL) {
- interp = tsdPtr->halfdeadWindowList->winPtr->mainPtr->interp;
- Tcl_Preserve((ClientData) interp);
- tsdPtr->halfdeadWindowList->flags |= HD_CLEANUP;
- tsdPtr->halfdeadWindowList->winPtr->flags &= ~TK_ALREADY_DEAD;
- Tk_DestroyWindow((Tk_Window) tsdPtr->halfdeadWindowList->winPtr);
- Tcl_Release((ClientData) interp);
+ interp = tsdPtr->halfdeadWindowList->winPtr->mainPtr->interp;
+ Tcl_Preserve((ClientData) interp);
+ tsdPtr->halfdeadWindowList->flags |= HD_CLEANUP;
+ tsdPtr->halfdeadWindowList->winPtr->flags &= ~TK_ALREADY_DEAD;
+ Tk_DestroyWindow((Tk_Window) tsdPtr->halfdeadWindowList->winPtr);
+ Tcl_Release((ClientData) interp);
}
/*
@@ -2790,36 +2796,34 @@ DeleteWindowsExitProc(clientData)
*/
while (tsdPtr->mainWindowList != NULL) {
- interp = tsdPtr->mainWindowList->interp;
- Tcl_Preserve((ClientData) interp);
- Tk_DestroyWindow((Tk_Window) tsdPtr->mainWindowList->winPtr);
- Tcl_Release((ClientData) interp);
+ interp = tsdPtr->mainWindowList->interp;
+ Tcl_Preserve((ClientData) interp);
+ Tk_DestroyWindow((Tk_Window) tsdPtr->mainWindowList->winPtr);
+ Tcl_Release((ClientData) interp);
}
/*
- * Iterate destroying the displays until no more displays remain.
- * It is possible for displays to get recreated during exit by any
- * code that calls GetScreen, so we must destroy these new displays
- * as well as the old ones.
+ * Iterate destroying the displays until no more displays remain. It is
+ * possible for displays to get recreated during exit by any code that
+ * calls GetScreen, so we must destroy these new displays as well as the
+ * old ones.
*/
- for (dispPtr = tsdPtr->displayList;
- dispPtr != NULL;
- dispPtr = tsdPtr->displayList) {
- /*
- * Now iterate over the current list of open displays, and first
- * set the global pointer to NULL so we will be able to notice if
- * any new displays got created during deletion of the current set.
- * We must also do this to ensure that Tk_IdToWindow does not find
- * the old display as it is being destroyed, when it wants to see
- * if it needs to dispatch a message.
- */
-
- for (tsdPtr->displayList = NULL; dispPtr != NULL;
- dispPtr = nextPtr) {
- nextPtr = dispPtr->nextPtr;
- TkCloseDisplay(dispPtr);
- }
+ for (dispPtr = tsdPtr->displayList; dispPtr != NULL;
+ dispPtr = tsdPtr->displayList) {
+ /*
+ * Now iterate over the current list of open displays, and first set
+ * the global pointer to NULL so we will be able to notice if any new
+ * displays got created during deletion of the current set. We must
+ * also do this to ensure that Tk_IdToWindow does not find the old
+ * display as it is being destroyed, when it wants to see if it needs
+ * to dispatch a message.
+ */
+
+ for (tsdPtr->displayList = NULL; dispPtr != NULL; dispPtr = nextPtr) {
+ nextPtr = dispPtr->nextPtr;
+ TkCloseDisplay(dispPtr);
+ }
}
tsdPtr->numMainWindows = 0;
@@ -2877,18 +2881,17 @@ TkCygwinMainEx(argc, argv, appInitProc, interp)
*
* Tk_Init --
*
- * This procedure is invoked to add Tk to an interpreter. It
- * incorporates all of Tk's commands into the interpreter and
- * creates the main window for a new Tk application. If the
- * interpreter contains a variable "argv", this procedure
- * extracts several arguments from that variable, uses them
- * to configure the main window, and modifies argv to exclude
- * the arguments (see the "wish" documentation for a list of
- * the arguments that are extracted).
+ * This function is invoked to add Tk to an interpreter. It incorporates
+ * all of Tk's commands into the interpreter and creates the main window
+ * for a new Tk application. If the interpreter contains a variable
+ * "argv", this function extracts several arguments from that variable,
+ * uses them to configure the main window, and modifies argv to exclude
+ * the arguments (see the "wish" documentation for a list of the
+ * arguments that are extracted).
*
* Results:
- * Returns a standard Tcl completion code and sets the interp's result
- * if there is an error.
+ * Returns a standard Tcl completion code and sets the interp's result if
+ * there is an error.
*
* Side effects:
* Depends on various initialization scripts that get invoked.
@@ -2897,8 +2900,8 @@ TkCygwinMainEx(argc, argv, appInitProc, interp)
*/
int
-Tk_Init(interp)
- Tcl_Interp *interp; /* Interpreter to initialize. */
+Tk_Init(
+ Tcl_Interp *interp) /* Interpreter to initialize. */
{
#if defined(__WIN32__) && !defined(__WIN64__)
if (tkcygwindll) {
@@ -2918,12 +2921,12 @@ Tk_Init(interp)
*
* Tk_SafeInit --
*
- * This procedure is invoked to add Tk to a safe interpreter. It
- * invokes the internal procedure that does the real work.
+ * This function is invoked to add Tk to a safe interpreter. It invokes
+ * the internal function that does the real work.
*
* Results:
- * Returns a standard Tcl completion code and sets the interp's result
- * if there is an error.
+ * Returns a standard Tcl completion code and sets the interp's result if
+ * there is an error.
*
* Side effects:
* Depends on various initialization scripts that are invoked.
@@ -2932,44 +2935,45 @@ Tk_Init(interp)
*/
int
-Tk_SafeInit(interp)
- Tcl_Interp *interp; /* Interpreter to initialize. */
+Tk_SafeInit(
+ Tcl_Interp *interp) /* Interpreter to initialize. */
{
/*
- * Initialize the interpreter with Tk, safely. This removes
- * all the Tk commands that are unsafe.
+ * Initialize the interpreter with Tk, safely. This removes all the Tk
+ * commands that are unsafe.
*
* Rationale:
*
- * - Toplevel and menu are unsafe because they can be used to cover
- * the entire screen and to steal input from the user.
+ * - Toplevel and menu are unsafe because they can be used to cover the
+ * entire screen and to steal input from the user.
* - Continuous ringing of the bell is a nuisance.
- * - Cannot allow access to the clipboard because a malicious script
- * can replace the contents with the string "rm -r *" and lead to
- * surprises when the contents of the clipboard are pasted. Similarly,
- * the selection command is blocked.
- * - Cannot allow send because it can be used to cause unsafe
- * interpreters to execute commands. The tk command recreates the
- * send command, so that too must be hidden.
- * - Focus can be used to grab the focus away from another window,
- * in effect stealing user input. Cannot allow that.
- * NOTE: We currently do *not* hide focus as it would make it
- * impossible to provide keyboard input to Tk in a safe interpreter.
- * - Grab can be used to block the user from using any other apps
- * on the screen.
+ * - Cannot allow access to the clipboard because a malicious script can
+ * replace the contents with the string "rm -r *" and lead to surprises
+ * when the contents of the clipboard are pasted. Similarly, the
+ * selection command is blocked.
+ * - Cannot allow send because it can be used to cause unsafe interpreters
+ * to execute commands. The tk command recreates the send command, so
+ * that too must be hidden.
+ * - Focus can be used to grab the focus away from another window, in
+ * effect stealing user input. Cannot allow that.
+ * NOTE: We currently do *not* hide focus as it would make it impossible
+ * to provide keyboard input to Tk in a safe interpreter.
+ * - Grab can be used to block the user from using any other apps on the
+ * screen.
* - Tkwait can block the containing process forever. Use bindings,
* fileevents and split the protocol into before-the-wait and
* after-the-wait parts. More work but necessary.
- * - Wm is unsafe because (if toplevels are allowed, in the future)
- * it can be used to remove decorations, move windows around, cover
- * the entire screen etc etc.
+ * - Wm is unsafe because (if toplevels are allowed, in the future) it can
+ * be used to remove decorations, move windows around, cover the entire
+ * screen etc etc.
*
* Current risks:
*
* - No CPU time limit, no memory allocation limits, no color limits.
+ * CPU time limits can be imposed by an unsafe master interpreter.
*
- * The actual code called is the same as Tk_Init but Tcl_IsSafe()
- * is checked at several places to differentiate the two initialisations.
+ * The actual code called is the same as Tk_Init but Tcl_IsSafe() is
+ * checked at several places to differentiate the two initialisations.
*/
#if defined(__WIN32__) && !defined(__WIN64__)
@@ -2985,7 +2989,6 @@ Tk_SafeInit(interp)
return Initialize(interp);
}
-
extern TkStubs tkStubs;
/*
@@ -2993,6 +2996,7 @@ extern TkStubs tkStubs;
*
* Initialize --
*
+ * ???TODO???
*
* Results:
* A standard Tcl result. Also leaves an error message in the interp's
@@ -3005,8 +3009,8 @@ extern TkStubs tkStubs;
*/
static int
-Initialize(interp)
- Tcl_Interp *interp; /* Interpreter to initialize. */
+Initialize(
+ Tcl_Interp *interp) /* Interpreter to initialize. */
{
char *p;
int argc, code;
@@ -3017,20 +3021,21 @@ Initialize(interp)
ThreadSpecificData *tsdPtr;
/*
- * Ensure that we are getting the matching version of Tcl.
+ * Ensure that we are getting a compatible version of Tcl.
*/
- if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
- return TCL_ERROR;
+ if (Tcl_InitStubs(interp, "8.5.0", 0) == NULL) {
+ return TCL_ERROR;
}
/*
* Ensure that our obj-types are registered with the Tcl runtime.
*/
+
TkRegisterObjTypes();
tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
* Start by initializing all the static variables to default acceptable
@@ -3052,27 +3057,30 @@ Initialize(interp)
/*
* We start by resetting the result because it might not be clean
*/
+
Tcl_ResetResult(interp);
if (Tcl_IsSafe(interp)) {
/*
- * Get the clearance to start Tk and the "argv" parameters
- * from the master.
+ * Get the clearance to start Tk and the "argv" parameters from the
+ * master.
*/
+
Tcl_DString ds;
/*
- * Step 1 : find the master and construct the interp name
- * (could be a function if new APIs were ok).
- * We could also construct the path while walking, but there
- * is no API to get the name of an interp either.
+ * Step 1 : find the master and construct the interp name (could be a
+ * function if new APIs were ok). We could also construct the path
+ * while walking, but there is no API to get the name of an interp
+ * either.
*/
+
Tcl_Interp *master = interp;
while (1) {
master = Tcl_GetMaster(master);
if (master == NULL) {
- Tcl_AppendResult(interp, "NULL master", (char *) NULL);
+ Tcl_AppendResult(interp, "NULL master", NULL);
code = TCL_ERROR;
goto done;
}
@@ -3081,59 +3089,65 @@ Initialize(interp)
break;
}
}
+
/*
* Construct the name (rewalk...)
*/
- if ((code = Tcl_GetInterpPath(master, interp)) != TCL_OK) {
- Tcl_AppendResult(interp, "error in Tcl_GetInterpPath",
- (char *) NULL);
+
+ code = Tcl_GetInterpPath(master, interp);
+ if (code != TCL_OK) {
+ Tcl_AppendResult(interp, "error in Tcl_GetInterpPath", NULL);
goto done;
}
+
/*
* Build the string to eval.
*/
+
Tcl_DStringInit(&ds);
Tcl_DStringAppendElement(&ds, "::safe::TkInit");
Tcl_DStringAppendElement(&ds, Tcl_GetStringResult(master));
/*
- * Step 2 : Eval in the master. The argument is the *reversed*
- * interp path of the slave.
+ * Step 2 : Eval in the master. The argument is the *reversed* interp
+ * path of the slave.
*/
- if ((code = Tcl_Eval(master, Tcl_DStringValue(&ds))) != TCL_OK) {
+ code = Tcl_Eval(master, Tcl_DStringValue(&ds));
+ if (code != TCL_OK) {
/*
- * We might want to transfer the error message or not.
- * We don't. (no API to do it and maybe security reasons).
+ * We might want to transfer the error message or not. We don't.
+ * (No API to do it and maybe security reasons).
*/
+
Tcl_DStringFree(&ds);
Tcl_AppendResult(interp,
- "not allowed to start Tk by master's safe::TkInit",
- (char *) NULL);
+ "not allowed to start Tk by master's safe::TkInit", NULL);
goto done;
}
Tcl_DStringFree(&ds);
+
/*
- * Use the master's result as argv.
- * Note: We don't use the Obj interfaces to avoid dealing with
- * cross interp refcounting and changing the code below.
+ * Use the master's result as argv. Note: We don't use the Obj
+ * interfaces to avoid dealing with cross interp refcounting and
+ * changing the code below.
*/
argString = Tcl_GetStringResult(master);
} else {
/*
- * If there is an "argv" variable, get its value, extract out
- * relevant arguments from it, and rewrite the variable without
- * the arguments that we used.
+ * If there is an "argv" variable, get its value, extract out relevant
+ * arguments from it, and rewrite the variable without the arguments
+ * that we used.
*/
- argString = Tcl_GetVar2(interp, "argv", (char *) NULL, TCL_GLOBAL_ONLY);
+ argString = Tcl_GetVar2(interp, "argv", NULL, TCL_GLOBAL_ONLY);
}
if (argString != NULL) {
char buffer[TCL_INTEGER_SPACE];
if (Tcl_SplitList(interp, argString, &argc, &argv) != TCL_OK) {
- argError:
+ argError:
Tcl_AddErrorInfo(interp,
"\n (processing arguments in argv variable)");
code = TCL_ERROR;
@@ -3145,9 +3159,9 @@ Initialize(interp)
goto argError;
}
p = Tcl_Merge(argc, argv);
- Tcl_SetVar2(interp, "argv", (char *) NULL, p, TCL_GLOBAL_ONLY);
+ Tcl_SetVar2(interp, "argv", NULL, p, TCL_GLOBAL_ONLY);
sprintf(buffer, "%d", argc);
- Tcl_SetVar2(interp, "argc", (char *) NULL, buffer, TCL_GLOBAL_ONLY);
+ Tcl_SetVar2(interp, "argc", NULL, buffer, TCL_GLOBAL_ONLY);
ckfree(p);
}
@@ -3158,6 +3172,7 @@ Initialize(interp)
Tcl_DStringInit(&class);
if (name == NULL) {
int offset;
+
TkpGetAppName(interp, &class);
offset = Tcl_DStringLength(&class)+1;
Tcl_DStringSetLength(&class, offset);
@@ -3173,8 +3188,8 @@ Initialize(interp)
}
/*
- * Create an argument list for creating the top-level window,
- * using the information parsed from argv, if any.
+ * Create an argument list for creating the top-level window, using the
+ * information parsed from argv, if any.
*/
args[0] = "toplevel";
@@ -3188,9 +3203,9 @@ Initialize(interp)
argc += 2;
/*
- * If this is the first application for this process, save
- * the display name in the DISPLAY environment variable so
- * that it will be available to subprocesses created by us.
+ * If this is the first application for this process, save the display
+ * name in the DISPLAY environment variable so that it will be
+ * available to subprocesses created by us.
*/
if (tsdPtr->numMainWindows == 0) {
@@ -3201,19 +3216,19 @@ Initialize(interp)
args[argc] = "-colormap";
args[argc+1] = colormap;
argc += 2;
- colormap = NULL;
+ colormap = NULL;
}
if (use != NULL) {
args[argc] = "-use";
args[argc+1] = use;
argc += 2;
- use = NULL;
+ use = NULL;
}
if (visual != NULL) {
args[argc] = "-visual";
args[argc+1] = visual;
argc += 2;
- visual = NULL;
+ visual = NULL;
}
args[argc] = NULL;
code = TkCreateFrame((ClientData) NULL, interp, argc, args, 1, name);
@@ -3228,58 +3243,153 @@ Initialize(interp)
}
/*
- * Set the geometry of the main window, if requested. Put the
- * requested geometry into the "geometry" variable.
+ * Set the geometry of the main window, if requested. Put the requested
+ * geometry into the "geometry" variable.
*/
if (geometry != NULL) {
Tcl_SetVar(interp, "geometry", geometry, TCL_GLOBAL_ONLY);
- code = Tcl_VarEval(interp, "wm geometry . ", geometry, (char *) NULL);
+ code = Tcl_VarEval(interp, "wm geometry . ", geometry, NULL);
if (code != TCL_OK) {
goto done;
}
- geometry = NULL;
+ geometry = NULL;
}
/*
* Provide Tk and its stub table.
*/
- code = Tcl_PkgProvideEx(interp, "Tk", TK_VERSION, (ClientData) &tkStubs);
+ code = Tcl_PkgProvideEx(interp, "Tk", TK_PATCH_LEVEL,
+ (ClientData) &tkStubs);
if (code != TCL_OK) {
goto done;
- } else {
- /*
- * If we were able to provide ourselves as a package, then set
- * the main loop procedure in Tcl to our main loop proc. This
- * will cause tclsh to be event-aware when Tk is dynamically
- * loaded. This will have no effect in wish, which already is
- * prepared to run the event loop.
- */
-
- Tcl_SetMainLoop(Tk_MainLoop);
}
+ /*
+ * If we were able to provide ourselves as a package, then set the main
+ * loop function in Tcl to our main loop proc. This will cause tclsh to be
+ * event-aware when Tk is dynamically loaded. This will have no effect in
+ * wish, which already is prepared to run the event loop.
+ */
+
+ Tcl_SetMainLoop(Tk_MainLoop);
+
#undef Tk_InitStubs
Tk_InitStubs(interp, TK_VERSION, 1);
/*
- * Invoke platform-specific initialization.
- * Unlock mutex before entering TkpInit, as that may run through the
- * Tk_Init routine again for the console window interpreter.
+ * Initialized the themed widget set
+ */
+
+ code = Ttk_Init(interp);
+ if (code != TCL_OK) {
+ goto done;
+ }
+
+ /*
+ * Invoke platform-specific initialization. Unlock mutex before entering
+ * TkpInit, as that may run through the Tk_Init routine again for the
+ * console window interpreter.
*/
Tcl_MutexUnlock(&windowMutex);
if (argv != NULL) {
ckfree((char *) argv);
}
- return TkpInit(interp);
+ code = TkpInit(interp);
+ if (code == TCL_OK) {
+
+ /*
+ * In order to find tk.tcl during initialization, we evaluate the
+ * following script. It calls on the Tcl command [tcl_findLibrary]
+ * to perform the search. See the docs for that command for details
+ * on where it looks.
+ *
+ * Note that this entire search mechanism can be bypassed by defining
+ * an alternate [tkInit] command before calling Tk_Init().
+ */
+
+ code = Tcl_Eval(interp,
+"if {[namespace which -command tkInit] eq \"\"} {\n\
+ proc tkInit {} {\n\
+ global tk_library tk_version tk_patchLevel\n\
+ rename tkInit {}\n\
+ tcl_findLibrary tk $tk_version $tk_patchLevel tk.tcl TK_LIBRARY tk_library\n\
+ }\n\
+}\n\
+tkInit");
+ }
+ if (code == TCL_OK) {
+ /*
+ * Create exit handlers to delete all windows when the application or
+ * thread exits. The handler need to be invoked before other platform
+ * specific cleanups take place to avoid panics in finalization.
+ */
+
+ TkCreateThreadExitHandler(DeleteWindowsExitProc, (ClientData) tsdPtr);
+ }
+ return code;
- done:
+ done:
Tcl_MutexUnlock(&windowMutex);
if (argv != NULL) {
ckfree((char *) argv);
}
return code;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_PkgInitStubsCheck --
+ *
+ * This is a replacement routine for Tk_InitStubs() that is called
+ * from code where -DUSE_TK_STUBS has not been enabled.
+ *
+ * Results:
+ * Returns the version of a conforming Tk stubs table, or NULL, if
+ * the table version doesn't satisfy the requested requirements,
+ * according to historical practice.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+CONST char *
+Tk_PkgInitStubsCheck(
+ Tcl_Interp *interp,
+ CONST char * version,
+ int exact)
+{
+ CONST char *actualVersion = Tcl_PkgRequire(interp, "Tk", version, 0);
+
+ if (exact && actualVersion) {
+ CONST char *p = version;
+ int count = 0;
+
+ while (*p) {
+ count += !isdigit(UCHAR(*p++));
+ }
+ if (count == 1) {
+ if (0 != strncmp(version, actualVersion, strlen(version))) {
+ /* Construct error message */
+ Tcl_PkgPresent(interp, "Tk", version, 1);
+ return NULL;
+ }
+ } else {
+ return Tcl_PkgPresent(interp, "Tk", version, 1);
+ }
+ }
+ return actualVersion;
+}
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/ttk/ttk.decls b/generic/ttk/ttk.decls
new file mode 100644
index 0000000..8b2b50b
--- /dev/null
+++ b/generic/ttk/ttk.decls
@@ -0,0 +1,150 @@
+library ttk
+interface ttk
+epoch 0
+scspec TTKAPI
+
+declare 0 current {
+ Ttk_Theme Ttk_GetTheme(Tcl_Interp *interp, const char *name);
+}
+declare 1 current {
+ Ttk_Theme Ttk_GetDefaultTheme(Tcl_Interp *interp);
+}
+declare 2 current {
+ Ttk_Theme Ttk_GetCurrentTheme(Tcl_Interp *interp);
+}
+declare 3 current {
+ Ttk_Theme Ttk_CreateTheme(
+ Tcl_Interp *interp, const char *name, Ttk_Theme parent);
+}
+declare 4 current {
+ void Ttk_RegisterCleanup(
+ Tcl_Interp *interp, void *deleteData, Ttk_CleanupProc *cleanupProc);
+}
+
+declare 5 current {
+ int Ttk_RegisterElementSpec(
+ Ttk_Theme theme,
+ const char *elementName,
+ Ttk_ElementSpec *elementSpec,
+ void *clientData);
+}
+
+declare 6 current {
+ Ttk_ElementClass *Ttk_RegisterElement(
+ Tcl_Interp *interp,
+ Ttk_Theme theme,
+ const char *elementName,
+ Ttk_ElementSpec *elementSpec,
+ void *clientData);
+}
+
+declare 7 current {
+ int Ttk_RegisterElementFactory(
+ Tcl_Interp *interp,
+ const char *name,
+ Ttk_ElementFactory factoryProc,
+ void *clientData);
+}
+
+declare 8 current {
+ void Ttk_RegisterLayout(
+ Ttk_Theme theme, const char *className, Ttk_LayoutSpec layoutSpec);
+}
+
+#
+# State maps.
+#
+declare 10 current {
+ int Ttk_GetStateSpecFromObj(
+ Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_StateSpec *spec_rtn);
+}
+declare 11 current {
+ Tcl_Obj *Ttk_NewStateSpecObj(
+ unsigned int onbits, unsigned int offbits);
+}
+declare 12 current {
+ Ttk_StateMap Ttk_GetStateMapFromObj(
+ Tcl_Interp *interp, Tcl_Obj *objPtr);
+}
+declare 13 current {
+ Tcl_Obj *Ttk_StateMapLookup(
+ Tcl_Interp *interp, Ttk_StateMap map, Ttk_State state);
+}
+declare 14 current {
+ int Ttk_StateTableLookup(
+ Ttk_StateTable map[], Ttk_State state);
+}
+
+
+#
+# Low-level geometry utilities.
+#
+declare 20 current {
+ int Ttk_GetPaddingFromObj(
+ Tcl_Interp *interp,
+ Tk_Window tkwin,
+ Tcl_Obj *objPtr,
+ Ttk_Padding *pad_rtn);
+}
+declare 21 current {
+ int Ttk_GetBorderFromObj(
+ Tcl_Interp *interp,
+ Tcl_Obj *objPtr,
+ Ttk_Padding *pad_rtn);
+}
+declare 22 current {
+ int Ttk_GetStickyFromObj(
+ Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Sticky *sticky_rtn);
+}
+declare 23 current {
+ Ttk_Padding Ttk_MakePadding(
+ short l, short t, short r, short b);
+}
+declare 24 current {
+ Ttk_Padding Ttk_UniformPadding(
+ short borderWidth);
+}
+declare 25 current {
+ Ttk_Padding Ttk_AddPadding(Ttk_Padding pad1, Ttk_Padding pad2);
+}
+declare 26 current {
+ Ttk_Padding Ttk_RelievePadding(
+ Ttk_Padding padding, int relief, int n);
+}
+declare 27 current {
+ Ttk_Box Ttk_MakeBox(int x, int y, int width, int height);
+}
+declare 28 current {
+ int Ttk_BoxContains(Ttk_Box box, int x, int y);
+}
+declare 29 current {
+ Ttk_Box Ttk_PackBox(Ttk_Box *cavity, int w, int h, Ttk_Side side);
+}
+declare 30 current {
+ Ttk_Box Ttk_StickBox(Ttk_Box parcel, int w, int h, Ttk_Sticky sticky);
+}
+declare 31 current {
+ Ttk_Box Ttk_AnchorBox(Ttk_Box parcel, int w, int h, Tk_Anchor anchor);
+}
+declare 32 current {
+ Ttk_Box Ttk_PadBox(Ttk_Box b, Ttk_Padding p);
+}
+declare 33 current {
+ Ttk_Box Ttk_ExpandBox(Ttk_Box b, Ttk_Padding p);
+}
+declare 34 current {
+ Ttk_Box Ttk_PlaceBox(
+ Ttk_Box *cavity, int w, int h, Ttk_Side side, Ttk_Sticky sticky);
+}
+declare 35 current {
+ Tcl_Obj *Ttk_NewBoxObj(Ttk_Box box);
+}
+
+#
+# Utilities.
+#
+declare 40 current {
+ int Ttk_GetOrientFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *orient);
+}
+
+
diff --git a/generic/ttk/ttkBlink.c b/generic/ttk/ttkBlink.c
new file mode 100644
index 0000000..7e46fac
--- /dev/null
+++ b/generic/ttk/ttkBlink.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2004, Joe English.
+ *
+ * Usage:
+ * TtkBlinkCursor(corePtr), usually called in a widget's Init hook,
+ * arranges to periodically toggle the corePtr->flags CURSOR_ON bit
+ * on and off (and schedule a redisplay) whenever the widget has focus.
+ *
+ * Note: Widgets may have additional logic to decide whether
+ * to display the cursor or not (e.g., readonly or disabled states);
+ * TtkBlinkCursor() does not account for this.
+ *
+ * TODO:
+ * Add script-level access to configure application-wide blink rate.
+ */
+
+#include <tk.h>
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+#define DEF_CURSOR_ON_TIME 600 /* milliseconds */
+#define DEF_CURSOR_OFF_TIME 300 /* milliseconds */
+
+/* Interp-specific data for tracking cursors:
+ */
+typedef struct
+{
+ WidgetCore *owner; /* Widget that currently has cursor */
+ Tcl_TimerToken timer; /* Blink timer */
+ int onTime; /* #milliseconds to blink cursor on */
+ int offTime; /* #milliseconds to blink cursor off */
+} CursorManager;
+
+/* CursorManagerDeleteProc --
+ * InterpDeleteProc for cursor manager.
+ */
+static void CursorManagerDeleteProc(ClientData clientData, Tcl_Interp *interp)
+{
+ CursorManager *cm = (CursorManager*)clientData;
+ if (cm->timer) {
+ Tcl_DeleteTimerHandler(cm->timer);
+ }
+ ckfree(clientData);
+}
+
+/* GetCursorManager --
+ * Look up and create if necessary the interp's cursor manager.
+ */
+static CursorManager *GetCursorManager(Tcl_Interp *interp)
+{
+ static const char *cm_key = "ttk::CursorManager";
+ CursorManager *cm = (CursorManager *) Tcl_GetAssocData(interp, cm_key,0);
+
+ if (!cm) {
+ cm = (CursorManager*)ckalloc(sizeof(*cm));
+ cm->timer = 0;
+ cm->owner = 0;
+ cm->onTime = DEF_CURSOR_ON_TIME;
+ cm->offTime = DEF_CURSOR_OFF_TIME;
+ Tcl_SetAssocData(interp,cm_key,CursorManagerDeleteProc,(ClientData)cm);
+ }
+ return cm;
+}
+
+/* CursorBlinkProc --
+ * Timer handler to blink the insert cursor on and off.
+ */
+static void
+CursorBlinkProc(ClientData clientData)
+{
+ CursorManager *cm = (CursorManager*)clientData;
+ int blinkTime;
+
+ if (cm->owner->flags & CURSOR_ON) {
+ cm->owner->flags &= ~CURSOR_ON;
+ blinkTime = cm->offTime;
+ } else {
+ cm->owner->flags |= CURSOR_ON;
+ blinkTime = cm->onTime;
+ }
+ cm->timer = Tcl_CreateTimerHandler(blinkTime, CursorBlinkProc, clientData);
+ TtkRedisplayWidget(cm->owner);
+}
+
+/* LoseCursor --
+ * Turn cursor off, disable blink timer.
+ */
+static void LoseCursor(CursorManager *cm, WidgetCore *corePtr)
+{
+ if (corePtr->flags & CURSOR_ON) {
+ corePtr->flags &= ~CURSOR_ON;
+ TtkRedisplayWidget(corePtr);
+ }
+ if (cm->owner == corePtr) {
+ cm->owner = NULL;
+ }
+ if (cm->timer) {
+ Tcl_DeleteTimerHandler(cm->timer);
+ cm->timer = 0;
+ }
+}
+
+/* ClaimCursor --
+ * Claim ownership of the insert cursor and blink on.
+ */
+static void ClaimCursor(CursorManager *cm, WidgetCore *corePtr)
+{
+ if (cm->owner == corePtr)
+ return;
+ if (cm->owner)
+ LoseCursor(cm, cm->owner);
+
+ corePtr->flags |= CURSOR_ON;
+ TtkRedisplayWidget(corePtr);
+
+ cm->owner = corePtr;
+ cm->timer = Tcl_CreateTimerHandler(cm->onTime, CursorBlinkProc, cm);
+}
+
+/*
+ * CursorEventProc --
+ * Event handler for FocusIn and FocusOut events;
+ * claim/lose ownership of the insert cursor when the widget
+ * acquires/loses keyboard focus.
+ */
+
+#define CursorEventMask (FocusChangeMask|StructureNotifyMask)
+#define RealFocusEvent(d) \
+ (d == NotifyInferior || d == NotifyAncestor || d == NotifyNonlinear)
+
+static void
+CursorEventProc(ClientData clientData, XEvent *eventPtr)
+{
+ WidgetCore *corePtr = (WidgetCore *)clientData;
+ CursorManager *cm = GetCursorManager(corePtr->interp);
+
+ switch (eventPtr->type) {
+ case DestroyNotify:
+ if (cm->owner == corePtr)
+ LoseCursor(cm, corePtr);
+ Tk_DeleteEventHandler(
+ corePtr->tkwin, CursorEventMask, CursorEventProc, clientData);
+ break;
+ case FocusIn:
+ if (RealFocusEvent(eventPtr->xfocus.detail))
+ ClaimCursor(cm, corePtr);
+ break;
+ case FocusOut:
+ if (RealFocusEvent(eventPtr->xfocus.detail))
+ LoseCursor(cm, corePtr);
+ break;
+ }
+}
+
+/*
+ * TtkBlinkCursor (main routine) --
+ * Arrange to blink the cursor on and off whenever the
+ * widget has focus.
+ */
+void TtkBlinkCursor(WidgetCore *corePtr)
+{
+ Tk_CreateEventHandler(
+ corePtr->tkwin, CursorEventMask, CursorEventProc, corePtr);
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkButton.c b/generic/ttk/ttkButton.c
new file mode 100644
index 0000000..2954184
--- /dev/null
+++ b/generic/ttk/ttkButton.c
@@ -0,0 +1,853 @@
+/*
+ * Copyright (c) 2003, Joe English
+ *
+ * label, button, checkbutton, radiobutton, and menubutton widgets.
+ */
+
+#include <string.h>
+#include <tk.h>
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+/* Bit fields for OptionSpec mask field:
+ */
+#define STATE_CHANGED (0x100) /* -state option changed */
+#define DEFAULTSTATE_CHANGED (0x200) /* -default option changed */
+
+/*------------------------------------------------------------------------
+ * +++ Base resources for labels, buttons, checkbuttons, etc:
+ */
+typedef struct
+{
+ /*
+ * Text element resources:
+ */
+ Tcl_Obj *textObj;
+ Tcl_Obj *textVariableObj;
+ Tcl_Obj *underlineObj;
+ Tcl_Obj *widthObj;
+
+ Ttk_TraceHandle *textVariableTrace;
+ Ttk_ImageSpec *imageSpec;
+
+ /*
+ * Image element resources:
+ */
+ Tcl_Obj *imageObj;
+
+ /*
+ * Compound label/image resources:
+ */
+ Tcl_Obj *compoundObj;
+ Tcl_Obj *paddingObj;
+
+ /*
+ * Compatibility/legacy options:
+ */
+ Tcl_Obj *stateObj;
+
+} BasePart;
+
+typedef struct
+{
+ WidgetCore core;
+ BasePart base;
+} Base;
+
+static Tk_OptionSpec BaseOptionSpecs[] =
+{
+ {TK_OPTION_STRING, "-text", "text", "Text", "",
+ Tk_Offset(Base,base.textObj), -1,
+ 0,0,GEOMETRY_CHANGED },
+ {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", "",
+ Tk_Offset(Base,base.textVariableObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+ {TK_OPTION_INT, "-underline", "underline", "Underline",
+ "-1", Tk_Offset(Base,base.underlineObj), -1,
+ 0,0,0 },
+ /* SB: OPTION_INT, see <<NOTE-NULLOPTIONS>> */
+ {TK_OPTION_STRING, "-width", "width", "Width",
+ NULL, Tk_Offset(Base,base.widthObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+
+ /*
+ * Image options
+ */
+ {TK_OPTION_STRING, "-image", "image", "Image", NULL/*default*/,
+ Tk_Offset(Base,base.imageObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+
+ /*
+ * Compound base/image options
+ */
+ {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
+ "none", Tk_Offset(Base,base.compoundObj), -1,
+ 0,(ClientData)ttkCompoundStrings,GEOMETRY_CHANGED },
+ {TK_OPTION_STRING, "-padding", "padding", "Pad",
+ NULL, Tk_Offset(Base,base.paddingObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED},
+
+ /*
+ * Compatibility/legacy options
+ */
+ {TK_OPTION_STRING, "-state", "state", "State",
+ "normal", Tk_Offset(Base,base.stateObj), -1,
+ 0,0,STATE_CHANGED },
+
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
+};
+
+/*
+ * Variable trace procedure for -textvariable option:
+ */
+static void TextVariableChanged(void *clientData, const char *value)
+{
+ Base *basePtr = clientData;
+ Tcl_Obj *newText;
+
+ if (WidgetDestroyed(&basePtr->core)) {
+ return;
+ }
+
+ newText = value ? Tcl_NewStringObj(value, -1) : Tcl_NewStringObj("", 0);
+
+ Tcl_IncrRefCount(newText);
+ Tcl_DecrRefCount(basePtr->base.textObj);
+ basePtr->base.textObj = newText;
+
+ TtkResizeWidget(&basePtr->core);
+}
+
+static void
+BaseInitialize(Tcl_Interp *interp, void *recordPtr)
+{
+ Base *basePtr = recordPtr;
+ basePtr->base.textVariableTrace = 0;
+ basePtr->base.imageSpec = NULL;
+}
+
+static void
+BaseCleanup(void *recordPtr)
+{
+ Base *basePtr = recordPtr;
+ if (basePtr->base.textVariableTrace)
+ Ttk_UntraceVariable(basePtr->base.textVariableTrace);
+ if (basePtr->base.imageSpec)
+ TtkFreeImageSpec(basePtr->base.imageSpec);
+}
+
+static int BaseConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Base *basePtr = recordPtr;
+ Tcl_Obj *textVarName = basePtr->base.textVariableObj;
+ Ttk_TraceHandle *vt = 0;
+ Ttk_ImageSpec *imageSpec = NULL;
+
+ if (textVarName != NULL && *Tcl_GetString(textVarName) != '\0') {
+ vt = Ttk_TraceVariable(interp,textVarName,TextVariableChanged,basePtr);
+ if (!vt) return TCL_ERROR;
+ }
+
+ if (basePtr->base.imageObj) {
+ imageSpec = TtkGetImageSpec(
+ interp, basePtr->core.tkwin, basePtr->base.imageObj);
+ if (!imageSpec) {
+ goto error;
+ }
+ }
+
+ if (TtkCoreConfigure(interp, recordPtr, mask) != TCL_OK) {
+error:
+ if (imageSpec) TtkFreeImageSpec(imageSpec);
+ if (vt) Ttk_UntraceVariable(vt);
+ return TCL_ERROR;
+ }
+
+ if (basePtr->base.textVariableTrace) {
+ Ttk_UntraceVariable(basePtr->base.textVariableTrace);
+ }
+ basePtr->base.textVariableTrace = vt;
+
+ if (basePtr->base.imageSpec) {
+ TtkFreeImageSpec(basePtr->base.imageSpec);
+ }
+ basePtr->base.imageSpec = imageSpec;
+
+ if (mask & STATE_CHANGED) {
+ TtkCheckStateOption(&basePtr->core, basePtr->base.stateObj);
+ }
+
+ return TCL_OK;
+}
+
+static int
+BasePostConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Base *basePtr = recordPtr;
+ int status = TCL_OK;
+
+ if (basePtr->base.textVariableTrace) {
+ status = Ttk_FireTrace(basePtr->base.textVariableTrace);
+ }
+
+ return status;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Label widget.
+ * Just a base widget that adds a few appearance-related options
+ */
+
+typedef struct
+{
+ Tcl_Obj *backgroundObj;
+ Tcl_Obj *foregroundObj;
+ Tcl_Obj *fontObj;
+ Tcl_Obj *borderWidthObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *anchorObj;
+ Tcl_Obj *justifyObj;
+ Tcl_Obj *wrapLengthObj;
+} LabelPart;
+
+typedef struct
+{
+ WidgetCore core;
+ BasePart base;
+ LabelPart label;
+} Label;
+
+static Tk_OptionSpec LabelOptionSpecs[] =
+{
+ {TK_OPTION_BORDER, "-background", "frameColor", "FrameColor",
+ NULL, Tk_Offset(Label,label.backgroundObj), -1,
+ TK_OPTION_NULL_OK,0,0 },
+ {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
+ NULL, Tk_Offset(Label,label.foregroundObj), -1,
+ TK_OPTION_NULL_OK,0,0 },
+ {TK_OPTION_FONT, "-font", "font", "Font",
+ NULL, Tk_Offset(Label,label.fontObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+ {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
+ NULL, Tk_Offset(Label,label.borderWidthObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+ {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
+ NULL, Tk_Offset(Label,label.reliefObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+ {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
+ NULL, Tk_Offset(Label,label.anchorObj), -1,
+ TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED},
+ {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
+ NULL, Tk_Offset(Label, label.justifyObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+ {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
+ NULL, Tk_Offset(Label, label.wrapLengthObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED /*SB: SIZE_CHANGED*/ },
+
+ WIDGET_TAKEFOCUS_FALSE,
+ WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
+};
+
+static const Ttk_Ensemble LabelCommands[] = {
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ { 0,0,0 }
+};
+
+static WidgetSpec LabelWidgetSpec =
+{
+ "TLabel", /* className */
+ sizeof(Label), /* recordSize */
+ LabelOptionSpecs, /* optionSpecs */
+ LabelCommands, /* subcommands */
+ BaseInitialize, /* initializeProc */
+ BaseCleanup, /* cleanupProc */
+ BaseConfigure, /* configureProc */
+ BasePostConfigure, /* postConfigureProc */
+ TtkWidgetGetLayout, /* getLayoutProc */
+ TtkWidgetSize, /* sizeProc */
+ TtkWidgetDoLayout, /* layoutProc */
+ TtkWidgetDisplay /* displayProc */
+};
+
+TTK_BEGIN_LAYOUT(LabelLayout)
+ TTK_GROUP("Label.border", TTK_FILL_BOTH|TTK_BORDER,
+ TTK_GROUP("Label.padding", TTK_FILL_BOTH|TTK_BORDER,
+ TTK_NODE("Label.label", TTK_FILL_BOTH)))
+TTK_END_LAYOUT
+
+/*------------------------------------------------------------------------
+ * +++ Button widget.
+ * Adds a new subcommand "invoke", and options "-command" and "-default"
+ */
+
+typedef struct
+{
+ Tcl_Obj *commandObj;
+ Tcl_Obj *defaultStateObj;
+} ButtonPart;
+
+typedef struct
+{
+ WidgetCore core;
+ BasePart base;
+ ButtonPart button;
+} Button;
+
+/*
+ * Option specifications:
+ */
+static Tk_OptionSpec ButtonOptionSpecs[] =
+{
+ {TK_OPTION_STRING, "-command", "command", "Command",
+ "", Tk_Offset(Button, button.commandObj), -1, 0,0,0},
+ {TK_OPTION_STRING_TABLE, "-default", "default", "Default",
+ "normal", Tk_Offset(Button, button.defaultStateObj), -1,
+ 0, (ClientData) ttkDefaultStrings, DEFAULTSTATE_CHANGED},
+
+ WIDGET_TAKEFOCUS_TRUE,
+ WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
+};
+
+static int ButtonConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Button *buttonPtr = recordPtr;
+
+ if (BaseConfigure(interp, recordPtr, mask) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /* Handle "-default" option:
+ */
+ if (mask & DEFAULTSTATE_CHANGED) {
+ int defaultState = TTK_BUTTON_DEFAULT_DISABLED;
+ Ttk_GetButtonDefaultStateFromObj(
+ NULL, buttonPtr->button.defaultStateObj, &defaultState);
+ if (defaultState == TTK_BUTTON_DEFAULT_ACTIVE) {
+ TtkWidgetChangeState(&buttonPtr->core, TTK_STATE_ALTERNATE, 0);
+ } else {
+ TtkWidgetChangeState(&buttonPtr->core, 0, TTK_STATE_ALTERNATE);
+ }
+ }
+ return TCL_OK;
+}
+
+/* $button invoke --
+ * Evaluate the button's -command.
+ */
+static int
+ButtonInvokeCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Button *buttonPtr = recordPtr;
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "invoke");
+ return TCL_ERROR;
+ }
+ if (buttonPtr->core.state & TTK_STATE_DISABLED) {
+ return TCL_OK;
+ }
+ return Tcl_EvalObjEx(interp, buttonPtr->button.commandObj, TCL_EVAL_GLOBAL);
+}
+
+static const Ttk_Ensemble ButtonCommands[] = {
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "invoke", ButtonInvokeCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ { 0,0,0 }
+};
+
+static WidgetSpec ButtonWidgetSpec =
+{
+ "TButton", /* className */
+ sizeof(Button), /* recordSize */
+ ButtonOptionSpecs, /* optionSpecs */
+ ButtonCommands, /* subcommands */
+ BaseInitialize, /* initializeProc */
+ BaseCleanup, /* cleanupProc */
+ ButtonConfigure, /* configureProc */
+ BasePostConfigure, /* postConfigureProc */
+ TtkWidgetGetLayout, /* getLayoutProc */
+ TtkWidgetSize, /* sizeProc */
+ TtkWidgetDoLayout, /* layoutProc */
+ TtkWidgetDisplay /* displayProc */
+};
+
+TTK_BEGIN_LAYOUT(ButtonLayout)
+ TTK_GROUP("Button.border", TTK_FILL_BOTH|TTK_BORDER,
+ TTK_GROUP("Button.focus", TTK_FILL_BOTH,
+ TTK_GROUP("Button.padding", TTK_FILL_BOTH,
+ TTK_NODE("Button.label", TTK_FILL_BOTH))))
+TTK_END_LAYOUT
+
+/*------------------------------------------------------------------------
+ * +++ Checkbutton widget.
+ */
+typedef struct
+{
+ Tcl_Obj *variableObj;
+ Tcl_Obj *onValueObj;
+ Tcl_Obj *offValueObj;
+ Tcl_Obj *commandObj;
+
+ Ttk_TraceHandle *variableTrace;
+
+} CheckbuttonPart;
+
+typedef struct
+{
+ WidgetCore core;
+ BasePart base;
+ CheckbuttonPart checkbutton;
+} Checkbutton;
+
+/*
+ * Option specifications:
+ */
+static Tk_OptionSpec CheckbuttonOptionSpecs[] =
+{
+ {TK_OPTION_STRING, "-variable", "variable", "Variable",
+ "", Tk_Offset(Checkbutton, checkbutton.variableObj), -1,
+ TK_OPTION_DONT_SET_DEFAULT,0,0},
+ {TK_OPTION_STRING, "-onvalue", "onValue", "OnValue",
+ "1", Tk_Offset(Checkbutton, checkbutton.onValueObj), -1,
+ 0,0,0},
+ {TK_OPTION_STRING, "-offvalue", "offValue", "OffValue",
+ "0", Tk_Offset(Checkbutton, checkbutton.offValueObj), -1,
+ 0,0,0},
+ {TK_OPTION_STRING, "-command", "command", "Command",
+ "", Tk_Offset(Checkbutton, checkbutton.commandObj), -1,
+ 0,0,0},
+
+ WIDGET_TAKEFOCUS_TRUE,
+ WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
+};
+
+/*
+ * Variable trace procedure for checkbutton -variable option
+ */
+static void CheckbuttonVariableChanged(void *clientData, const char *value)
+{
+ Checkbutton *checkPtr = clientData;
+
+ if (WidgetDestroyed(&checkPtr->core)) {
+ return;
+ }
+
+ if (!value) {
+ TtkWidgetChangeState(&checkPtr->core, TTK_STATE_ALTERNATE, 0);
+ return;
+ }
+ /* else */
+ TtkWidgetChangeState(&checkPtr->core, 0, TTK_STATE_ALTERNATE);
+ if (!strcmp(value, Tcl_GetString(checkPtr->checkbutton.onValueObj))) {
+ TtkWidgetChangeState(&checkPtr->core, TTK_STATE_SELECTED, 0);
+ } else {
+ TtkWidgetChangeState(&checkPtr->core, 0, TTK_STATE_SELECTED);
+ }
+}
+
+static void
+CheckbuttonInitialize(Tcl_Interp *interp, void *recordPtr)
+{
+ Checkbutton *checkPtr = recordPtr;
+ Tcl_Obj *variableObj;
+
+ /* default -variable is the widget name:
+ */
+ variableObj = Tcl_NewStringObj(Tk_PathName(checkPtr->core.tkwin), -1);
+ Tcl_IncrRefCount(variableObj);
+ checkPtr->checkbutton.variableObj = variableObj;
+ BaseInitialize(interp, recordPtr);
+}
+
+static void
+CheckbuttonCleanup(void *recordPtr)
+{
+ Checkbutton *checkPtr = recordPtr;
+ Ttk_UntraceVariable(checkPtr->checkbutton.variableTrace);
+ checkPtr->checkbutton.variableTrace = 0;
+ BaseCleanup(recordPtr);
+}
+
+static int
+CheckbuttonConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Checkbutton *checkPtr = recordPtr;
+ Ttk_TraceHandle *vt = Ttk_TraceVariable(
+ interp, checkPtr->checkbutton.variableObj,
+ CheckbuttonVariableChanged, checkPtr);
+
+ if (!vt) {
+ return TCL_ERROR;
+ }
+
+ if (BaseConfigure(interp, recordPtr, mask) != TCL_OK){
+ Ttk_UntraceVariable(vt);
+ return TCL_ERROR;
+ }
+
+ Ttk_UntraceVariable(checkPtr->checkbutton.variableTrace);
+ checkPtr->checkbutton.variableTrace = vt;
+
+ return TCL_OK;
+}
+
+static int
+CheckbuttonPostConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Checkbutton *checkPtr = recordPtr;
+ int status = TCL_OK;
+
+ if (checkPtr->checkbutton.variableTrace)
+ status = Ttk_FireTrace(checkPtr->checkbutton.variableTrace);
+ if (status == TCL_OK && !WidgetDestroyed(&checkPtr->core))
+ status = BasePostConfigure(interp, recordPtr, mask);
+ return status;
+}
+
+/*
+ * Checkbutton 'invoke' subcommand:
+ * Toggles the checkbutton state.
+ */
+static int
+CheckbuttonInvokeCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Checkbutton *checkPtr = recordPtr;
+ WidgetCore *corePtr = &checkPtr->core;
+ Tcl_Obj *newValue;
+
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "invoke");
+ return TCL_ERROR;
+ }
+ if (corePtr->state & TTK_STATE_DISABLED)
+ return TCL_OK;
+
+ /*
+ * Toggle the selected state.
+ */
+ if (corePtr->state & TTK_STATE_SELECTED)
+ newValue = checkPtr->checkbutton.offValueObj;
+ else
+ newValue = checkPtr->checkbutton.onValueObj;
+
+ if (Tcl_ObjSetVar2(interp,
+ checkPtr->checkbutton.variableObj, NULL, newValue,
+ TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
+ == NULL)
+ return TCL_ERROR;
+
+ if (WidgetDestroyed(corePtr))
+ return TCL_ERROR;
+
+ return Tcl_EvalObjEx(interp,
+ checkPtr->checkbutton.commandObj, TCL_EVAL_GLOBAL);
+}
+
+static const Ttk_Ensemble CheckbuttonCommands[] = {
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "invoke", CheckbuttonInvokeCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ /* MISSING: select, deselect, toggle */
+ { 0,0,0 }
+};
+
+static WidgetSpec CheckbuttonWidgetSpec =
+{
+ "TCheckbutton", /* className */
+ sizeof(Checkbutton), /* recordSize */
+ CheckbuttonOptionSpecs, /* optionSpecs */
+ CheckbuttonCommands, /* subcommands */
+ CheckbuttonInitialize, /* initializeProc */
+ CheckbuttonCleanup, /* cleanupProc */
+ CheckbuttonConfigure, /* configureProc */
+ CheckbuttonPostConfigure, /* postConfigureProc */
+ TtkWidgetGetLayout, /* getLayoutProc */
+ TtkWidgetSize, /* sizeProc */
+ TtkWidgetDoLayout, /* layoutProc */
+ TtkWidgetDisplay /* displayProc */
+};
+
+TTK_BEGIN_LAYOUT(CheckbuttonLayout)
+ TTK_GROUP("Checkbutton.padding", TTK_FILL_BOTH,
+ TTK_NODE("Checkbutton.indicator", TTK_PACK_LEFT)
+ TTK_GROUP("Checkbutton.focus", TTK_PACK_LEFT | TTK_STICK_W,
+ TTK_NODE("Checkbutton.label", TTK_FILL_BOTH)))
+TTK_END_LAYOUT
+
+/*------------------------------------------------------------------------
+ * +++ Radiobutton widget.
+ */
+
+typedef struct
+{
+ Tcl_Obj *variableObj;
+ Tcl_Obj *valueObj;
+ Tcl_Obj *commandObj;
+
+ Ttk_TraceHandle *variableTrace;
+
+} RadiobuttonPart;
+
+typedef struct
+{
+ WidgetCore core;
+ BasePart base;
+ RadiobuttonPart radiobutton;
+} Radiobutton;
+
+/*
+ * Option specifications:
+ */
+static Tk_OptionSpec RadiobuttonOptionSpecs[] =
+{
+ {TK_OPTION_STRING, "-variable", "variable", "Variable",
+ "::selectedButton", Tk_Offset(Radiobutton, radiobutton.variableObj),-1,
+ 0,0,0},
+ {TK_OPTION_STRING, "-value", "Value", "Value",
+ "1", Tk_Offset(Radiobutton, radiobutton.valueObj), -1,
+ 0,0,0},
+ {TK_OPTION_STRING, "-command", "command", "Command",
+ "", Tk_Offset(Radiobutton, radiobutton.commandObj), -1,
+ 0,0,0},
+
+ WIDGET_TAKEFOCUS_TRUE,
+ WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
+};
+
+/*
+ * Variable trace procedure for radiobuttons.
+ */
+static void
+RadiobuttonVariableChanged(void *clientData, const char *value)
+{
+ Radiobutton *radioPtr = clientData;
+
+ if (WidgetDestroyed(&radioPtr->core)) {
+ return;
+ }
+
+ if (!value) {
+ TtkWidgetChangeState(&radioPtr->core, TTK_STATE_ALTERNATE, 0);
+ return;
+ }
+ /* else */
+ TtkWidgetChangeState(&radioPtr->core, 0, TTK_STATE_ALTERNATE);
+ if (!strcmp(value, Tcl_GetString(radioPtr->radiobutton.valueObj))) {
+ TtkWidgetChangeState(&radioPtr->core, TTK_STATE_SELECTED, 0);
+ } else {
+ TtkWidgetChangeState(&radioPtr->core, 0, TTK_STATE_SELECTED);
+ }
+}
+
+static void
+RadiobuttonCleanup(void *recordPtr)
+{
+ Radiobutton *radioPtr = recordPtr;
+ Ttk_UntraceVariable(radioPtr->radiobutton.variableTrace);
+ radioPtr->radiobutton.variableTrace = 0;
+ BaseCleanup(recordPtr);
+}
+
+static int
+RadiobuttonConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Radiobutton *radioPtr = recordPtr;
+ Ttk_TraceHandle *vt = Ttk_TraceVariable(
+ interp, radioPtr->radiobutton.variableObj,
+ RadiobuttonVariableChanged, radioPtr);
+
+ if (!vt) {
+ return TCL_ERROR;
+ }
+
+ if (BaseConfigure(interp, recordPtr, mask) != TCL_OK) {
+ Ttk_UntraceVariable(vt);
+ return TCL_ERROR;
+ }
+
+ Ttk_UntraceVariable(radioPtr->radiobutton.variableTrace);
+ radioPtr->radiobutton.variableTrace = vt;
+
+ return TCL_OK;
+}
+
+static int
+RadiobuttonPostConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Radiobutton *radioPtr = recordPtr;
+ int status = TCL_OK;
+
+ if (radioPtr->radiobutton.variableTrace)
+ status = Ttk_FireTrace(radioPtr->radiobutton.variableTrace);
+ if (status == TCL_OK && !WidgetDestroyed(&radioPtr->core))
+ status = BasePostConfigure(interp, recordPtr, mask);
+ return status;
+}
+
+/*
+ * Radiobutton 'invoke' subcommand:
+ * Sets the radiobutton -variable to the -value, evaluates the -command.
+ */
+static int
+RadiobuttonInvokeCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Radiobutton *radioPtr = recordPtr;
+ WidgetCore *corePtr = &radioPtr->core;
+
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "invoke");
+ return TCL_ERROR;
+ }
+ if (corePtr->state & TTK_STATE_DISABLED)
+ return TCL_OK;
+
+ if (Tcl_ObjSetVar2(interp,
+ radioPtr->radiobutton.variableObj, NULL,
+ radioPtr->radiobutton.valueObj,
+ TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
+ == NULL)
+ return TCL_ERROR;
+
+ if (WidgetDestroyed(corePtr))
+ return TCL_ERROR;
+
+ return Tcl_EvalObjEx(interp,
+ radioPtr->radiobutton.commandObj, TCL_EVAL_GLOBAL);
+}
+
+static const Ttk_Ensemble RadiobuttonCommands[] = {
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "invoke", RadiobuttonInvokeCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ /* MISSING: select, deselect */
+ { 0,0,0 }
+};
+
+static WidgetSpec RadiobuttonWidgetSpec =
+{
+ "TRadiobutton", /* className */
+ sizeof(Radiobutton), /* recordSize */
+ RadiobuttonOptionSpecs, /* optionSpecs */
+ RadiobuttonCommands, /* subcommands */
+ BaseInitialize, /* initializeProc */
+ RadiobuttonCleanup, /* cleanupProc */
+ RadiobuttonConfigure, /* configureProc */
+ RadiobuttonPostConfigure, /* postConfigureProc */
+ TtkWidgetGetLayout, /* getLayoutProc */
+ TtkWidgetSize, /* sizeProc */
+ TtkWidgetDoLayout, /* layoutProc */
+ TtkWidgetDisplay /* displayProc */
+};
+
+TTK_BEGIN_LAYOUT(RadiobuttonLayout)
+ TTK_GROUP("Radiobutton.padding", TTK_FILL_BOTH,
+ TTK_NODE("Radiobutton.indicator", TTK_PACK_LEFT)
+ TTK_GROUP("Radiobutton.focus", TTK_PACK_LEFT,
+ TTK_NODE("Radiobutton.label", TTK_FILL_BOTH)))
+TTK_END_LAYOUT
+
+/*------------------------------------------------------------------------
+ * +++ Menubutton widget.
+ */
+
+typedef struct
+{
+ Tcl_Obj *menuObj;
+ Tcl_Obj *directionObj;
+} MenubuttonPart;
+
+typedef struct
+{
+ WidgetCore core;
+ BasePart base;
+ MenubuttonPart menubutton;
+} Menubutton;
+
+/*
+ * Option specifications:
+ */
+static const char *const directionStrings[] = {
+ "above", "below", "left", "right", "flush", NULL
+};
+static Tk_OptionSpec MenubuttonOptionSpecs[] =
+{
+ {TK_OPTION_STRING, "-menu", "menu", "Menu",
+ "", Tk_Offset(Menubutton, menubutton.menuObj), -1, 0,0,0},
+ {TK_OPTION_STRING_TABLE, "-direction", "direction", "Direction",
+ "below", Tk_Offset(Menubutton, menubutton.directionObj), -1,
+ 0,(ClientData)directionStrings,GEOMETRY_CHANGED},
+
+ WIDGET_TAKEFOCUS_TRUE,
+ WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
+};
+
+static const Ttk_Ensemble MenubuttonCommands[] = {
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ { 0,0,0 }
+};
+
+static WidgetSpec MenubuttonWidgetSpec =
+{
+ "TMenubutton", /* className */
+ sizeof(Menubutton), /* recordSize */
+ MenubuttonOptionSpecs, /* optionSpecs */
+ MenubuttonCommands, /* subcommands */
+ BaseInitialize, /* initializeProc */
+ BaseCleanup, /* cleanupProc */
+ BaseConfigure, /* configureProc */
+ BasePostConfigure, /* postConfigureProc */
+ TtkWidgetGetLayout, /* getLayoutProc */
+ TtkWidgetSize, /* sizeProc */
+ TtkWidgetDoLayout, /* layoutProc */
+ TtkWidgetDisplay /* displayProc */
+};
+
+TTK_BEGIN_LAYOUT(MenubuttonLayout)
+ TTK_GROUP("Menubutton.border", TTK_FILL_BOTH,
+ TTK_GROUP("Menubutton.focus", TTK_FILL_BOTH,
+ TTK_NODE("Menubutton.indicator", TTK_PACK_RIGHT)
+ TTK_GROUP("Menubutton.padding", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_X,
+ TTK_NODE("Menubutton.label", TTK_PACK_LEFT))))
+TTK_END_LAYOUT
+
+/*------------------------------------------------------------------------
+ * +++ Initialization.
+ */
+
+MODULE_SCOPE
+void TtkButton_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme theme = Ttk_GetDefaultTheme(interp);
+
+ Ttk_RegisterLayout(theme, "TLabel", LabelLayout);
+ Ttk_RegisterLayout(theme, "TButton", ButtonLayout);
+ Ttk_RegisterLayout(theme, "TCheckbutton", CheckbuttonLayout);
+ Ttk_RegisterLayout(theme, "TRadiobutton", RadiobuttonLayout);
+ Ttk_RegisterLayout(theme, "TMenubutton", MenubuttonLayout);
+
+ RegisterWidget(interp, "ttk::label", &LabelWidgetSpec);
+ RegisterWidget(interp, "ttk::button", &ButtonWidgetSpec);
+ RegisterWidget(interp, "ttk::checkbutton", &CheckbuttonWidgetSpec);
+ RegisterWidget(interp, "ttk::radiobutton", &RadiobuttonWidgetSpec);
+ RegisterWidget(interp, "ttk::menubutton", &MenubuttonWidgetSpec);
+}
diff --git a/generic/ttk/ttkCache.c b/generic/ttk/ttkCache.c
new file mode 100644
index 0000000..e3aeaba
--- /dev/null
+++ b/generic/ttk/ttkCache.c
@@ -0,0 +1,350 @@
+/*
+ * Theme engine resource cache.
+ *
+ * Copyright (c) 2004, Joe English
+ *
+ * The problem:
+ *
+ * Tk maintains reference counts for fonts, colors, and images,
+ * and deallocates them when the reference count goes to zero.
+ * With the theme engine, resources are allocated right before
+ * drawing an element and released immediately after.
+ * This causes a severe performance penalty, and on PseudoColor
+ * visuals it causes colormap cycling as colormap entries are
+ * released and reused.
+ *
+ * Solution: Acquire fonts, colors, and objects from a
+ * resource cache instead of directly from Tk; the cache
+ * holds a semipermanent reference to the resource to keep
+ * it from being deallocated.
+ *
+ * The plumbing and control flow here is quite contorted;
+ * it would be better to address this problem in the core instead.
+ *
+ * @@@ BUGS/TODO: Need distinct caches for each combination
+ * of display, visual, and colormap.
+ *
+ * @@@ Colormap flashing on PseudoColor visuals is still possible,
+ * but this will be a transient effect.
+ */
+
+#include <stdio.h> /* for sprintf */
+#include <tk.h>
+#include "ttkTheme.h"
+
+struct Ttk_ResourceCache_ {
+ Tcl_Interp *interp; /* Interpreter for error reporting */
+ Tk_Window tkwin; /* Cache window. */
+ Tcl_HashTable fontTable; /* Entries: Tcl_Obj* holding FontObjs */
+ Tcl_HashTable colorTable; /* Entries: Tcl_Obj* holding ColorObjs */
+ Tcl_HashTable borderTable; /* Entries: Tcl_Obj* holding BorderObjs */
+ Tcl_HashTable imageTable; /* Entries: Tk_Images */
+
+ Tcl_HashTable namedColors; /* Entries: RGB values as Tcl_StringObjs */
+};
+
+/*
+ * Ttk_CreateResourceCache --
+ * Initialize a new resource cache.
+ */
+Ttk_ResourceCache Ttk_CreateResourceCache(Tcl_Interp *interp)
+{
+ Ttk_ResourceCache cache = (Ttk_ResourceCache)ckalloc(sizeof(*cache));
+
+ cache->tkwin = NULL; /* initialized later */
+ cache->interp = interp;
+ Tcl_InitHashTable(&cache->fontTable, TCL_STRING_KEYS);
+ Tcl_InitHashTable(&cache->colorTable, TCL_STRING_KEYS);
+ Tcl_InitHashTable(&cache->borderTable, TCL_STRING_KEYS);
+ Tcl_InitHashTable(&cache->imageTable, TCL_STRING_KEYS);
+ Tcl_InitHashTable(&cache->namedColors, TCL_STRING_KEYS);
+
+ return cache;
+}
+
+/*
+ * Ttk_ClearCache --
+ * Release references to all cached resources.
+ */
+static void Ttk_ClearCache(Ttk_ResourceCache cache)
+{
+ Tcl_HashSearch search;
+ Tcl_HashEntry *entryPtr;
+
+ /*
+ * Free fonts:
+ */
+ entryPtr = Tcl_FirstHashEntry(&cache->fontTable, &search);
+ while (entryPtr != NULL) {
+ Tcl_Obj *fontObj = Tcl_GetHashValue(entryPtr);
+ if (fontObj) {
+ Tk_FreeFontFromObj(cache->tkwin, fontObj);
+ Tcl_DecrRefCount(fontObj);
+ }
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+ Tcl_DeleteHashTable(&cache->fontTable);
+ Tcl_InitHashTable(&cache->fontTable, TCL_STRING_KEYS);
+
+ /*
+ * Free colors:
+ */
+ entryPtr = Tcl_FirstHashEntry(&cache->colorTable, &search);
+ while (entryPtr != NULL) {
+ Tcl_Obj *colorObj = Tcl_GetHashValue(entryPtr);
+ if (colorObj) {
+ Tk_FreeColorFromObj(cache->tkwin, colorObj);
+ Tcl_DecrRefCount(colorObj);
+ }
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+ Tcl_DeleteHashTable(&cache->colorTable);
+ Tcl_InitHashTable(&cache->colorTable, TCL_STRING_KEYS);
+
+ /*
+ * Free borders:
+ */
+ entryPtr = Tcl_FirstHashEntry(&cache->borderTable, &search);
+ while (entryPtr != NULL) {
+ Tcl_Obj *borderObj = Tcl_GetHashValue(entryPtr);
+ if (borderObj) {
+ Tk_Free3DBorderFromObj(cache->tkwin, borderObj);
+ Tcl_DecrRefCount(borderObj);
+ }
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+ Tcl_DeleteHashTable(&cache->borderTable);
+ Tcl_InitHashTable(&cache->borderTable, TCL_STRING_KEYS);
+
+ /*
+ * Free images:
+ */
+ entryPtr = Tcl_FirstHashEntry(&cache->imageTable, &search);
+ while (entryPtr != NULL) {
+ Tk_Image image = Tcl_GetHashValue(entryPtr);
+ if (image) {
+ Tk_FreeImage(image);
+ }
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+ Tcl_DeleteHashTable(&cache->imageTable);
+ Tcl_InitHashTable(&cache->imageTable, TCL_STRING_KEYS);
+
+ return;
+}
+
+/*
+ * Ttk_FreeResourceCache --
+ * Release references to all cached resources, delete the cache.
+ */
+
+void Ttk_FreeResourceCache(Ttk_ResourceCache cache)
+{
+ Tcl_HashEntry *entryPtr;
+ Tcl_HashSearch search;
+
+ Ttk_ClearCache(cache);
+
+ Tcl_DeleteHashTable(&cache->colorTable);
+ Tcl_DeleteHashTable(&cache->fontTable);
+ Tcl_DeleteHashTable(&cache->imageTable);
+
+ /*
+ * Free named colors:
+ */
+ entryPtr = Tcl_FirstHashEntry(&cache->namedColors, &search);
+ while (entryPtr != NULL) {
+ Tcl_Obj *colorNameObj = Tcl_GetHashValue(entryPtr);
+ Tcl_DecrRefCount(colorNameObj);
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+ Tcl_DeleteHashTable(&cache->namedColors);
+
+ ckfree((ClientData)cache);
+}
+
+/*
+ * CacheWinEventHandler --
+ * Detect when the cache window is destroyed, clear cache.
+ */
+static void CacheWinEventHandler(ClientData clientData, XEvent *eventPtr)
+{
+ Ttk_ResourceCache cache = clientData;
+
+ if (eventPtr->type != DestroyNotify) {
+ return;
+ }
+ Tk_DeleteEventHandler(cache->tkwin, StructureNotifyMask,
+ CacheWinEventHandler, clientData);
+ Ttk_ClearCache(cache);
+ cache->tkwin = NULL;
+}
+
+/*
+ * InitCacheWindow --
+ * Specify the cache window if not already set.
+ * @@@ SHOULD: use separate caches for each combination
+ * @@@ of display, visual, and colormap.
+ */
+static void InitCacheWindow(Ttk_ResourceCache cache, Tk_Window tkwin)
+{
+ if (cache->tkwin == NULL) {
+ cache->tkwin = tkwin;
+ Tk_CreateEventHandler(tkwin, StructureNotifyMask,
+ CacheWinEventHandler, cache);
+ }
+}
+
+/*
+ * Ttk_RegisterNamedColor --
+ * Specify an RGB triplet as a named color.
+ * Overrides any previous named color specification.
+ */
+void Ttk_RegisterNamedColor(
+ Ttk_ResourceCache cache,
+ const char *colorName,
+ XColor *colorPtr)
+{
+ int newEntry;
+ Tcl_HashEntry *entryPtr;
+ char nameBuf[14];
+ Tcl_Obj *colorNameObj;
+
+ sprintf(nameBuf, "#%04X%04X%04X",
+ colorPtr->red, colorPtr->green, colorPtr->blue);
+ colorNameObj = Tcl_NewStringObj(nameBuf, -1);
+ Tcl_IncrRefCount(colorNameObj);
+
+ entryPtr = Tcl_CreateHashEntry(&cache->namedColors, colorName, &newEntry);
+ if (!newEntry) {
+ Tcl_Obj *oldColor = Tcl_GetHashValue(entryPtr);
+ Tcl_DecrRefCount(oldColor);
+ }
+
+ Tcl_SetHashValue(entryPtr, colorNameObj);
+}
+
+/*
+ * CheckNamedColor(objPtr) --
+ * If objPtr is a registered color name, return a Tcl_Obj *
+ * containing the registered color value specification.
+ * Otherwise, return the input argument.
+ */
+static Tcl_Obj *CheckNamedColor(Ttk_ResourceCache cache, Tcl_Obj *objPtr)
+{
+ Tcl_HashEntry *entryPtr =
+ Tcl_FindHashEntry(&cache->namedColors, Tcl_GetString(objPtr));
+ if (entryPtr) { /* Use named color instead */
+ objPtr = Tcl_GetHashValue(entryPtr);
+ }
+ return objPtr;
+}
+
+/*
+ * Template for allocation routines:
+ */
+typedef void *(*Allocator)(Tcl_Interp *, Tk_Window, Tcl_Obj *);
+
+static Tcl_Obj *Ttk_Use(
+ Tcl_Interp *interp,
+ Tcl_HashTable *table,
+ Allocator allocate,
+ Tk_Window tkwin,
+ Tcl_Obj *objPtr)
+{
+ int newEntry;
+ Tcl_HashEntry *entryPtr =
+ Tcl_CreateHashEntry(table,Tcl_GetString(objPtr),&newEntry);
+ Tcl_Obj *cacheObj;
+
+ if (!newEntry) {
+ return Tcl_GetHashValue(entryPtr);
+ }
+
+ cacheObj = Tcl_DuplicateObj(objPtr);
+ Tcl_IncrRefCount(cacheObj);
+
+ if (allocate(interp, tkwin, cacheObj)) {
+ Tcl_SetHashValue(entryPtr, cacheObj);
+ return cacheObj;
+ } else {
+ Tcl_DecrRefCount(cacheObj);
+ Tcl_SetHashValue(entryPtr, NULL);
+ Tcl_BackgroundError(interp);
+ return NULL;
+ }
+}
+
+/*
+ * Ttk_UseFont --
+ * Acquire a font from the cache.
+ */
+Tcl_Obj *Ttk_UseFont(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
+{
+ InitCacheWindow(cache, tkwin);
+ return Ttk_Use(cache->interp,
+ &cache->fontTable,(Allocator)Tk_AllocFontFromObj, tkwin, objPtr);
+}
+
+/*
+ * Ttk_UseColor --
+ * Acquire a color from the cache.
+ */
+Tcl_Obj *Ttk_UseColor(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
+{
+ objPtr = CheckNamedColor(cache, objPtr);
+ InitCacheWindow(cache, tkwin);
+ return Ttk_Use(cache->interp,
+ &cache->colorTable,(Allocator)Tk_AllocColorFromObj, tkwin, objPtr);
+}
+
+/*
+ * Ttk_UseBorder --
+ * Acquire a Tk_3DBorder from the cache.
+ */
+Tcl_Obj *Ttk_UseBorder(
+ Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
+{
+ objPtr = CheckNamedColor(cache, objPtr);
+ InitCacheWindow(cache, tkwin);
+ return Ttk_Use(cache->interp,
+ &cache->borderTable,(Allocator)Tk_Alloc3DBorderFromObj, tkwin, objPtr);
+}
+
+/* NullImageChanged --
+ * Tk_ImageChangedProc for Ttk_UseImage
+ */
+
+static void NullImageChanged(ClientData clientData,
+ int x, int y, int width, int height, int imageWidth, int imageHeight)
+{ /* No-op */ }
+
+/*
+ * Ttk_UseImage --
+ * Acquire a Tk_Image from the cache.
+ */
+Tk_Image Ttk_UseImage(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
+{
+ const char *imageName = Tcl_GetString(objPtr);
+ int newEntry;
+ Tcl_HashEntry *entryPtr =
+ Tcl_CreateHashEntry(&cache->imageTable,imageName,&newEntry);
+ Tk_Image image;
+
+ InitCacheWindow(cache, tkwin);
+
+ if (!newEntry) {
+ return Tcl_GetHashValue(entryPtr);
+ }
+
+ image = Tk_GetImage(cache->interp, tkwin, imageName, NullImageChanged,0);
+ Tcl_SetHashValue(entryPtr, image);
+
+ if (!image) {
+ Tcl_BackgroundError(cache->interp);
+ }
+
+ return image;
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkClamTheme.c b/generic/ttk/ttkClamTheme.c
new file mode 100644
index 0000000..572f630
--- /dev/null
+++ b/generic/ttk/ttkClamTheme.c
@@ -0,0 +1,971 @@
+/*
+ * Copyright (C) 2004 Joe English
+ *
+ * "clam" theme; inspired by the XFCE family of Gnome themes.
+ */
+
+#include <tk.h>
+#include "ttkTheme.h"
+
+/*
+ * Under windows, the Tk-provided XDrawLine and XDrawArc have an
+ * off-by-one error in the end point. This is especially apparent with this
+ * theme. Defining this macro as true handles this case.
+ */
+#if defined(WIN32) && !defined(WIN32_XDRAWLINE_HACK)
+# define WIN32_XDRAWLINE_HACK 1
+#else
+# define WIN32_XDRAWLINE_HACK 0
+#endif
+
+#define STR(x) StR(x)
+#define StR(x) #x
+
+#define SCROLLBAR_THICKNESS 14
+
+#define FRAME_COLOR "#dcdad5"
+#define LIGHT_COLOR "#ffffff"
+#define DARK_COLOR "#cfcdc8"
+#define DARKER_COLOR "#bab5ab"
+#define DARKEST_COLOR "#9e9a91"
+
+/*------------------------------------------------------------------------
+ * +++ Utilities.
+ */
+
+static GC Ttk_GCForColor(Tk_Window tkwin, Tcl_Obj* colorObj, Drawable d)
+{
+ GC gc = Tk_GCForColor(Tk_GetColorFromObj(tkwin, colorObj), d);
+
+#ifdef MAC_OSX_TK
+ /*
+ * Workaround for Tk bug under Aqua where the default line width is 0.
+ */
+ Display *display = Tk_Display(tkwin);
+ unsigned long mask = 0ul;
+ XGCValues gcValues;
+
+ gcValues.line_width = 1;
+ mask = GCLineWidth;
+
+ XChangeGC(display, gc, mask, &gcValues);
+#endif
+
+ return gc;
+}
+
+static void DrawSmoothBorder(
+ Tk_Window tkwin, Drawable d, Ttk_Box b,
+ Tcl_Obj *outerColorObj, Tcl_Obj *upperColorObj, Tcl_Obj *lowerColorObj)
+{
+ Display *display = Tk_Display(tkwin);
+ int x1 = b.x, x2 = b.x + b.width - 1;
+ int y1 = b.y, y2 = b.y + b.height - 1;
+ const int w = WIN32_XDRAWLINE_HACK;
+ GC gc;
+
+ if ( outerColorObj
+ && (gc=Ttk_GCForColor(tkwin,outerColorObj,d)))
+ {
+ XDrawLine(display,d,gc, x1+1,y1, x2-1+w,y1); /* N */
+ XDrawLine(display,d,gc, x1+1,y2, x2-1+w,y2); /* S */
+ XDrawLine(display,d,gc, x1,y1+1, x1,y2-1+w); /* E */
+ XDrawLine(display,d,gc, x2,y1+1, x2,y2-1+w); /* W */
+ }
+
+ if ( upperColorObj
+ && (gc=Ttk_GCForColor(tkwin,upperColorObj,d)))
+ {
+ XDrawLine(display,d,gc, x1+1,y1+1, x2-1+w,y1+1); /* N */
+ XDrawLine(display,d,gc, x1+1,y1+1, x1+1,y2-1); /* E */
+ }
+
+ if ( lowerColorObj
+ && (gc=Ttk_GCForColor(tkwin,lowerColorObj,d)))
+ {
+ XDrawLine(display,d,gc, x2-1,y2-1, x1+1-w,y2-1); /* S */
+ XDrawLine(display,d,gc, x2-1,y2-1, x2-1,y1+1-w); /* W */
+ }
+}
+
+static GC BackgroundGC(Tk_Window tkwin, Tcl_Obj *backgroundObj)
+{
+ Tk_3DBorder bd = Tk_Get3DBorderFromObj(tkwin, backgroundObj);
+ return Tk_3DBorderGC(tkwin, bd, TK_3D_FLAT_GC);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Border element.
+ */
+
+typedef struct {
+ Tcl_Obj *borderColorObj;
+ Tcl_Obj *lightColorObj;
+ Tcl_Obj *darkColorObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *borderWidthObj; /* See <<NOTE-BORDERWIDTH>> */
+} BorderElement;
+
+static Ttk_ElementOptionSpec BorderElementOptions[] = {
+ { "-bordercolor", TK_OPTION_COLOR,
+ Tk_Offset(BorderElement,borderColorObj), DARKEST_COLOR },
+ { "-lightcolor", TK_OPTION_COLOR,
+ Tk_Offset(BorderElement,lightColorObj), LIGHT_COLOR },
+ { "-darkcolor", TK_OPTION_COLOR,
+ Tk_Offset(BorderElement,darkColorObj), DARK_COLOR },
+ { "-relief", TK_OPTION_RELIEF,
+ Tk_Offset(BorderElement,reliefObj), "flat" },
+ { "-borderwidth", TK_OPTION_PIXELS,
+ Tk_Offset(BorderElement,borderWidthObj), "2" },
+ { NULL, 0, 0, NULL }
+};
+
+/*
+ * <<NOTE-BORDERWIDTH>>: -borderwidth is only partially supported:
+ * in this theme, borders are always exactly 2 pixels thick.
+ * With -borderwidth 0, border is not drawn at all;
+ * otherwise a 2-pixel border is used. For -borderwidth > 2,
+ * the excess is used as padding.
+ */
+
+static void BorderElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ BorderElement *border = (BorderElement*)elementRecord;
+ int borderWidth = 2;
+ Tk_GetPixelsFromObj(NULL, tkwin, border->borderWidthObj, &borderWidth);
+ if (borderWidth == 1) ++borderWidth;
+ *paddingPtr = Ttk_UniformPadding((short)borderWidth);
+}
+
+static void BorderElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned state)
+{
+ BorderElement *border = elementRecord;
+ int relief = TK_RELIEF_FLAT;
+ int borderWidth = 2;
+ Tcl_Obj *outer = 0, *upper = 0, *lower = 0;
+
+ Tk_GetReliefFromObj(NULL, border->reliefObj, &relief);
+ Tk_GetPixelsFromObj(NULL, tkwin, border->borderWidthObj, &borderWidth);
+
+ if (borderWidth == 0) return;
+
+ switch (relief) {
+ case TK_RELIEF_GROOVE :
+ case TK_RELIEF_RIDGE :
+ case TK_RELIEF_RAISED :
+ outer = border->borderColorObj;
+ upper = border->lightColorObj;
+ lower = border->darkColorObj;
+ break;
+ case TK_RELIEF_SUNKEN :
+ outer = border->borderColorObj;
+ upper = border->darkColorObj;
+ lower = border->lightColorObj;
+ break;
+ case TK_RELIEF_FLAT :
+ outer = upper = lower = 0;
+ break;
+ case TK_RELIEF_SOLID :
+ outer = upper = lower = border->borderColorObj;
+ break;
+ }
+
+ DrawSmoothBorder(tkwin, d, b, outer, upper, lower);
+}
+
+static Ttk_ElementSpec BorderElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(BorderElement),
+ BorderElementOptions,
+ BorderElementSize,
+ BorderElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Field element.
+ */
+
+typedef struct {
+ Tcl_Obj *borderColorObj;
+ Tcl_Obj *lightColorObj;
+ Tcl_Obj *darkColorObj;
+ Tcl_Obj *backgroundObj;
+} FieldElement;
+
+static Ttk_ElementOptionSpec FieldElementOptions[] = {
+ { "-bordercolor", TK_OPTION_COLOR,
+ Tk_Offset(FieldElement,borderColorObj), DARKEST_COLOR },
+ { "-lightcolor", TK_OPTION_COLOR,
+ Tk_Offset(FieldElement,lightColorObj), LIGHT_COLOR },
+ { "-darkcolor", TK_OPTION_COLOR,
+ Tk_Offset(FieldElement,darkColorObj), DARK_COLOR },
+ { "-fieldbackground", TK_OPTION_BORDER,
+ Tk_Offset(FieldElement,backgroundObj), "white" },
+ { NULL, 0, 0, NULL }
+};
+
+static void FieldElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ *paddingPtr = Ttk_UniformPadding(2);
+}
+
+static void FieldElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned state)
+{
+ FieldElement *field = elementRecord;
+ Tk_3DBorder bg = Tk_Get3DBorderFromObj(tkwin, field->backgroundObj);
+ Ttk_Box f = Ttk_PadBox(b, Ttk_UniformPadding(2));
+ Tcl_Obj *outer = field->borderColorObj,
+ *inner = field->lightColorObj;
+
+ DrawSmoothBorder(tkwin, d, b, outer, inner, inner);
+ Tk_Fill3DRectangle(
+ tkwin, d, bg, f.x, f.y, f.width, f.height, 0, TK_RELIEF_SUNKEN);
+}
+
+static Ttk_ElementSpec FieldElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(FieldElement),
+ FieldElementOptions,
+ FieldElementSize,
+ FieldElementDraw
+};
+
+/*
+ * Modified field element for comboboxes:
+ * Right edge is expanded to overlap the dropdown button.
+ */
+static void ComboboxFieldElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned state)
+{
+ FieldElement *field = elementRecord;
+ GC gc = Ttk_GCForColor(tkwin,field->borderColorObj,d);
+
+ ++b.width;
+ FieldElementDraw(clientData, elementRecord, tkwin, d, b, state);
+
+ XDrawLine(Tk_Display(tkwin), d, gc,
+ b.x + b.width - 1, b.y,
+ b.x + b.width - 1, b.y + b.height - 1 + WIN32_XDRAWLINE_HACK);
+}
+
+static Ttk_ElementSpec ComboboxFieldElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(FieldElement),
+ FieldElementOptions,
+ FieldElementSize,
+ ComboboxFieldElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Indicator elements for check and radio buttons.
+ */
+
+typedef struct {
+ Tcl_Obj *sizeObj;
+ Tcl_Obj *marginObj;
+ Tcl_Obj *backgroundObj;
+ Tcl_Obj *foregroundObj;
+ Tcl_Obj *upperColorObj;
+ Tcl_Obj *lowerColorObj;
+} IndicatorElement;
+
+static Ttk_ElementOptionSpec IndicatorElementOptions[] = {
+ { "-indicatorsize", TK_OPTION_PIXELS,
+ Tk_Offset(IndicatorElement,sizeObj), "10" },
+ { "-indicatormargin", TK_OPTION_STRING,
+ Tk_Offset(IndicatorElement,marginObj), "1" },
+ { "-indicatorbackground", TK_OPTION_COLOR,
+ Tk_Offset(IndicatorElement,backgroundObj), "white" },
+ { "-indicatorforeground", TK_OPTION_COLOR,
+ Tk_Offset(IndicatorElement,foregroundObj), "black" },
+ { "-upperbordercolor", TK_OPTION_COLOR,
+ Tk_Offset(IndicatorElement,upperColorObj), DARKEST_COLOR },
+ { "-lowerbordercolor", TK_OPTION_COLOR,
+ Tk_Offset(IndicatorElement,lowerColorObj), DARK_COLOR },
+ { NULL, 0, 0, NULL }
+};
+
+static void IndicatorElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ IndicatorElement *indicator = elementRecord;
+ Ttk_Padding margins;
+ int size = 10;
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
+ Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);
+ *widthPtr = size + Ttk_PaddingWidth(margins);
+ *heightPtr = size + Ttk_PaddingHeight(margins);
+}
+
+static void RadioIndicatorElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned state)
+{
+ IndicatorElement *indicator = elementRecord;
+ GC gcb=Ttk_GCForColor(tkwin,indicator->backgroundObj,d);
+ GC gcf=Ttk_GCForColor(tkwin,indicator->foregroundObj,d);
+ GC gcu=Ttk_GCForColor(tkwin,indicator->upperColorObj,d);
+ GC gcl=Ttk_GCForColor(tkwin,indicator->lowerColorObj,d);
+ Ttk_Padding padding;
+
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
+ b = Ttk_PadBox(b, padding);
+
+ XFillArc(Tk_Display(tkwin),d,gcb, b.x,b.y,b.width,b.height, 0,360*64);
+ XDrawArc(Tk_Display(tkwin),d,gcl, b.x,b.y,b.width,b.height, 225*64,180*64);
+ XDrawArc(Tk_Display(tkwin),d,gcu, b.x,b.y,b.width,b.height, 45*64,180*64);
+
+ if (state & TTK_STATE_SELECTED) {
+ b = Ttk_PadBox(b,Ttk_UniformPadding(3));
+ XFillArc(Tk_Display(tkwin),d,gcf, b.x,b.y,b.width,b.height, 0,360*64);
+ XDrawArc(Tk_Display(tkwin),d,gcf, b.x,b.y,b.width,b.height, 0,360*64);
+#if WIN32_XDRAWLINE_HACK
+ XDrawArc(Tk_Display(tkwin),d,gcf, b.x,b.y,b.width,b.height, 300*64,360*64);
+#endif
+ }
+}
+
+static void CheckIndicatorElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned state)
+{
+ Display *display = Tk_Display(tkwin);
+ IndicatorElement *indicator = elementRecord;
+ GC gcb=Ttk_GCForColor(tkwin,indicator->backgroundObj,d);
+ GC gcf=Ttk_GCForColor(tkwin,indicator->foregroundObj,d);
+ GC gcu=Ttk_GCForColor(tkwin,indicator->upperColorObj,d);
+ GC gcl=Ttk_GCForColor(tkwin,indicator->lowerColorObj,d);
+ Ttk_Padding padding;
+ const int w = WIN32_XDRAWLINE_HACK;
+
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
+ b = Ttk_PadBox(b, padding);
+
+ XFillRectangle(display,d,gcb, b.x,b.y,b.width,b.height);
+ XDrawLine(display,d,gcl,b.x,b.y+b.height,b.x+b.width+w,b.y+b.height);/*S*/
+ XDrawLine(display,d,gcl,b.x+b.width,b.y,b.x+b.width,b.y+b.height+w); /*E*/
+ XDrawLine(display,d,gcu,b.x,b.y, b.x,b.y+b.height+w); /*W*/
+ XDrawLine(display,d,gcu,b.x,b.y, b.x+b.width+w,b.y); /*N*/
+
+ if (state & TTK_STATE_SELECTED) {
+ int p,q,r,s;
+
+ b = Ttk_PadBox(b,Ttk_UniformPadding(2));
+ p = b.x, q = b.y, r = b.x+b.width, s = b.y+b.height;
+
+ r+=w, s+=w;
+ XDrawLine(display, d, gcf, p, q, r, s);
+ XDrawLine(display, d, gcf, p+1, q, r, s-1);
+ XDrawLine(display, d, gcf, p, q+1, r-1, s);
+
+ s-=w, q-=w;
+ XDrawLine(display, d, gcf, p, s, r, q);
+ XDrawLine(display, d, gcf, p+1, s, r, q+1);
+ XDrawLine(display, d, gcf, p, s-1, r-1, q);
+ }
+}
+
+static Ttk_ElementSpec RadioIndicatorElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(IndicatorElement),
+ IndicatorElementOptions,
+ IndicatorElementSize,
+ RadioIndicatorElementDraw
+};
+
+static Ttk_ElementSpec CheckIndicatorElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(IndicatorElement),
+ IndicatorElementOptions,
+ IndicatorElementSize,
+ CheckIndicatorElementDraw
+};
+
+#define MENUBUTTON_ARROW_SIZE 5
+
+typedef struct {
+ Tcl_Obj *sizeObj;
+ Tcl_Obj *colorObj;
+ Tcl_Obj *paddingObj;
+} MenuIndicatorElement;
+
+static Ttk_ElementOptionSpec MenuIndicatorElementOptions[] =
+{
+ { "-arrowsize", TK_OPTION_PIXELS,
+ Tk_Offset(MenuIndicatorElement,sizeObj),
+ STR(MENUBUTTON_ARROW_SIZE)},
+ { "-arrowcolor",TK_OPTION_COLOR,
+ Tk_Offset(MenuIndicatorElement,colorObj),
+ "black" },
+ { "-arrowpadding",TK_OPTION_STRING,
+ Tk_Offset(MenuIndicatorElement,paddingObj),
+ "3" },
+ { NULL, 0, 0, NULL }
+};
+
+static void MenuIndicatorElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ MenuIndicatorElement *indicator = elementRecord;
+ Ttk_Padding margins;
+ int size = MENUBUTTON_ARROW_SIZE;
+ Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->paddingObj, &margins);
+ TtkArrowSize(size, ARROW_DOWN, widthPtr, heightPtr);
+ *widthPtr += Ttk_PaddingWidth(margins);
+ *heightPtr += Ttk_PaddingHeight(margins);
+}
+
+static void MenuIndicatorElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ MenuIndicatorElement *indicator = elementRecord;
+ XColor *arrowColor = Tk_GetColorFromObj(tkwin, indicator->colorObj);
+ GC gc = Tk_GCForColor(arrowColor, d);
+ int size = MENUBUTTON_ARROW_SIZE;
+ int width, height;
+
+ Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);
+
+ TtkArrowSize(size, ARROW_DOWN, &width, &height);
+ b = Ttk_StickBox(b, width, height, 0);
+ TtkFillArrow(Tk_Display(tkwin), d, gc, b, ARROW_DOWN);
+}
+
+static Ttk_ElementSpec MenuIndicatorElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(MenuIndicatorElement),
+ MenuIndicatorElementOptions,
+ MenuIndicatorElementSize,
+ MenuIndicatorElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Grips.
+ *
+ * TODO: factor this with ThumbElementDraw
+ */
+
+static Ttk_Orient GripClientData[] = {
+ TTK_ORIENT_HORIZONTAL, TTK_ORIENT_VERTICAL
+};
+
+typedef struct {
+ Tcl_Obj *lightColorObj;
+ Tcl_Obj *borderColorObj;
+ Tcl_Obj *gripCountObj;
+} GripElement;
+
+static Ttk_ElementOptionSpec GripElementOptions[] = {
+ { "-lightcolor", TK_OPTION_COLOR,
+ Tk_Offset(GripElement,lightColorObj), LIGHT_COLOR },
+ { "-bordercolor", TK_OPTION_COLOR,
+ Tk_Offset(GripElement,borderColorObj), DARKEST_COLOR },
+ { "-gripcount", TK_OPTION_INT,
+ Tk_Offset(GripElement,gripCountObj), "5" },
+ { NULL, 0, 0, NULL }
+};
+
+static void GripElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ int horizontal = *((Ttk_Orient*)clientData) == TTK_ORIENT_HORIZONTAL;
+ GripElement *grip = elementRecord;
+ int gripCount = 0;
+
+ Tcl_GetIntFromObj(NULL, grip->gripCountObj, &gripCount);
+ if (horizontal) {
+ *widthPtr = 2*gripCount;
+ } else {
+ *heightPtr = 2*gripCount;
+ }
+}
+
+static void GripElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned state)
+{
+ const int w = WIN32_XDRAWLINE_HACK;
+ int horizontal = *((Ttk_Orient*)clientData) == TTK_ORIENT_HORIZONTAL;
+ GripElement *grip = elementRecord;
+ GC lightGC = Ttk_GCForColor(tkwin,grip->lightColorObj,d);
+ GC darkGC = Ttk_GCForColor(tkwin,grip->borderColorObj,d);
+ int gripPad = 1, gripCount = 0;
+ int i;
+
+ Tcl_GetIntFromObj(NULL, grip->gripCountObj, &gripCount);
+
+ if (horizontal) {
+ int x = b.x + b.width / 2 - gripCount;
+ int y1 = b.y + gripPad, y2 = b.y + b.height - gripPad - 1 + w;
+ for (i=0; i<gripCount; ++i) {
+ XDrawLine(Tk_Display(tkwin), d, darkGC, x,y1, x,y2); ++x;
+ XDrawLine(Tk_Display(tkwin), d, lightGC, x,y1, x,y2); ++x;
+ }
+ } else {
+ int y = b.y + b.height / 2 - gripCount;
+ int x1 = b.x + gripPad, x2 = b.x + b.width - gripPad - 1 + w;
+ for (i=0; i<gripCount; ++i) {
+ XDrawLine(Tk_Display(tkwin), d, darkGC, x1,y, x2,y); ++y;
+ XDrawLine(Tk_Display(tkwin), d, lightGC, x1,y, x2,y); ++y;
+ }
+ }
+}
+
+static Ttk_ElementSpec GripElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(GripElement),
+ GripElementOptions,
+ GripElementSize,
+ GripElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Scrollbar elements: trough, arrows, thumb.
+ *
+ * Notice that the trough element has 0 internal padding;
+ * that way the thumb and arrow borders overlap the trough.
+ */
+
+typedef struct { /* Common element record for scrollbar elements */
+ Tcl_Obj *orientObj;
+ Tcl_Obj *backgroundObj;
+ Tcl_Obj *borderColorObj;
+ Tcl_Obj *troughColorObj;
+ Tcl_Obj *lightColorObj;
+ Tcl_Obj *darkColorObj;
+ Tcl_Obj *arrowColorObj;
+ Tcl_Obj *arrowSizeObj;
+ Tcl_Obj *gripCountObj;
+ Tcl_Obj *sliderlengthObj;
+} ScrollbarElement;
+
+static Ttk_ElementOptionSpec ScrollbarElementOptions[] = {
+ { "-orient", TK_OPTION_ANY,
+ Tk_Offset(ScrollbarElement, orientObj), "horizontal" },
+ { "-background", TK_OPTION_BORDER,
+ Tk_Offset(ScrollbarElement,backgroundObj), FRAME_COLOR },
+ { "-bordercolor", TK_OPTION_COLOR,
+ Tk_Offset(ScrollbarElement,borderColorObj), DARKEST_COLOR },
+ { "-troughcolor", TK_OPTION_COLOR,
+ Tk_Offset(ScrollbarElement,troughColorObj), DARKER_COLOR },
+ { "-lightcolor", TK_OPTION_COLOR,
+ Tk_Offset(ScrollbarElement,lightColorObj), LIGHT_COLOR },
+ { "-darkcolor", TK_OPTION_COLOR,
+ Tk_Offset(ScrollbarElement,darkColorObj), DARK_COLOR },
+ { "-arrowcolor", TK_OPTION_COLOR,
+ Tk_Offset(ScrollbarElement,arrowColorObj), "#000000" },
+ { "-arrowsize", TK_OPTION_PIXELS,
+ Tk_Offset(ScrollbarElement,arrowSizeObj), STR(SCROLLBAR_THICKNESS) },
+ { "-gripcount", TK_OPTION_INT,
+ Tk_Offset(ScrollbarElement,gripCountObj), "5" },
+ { "-sliderlength", TK_OPTION_INT,
+ Tk_Offset(ScrollbarElement,sliderlengthObj), "30" },
+ { NULL, 0, 0, NULL }
+};
+
+static void TroughElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned state)
+{
+ ScrollbarElement *sb = elementRecord;
+ GC gcb = Ttk_GCForColor(tkwin,sb->borderColorObj,d);
+ GC gct = Ttk_GCForColor(tkwin,sb->troughColorObj,d);
+ XFillRectangle(Tk_Display(tkwin), d, gct, b.x, b.y, b.width-1, b.height-1);
+ XDrawRectangle(Tk_Display(tkwin), d, gcb, b.x, b.y, b.width-1, b.height-1);
+}
+
+static Ttk_ElementSpec TroughElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(ScrollbarElement),
+ ScrollbarElementOptions,
+ TtkNullElementSize,
+ TroughElementDraw
+};
+
+static void ThumbElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ ScrollbarElement *sb = elementRecord;
+ int size = SCROLLBAR_THICKNESS;
+ Tcl_GetIntFromObj(NULL, sb->arrowSizeObj, &size);
+ *widthPtr = *heightPtr = size;
+}
+
+static void ThumbElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned state)
+{
+ ScrollbarElement *sb = elementRecord;
+ int gripCount = 0, orient = TTK_ORIENT_HORIZONTAL;
+ GC lightGC, darkGC;
+ int x1, y1, x2, y2, dx, dy, i;
+ const int w = WIN32_XDRAWLINE_HACK;
+
+ DrawSmoothBorder(tkwin, d, b,
+ sb->borderColorObj, sb->lightColorObj, sb->darkColorObj);
+ XFillRectangle(
+ Tk_Display(tkwin), d, BackgroundGC(tkwin, sb->backgroundObj),
+ b.x+2, b.y+2, b.width-4, b.height-4);
+
+ /*
+ * Draw grip:
+ */
+ Ttk_GetOrientFromObj(NULL, sb->orientObj, &orient);
+ Tcl_GetIntFromObj(NULL, sb->gripCountObj, &gripCount);
+ lightGC = Ttk_GCForColor(tkwin,sb->lightColorObj,d);
+ darkGC = Ttk_GCForColor(tkwin,sb->borderColorObj,d);
+
+ if (orient == TTK_ORIENT_HORIZONTAL) {
+ dx = 1; dy = 0;
+ x1 = x2 = b.x + b.width / 2 - gripCount;
+ y1 = b.y + 2;
+ y2 = b.y + b.height - 3 + w;
+ } else {
+ dx = 0; dy = 1;
+ y1 = y2 = b.y + b.height / 2 - gripCount;
+ x1 = b.x + 2;
+ x2 = b.x + b.width - 3 + w;
+ }
+
+ for (i=0; i<gripCount; ++i) {
+ XDrawLine(Tk_Display(tkwin), d, darkGC, x1,y1, x2,y2);
+ x1 += dx; x2 += dx; y1 += dy; y2 += dy;
+ XDrawLine(Tk_Display(tkwin), d, lightGC, x1,y1, x2,y2);
+ x1 += dx; x2 += dx; y1 += dy; y2 += dy;
+ }
+}
+
+static Ttk_ElementSpec ThumbElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(ScrollbarElement),
+ ScrollbarElementOptions,
+ ThumbElementSize,
+ ThumbElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Slider element.
+ */
+static void SliderElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ ScrollbarElement *sb = elementRecord;
+ int length, thickness, orient;
+
+ length = thickness = SCROLLBAR_THICKNESS;
+ Ttk_GetOrientFromObj(NULL, sb->orientObj, &orient);
+ Tcl_GetIntFromObj(NULL, sb->arrowSizeObj, &thickness);
+ Tk_GetPixelsFromObj(NULL, tkwin, sb->sliderlengthObj, &length);
+ if (orient == TTK_ORIENT_VERTICAL) {
+ *heightPtr = length;
+ *widthPtr = thickness;
+ } else {
+ *heightPtr = thickness;
+ *widthPtr = length;
+ }
+
+}
+
+static Ttk_ElementSpec SliderElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(ScrollbarElement),
+ ScrollbarElementOptions,
+ SliderElementSize,
+ ThumbElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Progress bar element
+ */
+static void PbarElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ SliderElementSize(clientData, elementRecord, tkwin,
+ widthPtr, heightPtr, paddingPtr);
+ *paddingPtr = Ttk_UniformPadding(2);
+ *widthPtr += 4;
+ *heightPtr += 4;
+}
+
+static void PbarElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned state)
+{
+ ScrollbarElement *sb = elementRecord;
+
+ b = Ttk_PadBox(b, Ttk_UniformPadding(2));
+ if (b.width > 4 && b.height > 4) {
+ DrawSmoothBorder(tkwin, d, b,
+ sb->borderColorObj, sb->lightColorObj, sb->darkColorObj);
+ XFillRectangle(Tk_Display(tkwin), d,
+ BackgroundGC(tkwin, sb->backgroundObj),
+ b.x+2, b.y+2, b.width-4, b.height-4);
+ }
+}
+
+static Ttk_ElementSpec PbarElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(ScrollbarElement),
+ ScrollbarElementOptions,
+ PbarElementSize,
+ PbarElementDraw
+};
+
+
+/*------------------------------------------------------------------------
+ * +++ Scrollbar arrows.
+ */
+static int ArrowElements[] = { ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT };
+
+static void ArrowElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ ScrollbarElement *sb = elementRecord;
+ int size = SCROLLBAR_THICKNESS;
+ Tcl_GetIntFromObj(NULL, sb->arrowSizeObj, &size);
+ *widthPtr = *heightPtr = size;
+}
+
+static void ArrowElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned state)
+{
+ ArrowDirection dir = *(ArrowDirection*)clientData;
+ ScrollbarElement *sb = elementRecord;
+ GC gc = Ttk_GCForColor(tkwin,sb->arrowColorObj, d);
+ int h, cx, cy;
+
+ DrawSmoothBorder(tkwin, d, b,
+ sb->borderColorObj, sb->lightColorObj, sb->darkColorObj);
+
+ XFillRectangle(
+ Tk_Display(tkwin), d, BackgroundGC(tkwin, sb->backgroundObj),
+ b.x+2, b.y+2, b.width-4, b.height-4);
+
+ b = Ttk_PadBox(b, Ttk_UniformPadding(3));
+ h = b.width < b.height ? b.width : b.height;
+ TtkArrowSize(h/2, dir, &cx, &cy);
+ b = Ttk_AnchorBox(b, cx, cy, TK_ANCHOR_CENTER);
+
+ TtkFillArrow(Tk_Display(tkwin), d, gc, b, dir);
+}
+
+static Ttk_ElementSpec ArrowElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(ScrollbarElement),
+ ScrollbarElementOptions,
+ ArrowElementSize,
+ ArrowElementDraw
+};
+
+
+/*------------------------------------------------------------------------
+ * +++ Notebook elements.
+ *
+ * Note: Tabs, except for the rightmost, overlap the neighbor to
+ * their right by one pixel.
+ */
+
+typedef struct {
+ Tcl_Obj *backgroundObj;
+ Tcl_Obj *borderColorObj;
+ Tcl_Obj *lightColorObj;
+ Tcl_Obj *darkColorObj;
+} NotebookElement;
+
+static Ttk_ElementOptionSpec NotebookElementOptions[] = {
+ { "-background", TK_OPTION_BORDER,
+ Tk_Offset(NotebookElement,backgroundObj), FRAME_COLOR },
+ { "-bordercolor", TK_OPTION_COLOR,
+ Tk_Offset(NotebookElement,borderColorObj), DARKEST_COLOR },
+ { "-lightcolor", TK_OPTION_COLOR,
+ Tk_Offset(NotebookElement,lightColorObj), LIGHT_COLOR },
+ { "-darkcolor", TK_OPTION_COLOR,
+ Tk_Offset(NotebookElement,darkColorObj), DARK_COLOR },
+ { NULL, 0, 0, NULL }
+};
+
+static void TabElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ int borderWidth = 2;
+ paddingPtr->top = paddingPtr->left = paddingPtr->right = borderWidth;
+ paddingPtr->bottom = 0;
+}
+
+static void TabElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ NotebookElement *tab = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, tab->backgroundObj);
+ Display *display = Tk_Display(tkwin);
+ int borderWidth = 2, dh = 0;
+ int x1,y1,x2,y2;
+ GC gc;
+ const int w = WIN32_XDRAWLINE_HACK;
+
+ if (state & TTK_STATE_SELECTED) {
+ dh = borderWidth;
+ }
+
+ if (state & TTK_STATE_USER2) { /* Rightmost tab */
+ --b.width;
+ }
+
+ Tk_Fill3DRectangle(tkwin, d, border,
+ b.x+2, b.y+2, b.width-1, b.height-2+dh, borderWidth, TK_RELIEF_FLAT);
+
+ x1 = b.x, x2 = b.x + b.width;
+ y1 = b.y, y2 = b.y + b.height;
+
+
+ gc=Ttk_GCForColor(tkwin,tab->borderColorObj,d);
+ XDrawLine(display,d,gc, x1,y1+1, x1,y2+w);
+ XDrawLine(display,d,gc, x2,y1+1, x2,y2+w);
+ XDrawLine(display,d,gc, x1+1,y1, x2-1+w,y1);
+
+ gc=Ttk_GCForColor(tkwin,tab->lightColorObj,d);
+ XDrawLine(display,d,gc, x1+1,y1+1, x1+1,y2-1+dh+w);
+ XDrawLine(display,d,gc, x1+1,y1+1, x2-1+w,y1+1);
+}
+
+static Ttk_ElementSpec TabElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(NotebookElement),
+ NotebookElementOptions,
+ TabElementSize,
+ TabElementDraw
+};
+
+static void ClientElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ int borderWidth = 2;
+ *paddingPtr = Ttk_UniformPadding((short)borderWidth);
+}
+
+static void ClientElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ NotebookElement *ce = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, ce->backgroundObj);
+ int borderWidth = 2;
+
+ Tk_Fill3DRectangle(tkwin, d, border,
+ b.x, b.y, b.width, b.height, borderWidth,TK_RELIEF_FLAT);
+ DrawSmoothBorder(tkwin, d, b,
+ ce->borderColorObj, ce->lightColorObj, ce->darkColorObj);
+}
+
+static Ttk_ElementSpec ClientElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(NotebookElement),
+ NotebookElementOptions,
+ ClientElementSize,
+ ClientElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Modified widget layouts.
+ */
+
+TTK_BEGIN_LAYOUT_TABLE(LayoutTable)
+
+TTK_LAYOUT("TCombobox",
+ TTK_NODE("Combobox.downarrow", TTK_PACK_RIGHT|TTK_FILL_Y)
+ TTK_GROUP("Combobox.field", TTK_PACK_LEFT|TTK_FILL_BOTH|TTK_EXPAND,
+ TTK_GROUP("Combobox.padding", TTK_FILL_BOTH,
+ TTK_NODE("Combobox.textarea", TTK_FILL_BOTH))))
+
+TTK_LAYOUT("Horizontal.Sash",
+ TTK_GROUP("Sash.hsash", TTK_FILL_BOTH,
+ TTK_NODE("Sash.hgrip", TTK_FILL_BOTH)))
+
+TTK_LAYOUT("Vertical.Sash",
+ TTK_GROUP("Sash.vsash", TTK_FILL_BOTH,
+ TTK_NODE("Sash.vgrip", TTK_FILL_BOTH)))
+
+TTK_END_LAYOUT_TABLE
+
+/*------------------------------------------------------------------------
+ * +++ Initialization.
+ */
+
+MODULE_SCOPE int
+TtkClamTheme_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme theme = Ttk_CreateTheme(interp, "clam", 0);
+
+ if (!theme) {
+ return TCL_ERROR;
+ }
+
+ Ttk_RegisterElement(interp,
+ theme, "border", &BorderElementSpec, NULL);
+ Ttk_RegisterElement(interp,
+ theme, "field", &FieldElementSpec, NULL);
+ Ttk_RegisterElement(interp,
+ theme, "Combobox.field", &ComboboxFieldElementSpec, NULL);
+ Ttk_RegisterElement(interp,
+ theme, "trough", &TroughElementSpec, NULL);
+ Ttk_RegisterElement(interp,
+ theme, "thumb", &ThumbElementSpec, NULL);
+ Ttk_RegisterElement(interp,
+ theme, "uparrow", &ArrowElementSpec, &ArrowElements[0]);
+ Ttk_RegisterElement(interp,
+ theme, "downarrow", &ArrowElementSpec, &ArrowElements[1]);
+ Ttk_RegisterElement(interp,
+ theme, "leftarrow", &ArrowElementSpec, &ArrowElements[2]);
+ Ttk_RegisterElement(interp,
+ theme, "rightarrow", &ArrowElementSpec, &ArrowElements[3]);
+
+ Ttk_RegisterElement(interp,
+ theme, "Radiobutton.indicator", &RadioIndicatorElementSpec, NULL);
+ Ttk_RegisterElement(interp,
+ theme, "Checkbutton.indicator", &CheckIndicatorElementSpec, NULL);
+ Ttk_RegisterElement(interp,
+ theme, "Menubutton.indicator", &MenuIndicatorElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "tab", &TabElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "client", &ClientElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "slider", &SliderElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "bar", &PbarElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "pbar", &PbarElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "hgrip",
+ &GripElementSpec, &GripClientData[0]);
+ Ttk_RegisterElement(interp, theme, "vgrip",
+ &GripElementSpec, &GripClientData[1]);
+
+ Ttk_RegisterLayouts(theme, LayoutTable);
+
+ Tcl_PkgProvide(interp, "ttk::theme::clam", TTK_VERSION);
+
+ return TCL_OK;
+}
diff --git a/generic/ttk/ttkClassicTheme.c b/generic/ttk/ttkClassicTheme.c
new file mode 100644
index 0000000..2fbcd76
--- /dev/null
+++ b/generic/ttk/ttkClassicTheme.c
@@ -0,0 +1,513 @@
+/*
+ * Copyright (c) 2004, Joe English
+ *
+ * "classic" theme; implements the classic Motif-like Tk look.
+ *
+ */
+
+#include <tk.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "ttkTheme.h"
+
+#define DEFAULT_BORDERWIDTH "2"
+#define DEFAULT_ARROW_SIZE "15"
+
+/*----------------------------------------------------------------------
+ * +++ Highlight element implementation.
+ * Draw a solid highlight border to indicate focus.
+ */
+
+typedef struct {
+ Tcl_Obj *highlightColorObj;
+ Tcl_Obj *highlightThicknessObj;
+} HighlightElement;
+
+static Ttk_ElementOptionSpec HighlightElementOptions[] = {
+ { "-highlightcolor",TK_OPTION_COLOR,
+ Tk_Offset(HighlightElement,highlightColorObj), DEFAULT_BACKGROUND },
+ { "-highlightthickness",TK_OPTION_PIXELS,
+ Tk_Offset(HighlightElement,highlightThicknessObj), "0" },
+ { NULL, 0, 0, NULL }
+};
+
+static void HighlightElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ HighlightElement *hl = elementRecord;
+ int highlightThickness = 0;
+
+ Tcl_GetIntFromObj(NULL,hl->highlightThicknessObj,&highlightThickness);
+ *paddingPtr = Ttk_UniformPadding((short)highlightThickness);
+}
+
+static void HighlightElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ HighlightElement *hl = elementRecord;
+ int highlightThickness = 0;
+ XColor *highlightColor = Tk_GetColorFromObj(tkwin, hl->highlightColorObj);
+
+ Tcl_GetIntFromObj(NULL,hl->highlightThicknessObj,&highlightThickness);
+ if (highlightColor && highlightThickness > 0) {
+ GC gc = Tk_GCForColor(highlightColor, d);
+ Tk_DrawFocusHighlight(tkwin, gc, highlightThickness, d);
+ }
+}
+
+static Ttk_ElementSpec HighlightElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(HighlightElement),
+ HighlightElementOptions,
+ HighlightElementSize,
+ HighlightElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Button Border element:
+ *
+ * The Motif-style button border on X11 consists of (from outside-in):
+ *
+ * + focus indicator (controlled by -highlightcolor and -highlightthickness),
+ * + default ring (if -default active; blank if -default normal)
+ * + shaded border (controlled by -background, -borderwidth, and -relief)
+ */
+
+typedef struct {
+ Tcl_Obj *borderObj;
+ Tcl_Obj *borderWidthObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *defaultStateObj;
+} ButtonBorderElement;
+
+static Ttk_ElementOptionSpec ButtonBorderElementOptions[] =
+{
+ { "-background", TK_OPTION_BORDER,
+ Tk_Offset(ButtonBorderElement,borderObj), DEFAULT_BACKGROUND },
+ { "-borderwidth", TK_OPTION_PIXELS,
+ Tk_Offset(ButtonBorderElement,borderWidthObj), DEFAULT_BORDERWIDTH },
+ { "-relief", TK_OPTION_RELIEF,
+ Tk_Offset(ButtonBorderElement,reliefObj), "flat" },
+ { "-default", TK_OPTION_ANY,
+ Tk_Offset(ButtonBorderElement,defaultStateObj), "disabled" },
+ { NULL, 0, 0, NULL }
+};
+
+static void ButtonBorderElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ ButtonBorderElement *bd = elementRecord;
+ int defaultState = TTK_BUTTON_DEFAULT_DISABLED;
+ int borderWidth = 0;
+
+ Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
+ Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);
+
+ if (defaultState != TTK_BUTTON_DEFAULT_DISABLED) {
+ borderWidth += 5;
+ }
+ *paddingPtr = Ttk_UniformPadding((short)borderWidth);
+}
+
+/*
+ * (@@@ Note: ButtonBorderElement still still still buggy:
+ * padding for default ring is drawn in the wrong color
+ * when the button is active.)
+ */
+static void ButtonBorderElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ ButtonBorderElement *bd = elementRecord;
+ Tk_3DBorder border = NULL;
+ int borderWidth = 1, relief = TK_RELIEF_FLAT;
+ int defaultState = TTK_BUTTON_DEFAULT_DISABLED;
+ int inset = 0;
+
+ /*
+ * Get option values.
+ */
+ border = Tk_Get3DBorderFromObj(tkwin, bd->borderObj);
+ Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
+ Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
+ Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);
+
+ /*
+ * Default ring:
+ */
+ switch (defaultState)
+ {
+ case TTK_BUTTON_DEFAULT_DISABLED :
+ break;
+ case TTK_BUTTON_DEFAULT_NORMAL :
+ inset += 5;
+ break;
+ case TTK_BUTTON_DEFAULT_ACTIVE :
+ Tk_Draw3DRectangle(tkwin, d, border,
+ b.x+inset, b.y+inset, b.width - 2*inset, b.height - 2*inset,
+ 2, TK_RELIEF_FLAT);
+ inset += 2;
+ Tk_Draw3DRectangle(tkwin, d, border,
+ b.x+inset, b.y+inset, b.width - 2*inset, b.height - 2*inset,
+ 1, TK_RELIEF_SUNKEN);
+ ++inset;
+ Tk_Draw3DRectangle(tkwin, d, border,
+ b.x+inset, b.y+inset, b.width - 2*inset, b.height - 2*inset,
+ 2, TK_RELIEF_FLAT);
+ inset += 2;
+ break;
+ }
+
+ /*
+ * 3-D border:
+ */
+ if (border && borderWidth > 0) {
+ Tk_Draw3DRectangle(tkwin, d, border,
+ b.x+inset, b.y+inset, b.width - 2*inset, b.height - 2*inset,
+ borderWidth,relief);
+ }
+}
+
+static Ttk_ElementSpec ButtonBorderElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(ButtonBorderElement),
+ ButtonBorderElementOptions,
+ ButtonBorderElementSize,
+ ButtonBorderElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Arrow element(s).
+ *
+ * Draws a 3-D shaded triangle.
+ * clientData is an enum ArrowDirection pointer.
+ */
+
+static int ArrowElements[] = { ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT };
+typedef struct
+{
+ Tcl_Obj *sizeObj;
+ Tcl_Obj *borderObj;
+ Tcl_Obj *borderWidthObj;
+ Tcl_Obj *reliefObj;
+} ArrowElement;
+
+static Ttk_ElementOptionSpec ArrowElementOptions[] =
+{
+ { "-arrowsize", TK_OPTION_PIXELS, Tk_Offset(ArrowElement,sizeObj),
+ DEFAULT_ARROW_SIZE },
+ { "-background", TK_OPTION_BORDER, Tk_Offset(ArrowElement,borderObj),
+ DEFAULT_BACKGROUND },
+ { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(ArrowElement,borderWidthObj),
+ DEFAULT_BORDERWIDTH },
+ { "-relief", TK_OPTION_RELIEF, Tk_Offset(ArrowElement,reliefObj),"raised" },
+ { NULL, 0, 0, NULL }
+};
+
+static void ArrowElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ ArrowElement *arrow = elementRecord;
+ int size = 12;
+
+ Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
+ *widthPtr = *heightPtr = size;
+}
+
+static void ArrowElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ int direction = *(int *)clientData;
+ ArrowElement *arrow = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
+ int borderWidth = 2;
+ int relief = TK_RELIEF_RAISED;
+ int size = b.width < b.height ? b.width : b.height;
+ XPoint points[3];
+
+ Tk_GetPixelsFromObj(NULL, tkwin, arrow->borderWidthObj, &borderWidth);
+ Tk_GetReliefFromObj(NULL, arrow->reliefObj, &relief);
+
+
+ /*
+ * @@@ There are off-by-one pixel errors in the way these are drawn;
+ * @@@ need to take a look at Tk_Fill3DPolygon and X11 to find the
+ * @@@ exact rules.
+ */
+ switch (direction)
+ {
+ case ARROW_UP:
+ points[2].x = b.x; points[2].y = b.y + size;
+ points[1].x = b.x + size/2; points[1].y = b.y;
+ points[0].x = b.x + size; points[0].y = b.y + size;
+ break;
+ case ARROW_DOWN:
+ points[0].x = b.x; points[0].y = b.y;
+ points[1].x = b.x + size/2; points[1].y = b.y + size;
+ points[2].x = b.x + size; points[2].y = b.y;
+ break;
+ case ARROW_LEFT:
+ points[0].x = b.x; points[0].y = b.y + size / 2;
+ points[1].x = b.x + size; points[1].y = b.y + size;
+ points[2].x = b.x + size; points[2].y = b.y;
+ break;
+ case ARROW_RIGHT:
+ points[0].x = b.x + size; points[0].y = b.y + size / 2;
+ points[1].x = b.x; points[1].y = b.y;
+ points[2].x = b.x; points[2].y = b.y + size;
+ break;
+ }
+
+ Tk_Fill3DPolygon(tkwin, d, border, points, 3, borderWidth, relief);
+}
+
+static Ttk_ElementSpec ArrowElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(ArrowElement),
+ ArrowElementOptions,
+ ArrowElementSize,
+ ArrowElementDraw
+};
+
+
+/*------------------------------------------------------------------------
+ * +++ Sash element (for ttk::panedwindow)
+ *
+ * NOTES:
+ *
+ * panedwindows with -orient horizontal use vertical sashes, and vice versa.
+ *
+ * Interpretation of -sashrelief 'groove' and 'ridge' are
+ * swapped wrt. the core panedwindow, which (I think) has them backwards.
+ *
+ * Default -sashrelief is sunken; the core panedwindow has default
+ * -sashrelief raised, but that looks wrong to me.
+ */
+
+static Ttk_Orient SashClientData[] = {
+ TTK_ORIENT_HORIZONTAL, TTK_ORIENT_VERTICAL
+};
+
+typedef struct {
+ Tcl_Obj *borderObj; /* background color */
+ Tcl_Obj *sashReliefObj; /* sash relief */
+ Tcl_Obj *sashThicknessObj; /* overall thickness of sash */
+ Tcl_Obj *sashPadObj; /* padding on either side of handle */
+ Tcl_Obj *handleSizeObj; /* handle width and height */
+ Tcl_Obj *handlePadObj; /* handle's distance from edge */
+} SashElement;
+
+static Ttk_ElementOptionSpec SashOptions[] = {
+ { "-background", TK_OPTION_BORDER,
+ Tk_Offset(SashElement,borderObj), DEFAULT_BACKGROUND },
+ { "-sashrelief", TK_OPTION_RELIEF,
+ Tk_Offset(SashElement,sashReliefObj), "sunken" },
+ { "-sashthickness", TK_OPTION_PIXELS,
+ Tk_Offset(SashElement,sashThicknessObj), "6" },
+ { "-sashpad", TK_OPTION_PIXELS,
+ Tk_Offset(SashElement,sashPadObj), "2" },
+ { "-handlesize", TK_OPTION_PIXELS,
+ Tk_Offset(SashElement,handleSizeObj), "8" },
+ { "-handlepad", TK_OPTION_PIXELS,
+ Tk_Offset(SashElement,handlePadObj), "8" },
+ { NULL, 0, 0, NULL }
+};
+
+static void SashElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ SashElement *sash = elementRecord;
+ int sashPad = 2, sashThickness = 6, handleSize = 8;
+ int horizontal = *((Ttk_Orient*)clientData) == TTK_ORIENT_HORIZONTAL;
+
+ Tk_GetPixelsFromObj(NULL, tkwin, sash->sashThicknessObj, &sashThickness);
+ Tk_GetPixelsFromObj(NULL, tkwin, sash->handleSizeObj, &handleSize);
+ Tk_GetPixelsFromObj(NULL, tkwin, sash->sashPadObj, &sashPad);
+
+ if (sashThickness < handleSize + 2*sashPad)
+ sashThickness = handleSize + 2*sashPad;
+
+ if (horizontal)
+ *heightPtr = sashThickness;
+ else
+ *widthPtr = sashThickness;
+}
+
+static void SashElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, Ttk_State state)
+{
+ SashElement *sash = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, sash->borderObj);
+ GC gc1,gc2;
+ int relief = TK_RELIEF_RAISED;
+ int handleSize = 8, handlePad = 8;
+ int horizontal = *((Ttk_Orient*)clientData) == TTK_ORIENT_HORIZONTAL;
+ Ttk_Box hb;
+
+ Tk_GetPixelsFromObj(NULL, tkwin, sash->handleSizeObj, &handleSize);
+ Tk_GetPixelsFromObj(NULL, tkwin, sash->handlePadObj, &handlePad);
+ Tk_GetReliefFromObj(NULL, sash->sashReliefObj, &relief);
+
+ switch (relief) {
+ case TK_RELIEF_RAISED: case TK_RELIEF_RIDGE:
+ gc1 = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
+ gc2 = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
+ break;
+ case TK_RELIEF_SUNKEN: case TK_RELIEF_GROOVE:
+ gc1 = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
+ gc2 = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
+ break;
+ case TK_RELIEF_SOLID:
+ gc1 = gc2 = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
+ break;
+ case TK_RELIEF_FLAT:
+ default:
+ gc1 = gc2 = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
+ break;
+ }
+
+ /* Draw sash line:
+ */
+ if (horizontal) {
+ int y = b.y + b.height/2 - 1;
+ XDrawLine(Tk_Display(tkwin), d, gc1, b.x, y, b.x+b.width, y); ++y;
+ XDrawLine(Tk_Display(tkwin), d, gc2, b.x, y, b.x+b.width, y);
+ } else {
+ int x = b.x + b.width/2 - 1;
+ XDrawLine(Tk_Display(tkwin), d, gc1, x, b.y, x, b.y+b.height); ++x;
+ XDrawLine(Tk_Display(tkwin), d, gc2, x, b.y, x, b.y+b.height);
+ }
+
+ /* Draw handle:
+ */
+ if (handleSize >= 0) {
+ if (horizontal) {
+ hb = Ttk_StickBox(b, handleSize, handleSize, TTK_STICK_W);
+ hb.x += handlePad;
+ } else {
+ hb = Ttk_StickBox(b, handleSize, handleSize, TTK_STICK_N);
+ hb.y += handlePad;
+ }
+ Tk_Fill3DRectangle(tkwin, d, border,
+ hb.x, hb.y, hb.width, hb.height, 1, TK_RELIEF_RAISED);
+ }
+}
+
+static Ttk_ElementSpec SashElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(SashElement),
+ SashOptions,
+ SashElementSize,
+ SashElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Widget layouts.
+ */
+
+TTK_BEGIN_LAYOUT_TABLE(LayoutTable)
+
+TTK_LAYOUT("TButton",
+ TTK_GROUP("Button.highlight", TTK_FILL_BOTH,
+ TTK_GROUP("Button.border", TTK_FILL_BOTH|TTK_BORDER,
+ TTK_GROUP("Button.padding", TTK_FILL_BOTH,
+ TTK_NODE("Button.label", TTK_FILL_BOTH)))))
+
+TTK_LAYOUT("TCheckbutton",
+ TTK_GROUP("Checkbutton.highlight", TTK_FILL_BOTH,
+ TTK_GROUP("Checkbutton.border", TTK_FILL_BOTH,
+ TTK_GROUP("Checkbutton.padding", TTK_FILL_BOTH,
+ TTK_NODE("Checkbutton.indicator", TTK_PACK_LEFT)
+ TTK_NODE("Checkbutton.label", TTK_PACK_LEFT|TTK_FILL_BOTH)))))
+
+TTK_LAYOUT("TRadiobutton",
+ TTK_GROUP("Radiobutton.highlight", TTK_FILL_BOTH,
+ TTK_GROUP("Radiobutton.border", TTK_FILL_BOTH,
+ TTK_GROUP("Radiobutton.padding", TTK_FILL_BOTH,
+ TTK_NODE("Radiobutton.indicator", TTK_PACK_LEFT)
+ TTK_NODE("Radiobutton.label", TTK_PACK_LEFT|TTK_FILL_BOTH)))))
+
+TTK_LAYOUT("TMenubutton",
+ TTK_GROUP("Menubutton.highlight", TTK_FILL_BOTH,
+ TTK_GROUP("Menubutton.border", TTK_FILL_BOTH,
+ TTK_NODE("Menubutton.indicator", TTK_PACK_RIGHT)
+ TTK_GROUP("Menubutton.padding", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_X,
+ TTK_NODE("Menubutton.label", 0)))))
+
+/* "classic" entry, includes highlight border */
+TTK_LAYOUT("TEntry",
+ TTK_GROUP("Entry.highlight", TTK_FILL_BOTH,
+ TTK_GROUP("Entry.field", TTK_FILL_BOTH|TTK_BORDER,
+ TTK_GROUP("Entry.padding", TTK_FILL_BOTH,
+ TTK_NODE("Entry.textarea", TTK_FILL_BOTH)))))
+
+/* Notebook tabs -- omit focus ring */
+TTK_LAYOUT("Tab",
+ TTK_GROUP("Notebook.tab", TTK_FILL_BOTH,
+ TTK_GROUP("Notebook.padding", TTK_FILL_BOTH,
+ TTK_NODE("Notebook.label", TTK_FILL_BOTH))))
+
+TTK_END_LAYOUT_TABLE
+
+/* POSSIBLY: include Scale layouts w/focus border
+ */
+
+/*------------------------------------------------------------------------
+ * TtkClassicTheme_Init --
+ * Install classic theme.
+ */
+
+MODULE_SCOPE int TtkClassicTheme_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme theme = Ttk_CreateTheme(interp, "classic", NULL);
+
+ if (!theme) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Register elements:
+ */
+ Ttk_RegisterElement(interp, theme, "highlight",
+ &HighlightElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "Button.border",
+ &ButtonBorderElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "uparrow",
+ &ArrowElementSpec, &ArrowElements[0]);
+ Ttk_RegisterElement(interp, theme, "downarrow",
+ &ArrowElementSpec, &ArrowElements[1]);
+ Ttk_RegisterElement(interp, theme, "leftarrow",
+ &ArrowElementSpec, &ArrowElements[2]);
+ Ttk_RegisterElement(interp, theme, "rightarrow",
+ &ArrowElementSpec, &ArrowElements[3]);
+ Ttk_RegisterElement(interp, theme, "arrow",
+ &ArrowElementSpec, &ArrowElements[0]);
+
+ Ttk_RegisterElement(interp, theme, "hsash",
+ &SashElementSpec, &SashClientData[0]);
+ Ttk_RegisterElement(interp, theme, "vsash",
+ &SashElementSpec, &SashClientData[1]);
+
+ /*
+ * Register layouts:
+ */
+ Ttk_RegisterLayouts(theme, LayoutTable);
+
+ Tcl_PkgProvide(interp, "ttk::theme::classic", TTK_VERSION);
+
+ return TCL_OK;
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkDecls.h b/generic/ttk/ttkDecls.h
new file mode 100644
index 0000000..ee679b7
--- /dev/null
+++ b/generic/ttk/ttkDecls.h
@@ -0,0 +1,272 @@
+/*
+ * This file is (mostly) automatically generated from ttk.decls.
+ */
+
+#ifndef _TTKDECLS
+#define _TTKDECLS
+
+#if defined(USE_TTK_STUBS)
+
+extern const char *TtkInitializeStubs(
+ Tcl_Interp *, const char *version, int epoch, int revision);
+#define Ttk_InitStubs(interp) TtkInitializeStubs( \
+ interp, TTK_VERSION, TTK_STUBS_EPOCH, TTK_STUBS_REVISION)
+#else
+
+#define Ttk_InitStubs(interp) Tcl_PkgRequire(interp, "Ttk", TTK_VERSION, 0)
+
+#endif
+
+
+/* !BEGIN!: Do not edit below this line. */
+
+#define TTK_STUBS_EPOCH 0
+#define TTK_STUBS_REVISION 31
+
+/*
+ * Exported function declarations:
+ */
+
+/* 0 */
+TTKAPI Ttk_Theme Ttk_GetTheme(Tcl_Interp *interp, CONST char *name);
+/* 1 */
+TTKAPI Ttk_Theme Ttk_GetDefaultTheme(Tcl_Interp *interp);
+/* 2 */
+TTKAPI Ttk_Theme Ttk_GetCurrentTheme(Tcl_Interp *interp);
+/* 3 */
+TTKAPI Ttk_Theme Ttk_CreateTheme(Tcl_Interp *interp, CONST char *name,
+ Ttk_Theme parent);
+/* 4 */
+TTKAPI void Ttk_RegisterCleanup(Tcl_Interp *interp,
+ VOID *deleteData,
+ Ttk_CleanupProc *cleanupProc);
+/* 5 */
+TTKAPI int Ttk_RegisterElementSpec(Ttk_Theme theme,
+ CONST char *elementName,
+ Ttk_ElementSpec *elementSpec,
+ VOID *clientData);
+/* 6 */
+TTKAPI Ttk_ElementClass * Ttk_RegisterElement(Tcl_Interp *interp,
+ Ttk_Theme theme, CONST char *elementName,
+ Ttk_ElementSpec *elementSpec,
+ VOID *clientData);
+/* 7 */
+TTKAPI int Ttk_RegisterElementFactory(Tcl_Interp *interp,
+ CONST char *name,
+ Ttk_ElementFactory factoryProc,
+ VOID *clientData);
+/* 8 */
+TTKAPI void Ttk_RegisterLayout(Ttk_Theme theme,
+ CONST char *className,
+ Ttk_LayoutSpec layoutSpec);
+/* Slot 9 is reserved */
+/* 10 */
+TTKAPI int Ttk_GetStateSpecFromObj(Tcl_Interp *interp,
+ Tcl_Obj *objPtr, Ttk_StateSpec *spec_rtn);
+/* 11 */
+TTKAPI Tcl_Obj * Ttk_NewStateSpecObj(unsigned int onbits,
+ unsigned int offbits);
+/* 12 */
+TTKAPI Ttk_StateMap Ttk_GetStateMapFromObj(Tcl_Interp *interp,
+ Tcl_Obj *objPtr);
+/* 13 */
+TTKAPI Tcl_Obj * Ttk_StateMapLookup(Tcl_Interp *interp,
+ Ttk_StateMap map, Ttk_State state);
+/* 14 */
+TTKAPI int Ttk_StateTableLookup(Ttk_StateTable map[],
+ Ttk_State state);
+/* Slot 15 is reserved */
+/* Slot 16 is reserved */
+/* Slot 17 is reserved */
+/* Slot 18 is reserved */
+/* Slot 19 is reserved */
+/* 20 */
+TTKAPI int Ttk_GetPaddingFromObj(Tcl_Interp *interp,
+ Tk_Window tkwin, Tcl_Obj *objPtr,
+ Ttk_Padding *pad_rtn);
+/* 21 */
+TTKAPI int Ttk_GetBorderFromObj(Tcl_Interp *interp,
+ Tcl_Obj *objPtr, Ttk_Padding *pad_rtn);
+/* 22 */
+TTKAPI int Ttk_GetStickyFromObj(Tcl_Interp *interp,
+ Tcl_Obj *objPtr, Ttk_Sticky *sticky_rtn);
+/* 23 */
+TTKAPI Ttk_Padding Ttk_MakePadding(short l, short t, short r, short b);
+/* 24 */
+TTKAPI Ttk_Padding Ttk_UniformPadding(short borderWidth);
+/* 25 */
+TTKAPI Ttk_Padding Ttk_AddPadding(Ttk_Padding pad1, Ttk_Padding pad2);
+/* 26 */
+TTKAPI Ttk_Padding Ttk_RelievePadding(Ttk_Padding padding, int relief,
+ int n);
+/* 27 */
+TTKAPI Ttk_Box Ttk_MakeBox(int x, int y, int width, int height);
+/* 28 */
+TTKAPI int Ttk_BoxContains(Ttk_Box box, int x, int y);
+/* 29 */
+TTKAPI Ttk_Box Ttk_PackBox(Ttk_Box *cavity, int w, int h,
+ Ttk_Side side);
+/* 30 */
+TTKAPI Ttk_Box Ttk_StickBox(Ttk_Box parcel, int w, int h,
+ Ttk_Sticky sticky);
+/* 31 */
+TTKAPI Ttk_Box Ttk_AnchorBox(Ttk_Box parcel, int w, int h,
+ Tk_Anchor anchor);
+/* 32 */
+TTKAPI Ttk_Box Ttk_PadBox(Ttk_Box b, Ttk_Padding p);
+/* 33 */
+TTKAPI Ttk_Box Ttk_ExpandBox(Ttk_Box b, Ttk_Padding p);
+/* 34 */
+TTKAPI Ttk_Box Ttk_PlaceBox(Ttk_Box *cavity, int w, int h,
+ Ttk_Side side, Ttk_Sticky sticky);
+/* 35 */
+TTKAPI Tcl_Obj * Ttk_NewBoxObj(Ttk_Box box);
+/* Slot 36 is reserved */
+/* Slot 37 is reserved */
+/* Slot 38 is reserved */
+/* Slot 39 is reserved */
+/* 40 */
+TTKAPI int Ttk_GetOrientFromObj(Tcl_Interp *interp,
+ Tcl_Obj *objPtr, int *orient);
+
+typedef struct TtkStubs {
+ int magic;
+ int epoch;
+ int revision;
+ const struct TtkStubHooks *hooks;
+
+ Ttk_Theme (*ttk_GetTheme) (Tcl_Interp *interp, CONST char *name); /* 0 */
+ Ttk_Theme (*ttk_GetDefaultTheme) (Tcl_Interp *interp); /* 1 */
+ Ttk_Theme (*ttk_GetCurrentTheme) (Tcl_Interp *interp); /* 2 */
+ Ttk_Theme (*ttk_CreateTheme) (Tcl_Interp *interp, CONST char *name, Ttk_Theme parent); /* 3 */
+ void (*ttk_RegisterCleanup) (Tcl_Interp *interp, VOID *deleteData, Ttk_CleanupProc *cleanupProc); /* 4 */
+ int (*ttk_RegisterElementSpec) (Ttk_Theme theme, CONST char *elementName, Ttk_ElementSpec *elementSpec, VOID *clientData); /* 5 */
+ Ttk_ElementClass * (*ttk_RegisterElement) (Tcl_Interp *interp, Ttk_Theme theme, CONST char *elementName, Ttk_ElementSpec *elementSpec, VOID *clientData); /* 6 */
+ int (*ttk_RegisterElementFactory) (Tcl_Interp *interp, CONST char *name, Ttk_ElementFactory factoryProc, VOID *clientData); /* 7 */
+ void (*ttk_RegisterLayout) (Ttk_Theme theme, CONST char *className, Ttk_LayoutSpec layoutSpec); /* 8 */
+ void (*reserved9)(void);
+ int (*ttk_GetStateSpecFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_StateSpec *spec_rtn); /* 10 */
+ Tcl_Obj * (*ttk_NewStateSpecObj) (unsigned int onbits, unsigned int offbits); /* 11 */
+ Ttk_StateMap (*ttk_GetStateMapFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 12 */
+ Tcl_Obj * (*ttk_StateMapLookup) (Tcl_Interp *interp, Ttk_StateMap map, Ttk_State state); /* 13 */
+ int (*ttk_StateTableLookup) (Ttk_StateTable map[], Ttk_State state); /* 14 */
+ void (*reserved15)(void);
+ void (*reserved16)(void);
+ void (*reserved17)(void);
+ void (*reserved18)(void);
+ void (*reserved19)(void);
+ int (*ttk_GetPaddingFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Ttk_Padding *pad_rtn); /* 20 */
+ int (*ttk_GetBorderFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Padding *pad_rtn); /* 21 */
+ int (*ttk_GetStickyFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Sticky *sticky_rtn); /* 22 */
+ Ttk_Padding (*ttk_MakePadding) (short l, short t, short r, short b); /* 23 */
+ Ttk_Padding (*ttk_UniformPadding) (short borderWidth); /* 24 */
+ Ttk_Padding (*ttk_AddPadding) (Ttk_Padding pad1, Ttk_Padding pad2); /* 25 */
+ Ttk_Padding (*ttk_RelievePadding) (Ttk_Padding padding, int relief, int n); /* 26 */
+ Ttk_Box (*ttk_MakeBox) (int x, int y, int width, int height); /* 27 */
+ int (*ttk_BoxContains) (Ttk_Box box, int x, int y); /* 28 */
+ Ttk_Box (*ttk_PackBox) (Ttk_Box *cavity, int w, int h, Ttk_Side side); /* 29 */
+ Ttk_Box (*ttk_StickBox) (Ttk_Box parcel, int w, int h, Ttk_Sticky sticky); /* 30 */
+ Ttk_Box (*ttk_AnchorBox) (Ttk_Box parcel, int w, int h, Tk_Anchor anchor); /* 31 */
+ Ttk_Box (*ttk_PadBox) (Ttk_Box b, Ttk_Padding p); /* 32 */
+ Ttk_Box (*ttk_ExpandBox) (Ttk_Box b, Ttk_Padding p); /* 33 */
+ Ttk_Box (*ttk_PlaceBox) (Ttk_Box *cavity, int w, int h, Ttk_Side side, Ttk_Sticky sticky); /* 34 */
+ Tcl_Obj * (*ttk_NewBoxObj) (Ttk_Box box); /* 35 */
+ void (*reserved36)(void);
+ void (*reserved37)(void);
+ void (*reserved38)(void);
+ void (*reserved39)(void);
+ int (*ttk_GetOrientFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *orient); /* 40 */
+} TtkStubs;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern const TtkStubs *ttkStubsPtr;
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(USE_TTK_STUBS)
+
+/*
+ * Inline function declarations:
+ */
+
+#define Ttk_GetTheme \
+ (ttkStubsPtr->ttk_GetTheme) /* 0 */
+#define Ttk_GetDefaultTheme \
+ (ttkStubsPtr->ttk_GetDefaultTheme) /* 1 */
+#define Ttk_GetCurrentTheme \
+ (ttkStubsPtr->ttk_GetCurrentTheme) /* 2 */
+#define Ttk_CreateTheme \
+ (ttkStubsPtr->ttk_CreateTheme) /* 3 */
+#define Ttk_RegisterCleanup \
+ (ttkStubsPtr->ttk_RegisterCleanup) /* 4 */
+#define Ttk_RegisterElementSpec \
+ (ttkStubsPtr->ttk_RegisterElementSpec) /* 5 */
+#define Ttk_RegisterElement \
+ (ttkStubsPtr->ttk_RegisterElement) /* 6 */
+#define Ttk_RegisterElementFactory \
+ (ttkStubsPtr->ttk_RegisterElementFactory) /* 7 */
+#define Ttk_RegisterLayout \
+ (ttkStubsPtr->ttk_RegisterLayout) /* 8 */
+/* Slot 9 is reserved */
+#define Ttk_GetStateSpecFromObj \
+ (ttkStubsPtr->ttk_GetStateSpecFromObj) /* 10 */
+#define Ttk_NewStateSpecObj \
+ (ttkStubsPtr->ttk_NewStateSpecObj) /* 11 */
+#define Ttk_GetStateMapFromObj \
+ (ttkStubsPtr->ttk_GetStateMapFromObj) /* 12 */
+#define Ttk_StateMapLookup \
+ (ttkStubsPtr->ttk_StateMapLookup) /* 13 */
+#define Ttk_StateTableLookup \
+ (ttkStubsPtr->ttk_StateTableLookup) /* 14 */
+/* Slot 15 is reserved */
+/* Slot 16 is reserved */
+/* Slot 17 is reserved */
+/* Slot 18 is reserved */
+/* Slot 19 is reserved */
+#define Ttk_GetPaddingFromObj \
+ (ttkStubsPtr->ttk_GetPaddingFromObj) /* 20 */
+#define Ttk_GetBorderFromObj \
+ (ttkStubsPtr->ttk_GetBorderFromObj) /* 21 */
+#define Ttk_GetStickyFromObj \
+ (ttkStubsPtr->ttk_GetStickyFromObj) /* 22 */
+#define Ttk_MakePadding \
+ (ttkStubsPtr->ttk_MakePadding) /* 23 */
+#define Ttk_UniformPadding \
+ (ttkStubsPtr->ttk_UniformPadding) /* 24 */
+#define Ttk_AddPadding \
+ (ttkStubsPtr->ttk_AddPadding) /* 25 */
+#define Ttk_RelievePadding \
+ (ttkStubsPtr->ttk_RelievePadding) /* 26 */
+#define Ttk_MakeBox \
+ (ttkStubsPtr->ttk_MakeBox) /* 27 */
+#define Ttk_BoxContains \
+ (ttkStubsPtr->ttk_BoxContains) /* 28 */
+#define Ttk_PackBox \
+ (ttkStubsPtr->ttk_PackBox) /* 29 */
+#define Ttk_StickBox \
+ (ttkStubsPtr->ttk_StickBox) /* 30 */
+#define Ttk_AnchorBox \
+ (ttkStubsPtr->ttk_AnchorBox) /* 31 */
+#define Ttk_PadBox \
+ (ttkStubsPtr->ttk_PadBox) /* 32 */
+#define Ttk_ExpandBox \
+ (ttkStubsPtr->ttk_ExpandBox) /* 33 */
+#define Ttk_PlaceBox \
+ (ttkStubsPtr->ttk_PlaceBox) /* 34 */
+#define Ttk_NewBoxObj \
+ (ttkStubsPtr->ttk_NewBoxObj) /* 35 */
+/* Slot 36 is reserved */
+/* Slot 37 is reserved */
+/* Slot 38 is reserved */
+/* Slot 39 is reserved */
+#define Ttk_GetOrientFromObj \
+ (ttkStubsPtr->ttk_GetOrientFromObj) /* 40 */
+
+#endif /* defined(USE_TTK_STUBS) */
+
+/* !END!: Do not edit above this line. */
+
+#endif /* _TTKDECLS */
diff --git a/generic/ttk/ttkDefaultTheme.c b/generic/ttk/ttkDefaultTheme.c
new file mode 100644
index 0000000..d2deee8
--- /dev/null
+++ b/generic/ttk/ttkDefaultTheme.c
@@ -0,0 +1,1130 @@
+/*
+ * Copyright (c) 2003, Joe English
+ *
+ * Tk alternate theme, intended to match the MSUE and Gtk's (old) default theme
+ */
+
+#include <math.h>
+#include <string.h>
+
+#include <tkInt.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "ttkTheme.h"
+
+#if defined(WIN32)
+static const int WIN32_XDRAWLINE_HACK = 1;
+#else
+static const int WIN32_XDRAWLINE_HACK = 0;
+#endif
+
+#define BORDERWIDTH 2
+#define SCROLLBAR_WIDTH 14
+#define MIN_THUMB_SIZE 8
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Helper routines for border drawing:
+ *
+ * NOTE: MSUE specifies a slightly different arrangement
+ * for button borders than for other elements; "shadowColors"
+ * is for button borders.
+ *
+ * Please excuse the gross misspelling "LITE" for "LIGHT",
+ * but it makes things line up nicer.
+ */
+
+enum BorderColor { FLAT = 1, LITE = 2, DARK = 3, BRDR = 4 };
+
+/* top-left outer, top-left inner, bottom-right inner, bottom-right outer */
+static int const shadowColors[6][4] = {
+ { FLAT, FLAT, FLAT, FLAT }, /* TK_RELIEF_FLAT = 0*/
+ { DARK, LITE, DARK, LITE }, /* TK_RELIEF_GROOVE = 1*/
+ { LITE, FLAT, DARK, BRDR }, /* TK_RELIEF_RAISED = 2*/
+ { LITE, DARK, LITE, DARK }, /* TK_RELIEF_RIDGE = 3*/
+ { BRDR, BRDR, BRDR, BRDR }, /* TK_RELIEF_SOLID = 4*/
+ { BRDR, DARK, FLAT, LITE } /* TK_RELIEF_SUNKEN = 5*/
+};
+
+/* top-left, bottom-right */
+static int const thinShadowColors[6][4] = {
+ { FLAT, FLAT }, /* TK_RELIEF_FLAT = 0*/
+ { DARK, LITE }, /* TK_RELIEF_GROOVE = 1*/
+ { LITE, DARK }, /* TK_RELIEF_RAISED = 2*/
+ { LITE, DARK }, /* TK_RELIEF_RIDGE = 3*/
+ { BRDR, BRDR }, /* TK_RELIEF_SOLID = 4*/
+ { DARK, LITE } /* TK_RELIEF_SUNKEN = 5*/
+};
+
+static void DrawCorner(
+ Tk_Window tkwin,
+ Drawable d,
+ Tk_3DBorder border, /* get most GCs from here... */
+ GC borderGC, /* "window border" color GC */
+ int x,int y, int width,int height, /* where to draw */
+ int corner, /* 0 => top left; 1 => bottom right */
+ enum BorderColor color)
+{
+ XPoint points[3];
+ GC gc;
+
+ --width; --height;
+ points[0].x = x; points[0].y = y+height;
+ points[1].x = x+width*corner; points[1].y = y+height*corner;
+ points[2].x = x+width; points[2].y = y;
+
+ if (color == BRDR)
+ gc = borderGC;
+ else
+ gc = Tk_3DBorderGC(tkwin, border, (int)color);
+
+ XDrawLines(Tk_Display(tkwin), d, gc, points, 3, CoordModeOrigin);
+}
+
+static void DrawBorder(
+ Tk_Window tkwin, Drawable d, Tk_3DBorder border, XColor *borderColor,
+ Ttk_Box b, int borderWidth, int relief)
+{
+ GC borderGC = Tk_GCForColor(borderColor, d);
+
+ switch (borderWidth) {
+ case 2: /* "thick" border */
+ DrawCorner(tkwin, d, border, borderGC,
+ b.x, b.y, b.width, b.height, 0,shadowColors[relief][0]);
+ DrawCorner(tkwin, d, border, borderGC,
+ b.x+1, b.y+1, b.width-2, b.height-2, 0,shadowColors[relief][1]);
+ DrawCorner(tkwin, d, border, borderGC,
+ b.x+1, b.y+1, b.width-2, b.height-2, 1,shadowColors[relief][2]);
+ DrawCorner(tkwin, d, border, borderGC,
+ b.x, b.y, b.width, b.height, 1,shadowColors[relief][3]);
+ break;
+ case 1: /* "thin" border */
+ DrawCorner(tkwin, d, border, borderGC,
+ b.x, b.y, b.width, b.height, 0, thinShadowColors[relief][0]);
+ DrawCorner(tkwin, d, border, borderGC,
+ b.x, b.y, b.width, b.height, 1, thinShadowColors[relief][1]);
+ break;
+ case 0: /* no border -- do nothing */
+ break;
+ default: /* Fall back to Motif-style borders: */
+ Tk_Draw3DRectangle(tkwin, d, border,
+ b.x, b.y, b.width, b.height, borderWidth,relief);
+ break;
+ }
+}
+
+/* Alternate shadow colors for entry fields:
+ * NOTE: FLAT color is normally white, and the LITE color is a darker shade.
+ */
+static int fieldShadowColors[4] = { DARK, BRDR, LITE, FLAT };
+
+static void DrawFieldBorder(
+ Tk_Window tkwin, Drawable d, Tk_3DBorder border, XColor *borderColor,
+ Ttk_Box b)
+{
+ GC borderGC = Tk_GCForColor(borderColor, d);
+ DrawCorner(tkwin, d, border, borderGC,
+ b.x, b.y, b.width, b.height, 0,fieldShadowColors[0]);
+ DrawCorner(tkwin, d, border, borderGC,
+ b.x+1, b.y+1, b.width-2, b.height-2, 0,fieldShadowColors[1]);
+ DrawCorner(tkwin, d, border, borderGC,
+ b.x+1, b.y+1, b.width-2, b.height-2, 1,fieldShadowColors[2]);
+ DrawCorner(tkwin, d, border, borderGC,
+ b.x, b.y, b.width, b.height, 1,fieldShadowColors[3]);
+ return;
+}
+
+/*
+ * ArrowPoints --
+ * Compute points of arrow polygon.
+ */
+static void ArrowPoints(Ttk_Box b, ArrowDirection dir, XPoint points[4])
+{
+ int cx, cy, h;
+
+ switch (dir) {
+ case ARROW_UP:
+ h = (b.width - 1)/2;
+ cx = b.x + h;
+ cy = b.y;
+ if (b.height <= h) h = b.height - 1;
+ points[0].x = cx; points[0].y = cy;
+ points[1].x = cx - h; points[1].y = cy + h;
+ points[2].x = cx + h; points[2].y = cy + h;
+ break;
+ case ARROW_DOWN:
+ h = (b.width - 1)/2;
+ cx = b.x + h;
+ cy = b.y + b.height - 1;
+ if (b.height <= h) h = b.height - 1;
+ points[0].x = cx; points[0].y = cy;
+ points[1].x = cx - h; points[1].y = cy - h;
+ points[2].x = cx + h; points[2].y = cy - h;
+ break;
+ case ARROW_LEFT:
+ h = (b.height - 1)/2;
+ cx = b.x;
+ cy = b.y + h;
+ if (b.width <= h) h = b.width - 1;
+ points[0].x = cx; points[0].y = cy;
+ points[1].x = cx + h; points[1].y = cy - h;
+ points[2].x = cx + h; points[2].y = cy + h;
+ break;
+ case ARROW_RIGHT:
+ h = (b.height - 1)/2;
+ cx = b.x + b.width - 1;
+ cy = b.y + h;
+ if (b.width <= h) h = b.width - 1;
+ points[0].x = cx; points[0].y = cy;
+ points[1].x = cx - h; points[1].y = cy - h;
+ points[2].x = cx - h; points[2].y = cy + h;
+ break;
+ }
+
+ points[3].x = points[0].x;
+ points[3].y = points[0].y;
+}
+
+/*public*/
+void TtkArrowSize(int h, ArrowDirection dir, int *widthPtr, int *heightPtr)
+{
+ switch (dir) {
+ case ARROW_UP:
+ case ARROW_DOWN: *widthPtr = 2*h+1; *heightPtr = h+1; break;
+ case ARROW_LEFT:
+ case ARROW_RIGHT: *widthPtr = h+1; *heightPtr = 2*h+1;
+ }
+}
+
+/*
+ * TtkDrawArrow, TtkFillArrow --
+ * Draw an arrow in the indicated direction inside the specified box.
+ */
+/*public*/
+void TtkFillArrow(
+ Display *display, Drawable d, GC gc, Ttk_Box b, ArrowDirection dir)
+{
+ XPoint points[4];
+ ArrowPoints(b, dir, points);
+ XFillPolygon(display, d, gc, points, 3, Convex, CoordModeOrigin);
+ XDrawLines(display, d, gc, points, 4, CoordModeOrigin);
+}
+
+/*public*/
+void TtkDrawArrow(
+ Display *display, Drawable d, GC gc, Ttk_Box b, ArrowDirection dir)
+{
+ XPoint points[4];
+ ArrowPoints(b, dir, points);
+ XDrawLines(display, d, gc, points, 4, CoordModeOrigin);
+}
+
+/*
+ *----------------------------------------------------------------------
+ * +++ Border element implementation.
+ *
+ * This border consists of (from outside-in):
+ *
+ * + a 1-pixel thick default indicator (defaultable widgets only)
+ * + 1- or 2- pixel shaded border (controlled by -background and -relief)
+ * + 1 pixel padding (???)
+ */
+
+typedef struct {
+ Tcl_Obj *borderObj;
+ Tcl_Obj *borderColorObj; /* Extra border color */
+ Tcl_Obj *borderWidthObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *defaultStateObj; /* for buttons */
+} BorderElement;
+
+static Ttk_ElementOptionSpec BorderElementOptions[] = {
+ { "-background", TK_OPTION_BORDER, Tk_Offset(BorderElement,borderObj),
+ DEFAULT_BACKGROUND },
+ { "-bordercolor",TK_OPTION_COLOR,
+ Tk_Offset(BorderElement,borderColorObj), "black" },
+ { "-default", TK_OPTION_ANY, Tk_Offset(BorderElement,defaultStateObj),
+ "disabled" },
+ { "-borderwidth",TK_OPTION_PIXELS,Tk_Offset(BorderElement,borderWidthObj),
+ STRINGIFY(BORDERWIDTH) },
+ { "-relief", TK_OPTION_RELIEF, Tk_Offset(BorderElement,reliefObj),
+ "flat" },
+ { NULL, 0, 0, NULL }
+};
+
+static void BorderElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ BorderElement *bd = elementRecord;
+ int borderWidth = 0;
+ int defaultState = TTK_BUTTON_DEFAULT_DISABLED;
+
+ Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
+ Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);
+
+ if (defaultState != TTK_BUTTON_DEFAULT_DISABLED) {
+ ++borderWidth;
+ }
+
+ *paddingPtr = Ttk_UniformPadding((short)borderWidth);
+}
+
+static void BorderElementDraw(
+ void *clientData, void *elementRecord,
+ Tk_Window tkwin, Drawable d, Ttk_Box b, unsigned int state)
+{
+ BorderElement *bd = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, bd->borderObj);
+ XColor *borderColor = Tk_GetColorFromObj(tkwin, bd->borderColorObj);
+ int borderWidth = 2;
+ int relief = TK_RELIEF_FLAT;
+ int defaultState = TTK_BUTTON_DEFAULT_DISABLED;
+
+ /*
+ * Get option values.
+ */
+ Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
+ Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
+ Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);
+
+ if (defaultState == TTK_BUTTON_DEFAULT_ACTIVE) {
+ GC gc = Tk_GCForColor(borderColor, d);
+ XDrawRectangle(Tk_Display(tkwin), d, gc,
+ b.x, b.y, b.width-1, b.height-1);
+ }
+ if (defaultState != TTK_BUTTON_DEFAULT_DISABLED) {
+ /* Space for default ring: */
+ b = Ttk_PadBox(b, Ttk_UniformPadding(1));
+ }
+
+ DrawBorder(tkwin, d, border, borderColor, b, borderWidth, relief);
+}
+
+static Ttk_ElementSpec BorderElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(BorderElement),
+ BorderElementOptions,
+ BorderElementSize,
+ BorderElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Field element:
+ * Used for editable fields.
+ */
+typedef struct {
+ Tcl_Obj *borderObj;
+ Tcl_Obj *borderColorObj; /* Extra border color */
+} FieldElement;
+
+static Ttk_ElementOptionSpec FieldElementOptions[] = {
+ { "-fieldbackground", TK_OPTION_BORDER, Tk_Offset(FieldElement,borderObj),
+ "white" },
+ { "-bordercolor",TK_OPTION_COLOR, Tk_Offset(FieldElement,borderColorObj),
+ "black" },
+ { NULL, 0, 0, NULL }
+};
+
+static void FieldElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ *paddingPtr = Ttk_UniformPadding(2);
+}
+
+static void FieldElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ FieldElement *field = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, field->borderObj);
+ XColor *borderColor = Tk_GetColorFromObj(tkwin, field->borderColorObj);
+
+ Tk_Fill3DRectangle(
+ tkwin, d, border, b.x, b.y, b.width, b.height, 0, TK_RELIEF_SUNKEN);
+ DrawFieldBorder(tkwin, d, border, borderColor, b);
+}
+
+static Ttk_ElementSpec FieldElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(FieldElement),
+ FieldElementOptions,
+ FieldElementSize,
+ FieldElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * Indicators --
+ *
+ * Code derived (probably incorrectly) from TIP 109 implementation,
+ * unix/tkUnixButton.c r 1.15.
+ */
+
+/*
+ * Indicator bitmap descriptor:
+ */
+typedef struct {
+ int width; /* Width of each image */
+ int height; /* Height of each image */
+ int nimages; /* #images / row */
+ const char *const *pixels; /* array[height] of char[width*nimage] */
+ Ttk_StateTable *map;/* used to look up image index by state */
+} IndicatorSpec;
+
+#if 0
+/*XPM*/
+static const char *const button_images[] = {
+ /* width height ncolors chars_per_pixel */
+ "52 13 8 1",
+ /* colors */
+ "A c #808000000000 s shadow",
+ "B c #000080800000 s highlight",
+ "C c #808080800000 s 3dlight",
+ "D c #000000008080 s window",
+ "E c #808000008080 s 3ddark",
+ "F c #000080808080 s frame",
+ "G c #000000000000 s foreground",
+ "H c #000080800000 s disabledfg",
+};
+#endif
+
+static Ttk_StateTable checkbutton_states[] = {
+ { 0, 0, TTK_STATE_SELECTED|TTK_STATE_DISABLED },
+ { 1, TTK_STATE_SELECTED, TTK_STATE_DISABLED },
+ { 2, TTK_STATE_DISABLED, TTK_STATE_SELECTED },
+ { 3, TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0 },
+ { 0, 0, 0 }
+};
+
+static const char *const checkbutton_pixels[] = {
+ "AAAAAAAAAAAABAAAAAAAAAAAABAAAAAAAAAAAABAAAAAAAAAAAAB",
+ "AEEEEEEEEEECBAEEEEEEEEEECBAEEEEEEEEEECBAEEEEEEEEEECB",
+ "AEDDDDDDDDDCBAEDDDDDDDDDCBAEFFFFFFFFFCBAEFFFFFFFFFCB",
+ "AEDDDDDDDDDCBAEDDDDDDDGDCBAEFFFFFFFFFCBAEFFFFFFFHFCB",
+ "AEDDDDDDDDDCBAEDDDDDDGGDCBAEFFFFFFFFFCBAEFFFFFFHHFCB",
+ "AEDDDDDDDDDCBAEDGDDDGGGDCBAEFFFFFFFFFCBAEFHFFFHHHFCB",
+ "AEDDDDDDDDDCBAEDGGDGGGDDCBAEFFFFFFFFFCBAEFHHFHHHFFCB",
+ "AEDDDDDDDDDCBAEDGGGGGDDDCBAEFFFFFFFFFCBAEFHHHHHFFFCB",
+ "AEDDDDDDDDDCBAEDDGGGDDDDCBAEFFFFFFFFFCBAEFFHHHFFFFCB",
+ "AEDDDDDDDDDCBAEDDDGDDDDDCBAEFFFFFFFFFCBAEFFFHFFFFFCB",
+ "AEDDDDDDDDDCBAEDDDDDDDDDCBAEFFFFFFFFFCBAEFFFFFFFFFCB",
+ "ACCCCCCCCCCCBACCCCCCCCCCCBACCCCCCCCCCCBACCCCCCCCCCCB",
+ "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
+};
+
+static IndicatorSpec checkbutton_spec = {
+ 13, 13, 4, /* width, height, nimages */
+ checkbutton_pixels,
+ checkbutton_states
+};
+
+static Ttk_StateTable radiobutton_states[] = {
+ { 0, 0, TTK_STATE_SELECTED|TTK_STATE_DISABLED },
+ { 1, TTK_STATE_SELECTED, TTK_STATE_DISABLED },
+ { 2, TTK_STATE_DISABLED, TTK_STATE_SELECTED },
+ { 3, TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0 },
+ { 0, 0, 0 }
+};
+
+static const char *const radiobutton_pixels[] = {
+ "FFFFAAAAFFFFFFFFFAAAAFFFFFFFFFAAAAFFFFFFFFFAAAAFFFFF",
+ "FFAAEEEEAAFFFFFAAEEEEAAFFFFFAAEEEEAAFFFFFAAEEEEAAFFF",
+ "FAEEDDDDEEBFFFAEEDDDDEEBFFFAEEFFFFEEBFFFAEEFFFFEEBFF",
+ "FAEDDDDDDCBFFFAEDDDDDDCBFFFAEFFFFFFCBFFFAEFFFFFFCBFF",
+ "AEDDDDDDDDCBFAEDDDGGDDDCBFAEFFFFFFFFCBFAEFFFHHFFFCBF",
+ "AEDDDDDDDDCBFAEDDGGGGDDCBFAEFFFFFFFFCBFAEFFHHHHFFCBF",
+ "AEDDDDDDDDCBFAEDDGGGGDDCBFAEFFFFFFFFCBFAEFFHHHHFFCBF",
+ "AEDDDDDDDDCBFAEDDDGGDDDCBFAEFFFFFFFFCBFAEFFFHHFFFCBF",
+ "FAEDDDDDDCBFFFAEDDDDDDCBFFFAEFFFFFFCBFFFAEFFFFFFCBFF",
+ "FACCDDDDCCBFFFACCDDDDCCBFFFACCFFFFCCBFFFACCFFFFCCBFF",
+ "FFBBCCCCBBFFFFFBBCCCCBBFFFFFBBCCCCBBFFFFFBBCCCCBBFFF",
+ "FFFFBBBBFFFFFFFFFBBBBFFFFFFFFFBBBBFFFFFFFFFBBBBFFFFF",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+};
+
+static IndicatorSpec radiobutton_spec = {
+ 13, 13, 4, /* width, height, nimages */
+ radiobutton_pixels,
+ radiobutton_states
+};
+
+typedef struct {
+ Tcl_Obj *backgroundObj;
+ Tcl_Obj *foregroundObj;
+ Tcl_Obj *colorObj;
+ Tcl_Obj *lightColorObj;
+ Tcl_Obj *shadeColorObj;
+ Tcl_Obj *borderColorObj;
+ Tcl_Obj *marginObj;
+} IndicatorElement;
+
+static Ttk_ElementOptionSpec IndicatorElementOptions[] = {
+ { "-background", TK_OPTION_COLOR,
+ Tk_Offset(IndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
+ { "-foreground", TK_OPTION_COLOR,
+ Tk_Offset(IndicatorElement,foregroundObj), DEFAULT_FOREGROUND },
+ { "-indicatorcolor", TK_OPTION_COLOR,
+ Tk_Offset(IndicatorElement,colorObj), "#FFFFFF" },
+ { "-lightcolor", TK_OPTION_COLOR,
+ Tk_Offset(IndicatorElement,lightColorObj), "#DDDDDD" },
+ { "-shadecolor", TK_OPTION_COLOR,
+ Tk_Offset(IndicatorElement,shadeColorObj), "#888888" },
+ { "-bordercolor", TK_OPTION_COLOR,
+ Tk_Offset(IndicatorElement,borderColorObj), "black" },
+ { "-indicatormargin", TK_OPTION_STRING,
+ Tk_Offset(IndicatorElement,marginObj), "0 2 4 2" },
+ { NULL, 0, 0, NULL }
+};
+
+static void IndicatorElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ IndicatorSpec *spec = clientData;
+ IndicatorElement *indicator = elementRecord;
+ Ttk_Padding margins;
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
+ *widthPtr = spec->width + Ttk_PaddingWidth(margins);
+ *heightPtr = spec->height + Ttk_PaddingHeight(margins);
+}
+
+static void IndicatorElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ IndicatorSpec *spec = clientData;
+ IndicatorElement *indicator = elementRecord;
+ Display *display = Tk_Display(tkwin);
+ Ttk_Padding padding;
+ XColor *fgColor, *frameColor, *shadeColor, *indicatorColor, *borderColor;
+
+ int index, ix, iy;
+ XGCValues gcValues;
+ GC copyGC;
+ unsigned long imgColors[8];
+ XImage *img;
+
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
+ b = Ttk_PadBox(b, padding);
+
+ if ( b.x < 0
+ || b.y < 0
+ || Tk_Width(tkwin) < b.x + spec->width
+ || Tk_Height(tkwin) < b.y + spec->height)
+ {
+ /* Oops! not enough room to display the image.
+ * Don't draw anything.
+ */
+ return;
+ }
+
+ /*
+ * Fill in imgColors palette:
+ *
+ * (SHOULD: take light and shade colors from the border object,
+ * but Tk doesn't provide easy access to these in the public API.)
+ */
+ fgColor = Tk_GetColorFromObj(tkwin, indicator->foregroundObj);
+ frameColor = Tk_GetColorFromObj(tkwin, indicator->backgroundObj);
+ shadeColor = Tk_GetColorFromObj(tkwin, indicator->shadeColorObj);
+ indicatorColor = Tk_GetColorFromObj(tkwin, indicator->colorObj);
+ borderColor = Tk_GetColorFromObj(tkwin, indicator->borderColorObj);
+
+ imgColors[0 /*A*/] = shadeColor->pixel;
+ imgColors[1 /*B*/] = indicatorColor->pixel;
+ imgColors[2 /*C*/] = frameColor->pixel;
+ imgColors[3 /*D*/] = indicatorColor->pixel;
+ imgColors[4 /*E*/] = borderColor->pixel;
+ imgColors[5 /*F*/] = frameColor->pixel;
+ imgColors[6 /*G*/] = fgColor->pixel;
+ imgColors[7 /*H*/] = fgColor->pixel;
+
+ /*
+ * Create a scratch buffer to store the image:
+ */
+ img = XGetImage(display,d, 0, 0,
+ (unsigned int)spec->width, (unsigned int)spec->height,
+ AllPlanes, ZPixmap);
+ if (img == NULL)
+ return;
+
+ /*
+ * Create the image, painting it into an XImage one pixel at a time.
+ */
+ index = Ttk_StateTableLookup(spec->map, state);
+ for (iy=0 ; iy<spec->height ; iy++) {
+ for (ix=0 ; ix<spec->width ; ix++) {
+ XPutPixel(img, ix, iy,
+ imgColors[spec->pixels[iy][index*spec->width+ix] - 'A'] );
+ }
+ }
+
+ /*
+ * Copy onto our target drawable surface.
+ */
+ memset(&gcValues, 0, sizeof(gcValues));
+ copyGC = Tk_GetGC(tkwin, 0, &gcValues);
+
+ TkPutImage(NULL, 0, display, d, copyGC, img, 0, 0, b.x, b.y,
+ spec->width, spec->height);
+
+ /*
+ * Tidy up.
+ */
+ Tk_FreeGC(display, copyGC);
+ XDestroyImage(img);
+}
+
+static Ttk_ElementSpec IndicatorElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(IndicatorElement),
+ IndicatorElementOptions,
+ IndicatorElementSize,
+ IndicatorElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Arrow element(s).
+ *
+ * Draws a solid triangle, inside a box.
+ * clientData is an enum ArrowDirection pointer.
+ */
+
+static int ArrowElements[] = { ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT };
+typedef struct {
+ Tcl_Obj *sizeObj;
+ Tcl_Obj *borderObj;
+ Tcl_Obj *borderColorObj; /* Extra color for borders */
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *colorObj; /* Arrow color */
+} ArrowElement;
+
+static Ttk_ElementOptionSpec ArrowElementOptions[] = {
+ { "-arrowsize", TK_OPTION_PIXELS,
+ Tk_Offset(ArrowElement,sizeObj), STRINGIFY(SCROLLBAR_WIDTH) },
+ { "-background", TK_OPTION_BORDER,
+ Tk_Offset(ArrowElement,borderObj), DEFAULT_BACKGROUND },
+ { "-bordercolor", TK_OPTION_COLOR,
+ Tk_Offset(ArrowElement,borderColorObj), "black" },
+ { "-relief", TK_OPTION_RELIEF,
+ Tk_Offset(ArrowElement,reliefObj),"raised"},
+ { "-arrowcolor", TK_OPTION_COLOR,
+ Tk_Offset(ArrowElement,colorObj),"black"},
+ { NULL, 0, 0, NULL }
+};
+
+/*
+ * Note asymmetric padding:
+ * top/left padding is 1 less than bottom/right,
+ * since in this theme 2-pixel borders are asymmetric.
+ */
+static Ttk_Padding ArrowPadding = { 3,3,4,4 };
+
+static void ArrowElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ ArrowElement *arrow = elementRecord;
+ int direction = *(int *)clientData;
+ int width = SCROLLBAR_WIDTH;
+
+ Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &width);
+ width -= Ttk_PaddingWidth(ArrowPadding);
+ TtkArrowSize(width/2, direction, widthPtr, heightPtr);
+ *widthPtr += Ttk_PaddingWidth(ArrowPadding);
+ *heightPtr += Ttk_PaddingHeight(ArrowPadding);
+}
+
+static void ArrowElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ int direction = *(int *)clientData;
+ ArrowElement *arrow = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
+ XColor *borderColor = Tk_GetColorFromObj(tkwin, arrow->borderColorObj);
+ XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
+ int relief = TK_RELIEF_RAISED;
+ int borderWidth = 2;
+
+ Tk_GetReliefFromObj(NULL, arrow->reliefObj, &relief);
+
+ Tk_Fill3DRectangle(
+ tkwin, d, border, b.x, b.y, b.width, b.height, 0, TK_RELIEF_FLAT);
+ DrawBorder(tkwin,d,border,borderColor,b,borderWidth,relief);
+
+ TtkFillArrow(Tk_Display(tkwin), d, Tk_GCForColor(arrowColor, d),
+ Ttk_PadBox(b, ArrowPadding), direction);
+}
+
+static Ttk_ElementSpec ArrowElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(ArrowElement),
+ ArrowElementOptions,
+ ArrowElementSize,
+ ArrowElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Menubutton indicator:
+ * Draw an arrow in the direction where the menu will be posted.
+ */
+
+#define MENUBUTTON_ARROW_SIZE 5
+
+typedef struct {
+ Tcl_Obj *directionObj;
+ Tcl_Obj *sizeObj;
+ Tcl_Obj *colorObj;
+} MenubuttonArrowElement;
+
+static const char *directionStrings[] = { /* See also: button.c */
+ "above", "below", "left", "right", "flush", NULL
+};
+enum { POST_ABOVE, POST_BELOW, POST_LEFT, POST_RIGHT, POST_FLUSH };
+
+static Ttk_ElementOptionSpec MenubuttonArrowElementOptions[] = {
+ { "-direction", TK_OPTION_STRING,
+ Tk_Offset(MenubuttonArrowElement,directionObj), "below" },
+ { "-arrowsize", TK_OPTION_PIXELS,
+ Tk_Offset(MenubuttonArrowElement,sizeObj), STRINGIFY(MENUBUTTON_ARROW_SIZE)},
+ { "-arrowcolor",TK_OPTION_COLOR,
+ Tk_Offset(MenubuttonArrowElement,colorObj), "black"},
+ { NULL, 0, 0, NULL }
+};
+
+static Ttk_Padding MenubuttonArrowPadding = { 3, 0, 3, 0 };
+
+static void MenubuttonArrowElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ MenubuttonArrowElement *arrow = elementRecord;
+ int size = MENUBUTTON_ARROW_SIZE;
+ Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
+ *widthPtr = *heightPtr = 2 * size + 1;
+ *widthPtr += Ttk_PaddingWidth(MenubuttonArrowPadding);
+ *heightPtr += Ttk_PaddingHeight(MenubuttonArrowPadding);
+}
+
+static void MenubuttonArrowElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ MenubuttonArrowElement *arrow = elementRecord;
+ XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
+ GC gc = Tk_GCForColor(arrowColor, d);
+ int size = MENUBUTTON_ARROW_SIZE;
+ int postDirection = POST_BELOW;
+ ArrowDirection arrowDirection = ARROW_DOWN;
+ int width = 0, height = 0;
+
+ Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
+ Tcl_GetIndexFromObj(NULL, arrow->directionObj, directionStrings,
+ ""/*message*/, 0/*flags*/, &postDirection);
+
+ /* ... this might not be such a great idea ... */
+ switch (postDirection) {
+ case POST_ABOVE: arrowDirection = ARROW_UP; break;
+ case POST_BELOW: arrowDirection = ARROW_DOWN; break;
+ case POST_LEFT: arrowDirection = ARROW_LEFT; break;
+ case POST_RIGHT: arrowDirection = ARROW_RIGHT; break;
+ case POST_FLUSH: arrowDirection = ARROW_DOWN; break;
+ }
+
+ TtkArrowSize(size, arrowDirection, &width, &height);
+ b = Ttk_PadBox(b, MenubuttonArrowPadding);
+ b = Ttk_AnchorBox(b, width, height, TK_ANCHOR_CENTER);
+ TtkFillArrow(Tk_Display(tkwin), d, gc, b, arrowDirection);
+}
+
+static Ttk_ElementSpec MenubuttonArrowElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(MenubuttonArrowElement),
+ MenubuttonArrowElementOptions,
+ MenubuttonArrowElementSize,
+ MenubuttonArrowElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Trough element
+ *
+ * Used in scrollbars and the scale.
+ *
+ * The -groovewidth option can be used to set the size of the short axis
+ * for the drawn area. This will not affect the geometry, but can be used
+ * to draw a thin centered trough inside the packet alloted. This is used
+ * to show a win32-style scale widget. Use -1 or a large number to use the
+ * full area (default).
+ *
+ */
+
+typedef struct {
+ Tcl_Obj *colorObj;
+ Tcl_Obj *borderWidthObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *grooveWidthObj;
+ Tcl_Obj *orientObj;
+} TroughElement;
+
+static Ttk_ElementOptionSpec TroughElementOptions[] = {
+ { "-orient", TK_OPTION_ANY,
+ Tk_Offset(TroughElement, orientObj), "horizontal" },
+ { "-troughborderwidth", TK_OPTION_PIXELS,
+ Tk_Offset(TroughElement,borderWidthObj), "1" },
+ { "-troughcolor", TK_OPTION_BORDER,
+ Tk_Offset(TroughElement,colorObj), DEFAULT_BACKGROUND },
+ { "-troughrelief",TK_OPTION_RELIEF,
+ Tk_Offset(TroughElement,reliefObj), "sunken" },
+ { "-groovewidth", TK_OPTION_PIXELS,
+ Tk_Offset(TroughElement,grooveWidthObj), "-1" },
+ { NULL, 0, 0, NULL }
+};
+
+static void TroughElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ TroughElement *troughPtr = elementRecord;
+ int borderWidth = 2, grooveWidth = 0;
+
+ Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->borderWidthObj, &borderWidth);
+ Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->grooveWidthObj, &grooveWidth);
+
+ if (grooveWidth <= 0) {
+ *paddingPtr = Ttk_UniformPadding((short)borderWidth);
+ }
+}
+
+static void TroughElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ TroughElement *troughPtr = elementRecord;
+ Tk_3DBorder border = NULL;
+ int borderWidth = 2, relief = TK_RELIEF_SUNKEN, groove = -1, orient;
+
+ border = Tk_Get3DBorderFromObj(tkwin, troughPtr->colorObj);
+ Ttk_GetOrientFromObj(NULL, troughPtr->orientObj, &orient);
+ Tk_GetReliefFromObj(NULL, troughPtr->reliefObj, &relief);
+ Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->borderWidthObj, &borderWidth);
+ Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->grooveWidthObj, &groove);
+
+ if (groove != -1 && groove < b.height && groove < b.width) {
+ if (orient == TTK_ORIENT_HORIZONTAL) {
+ b.y = b.y + b.height/2 - groove/2;
+ b.height = groove;
+ } else {
+ b.x = b.x + b.width/2 - groove/2;
+ b.width = groove;
+ }
+ }
+
+ Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
+ borderWidth, relief);
+}
+
+static Ttk_ElementSpec TroughElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(TroughElement),
+ TroughElementOptions,
+ TroughElementSize,
+ TroughElementDraw
+};
+
+/*
+ *----------------------------------------------------------------------
+ * +++ Thumb element.
+ */
+
+typedef struct {
+ Tcl_Obj *sizeObj;
+ Tcl_Obj *firstObj;
+ Tcl_Obj *lastObj;
+ Tcl_Obj *borderObj;
+ Tcl_Obj *borderColorObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *orientObj;
+} ThumbElement;
+
+static Ttk_ElementOptionSpec ThumbElementOptions[] = {
+ { "-width", TK_OPTION_PIXELS, Tk_Offset(ThumbElement,sizeObj),
+ STRINGIFY(SCROLLBAR_WIDTH) },
+ { "-background", TK_OPTION_BORDER, Tk_Offset(ThumbElement,borderObj),
+ DEFAULT_BACKGROUND },
+ { "-bordercolor", TK_OPTION_COLOR, Tk_Offset(ThumbElement,borderColorObj),
+ "black" },
+ { "-relief", TK_OPTION_RELIEF,Tk_Offset(ThumbElement,reliefObj),"raised" },
+ { "-orient", TK_OPTION_ANY,Tk_Offset(ThumbElement,orientObj),"horizontal"},
+ { NULL, 0, 0, NULL }
+};
+
+static void ThumbElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ ThumbElement *thumb = elementRecord;
+ int orient, size;
+ Tk_GetPixelsFromObj(NULL, tkwin, thumb->sizeObj, &size);
+ Ttk_GetOrientFromObj(NULL, thumb->orientObj, &orient);
+
+ if (orient == TTK_ORIENT_VERTICAL) {
+ *widthPtr = size;
+ *heightPtr = MIN_THUMB_SIZE;
+ } else {
+ *widthPtr = MIN_THUMB_SIZE;
+ *heightPtr = size;
+ }
+}
+
+static void ThumbElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ ThumbElement *thumb = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, thumb->borderObj);
+ XColor *borderColor = Tk_GetColorFromObj(tkwin, thumb->borderColorObj);
+ int relief = TK_RELIEF_RAISED;
+ int borderWidth = 2;
+
+ /*
+ * Don't draw the thumb if we are disabled.
+ * This makes it behave like Windows ... if that's what we want.
+ if (state & TTK_STATE_DISABLED)
+ return;
+ */
+
+ Tk_GetReliefFromObj(NULL, thumb->reliefObj, &relief);
+
+ Tk_Fill3DRectangle(
+ tkwin, d, border, b.x,b.y,b.width,b.height, 0, TK_RELIEF_FLAT);
+ DrawBorder(tkwin, d, border, borderColor, b, borderWidth, relief);
+}
+
+static Ttk_ElementSpec ThumbElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(ThumbElement),
+ ThumbElementOptions,
+ ThumbElementSize,
+ ThumbElementDraw
+};
+
+/*
+ *----------------------------------------------------------------------
+ * +++ Slider element.
+ *
+ * This is the moving part of the scale widget.
+ *
+ * The slider element is the thumb in the scale widget. This is drawn
+ * as an arrow-type element that can point up, down, left or right.
+ *
+ */
+
+typedef struct {
+ Tcl_Obj *lengthObj; /* Long axis dimension */
+ Tcl_Obj *thicknessObj; /* Short axis dimension */
+ Tcl_Obj *reliefObj; /* Relief for this object */
+ Tcl_Obj *borderObj; /* Border / background color */
+ Tcl_Obj *borderColorObj; /* Additional border color */
+ Tcl_Obj *borderWidthObj;
+ Tcl_Obj *orientObj; /* Orientation of overall slider */
+} SliderElement;
+
+static Ttk_ElementOptionSpec SliderElementOptions[] = {
+ { "-sliderlength", TK_OPTION_PIXELS, Tk_Offset(SliderElement,lengthObj),
+ "15" },
+ { "-sliderthickness",TK_OPTION_PIXELS,Tk_Offset(SliderElement,thicknessObj),
+ "15" },
+ { "-sliderrelief", TK_OPTION_RELIEF, Tk_Offset(SliderElement,reliefObj),
+ "raised" },
+ { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(SliderElement,borderWidthObj),
+ STRINGIFY(BORDERWIDTH) },
+ { "-background", TK_OPTION_BORDER, Tk_Offset(SliderElement,borderObj),
+ DEFAULT_BACKGROUND },
+ { "-bordercolor", TK_OPTION_COLOR, Tk_Offset(ThumbElement,borderColorObj),
+ "black" },
+ { "-orient", TK_OPTION_ANY, Tk_Offset(SliderElement,orientObj),
+ "horizontal" },
+ { NULL, 0, 0, NULL }
+};
+
+static void SliderElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ SliderElement *slider = elementRecord;
+ int orient, length, thickness, borderWidth;
+
+ Ttk_GetOrientFromObj(NULL, slider->orientObj, &orient);
+ Tk_GetPixelsFromObj(NULL, tkwin, slider->borderWidthObj, &borderWidth);
+ Tk_GetPixelsFromObj(NULL, tkwin, slider->lengthObj, &length);
+ Tk_GetPixelsFromObj(NULL, tkwin, slider->thicknessObj, &thickness);
+
+ switch (orient) {
+ case TTK_ORIENT_VERTICAL:
+ *widthPtr = thickness + (borderWidth *2);
+ *heightPtr = *widthPtr/2;
+ break;
+
+ case TTK_ORIENT_HORIZONTAL:
+ *heightPtr = thickness + (borderWidth *2);
+ *widthPtr = *heightPtr/2;
+ break;
+ }
+}
+
+static void SliderElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ SliderElement *slider = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, slider->borderObj);
+ XColor *borderColor = Tk_GetColorFromObj(tkwin, slider->borderColorObj);
+ int relief = TK_RELIEF_RAISED, borderWidth = 2;
+
+ Tk_GetPixelsFromObj(NULL, tkwin, slider->borderWidthObj, &borderWidth);
+ Tk_GetReliefFromObj(NULL, slider->reliefObj, &relief);
+
+ Tk_Fill3DRectangle(tkwin, d, border,
+ b.x, b.y, b.width, b.height,
+ borderWidth, TK_RELIEF_FLAT);
+ DrawBorder(tkwin, d, border, borderColor, b, borderWidth, relief);
+}
+
+static Ttk_ElementSpec SliderElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(SliderElement),
+ SliderElementOptions,
+ SliderElementSize,
+ SliderElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Tree indicator element.
+ */
+
+#define TTK_STATE_OPEN TTK_STATE_USER1 /* XREF: treeview.c */
+#define TTK_STATE_LEAF TTK_STATE_USER2
+
+typedef struct {
+ Tcl_Obj *colorObj;
+ Tcl_Obj *marginObj;
+ Tcl_Obj *diameterObj;
+} TreeitemIndicator;
+
+static Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = {
+ { "-foreground", TK_OPTION_COLOR,
+ Tk_Offset(TreeitemIndicator,colorObj), DEFAULT_FOREGROUND },
+ { "-diameter", TK_OPTION_PIXELS,
+ Tk_Offset(TreeitemIndicator,diameterObj), "9" },
+ { "-indicatormargins", TK_OPTION_STRING,
+ Tk_Offset(TreeitemIndicator,marginObj), "2 2 4 2" },
+ { NULL, 0, 0, NULL }
+};
+
+static void TreeitemIndicatorSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ TreeitemIndicator *indicator = elementRecord;
+ int diameter = 0;
+ Ttk_Padding margins;
+
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
+ Tk_GetPixelsFromObj(NULL, tkwin, indicator->diameterObj, &diameter);
+ *widthPtr = diameter + Ttk_PaddingWidth(margins);
+ *heightPtr = diameter + Ttk_PaddingHeight(margins);
+}
+
+static void TreeitemIndicatorDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, Ttk_State state)
+{
+ TreeitemIndicator *indicator = elementRecord;
+ XColor *color = Tk_GetColorFromObj(tkwin, indicator->colorObj);
+ GC gc = Tk_GCForColor(color, d);
+ Ttk_Padding padding = Ttk_UniformPadding(0);
+ int w = WIN32_XDRAWLINE_HACK;
+ int cx, cy;
+
+ if (state & TTK_STATE_LEAF) {
+ /* don't draw anything ... */
+ return;
+ }
+
+ Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding);
+ b = Ttk_PadBox(b, padding);
+
+ XDrawRectangle(Tk_Display(tkwin), d, gc,
+ b.x, b.y, b.width - 1, b.height - 1);
+
+ cx = b.x + (b.width - 1) / 2;
+ cy = b.y + (b.height - 1) / 2;
+ XDrawLine(Tk_Display(tkwin), d, gc, b.x+2, cy, b.x+b.width-3+w, cy);
+
+ if (!(state & TTK_STATE_OPEN)) {
+ /* turn '-' into a '+' */
+ XDrawLine(Tk_Display(tkwin), d, gc, cx, b.y+2, cx, b.y+b.height-3+w);
+ }
+}
+
+static Ttk_ElementSpec TreeitemIndicatorElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(TreeitemIndicator),
+ TreeitemIndicatorOptions,
+ TreeitemIndicatorSize,
+ TreeitemIndicatorDraw
+};
+
+/*------------------------------------------------------------------------
+ * TtkAltTheme_Init --
+ * Install alternate theme.
+ */
+MODULE_SCOPE int TtkAltTheme_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme theme = Ttk_CreateTheme(interp, "alt", NULL);
+
+ if (!theme) {
+ return TCL_ERROR;
+ }
+
+ Ttk_RegisterElement(interp, theme, "border", &BorderElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
+ &IndicatorElementSpec, &checkbutton_spec);
+ Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
+ &IndicatorElementSpec, &radiobutton_spec);
+ Ttk_RegisterElement(interp, theme, "Menubutton.indicator",
+ &MenubuttonArrowElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "field", &FieldElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "trough", &TroughElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "thumb", &ThumbElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "slider", &SliderElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "uparrow",
+ &ArrowElementSpec, &ArrowElements[0]);
+ Ttk_RegisterElement(interp, theme, "downarrow",
+ &ArrowElementSpec, &ArrowElements[1]);
+ Ttk_RegisterElement(interp, theme, "leftarrow",
+ &ArrowElementSpec, &ArrowElements[2]);
+ Ttk_RegisterElement(interp, theme, "rightarrow",
+ &ArrowElementSpec, &ArrowElements[3]);
+ Ttk_RegisterElement(interp, theme, "arrow",
+ &ArrowElementSpec, &ArrowElements[0]);
+
+ Ttk_RegisterElement(interp, theme, "arrow",
+ &ArrowElementSpec, &ArrowElements[0]);
+
+ Ttk_RegisterElement(interp, theme, "Treeitem.indicator",
+ &TreeitemIndicatorElementSpec, 0);
+
+ Tcl_PkgProvide(interp, "ttk::theme::alt", TTK_VERSION);
+
+ return TCL_OK;
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkElements.c b/generic/ttk/ttkElements.c
new file mode 100644
index 0000000..22af1d6
--- /dev/null
+++ b/generic/ttk/ttkElements.c
@@ -0,0 +1,1281 @@
+/*
+ * Copyright (c) 2003, Joe English
+ *
+ * Default implementation for themed elements.
+ *
+ */
+
+#include <tcl.h>
+#include <tk.h>
+#include <string.h>
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+#define DEFAULT_BORDERWIDTH "2"
+#define DEFAULT_ARROW_SIZE "15"
+#define MIN_THUMB_SIZE 10
+
+/*----------------------------------------------------------------------
+ * +++ Null element. Does nothing; used as a stub.
+ * Null element methods, option table and element spec are public,
+ * and may be used in other engines.
+ */
+
+/* public */ Ttk_ElementOptionSpec TtkNullElementOptions[] = { { NULL, 0, 0, NULL } };
+
+/* public */ void
+TtkNullElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+}
+
+/* public */ void
+TtkNullElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+}
+
+/* public */ Ttk_ElementSpec ttkNullElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(NullElement),
+ TtkNullElementOptions,
+ TtkNullElementSize,
+ TtkNullElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Background and fill elements.
+ *
+ * The fill element fills its parcel with the background color.
+ * The background element ignores the parcel, and fills the entire window.
+ *
+ * Ttk_GetLayout() automatically includes a background element.
+ */
+
+typedef struct {
+ Tcl_Obj *backgroundObj;
+} BackgroundElement;
+
+static Ttk_ElementOptionSpec BackgroundElementOptions[] = {
+ { "-background", TK_OPTION_BORDER,
+ Tk_Offset(BackgroundElement,backgroundObj), DEFAULT_BACKGROUND },
+ { NULL, 0, 0, NULL }
+};
+
+static void FillElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ BackgroundElement *bg = elementRecord;
+ Tk_3DBorder backgroundPtr = Tk_Get3DBorderFromObj(tkwin,bg->backgroundObj);
+
+ XFillRectangle(Tk_Display(tkwin), d,
+ Tk_3DBorderGC(tkwin, backgroundPtr, TK_3D_FLAT_GC),
+ b.x, b.y, b.width, b.height);
+}
+
+static void BackgroundElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ FillElementDraw(
+ clientData, elementRecord, tkwin,
+ d, Ttk_WinBox(tkwin), state);
+}
+
+static Ttk_ElementSpec FillElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(BackgroundElement),
+ BackgroundElementOptions,
+ TtkNullElementSize,
+ FillElementDraw
+};
+
+static Ttk_ElementSpec BackgroundElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(BackgroundElement),
+ BackgroundElementOptions,
+ TtkNullElementSize,
+ BackgroundElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Border element.
+ */
+
+typedef struct {
+ Tcl_Obj *borderObj;
+ Tcl_Obj *borderWidthObj;
+ Tcl_Obj *reliefObj;
+} BorderElement;
+
+static Ttk_ElementOptionSpec BorderElementOptions[] = {
+ { "-background", TK_OPTION_BORDER,
+ Tk_Offset(BorderElement,borderObj), DEFAULT_BACKGROUND },
+ { "-borderwidth", TK_OPTION_PIXELS,
+ Tk_Offset(BorderElement,borderWidthObj), DEFAULT_BORDERWIDTH },
+ { "-relief", TK_OPTION_RELIEF,
+ Tk_Offset(BorderElement,reliefObj), "flat" },
+ { NULL, 0, 0, NULL }
+};
+
+static void BorderElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ BorderElement *bd = elementRecord;
+ int borderWidth = 0;
+ Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
+ *paddingPtr = Ttk_UniformPadding((short)borderWidth);
+}
+
+static void BorderElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ BorderElement *bd = elementRecord;
+ Tk_3DBorder border = NULL;
+ int borderWidth = 1, relief = TK_RELIEF_FLAT;
+
+ border = Tk_Get3DBorderFromObj(tkwin, bd->borderObj);
+ Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
+ Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
+
+ if (border && borderWidth > 0 && relief != TK_RELIEF_FLAT) {
+ Tk_Draw3DRectangle(tkwin, d, border,
+ b.x, b.y, b.width, b.height, borderWidth,relief);
+ }
+}
+
+static Ttk_ElementSpec BorderElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(BorderElement),
+ BorderElementOptions,
+ BorderElementSize,
+ BorderElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Field element.
+ * Used for editable fields.
+ */
+typedef struct {
+ Tcl_Obj *borderObj;
+ Tcl_Obj *borderWidthObj;
+} FieldElement;
+
+static Ttk_ElementOptionSpec FieldElementOptions[] = {
+ { "-fieldbackground", TK_OPTION_BORDER,
+ Tk_Offset(FieldElement,borderObj), "white" },
+ { "-borderwidth", TK_OPTION_PIXELS,
+ Tk_Offset(FieldElement,borderWidthObj), "2" },
+ { NULL, 0, 0, NULL }
+};
+
+static void FieldElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ FieldElement *field = elementRecord;
+ int borderWidth = 2;
+ Tk_GetPixelsFromObj(NULL, tkwin, field->borderWidthObj, &borderWidth);
+ *paddingPtr = Ttk_UniformPadding((short)borderWidth);
+}
+
+static void FieldElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ FieldElement *field = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, field->borderObj);
+ int borderWidth = 2;
+
+ Tk_GetPixelsFromObj(NULL, tkwin, field->borderWidthObj, &borderWidth);
+ Tk_Fill3DRectangle(tkwin, d, border,
+ b.x, b.y, b.width, b.height, borderWidth, TK_RELIEF_SUNKEN);
+}
+
+static Ttk_ElementSpec FieldElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(FieldElement),
+ FieldElementOptions,
+ FieldElementSize,
+ FieldElementDraw
+};
+
+/*
+ *----------------------------------------------------------------------
+ * +++ Padding element.
+ *
+ * This element has no visual representation, only geometry.
+ * It adds a (possibly non-uniform) internal border.
+ * In addition, if "-shiftrelief" is specified,
+ * adds additional pixels to shift child elements "in" or "out"
+ * depending on the -relief.
+ */
+
+typedef struct {
+ Tcl_Obj *paddingObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *shiftreliefObj;
+} PaddingElement;
+
+static Ttk_ElementOptionSpec PaddingElementOptions[] = {
+ { "-padding", TK_OPTION_STRING,
+ Tk_Offset(PaddingElement,paddingObj), "0" },
+ { "-relief", TK_OPTION_RELIEF,
+ Tk_Offset(PaddingElement,reliefObj), "flat" },
+ { "-shiftrelief", TK_OPTION_INT,
+ Tk_Offset(PaddingElement,shiftreliefObj), "0" },
+ { NULL, 0, 0, NULL }
+};
+
+static void PaddingElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ PaddingElement *padding = elementRecord;
+ int shiftRelief = 0;
+ int relief = TK_RELIEF_FLAT;
+ Ttk_Padding pad;
+
+ Tk_GetReliefFromObj(NULL, padding->reliefObj, &relief);
+ Tcl_GetIntFromObj(NULL, padding->shiftreliefObj, &shiftRelief);
+ Ttk_GetPaddingFromObj(NULL,tkwin,padding->paddingObj,&pad);
+ *paddingPtr = Ttk_RelievePadding(pad, relief, shiftRelief);
+}
+
+static Ttk_ElementSpec PaddingElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(PaddingElement),
+ PaddingElementOptions,
+ PaddingElementSize,
+ TtkNullElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Focus ring element.
+ * Draws a dashed focus ring, if the widget has keyboard focus.
+ */
+typedef struct {
+ Tcl_Obj *focusColorObj;
+ Tcl_Obj *focusThicknessObj;
+} FocusElement;
+
+/*
+ * DrawFocusRing --
+ * Draw a dotted rectangle to indicate focus.
+ */
+static void DrawFocusRing(
+ Tk_Window tkwin, Drawable d, Tcl_Obj *colorObj, Ttk_Box b)
+{
+ XColor *color = Tk_GetColorFromObj(tkwin, colorObj);
+ unsigned long mask = 0UL;
+ XGCValues gcvalues;
+ GC gc;
+
+ gcvalues.foreground = color->pixel;
+ gcvalues.line_style = LineOnOffDash;
+ gcvalues.line_width = 1;
+ gcvalues.dashes = 1;
+ gcvalues.dash_offset = 1;
+ mask = GCForeground | GCLineStyle | GCDashList | GCDashOffset | GCLineWidth;
+
+ gc = Tk_GetGC(tkwin, mask, &gcvalues);
+ XDrawRectangle(Tk_Display(tkwin), d, gc, b.x, b.y, b.width-1, b.height-1);
+ Tk_FreeGC(Tk_Display(tkwin), gc);
+}
+
+static Ttk_ElementOptionSpec FocusElementOptions[] = {
+ { "-focuscolor",TK_OPTION_COLOR,
+ Tk_Offset(FocusElement,focusColorObj), "black" },
+ { "-focusthickness",TK_OPTION_PIXELS,
+ Tk_Offset(FocusElement,focusThicknessObj), "1" },
+ { NULL, 0, 0, NULL }
+};
+
+static void FocusElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ FocusElement *focus = elementRecord;
+ int focusThickness = 0;
+
+ Tcl_GetIntFromObj(NULL, focus->focusThicknessObj, &focusThickness);
+ *paddingPtr = Ttk_UniformPadding((short)focusThickness);
+}
+
+static void FocusElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ FocusElement *focus = elementRecord;
+ int focusThickness = 0;
+
+ if (state & TTK_STATE_FOCUS) {
+ Tcl_GetIntFromObj(NULL,focus->focusThicknessObj,&focusThickness);
+ DrawFocusRing(tkwin, d, focus->focusColorObj, b);
+ }
+}
+
+static Ttk_ElementSpec FocusElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(FocusElement),
+ FocusElementOptions,
+ FocusElementSize,
+ FocusElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Separator element.
+ * Just draws a horizontal or vertical bar.
+ * Three elements are defined: horizontal, vertical, and general;
+ * the general separator checks the "-orient" option.
+ */
+
+typedef struct {
+ Tcl_Obj *orientObj;
+ Tcl_Obj *borderObj;
+} SeparatorElement;
+
+static Ttk_ElementOptionSpec SeparatorElementOptions[] = {
+ { "-orient", TK_OPTION_ANY,
+ Tk_Offset(SeparatorElement, orientObj), "horizontal" },
+ { "-background", TK_OPTION_BORDER,
+ Tk_Offset(SeparatorElement,borderObj), DEFAULT_BACKGROUND },
+ { NULL, 0, 0, NULL }
+};
+
+static void SeparatorElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ *widthPtr = *heightPtr = 2;
+}
+
+static void HorizontalSeparatorElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ SeparatorElement *separator = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, separator->borderObj);
+ GC lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
+ GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
+
+ XDrawLine(Tk_Display(tkwin), d, darkGC, b.x, b.y, b.x + b.width, b.y);
+ XDrawLine(Tk_Display(tkwin), d, lightGC, b.x, b.y+1, b.x + b.width, b.y+1);
+}
+
+static void VerticalSeparatorElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ SeparatorElement *separator = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, separator->borderObj);
+ GC lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
+ GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
+
+ XDrawLine(Tk_Display(tkwin), d, darkGC, b.x, b.y, b.x, b.y + b.height);
+ XDrawLine(Tk_Display(tkwin), d, lightGC, b.x+1, b.y, b.x+1, b.y+b.height);
+}
+
+static void GeneralSeparatorElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ SeparatorElement *separator = elementRecord;
+ int orient;
+ Ttk_GetOrientFromObj(NULL, separator->orientObj, &orient);
+ switch (orient) {
+ case TTK_ORIENT_HORIZONTAL:
+ HorizontalSeparatorElementDraw(
+ clientData, elementRecord, tkwin, d, b, state);
+ break;
+ case TTK_ORIENT_VERTICAL:
+ VerticalSeparatorElementDraw(
+ clientData, elementRecord, tkwin, d, b, state);
+ break;
+ }
+}
+
+static Ttk_ElementSpec HorizontalSeparatorElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(SeparatorElement),
+ SeparatorElementOptions,
+ SeparatorElementSize,
+ HorizontalSeparatorElementDraw
+};
+
+static Ttk_ElementSpec VerticalSeparatorElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(SeparatorElement),
+ SeparatorElementOptions,
+ SeparatorElementSize,
+ HorizontalSeparatorElementDraw
+};
+
+static Ttk_ElementSpec SeparatorElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(SeparatorElement),
+ SeparatorElementOptions,
+ SeparatorElementSize,
+ GeneralSeparatorElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Sizegrip: lower-right corner grip handle for resizing window.
+ */
+
+typedef struct {
+ Tcl_Obj *backgroundObj;
+} SizegripElement;
+
+static Ttk_ElementOptionSpec SizegripOptions[] = {
+ { "-background", TK_OPTION_BORDER,
+ Tk_Offset(SizegripElement,backgroundObj), DEFAULT_BACKGROUND },
+ {0,0,0,0}
+};
+
+static void SizegripSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ int gripCount = 3, gripSpace = 2, gripThickness = 3;
+ *widthPtr = *heightPtr = gripCount * (gripSpace + gripThickness);
+}
+
+static void SizegripDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, Ttk_State state)
+{
+ SizegripElement *grip = elementRecord;
+ int gripCount = 3, gripSpace = 2;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, grip->backgroundObj);
+ GC lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
+ GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
+ int x1 = b.x + b.width-1, y1 = b.y + b.height-1, x2 = x1, y2 = y1;
+
+ while (gripCount--) {
+ x1 -= gripSpace; y2 -= gripSpace;
+ XDrawLine(Tk_Display(tkwin), d, darkGC, x1,y1, x2,y2); --x1; --y2;
+ XDrawLine(Tk_Display(tkwin), d, darkGC, x1,y1, x2,y2); --x1; --y2;
+ XDrawLine(Tk_Display(tkwin), d, lightGC, x1,y1, x2,y2); --x1; --y2;
+ }
+}
+
+static Ttk_ElementSpec SizegripElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(SizegripElement),
+ SizegripOptions,
+ SizegripSize,
+ SizegripDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Indicator element.
+ *
+ * Draws the on/off indicator for checkbuttons and radiobuttons.
+ *
+ * Draws a 3-D square (or diamond), raised if off, sunken if on.
+ *
+ * This is actually a regression from Tk 8.5 back to the ugly old Motif
+ * style; use "altTheme" for the newer, nicer version.
+ */
+
+typedef struct {
+ Tcl_Obj *backgroundObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *colorObj;
+ Tcl_Obj *diameterObj;
+ Tcl_Obj *marginObj;
+ Tcl_Obj *borderWidthObj;
+} IndicatorElement;
+
+static Ttk_ElementOptionSpec IndicatorElementOptions[] = {
+ { "-background", TK_OPTION_BORDER,
+ Tk_Offset(IndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
+ { "-indicatorcolor", TK_OPTION_BORDER,
+ Tk_Offset(IndicatorElement,colorObj), DEFAULT_BACKGROUND },
+ { "-indicatorrelief", TK_OPTION_RELIEF,
+ Tk_Offset(IndicatorElement,reliefObj), "raised" },
+ { "-indicatordiameter", TK_OPTION_PIXELS,
+ Tk_Offset(IndicatorElement,diameterObj), "12" },
+ { "-indicatormargin", TK_OPTION_STRING,
+ Tk_Offset(IndicatorElement,marginObj), "0 2 4 2" },
+ { "-borderwidth", TK_OPTION_PIXELS,
+ Tk_Offset(IndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
+ { NULL, 0, 0, NULL }
+};
+
+/*
+ * Checkbutton indicators (default): 3-D square.
+ */
+static void SquareIndicatorElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ IndicatorElement *indicator = elementRecord;
+ Ttk_Padding margins;
+ int diameter = 0;
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
+ Tk_GetPixelsFromObj(NULL, tkwin, indicator->diameterObj, &diameter);
+ *widthPtr = diameter + Ttk_PaddingWidth(margins);
+ *heightPtr = diameter + Ttk_PaddingHeight(margins);
+}
+
+static void SquareIndicatorElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ IndicatorElement *indicator = elementRecord;
+ Tk_3DBorder border = 0, interior = 0;
+ int relief = TK_RELIEF_RAISED;
+ Ttk_Padding padding;
+ int borderWidth = 2;
+ int diameter;
+
+ interior = Tk_Get3DBorderFromObj(tkwin, indicator->colorObj);
+ border = Tk_Get3DBorderFromObj(tkwin, indicator->backgroundObj);
+ Tcl_GetIntFromObj(NULL,indicator->borderWidthObj,&borderWidth);
+ Tk_GetReliefFromObj(NULL,indicator->reliefObj,&relief);
+ Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding);
+
+ b = Ttk_PadBox(b, padding);
+
+ diameter = b.width < b.height ? b.width : b.height;
+ Tk_Fill3DRectangle(tkwin, d, interior, b.x, b.y,
+ diameter, diameter,borderWidth, TK_RELIEF_FLAT);
+ Tk_Draw3DRectangle(tkwin, d, border, b.x, b.y,
+ diameter, diameter, borderWidth, relief);
+}
+
+/*
+ * Radiobutton indicators: 3-D diamond.
+ */
+static void DiamondIndicatorElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ IndicatorElement *indicator = elementRecord;
+ Ttk_Padding margins;
+ int diameter = 0;
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
+ Tk_GetPixelsFromObj(NULL, tkwin, indicator->diameterObj, &diameter);
+ *widthPtr = diameter + 3 + Ttk_PaddingWidth(margins);
+ *heightPtr = diameter + 3 + Ttk_PaddingHeight(margins);
+}
+
+static void DiamondIndicatorElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ IndicatorElement *indicator = elementRecord;
+ Tk_3DBorder border = 0, interior = 0;
+ int borderWidth = 2;
+ int relief = TK_RELIEF_RAISED;
+ int diameter, radius;
+ XPoint points[4];
+ Ttk_Padding padding;
+
+ interior = Tk_Get3DBorderFromObj(tkwin, indicator->colorObj);
+ border = Tk_Get3DBorderFromObj(tkwin, indicator->backgroundObj);
+ Tcl_GetIntFromObj(NULL,indicator->borderWidthObj,&borderWidth);
+ Tk_GetReliefFromObj(NULL,indicator->reliefObj,&relief);
+ Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginObj,&padding);
+
+ b = Ttk_PadBox(b, padding);
+
+ diameter = b.width < b.height ? b.width : b.height;
+ radius = diameter / 2;
+
+ points[0].x = b.x;
+ points[0].y = b.y + radius;
+ points[1].x = b.x + radius;
+ points[1].y = b.y + 2*radius;
+ points[2].x = b.x + 2*radius;
+ points[2].y = b.y + radius;
+ points[3].x = b.x + radius;
+ points[3].y = b.y;
+
+ Tk_Fill3DPolygon(tkwin,d,interior,points,4,borderWidth,TK_RELIEF_FLAT);
+ Tk_Draw3DPolygon(tkwin,d,border,points,4,borderWidth,relief);
+}
+
+static Ttk_ElementSpec CheckbuttonIndicatorElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(IndicatorElement),
+ IndicatorElementOptions,
+ SquareIndicatorElementSize,
+ SquareIndicatorElementDraw
+};
+
+static Ttk_ElementSpec RadiobuttonIndicatorElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(IndicatorElement),
+ IndicatorElementOptions,
+ DiamondIndicatorElementSize,
+ DiamondIndicatorElementDraw
+};
+
+/*
+ *----------------------------------------------------------------------
+ * +++ Menubutton indicators.
+ *
+ * These aren't functional like radio/check indicators,
+ * they're just affordability indicators.
+ *
+ * Standard Tk sets the indicator size to 4.0 mm by 1.7 mm.
+ * I have no idea where these numbers came from.
+ */
+
+typedef struct {
+ Tcl_Obj *backgroundObj;
+ Tcl_Obj *widthObj;
+ Tcl_Obj *heightObj;
+ Tcl_Obj *borderWidthObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *marginObj;
+} MenuIndicatorElement;
+
+static Ttk_ElementOptionSpec MenuIndicatorElementOptions[] = {
+ { "-background", TK_OPTION_BORDER,
+ Tk_Offset(MenuIndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
+ { "-indicatorwidth", TK_OPTION_PIXELS,
+ Tk_Offset(MenuIndicatorElement,widthObj), "4.0m" },
+ { "-indicatorheight", TK_OPTION_PIXELS,
+ Tk_Offset(MenuIndicatorElement,heightObj), "1.7m" },
+ { "-borderwidth", TK_OPTION_PIXELS,
+ Tk_Offset(MenuIndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
+ { "-indicatorrelief", TK_OPTION_RELIEF,
+ Tk_Offset(MenuIndicatorElement,reliefObj),"raised" },
+ { "-indicatormargin", TK_OPTION_STRING,
+ Tk_Offset(MenuIndicatorElement,marginObj), "5 0" },
+ { NULL, 0, 0, NULL }
+};
+
+static void MenuIndicatorElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ MenuIndicatorElement *mi = elementRecord;
+ Ttk_Padding margins;
+ Tk_GetPixelsFromObj(NULL, tkwin, mi->widthObj, widthPtr);
+ Tk_GetPixelsFromObj(NULL, tkwin, mi->heightObj, heightPtr);
+ Ttk_GetPaddingFromObj(NULL,tkwin,mi->marginObj, &margins);
+ *widthPtr += Ttk_PaddingWidth(margins);
+ *heightPtr += Ttk_PaddingHeight(margins);
+}
+
+static void MenuIndicatorElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ MenuIndicatorElement *mi = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, mi->backgroundObj);
+ Ttk_Padding margins;
+ int borderWidth = 2;
+
+ Ttk_GetPaddingFromObj(NULL,tkwin,mi->marginObj,&margins);
+ b = Ttk_PadBox(b, margins);
+ Tk_GetPixelsFromObj(NULL, tkwin, mi->borderWidthObj, &borderWidth);
+ Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
+ borderWidth, TK_RELIEF_RAISED);
+}
+
+static Ttk_ElementSpec MenuIndicatorElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(MenuIndicatorElement),
+ MenuIndicatorElementOptions,
+ MenuIndicatorElementSize,
+ MenuIndicatorElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Arrow elements.
+ *
+ * Draws a solid triangle inside a box.
+ * clientData is an enum ArrowDirection pointer.
+ */
+
+static int ArrowElements[] = { ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT };
+typedef struct {
+ Tcl_Obj *borderObj;
+ Tcl_Obj *borderWidthObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *sizeObj;
+ Tcl_Obj *colorObj;
+} ArrowElement;
+
+static Ttk_ElementOptionSpec ArrowElementOptions[] = {
+ { "-background", TK_OPTION_BORDER,
+ Tk_Offset(ArrowElement,borderObj), DEFAULT_BACKGROUND },
+ { "-relief",TK_OPTION_RELIEF,
+ Tk_Offset(ArrowElement,reliefObj),"raised"},
+ { "-borderwidth", TK_OPTION_PIXELS,
+ Tk_Offset(ArrowElement,borderWidthObj), "1" },
+ { "-arrowcolor",TK_OPTION_COLOR,
+ Tk_Offset(ArrowElement,colorObj),"black"},
+ { "-arrowsize", TK_OPTION_PIXELS,
+ Tk_Offset(ArrowElement,sizeObj), "14" },
+ { NULL, 0, 0, NULL }
+};
+
+static Ttk_Padding ArrowMargins = { 3,3,3,3 };
+
+static void ArrowElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ ArrowElement *arrow = elementRecord;
+ int direction = *(int *)clientData;
+ int width = 14;
+
+ Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &width);
+ width -= Ttk_PaddingWidth(ArrowMargins);
+ TtkArrowSize(width/2, direction, widthPtr, heightPtr);
+ *widthPtr += Ttk_PaddingWidth(ArrowMargins);
+ *heightPtr += Ttk_PaddingWidth(ArrowMargins);
+}
+
+static void ArrowElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ int direction = *(int *)clientData;
+ ArrowElement *arrow = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
+ XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
+ int relief = TK_RELIEF_RAISED;
+ int borderWidth = 1;
+
+ Tk_GetReliefFromObj(NULL, arrow->reliefObj, &relief);
+
+ Tk_Fill3DRectangle(
+ tkwin, d, border, b.x, b.y, b.width, b.height, borderWidth, relief);
+
+ TtkFillArrow(Tk_Display(tkwin), d, Tk_GCForColor(arrowColor, d),
+ Ttk_PadBox(b, ArrowMargins), direction);
+}
+
+static Ttk_ElementSpec ArrowElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(ArrowElement),
+ ArrowElementOptions,
+ ArrowElementSize,
+ ArrowElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Trough element.
+ *
+ * Used in scrollbars and scales in place of "border".
+ */
+
+typedef struct {
+ Tcl_Obj *colorObj;
+ Tcl_Obj *borderWidthObj;
+ Tcl_Obj *reliefObj;
+} TroughElement;
+
+static Ttk_ElementOptionSpec TroughElementOptions[] = {
+ { "-borderwidth", TK_OPTION_PIXELS,
+ Tk_Offset(TroughElement,borderWidthObj), DEFAULT_BORDERWIDTH },
+ { "-troughcolor", TK_OPTION_BORDER,
+ Tk_Offset(TroughElement,colorObj), DEFAULT_BACKGROUND },
+ { "-troughrelief",TK_OPTION_RELIEF,
+ Tk_Offset(TroughElement,reliefObj), "sunken" },
+ { NULL, 0, 0, NULL }
+};
+
+static void TroughElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ TroughElement *troughPtr = elementRecord;
+ int borderWidth = 2;
+
+ Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->borderWidthObj, &borderWidth);
+ *paddingPtr = Ttk_UniformPadding((short)borderWidth);
+}
+
+static void TroughElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ TroughElement *troughPtr = elementRecord;
+ Tk_3DBorder border = NULL;
+ int borderWidth = 2, relief = TK_RELIEF_SUNKEN;
+
+ border = Tk_Get3DBorderFromObj(tkwin, troughPtr->colorObj);
+ Tk_GetReliefFromObj(NULL, troughPtr->reliefObj, &relief);
+ Tk_GetPixelsFromObj(NULL, tkwin, troughPtr->borderWidthObj, &borderWidth);
+
+ Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
+ borderWidth, relief);
+}
+
+static Ttk_ElementSpec TroughElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(TroughElement),
+ TroughElementOptions,
+ TroughElementSize,
+ TroughElementDraw
+};
+
+/*
+ *----------------------------------------------------------------------
+ * +++ Thumb element.
+ *
+ * Used in scrollbars.
+ */
+
+typedef struct {
+ Tcl_Obj *orientObj;
+ Tcl_Obj *thicknessObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *borderObj;
+ Tcl_Obj *borderWidthObj;
+} ThumbElement;
+
+static Ttk_ElementOptionSpec ThumbElementOptions[] = {
+ { "-orient", TK_OPTION_ANY,
+ Tk_Offset(ThumbElement, orientObj), "horizontal" },
+ { "-width", TK_OPTION_PIXELS,
+ Tk_Offset(ThumbElement,thicknessObj), DEFAULT_ARROW_SIZE },
+ { "-relief", TK_OPTION_RELIEF,
+ Tk_Offset(ThumbElement,reliefObj), "raised" },
+ { "-background", TK_OPTION_BORDER,
+ Tk_Offset(ThumbElement,borderObj), DEFAULT_BACKGROUND },
+ { "-borderwidth", TK_OPTION_PIXELS,
+ Tk_Offset(ThumbElement,borderWidthObj), DEFAULT_BORDERWIDTH },
+ { NULL, 0, 0, NULL }
+};
+
+static void ThumbElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ ThumbElement *thumb = elementRecord;
+ int orient, thickness;
+
+ Tk_GetPixelsFromObj(NULL, tkwin, thumb->thicknessObj, &thickness);
+ Ttk_GetOrientFromObj(NULL, thumb->orientObj, &orient);
+
+ if (orient == TTK_ORIENT_VERTICAL) {
+ *widthPtr = thickness;
+ *heightPtr = MIN_THUMB_SIZE;
+ } else {
+ *widthPtr = MIN_THUMB_SIZE;
+ *heightPtr = thickness;
+ }
+}
+
+static void ThumbElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ ThumbElement *thumb = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, thumb->borderObj);
+ int borderWidth = 2, relief = TK_RELIEF_RAISED;
+
+ Tk_GetPixelsFromObj(NULL, tkwin, thumb->borderWidthObj, &borderWidth);
+ Tk_GetReliefFromObj(NULL, thumb->reliefObj, &relief);
+ Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
+ borderWidth, relief);
+}
+
+static Ttk_ElementSpec ThumbElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(ThumbElement),
+ ThumbElementOptions,
+ ThumbElementSize,
+ ThumbElementDraw
+};
+
+/*
+ *----------------------------------------------------------------------
+ * +++ Slider element.
+ *
+ * This is the moving part of the scale widget. Drawn as a raised box.
+ */
+
+typedef struct {
+ Tcl_Obj *orientObj; /* orientation of overall slider */
+ Tcl_Obj *lengthObj; /* slider length */
+ Tcl_Obj *thicknessObj; /* slider thickness */
+ Tcl_Obj *reliefObj; /* the relief for this object */
+ Tcl_Obj *borderObj; /* the background color */
+ Tcl_Obj *borderWidthObj; /* the size of the border */
+} SliderElement;
+
+static Ttk_ElementOptionSpec SliderElementOptions[] = {
+ { "-sliderlength", TK_OPTION_PIXELS, Tk_Offset(SliderElement,lengthObj),
+ "30" },
+ { "-sliderthickness",TK_OPTION_PIXELS,Tk_Offset(SliderElement,thicknessObj),
+ "15" },
+ { "-sliderrelief", TK_OPTION_RELIEF, Tk_Offset(SliderElement,reliefObj),
+ "raised" },
+ { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(SliderElement,borderWidthObj),
+ DEFAULT_BORDERWIDTH },
+ { "-background", TK_OPTION_BORDER, Tk_Offset(SliderElement,borderObj),
+ DEFAULT_BACKGROUND },
+ { "-orient", TK_OPTION_ANY, Tk_Offset(SliderElement,orientObj),
+ "horizontal" },
+ { NULL, 0, 0, NULL }
+};
+
+static void SliderElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ SliderElement *slider = elementRecord;
+ int orient, length, thickness;
+
+ Ttk_GetOrientFromObj(NULL, slider->orientObj, &orient);
+ Tk_GetPixelsFromObj(NULL, tkwin, slider->lengthObj, &length);
+ Tk_GetPixelsFromObj(NULL, tkwin, slider->thicknessObj, &thickness);
+
+ switch (orient) {
+ case TTK_ORIENT_VERTICAL:
+ *widthPtr = thickness;
+ *heightPtr = length;
+ break;
+
+ case TTK_ORIENT_HORIZONTAL:
+ *widthPtr = length;
+ *heightPtr = thickness;
+ break;
+ }
+}
+
+static void SliderElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ SliderElement *slider = elementRecord;
+ Tk_3DBorder border = NULL;
+ int relief = TK_RELIEF_RAISED, borderWidth = 2, orient;
+
+ border = Tk_Get3DBorderFromObj(tkwin, slider->borderObj);
+ Ttk_GetOrientFromObj(NULL, slider->orientObj, &orient);
+ Tk_GetPixelsFromObj(NULL, tkwin, slider->borderWidthObj, &borderWidth);
+ Tk_GetReliefFromObj(NULL, slider->reliefObj, &relief);
+
+ Tk_Fill3DRectangle(tkwin, d, border,
+ b.x, b.y, b.width, b.height,
+ borderWidth, relief);
+
+ if (relief != TK_RELIEF_FLAT) {
+ if (orient == TTK_ORIENT_HORIZONTAL) {
+ if (b.width > 4) {
+ b.x += b.width/2;
+ XDrawLine(Tk_Display(tkwin), d,
+ Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC),
+ b.x-1, b.y+borderWidth, b.x-1, b.y+b.height-borderWidth);
+ XDrawLine(Tk_Display(tkwin), d,
+ Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
+ b.x, b.y+borderWidth, b.x, b.y+b.height-borderWidth);
+ }
+ } else {
+ if (b.height > 4) {
+ b.y += b.height/2;
+ XDrawLine(Tk_Display(tkwin), d,
+ Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC),
+ b.x+borderWidth, b.y-1, b.x+b.width-borderWidth, b.y-1);
+ XDrawLine(Tk_Display(tkwin), d,
+ Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
+ b.x+borderWidth, b.y, b.x+b.width-borderWidth, b.y);
+ }
+ }
+ }
+}
+
+static Ttk_ElementSpec SliderElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(SliderElement),
+ SliderElementOptions,
+ SliderElementSize,
+ SliderElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Progress bar element:
+ * Draws the moving part of the progress bar.
+ *
+ * -thickness specifies the size along the short axis of the bar.
+ * -length specifies the default size along the long axis;
+ * the bar will be this long in indeterminate mode.
+ */
+
+#define DEFAULT_PBAR_THICKNESS "15"
+#define DEFAULT_PBAR_LENGTH "30"
+
+typedef struct {
+ Tcl_Obj *orientObj; /* widget orientation */
+ Tcl_Obj *thicknessObj; /* the height/width of the bar */
+ Tcl_Obj *lengthObj; /* default width/height of the bar */
+ Tcl_Obj *reliefObj; /* border relief for this object */
+ Tcl_Obj *borderObj; /* background color */
+ Tcl_Obj *borderWidthObj; /* thickness of the border */
+} PbarElement;
+
+static Ttk_ElementOptionSpec PbarElementOptions[] = {
+ { "-orient", TK_OPTION_ANY, Tk_Offset(PbarElement,orientObj),
+ "horizontal" },
+ { "-thickness", TK_OPTION_PIXELS, Tk_Offset(PbarElement,thicknessObj),
+ DEFAULT_PBAR_THICKNESS },
+ { "-barsize", TK_OPTION_PIXELS, Tk_Offset(PbarElement,lengthObj),
+ DEFAULT_PBAR_LENGTH },
+ { "-pbarrelief", TK_OPTION_RELIEF, Tk_Offset(PbarElement,reliefObj),
+ "raised" },
+ { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(PbarElement,borderWidthObj),
+ DEFAULT_BORDERWIDTH },
+ { "-background", TK_OPTION_BORDER, Tk_Offset(PbarElement,borderObj),
+ DEFAULT_BACKGROUND },
+ { NULL, 0, 0, NULL }
+};
+
+static void PbarElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ PbarElement *pbar = elementRecord;
+ int orient, thickness = 15, length = 30, borderWidth = 2;
+
+ Ttk_GetOrientFromObj(NULL, pbar->orientObj, &orient);
+ Tk_GetPixelsFromObj(NULL, tkwin, pbar->thicknessObj, &thickness);
+ Tk_GetPixelsFromObj(NULL, tkwin, pbar->lengthObj, &length);
+ Tk_GetPixelsFromObj(NULL, tkwin, pbar->borderWidthObj, &borderWidth);
+
+ switch (orient) {
+ case TTK_ORIENT_HORIZONTAL:
+ *widthPtr = length + 2 * borderWidth;
+ *heightPtr = thickness + 2 * borderWidth;
+ break;
+ case TTK_ORIENT_VERTICAL:
+ *widthPtr = thickness + 2 * borderWidth;
+ *heightPtr = length + 2 * borderWidth;
+ break;
+ }
+}
+
+static void PbarElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, Ttk_State state)
+{
+ PbarElement *pbar = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, pbar->borderObj);
+ int relief = TK_RELIEF_RAISED, borderWidth = 2;
+
+ Tk_GetPixelsFromObj(NULL, tkwin, pbar->borderWidthObj, &borderWidth);
+ Tk_GetReliefFromObj(NULL, pbar->reliefObj, &relief);
+
+ Tk_Fill3DRectangle(tkwin, d, border,
+ b.x, b.y, b.width, b.height,
+ borderWidth, relief);
+}
+
+static Ttk_ElementSpec PbarElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(PbarElement),
+ PbarElementOptions,
+ PbarElementSize,
+ PbarElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Notebook tabs and client area.
+ */
+
+typedef struct {
+ Tcl_Obj *borderWidthObj;
+ Tcl_Obj *backgroundObj;
+} TabElement;
+
+static Ttk_ElementOptionSpec TabElementOptions[] = {
+ { "-borderwidth", TK_OPTION_PIXELS,
+ Tk_Offset(TabElement,borderWidthObj),"1" },
+ { "-background", TK_OPTION_BORDER,
+ Tk_Offset(TabElement,backgroundObj), DEFAULT_BACKGROUND },
+ {0,0,0,0}
+};
+
+static void TabElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ TabElement *tab = elementRecord;
+ int borderWidth = 1;
+ Tk_GetPixelsFromObj(0, tkwin, tab->borderWidthObj, &borderWidth);
+ paddingPtr->top = paddingPtr->left = paddingPtr->right = borderWidth;
+ paddingPtr->bottom = 0;
+}
+
+static void TabElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ TabElement *tab = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, tab->backgroundObj);
+ int borderWidth = 1;
+ int cut = 2;
+ XPoint pts[6];
+ int n = 0;
+
+ Tcl_GetIntFromObj(NULL, tab->borderWidthObj, &borderWidth);
+
+ if (state & TTK_STATE_SELECTED) {
+ /*
+ * Draw slightly outside of the allocated parcel,
+ * to overwrite the client area border.
+ */
+ b.height += borderWidth;
+ }
+
+ pts[n].x = b.x; pts[n].y = b.y + b.height - 1; ++n;
+ pts[n].x = b.x; pts[n].y = b.y + cut; ++n;
+ pts[n].x = b.x + cut; pts[n].y = b.y; ++n;
+ pts[n].x = b.x + b.width-1-cut; pts[n].y = b.y; ++n;
+ pts[n].x = b.x + b.width-1; pts[n].y = b.y + cut; ++n;
+ pts[n].x = b.x + b.width-1; pts[n].y = b.y + b.height; ++n;
+
+ XFillPolygon(Tk_Display(tkwin), d,
+ Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC),
+ pts, 6, Convex, CoordModeOrigin);
+
+#ifndef WIN32
+ /*
+ * Account for whether XDrawLines draws endpoints by platform
+ */
+ --pts[5].y;
+#endif
+
+ while (borderWidth--) {
+ XDrawLines(Tk_Display(tkwin), d,
+ Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
+ pts, 4, CoordModeOrigin);
+ XDrawLines(Tk_Display(tkwin), d,
+ Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC),
+ pts+3, 3, CoordModeOrigin);
+ ++pts[0].x; ++pts[1].x; ++pts[2].x; --pts[4].x; --pts[5].x;
+ ++pts[2].y; ++pts[3].y;
+ }
+
+}
+
+static Ttk_ElementSpec TabElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(TabElement),
+ TabElementOptions,
+ TabElementSize,
+ TabElementDraw
+};
+
+/*
+ * Client area element:
+ * Uses same resources as tab element.
+ */
+typedef TabElement ClientElement;
+#define ClientElementOptions TabElementOptions
+
+static void ClientElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ ClientElement *ce = elementRecord;
+ Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, ce->backgroundObj);
+ int borderWidth = 1;
+
+ Tcl_GetIntFromObj(NULL, ce->borderWidthObj, &borderWidth);
+
+ Tk_Fill3DRectangle(tkwin, d, border,
+ b.x, b.y, b.width, b.height, borderWidth,TK_RELIEF_RAISED);
+}
+
+static void ClientElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ ClientElement *ce = elementRecord;
+ int borderWidth = 1;
+ Tk_GetPixelsFromObj(0, tkwin, ce->borderWidthObj, &borderWidth);
+ *paddingPtr = Ttk_UniformPadding((short)borderWidth);
+}
+
+static Ttk_ElementSpec ClientElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(ClientElement),
+ ClientElementOptions,
+ ClientElementSize,
+ ClientElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * TtkElements_Init --
+ * Register default element implementations.
+ */
+
+MODULE_SCOPE
+void TtkElements_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme theme = Ttk_GetDefaultTheme(interp);
+
+ /*
+ * Elements:
+ */
+ Ttk_RegisterElement(interp, theme, "background",
+ &BackgroundElementSpec,NULL);
+
+ Ttk_RegisterElement(interp, theme, "fill", &FillElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "border", &BorderElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "field", &FieldElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "focus", &FocusElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "padding", &PaddingElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
+ &CheckbuttonIndicatorElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
+ &RadiobuttonIndicatorElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "Menubutton.indicator",
+ &MenuIndicatorElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "indicator", &ttkNullElementSpec,NULL);
+
+ Ttk_RegisterElement(interp, theme, "uparrow",
+ &ArrowElementSpec, &ArrowElements[0]);
+ Ttk_RegisterElement(interp, theme, "downarrow",
+ &ArrowElementSpec, &ArrowElements[1]);
+ Ttk_RegisterElement(interp, theme, "leftarrow",
+ &ArrowElementSpec, &ArrowElements[2]);
+ Ttk_RegisterElement(interp, theme, "rightarrow",
+ &ArrowElementSpec, &ArrowElements[3]);
+ Ttk_RegisterElement(interp, theme, "arrow",
+ &ArrowElementSpec, &ArrowElements[0]);
+
+ Ttk_RegisterElement(interp, theme, "trough", &TroughElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "thumb", &ThumbElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "slider", &SliderElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "pbar", &PbarElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "separator",
+ &SeparatorElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "hseparator",
+ &HorizontalSeparatorElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "vseparator",
+ &VerticalSeparatorElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "sizegrip", &SizegripElementSpec, NULL);
+
+ Ttk_RegisterElement(interp, theme, "tab", &TabElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "client", &ClientElementSpec, NULL);
+
+ /*
+ * Register "default" as a user-loadable theme (for now):
+ */
+ Tcl_PkgProvide(interp, "ttk::theme::default", TTK_VERSION);
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkEntry.c b/generic/ttk/ttkEntry.c
new file mode 100644
index 0000000..5c280e4
--- /dev/null
+++ b/generic/ttk/ttkEntry.c
@@ -0,0 +1,2048 @@
+/*
+ * DERIVED FROM: tk/generic/tkEntry.c r1.35.
+ *
+ * Copyright (c) 1990-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 2000 Ajuba Solutions.
+ * Copyright (c) 2002 ActiveState Corporation.
+ * Copyright (c) 2004 Joe English
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <tkInt.h>
+#include <X11/Xatom.h>
+
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+/*
+ * Extra bits for core.flags:
+ */
+#define GOT_SELECTION (WIDGET_USER_FLAG<<1)
+#define SYNCING_VARIABLE (WIDGET_USER_FLAG<<2)
+#define VALIDATING (WIDGET_USER_FLAG<<3)
+#define VALIDATION_SET_VALUE (WIDGET_USER_FLAG<<4)
+
+/*
+ * Definitions for -validate option values:
+ */
+typedef enum validateMode {
+ VMODE_ALL, VMODE_KEY, VMODE_FOCUS, VMODE_FOCUSIN, VMODE_FOCUSOUT, VMODE_NONE
+} VMODE;
+
+static const char *const validateStrings[] = {
+ "all", "key", "focus", "focusin", "focusout", "none", NULL
+};
+
+/*
+ * Validation reasons:
+ */
+typedef enum validateReason {
+ VALIDATE_INSERT, VALIDATE_DELETE,
+ VALIDATE_FOCUSIN, VALIDATE_FOCUSOUT,
+ VALIDATE_FORCED
+} VREASON;
+
+static const char *const validateReasonStrings[] = {
+ "key", "key", "focusin", "focusout", "forced", NULL
+};
+
+/*------------------------------------------------------------------------
+ * +++ Entry widget record.
+ *
+ * Dependencies:
+ *
+ * textVariableTrace : textVariableObj
+ *
+ * numBytes,numChars : string
+ * displayString : numChars, showChar
+ * layoutHeight,
+ * layoutWidth,
+ * textLayout : fontObj, displayString
+ * layoutX, layoutY : textLayout, justify, xscroll.first
+ *
+ * Invariants:
+ *
+ * 0 <= insertPos <= numChars
+ * 0 <= selectFirst < selectLast <= numChars || selectFirst == selectLast == -1
+ * displayString points to string if showChar == NULL,
+ * or to malloc'ed storage if showChar != NULL.
+ */
+
+/* Style parameters:
+ */
+typedef struct {
+ Tcl_Obj *foregroundObj; /* Foreground color for normal text */
+ Tcl_Obj *backgroundObj; /* Entry widget background color */
+ Tcl_Obj *selBorderObj; /* Border and background for selection */
+ Tcl_Obj *selBorderWidthObj; /* Width of selection border */
+ Tcl_Obj *selForegroundObj; /* Foreground color for selected text */
+ Tcl_Obj *insertColorObj; /* Color of insertion cursor */
+ Tcl_Obj *insertWidthObj; /* Insert cursor width */
+} EntryStyleData;
+
+typedef struct {
+ /*
+ * Internal state:
+ */
+ char *string; /* Storage for string (malloced) */
+ int numBytes; /* Length of string in bytes. */
+ int numChars; /* Length of string in characters. */
+
+ int insertPos; /* Insert index */
+ int selectFirst; /* Index of start of selection, or -1 */
+ int selectLast; /* Index of end of selection, or -1 */
+
+ Scrollable xscroll; /* Current scroll position */
+ ScrollHandle xscrollHandle;
+
+ /*
+ * Options managed by Tk_SetOptions:
+ */
+ Tcl_Obj *textVariableObj; /* Name of linked variable */
+ int exportSelection; /* Tie internal selection to X selection? */
+
+ VMODE validate; /* Validation mode */
+ char *validateCmd; /* Validation script template */
+ char *invalidCmd; /* Invalid callback script template */
+
+ char *showChar; /* Used to derive displayString */
+
+ Tcl_Obj *fontObj; /* Text font to use */
+ Tcl_Obj *widthObj; /* Desired width of window (in avgchars) */
+ Tk_Justify justify; /* Text justification */
+
+ EntryStyleData styleData; /* Display style data (widget options) */
+ EntryStyleData styleDefaults;/* Style defaults (fallback values) */
+
+ Tcl_Obj *stateObj; /* Compatibility option -- see CheckStateObj */
+
+ /*
+ * Derived resources:
+ */
+ Ttk_TraceHandle *textVariableTrace;
+
+ char *displayString; /* String to use when displaying */
+ Tk_TextLayout textLayout; /* Cached text layout information. */
+ int layoutWidth; /* textLayout width */
+ int layoutHeight; /* textLayout height */
+
+ int layoutX, layoutY; /* Origin for text layout. */
+
+} EntryPart;
+
+typedef struct {
+ WidgetCore core;
+ EntryPart entry;
+} Entry;
+
+/*
+ * Extra mask bits for Tk_SetOptions()
+ */
+#define STATE_CHANGED (0x100) /* -state option changed */
+#define TEXTVAR_CHANGED (0x200) /* -textvariable option changed */
+#define SCROLLCMD_CHANGED (0x400) /* -xscrollcommand option changed */
+
+/*
+ * Default option values:
+ */
+#define DEF_SELECT_BG "#000000"
+#define DEF_SELECT_FG "#ffffff"
+#define DEF_INSERT_BG "black"
+#define DEF_ENTRY_WIDTH "20"
+#define DEF_ENTRY_FONT "TkTextFont"
+#define DEF_LIST_HEIGHT "10"
+
+static Tk_OptionSpec EntryOptionSpecs[] = {
+ {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
+ "ExportSelection", "1", -1, Tk_Offset(Entry, entry.exportSelection),
+ 0,0,0 },
+ {TK_OPTION_FONT, "-font", "font", "Font",
+ DEF_ENTRY_FONT, Tk_Offset(Entry, entry.fontObj),-1,
+ 0,0,GEOMETRY_CHANGED},
+ {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
+ NULL, -1, Tk_Offset(Entry, entry.invalidCmd),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
+ "left", -1, Tk_Offset(Entry, entry.justify),
+ 0, 0, GEOMETRY_CHANGED},
+ {TK_OPTION_STRING, "-show", "show", "Show",
+ NULL, -1, Tk_Offset(Entry, entry.showChar),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_STRING, "-state", "state", "State",
+ "normal", Tk_Offset(Entry, entry.stateObj), -1,
+ 0,0,STATE_CHANGED},
+ {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
+ NULL, Tk_Offset(Entry, entry.textVariableObj), -1,
+ TK_OPTION_NULL_OK,0,TEXTVAR_CHANGED},
+ {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
+ "none", -1, Tk_Offset(Entry, entry.validate),
+ 0, (ClientData) validateStrings, 0},
+ {TK_OPTION_STRING, "-validatecommand", "validateCommand", "ValidateCommand",
+ NULL, -1, Tk_Offset(Entry, entry.validateCmd),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_INT, "-width", "width", "Width",
+ DEF_ENTRY_WIDTH, Tk_Offset(Entry, entry.widthObj), -1,
+ 0,0,GEOMETRY_CHANGED},
+ {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
+ NULL, -1, Tk_Offset(Entry, entry.xscroll.scrollCmd),
+ TK_OPTION_NULL_OK, 0, SCROLLCMD_CHANGED},
+
+ /* EntryStyleData options:
+ */
+ {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
+ NULL, Tk_Offset(Entry, entry.styleData.foregroundObj), -1,
+ TK_OPTION_NULL_OK,0,0},
+ {TK_OPTION_COLOR, "-background", "windowColor", "WindowColor",
+ NULL, Tk_Offset(Entry, entry.styleData.backgroundObj), -1,
+ TK_OPTION_NULL_OK,0,0},
+
+ WIDGET_TAKEFOCUS_TRUE,
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
+};
+
+/*------------------------------------------------------------------------
+ * +++ EntryStyleData management.
+ * This is still more awkward than it should be;
+ * it should be able to use the Element API instead.
+ */
+
+/* EntryInitStyleDefaults --
+ * Initialize EntryStyleData record to fallback values.
+ */
+static void EntryInitStyleDefaults(EntryStyleData *es)
+{
+#define INIT(member, value) \
+ es->member = Tcl_NewStringObj(value, -1); \
+ Tcl_IncrRefCount(es->member);
+ INIT(foregroundObj, DEFAULT_FOREGROUND)
+ INIT(selBorderObj, DEF_SELECT_BG)
+ INIT(selForegroundObj, DEF_SELECT_FG)
+ INIT(insertColorObj, DEFAULT_FOREGROUND)
+ INIT(selBorderWidthObj, "0")
+ INIT(insertWidthObj, "1")
+#undef INIT
+}
+
+static void EntryFreeStyleDefaults(EntryStyleData *es)
+{
+ Tcl_DecrRefCount(es->foregroundObj);
+ Tcl_DecrRefCount(es->selBorderObj);
+ Tcl_DecrRefCount(es->selForegroundObj);
+ Tcl_DecrRefCount(es->insertColorObj);
+ Tcl_DecrRefCount(es->selBorderWidthObj);
+ Tcl_DecrRefCount(es->insertWidthObj);
+}
+
+/*
+ * EntryInitStyleData --
+ * Look up style-specific data for an entry widget.
+ */
+static void EntryInitStyleData(Entry *entryPtr, EntryStyleData *es)
+{
+ Ttk_State state = entryPtr->core.state;
+ Ttk_ResourceCache cache = Ttk_GetResourceCache(entryPtr->core.interp);
+ Tk_Window tkwin = entryPtr->core.tkwin;
+ Tcl_Obj *tmp;
+
+ /* Initialize to fallback values:
+ */
+ *es = entryPtr->entry.styleDefaults;
+
+# define INIT(member, name) \
+ if ((tmp=Ttk_QueryOption(entryPtr->core.layout,name,state))) \
+ es->member=tmp;
+ INIT(foregroundObj, "-foreground");
+ INIT(selBorderObj, "-selectbackground")
+ INIT(selBorderWidthObj, "-selectborderwidth")
+ INIT(selForegroundObj, "-selectforeground")
+ INIT(insertColorObj, "-insertcolor")
+ INIT(insertWidthObj, "-insertwidth")
+#undef INIT
+
+ /* Reacquire color & border resources from resource cache.
+ */
+ es->foregroundObj = Ttk_UseColor(cache, tkwin, es->foregroundObj);
+ es->selForegroundObj = Ttk_UseColor(cache, tkwin, es->selForegroundObj);
+ es->insertColorObj = Ttk_UseColor(cache, tkwin, es->insertColorObj);
+ es->selBorderObj = Ttk_UseBorder(cache, tkwin, es->selBorderObj);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Resource management.
+ */
+
+/* EntryDisplayString --
+ * Return a malloc'ed string consisting of 'numChars' copies
+ * of (the first character in the string) 'showChar'.
+ * Used to compute the displayString if -show is non-NULL.
+ */
+static char *EntryDisplayString(const char *showChar, int numChars)
+{
+ char *displayString, *p;
+ int size;
+ Tcl_UniChar ch;
+ char buf[TCL_UTF_MAX];
+
+ Tcl_UtfToUniChar(showChar, &ch);
+ size = Tcl_UniCharToUtf(ch, buf);
+ p = displayString = ckalloc(numChars * size + 1);
+
+ while (numChars--) {
+ p += Tcl_UniCharToUtf(ch, p);
+ }
+ *p = '\0';
+
+ return displayString;
+}
+
+/* EntryUpdateTextLayout --
+ * Recompute textLayout, layoutWidth, and layoutHeight
+ * from displayString and fontObj.
+ */
+static void EntryUpdateTextLayout(Entry *entryPtr)
+{
+ Tk_FreeTextLayout(entryPtr->entry.textLayout);
+ entryPtr->entry.textLayout = Tk_ComputeTextLayout(
+ Tk_GetFontFromObj(entryPtr->core.tkwin, entryPtr->entry.fontObj),
+ entryPtr->entry.displayString, entryPtr->entry.numChars,
+ 0/*wraplength*/, entryPtr->entry.justify, TK_IGNORE_NEWLINES,
+ &entryPtr->entry.layoutWidth, &entryPtr->entry.layoutHeight);
+}
+
+/* EntryEditable --
+ * Returns 1 if the entry widget accepts user changes, 0 otherwise
+ */
+static int
+EntryEditable(Entry *entryPtr)
+{
+ return !(entryPtr->core.state & (TTK_STATE_DISABLED|TTK_STATE_READONLY));
+}
+
+/*------------------------------------------------------------------------
+ * +++ Selection management.
+ */
+
+/* EntryFetchSelection --
+ * Selection handler for entry widgets.
+ */
+static int
+EntryFetchSelection(
+ ClientData clientData, int offset, char *buffer, int maxBytes)
+{
+ Entry *entryPtr = (Entry *) clientData;
+ size_t byteCount;
+ const char *string;
+ const char *selStart, *selEnd;
+
+ if (entryPtr->entry.selectFirst < 0 || !entryPtr->entry.exportSelection) {
+ return -1;
+ }
+ string = entryPtr->entry.displayString;
+
+ selStart = Tcl_UtfAtIndex(string, entryPtr->entry.selectFirst);
+ selEnd = Tcl_UtfAtIndex(selStart,
+ entryPtr->entry.selectLast - entryPtr->entry.selectFirst);
+ byteCount = selEnd - selStart - offset;
+ if (byteCount > (size_t)maxBytes) {
+ /* @@@POSSIBLE BUG: Can transfer partial UTF-8 sequences. Is this OK? */
+ byteCount = maxBytes;
+ }
+ if (byteCount <= 0) {
+ return 0;
+ }
+ memcpy(buffer, selStart + offset, byteCount);
+ buffer[byteCount] = '\0';
+ return byteCount;
+}
+
+/* EntryLostSelection --
+ * Tk_LostSelProc for Entry widgets; called when an entry
+ * loses ownership of the selection.
+ */
+static void EntryLostSelection(ClientData clientData)
+{
+ Entry *entryPtr = (Entry *) clientData;
+ entryPtr->core.flags &= ~GOT_SELECTION;
+ entryPtr->entry.selectFirst = entryPtr->entry.selectLast = -1;
+ TtkRedisplayWidget(&entryPtr->core);
+}
+
+/* EntryOwnSelection --
+ * Assert ownership of the PRIMARY selection,
+ * if -exportselection set and selection is present.
+ */
+static void EntryOwnSelection(Entry *entryPtr)
+{
+ if (entryPtr->entry.exportSelection
+ && !(entryPtr->core.flags & GOT_SELECTION)) {
+ Tk_OwnSelection(entryPtr->core.tkwin, XA_PRIMARY, EntryLostSelection,
+ (ClientData) entryPtr);
+ entryPtr->core.flags |= GOT_SELECTION;
+ }
+}
+
+/*------------------------------------------------------------------------
+ * +++ Validation.
+ */
+
+/* ExpandPercents --
+ * Expand an entry validation script template (-validatecommand
+ * or -invalidcommand).
+ */
+static void
+ExpandPercents(
+ Entry *entryPtr, /* Entry that needs validation. */
+ const char *template, /* Script template */
+ const char *new, /* Potential new value of entry string */
+ int index, /* index of insert/delete */
+ int count, /* #changed characters */
+ VREASON reason, /* Reason for change */
+ Tcl_DString *dsPtr) /* Result of %-substitutions */
+{
+ int spaceNeeded, cvtFlags;
+ int number, length;
+ const char *string;
+ int stringLength;
+ Tcl_UniChar ch;
+ char numStorage[2*TCL_INTEGER_SPACE];
+
+ while (*template) {
+ /* Find everything up to the next % character and append it
+ * to the result string.
+ */
+ string = Tcl_UtfFindFirst(template, '%');
+ if (string == NULL) {
+ /* No more %-sequences to expand.
+ * Copy the rest of the template.
+ */
+ Tcl_DStringAppend(dsPtr, template, -1);
+ return;
+ }
+ if (string != template) {
+ Tcl_DStringAppend(dsPtr, template, string - template);
+ template = string;
+ }
+
+ /* There's a percent sequence here. Process it.
+ */
+ ++template; /* skip over % */
+ if (*template != '\0') {
+ template += Tcl_UtfToUniChar(template, &ch);
+ } else {
+ ch = '%';
+ }
+
+ stringLength = -1;
+ switch (ch) {
+ case 'd': /* Type of call that caused validation */
+ if (reason == VALIDATE_INSERT) {
+ number = 1;
+ } else if (reason == VALIDATE_DELETE) {
+ number = 0;
+ } else {
+ number = -1;
+ }
+ sprintf(numStorage, "%d", number);
+ string = numStorage;
+ break;
+ case 'i': /* index of insert/delete */
+ sprintf(numStorage, "%d", index);
+ string = numStorage;
+ break;
+ case 'P': /* 'Peeked' new value of the string */
+ string = new;
+ break;
+ case 's': /* Current string value */
+ string = entryPtr->entry.string;
+ break;
+ case 'S': /* string to be inserted/deleted, if any */
+ if (reason == VALIDATE_INSERT) {
+ string = Tcl_UtfAtIndex(new, index);
+ stringLength = Tcl_UtfAtIndex(string, count) - string;
+ } else if (reason == VALIDATE_DELETE) {
+ string = Tcl_UtfAtIndex(entryPtr->entry.string, index);
+ stringLength = Tcl_UtfAtIndex(string, count) - string;
+ } else {
+ string = "";
+ stringLength = 0;
+ }
+ break;
+ case 'v': /* type of validation currently set */
+ string = validateStrings[entryPtr->entry.validate];
+ break;
+ case 'V': /* type of validation in effect */
+ string = validateReasonStrings[reason];
+ break;
+ case 'W': /* widget name */
+ string = Tk_PathName(entryPtr->core.tkwin);
+ break;
+ default:
+ length = Tcl_UniCharToUtf(ch, numStorage);
+ numStorage[length] = '\0';
+ string = numStorage;
+ break;
+ }
+
+ spaceNeeded = Tcl_ScanCountedElement(string, stringLength, &cvtFlags);
+ length = Tcl_DStringLength(dsPtr);
+ Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
+ spaceNeeded = Tcl_ConvertCountedElement(string, stringLength,
+ Tcl_DStringValue(dsPtr) + length,
+ cvtFlags | TCL_DONT_USE_BRACES);
+ Tcl_DStringSetLength(dsPtr, length + spaceNeeded);
+ }
+}
+
+/* RunValidationScript --
+ * Build and evaluate an entry validation script.
+ * If the script raises an error, disable validation
+ * by setting '-validate none'
+ */
+static int RunValidationScript(
+ Tcl_Interp *interp, /* Interpreter to use */
+ Entry *entryPtr, /* Entry being validated */
+ const char *template, /* Script template */
+ const char *optionName, /* "-validatecommand", "-invalidcommand" */
+ const char *new, /* Potential new value of entry string */
+ int index, /* index of insert/delete */
+ int count, /* #changed characters */
+ VREASON reason) /* Reason for change */
+{
+ Tcl_DString script;
+ int code;
+
+ Tcl_DStringInit(&script);
+ ExpandPercents(entryPtr, template, new, index, count, reason, &script);
+ code = Tcl_EvalEx(interp,
+ Tcl_DStringValue(&script), Tcl_DStringLength(&script),
+ TCL_EVAL_GLOBAL);
+ Tcl_DStringFree(&script);
+ if (WidgetDestroyed(&entryPtr->core))
+ return TCL_ERROR;
+
+ if (code != TCL_OK && code != TCL_RETURN) {
+ Tcl_AddErrorInfo(interp, "\n\t(in ");
+ Tcl_AddErrorInfo(interp, optionName);
+ Tcl_AddErrorInfo(interp, " validation command executed by ");
+ Tcl_AddErrorInfo(interp, Tk_PathName(entryPtr->core.tkwin));
+ Tcl_AddErrorInfo(interp, ")");
+ entryPtr->entry.validate = VMODE_NONE;
+ return TCL_ERROR;
+ }
+ return TCL_OK;
+}
+
+/* EntryNeedsValidation --
+ * Determine whether the specified VREASON should trigger validation
+ * in the current VMODE.
+ */
+static int EntryNeedsValidation(VMODE vmode, VREASON reason)
+{
+ return (reason == VALIDATE_FORCED)
+ || (vmode == VMODE_ALL)
+ || (reason == VALIDATE_FOCUSIN
+ && (vmode == VMODE_FOCUSIN || vmode == VMODE_FOCUS))
+ || (reason == VALIDATE_FOCUSOUT
+ && (vmode == VMODE_FOCUSOUT || vmode == VMODE_FOCUS))
+ || (reason == VALIDATE_INSERT && vmode == VMODE_KEY)
+ || (reason == VALIDATE_DELETE && vmode == VMODE_KEY)
+ ;
+}
+
+/* EntryValidateChange --
+ * Validate a proposed change to the entry widget's value if required.
+ * Call the -invalidcommand if validation fails.
+ *
+ * Returns:
+ * TCL_OK if the change is accepted
+ * TCL_BREAK if the change is rejected
+ * TCL_ERROR if any errors occured
+ *
+ * The change will be rejected if -validatecommand returns 0,
+ * or if -validatecommand or -invalidcommand modifies the value.
+ */
+static int
+EntryValidateChange(
+ Entry *entryPtr, /* Entry that needs validation. */
+ const char *newValue, /* Potential new value of entry string */
+ int index, /* index of insert/delete, -1 otherwise */
+ int count, /* #changed characters */
+ VREASON reason) /* Reason for change */
+{
+ Tcl_Interp *interp = entryPtr->core.interp;
+ VMODE vmode = entryPtr->entry.validate;
+ int code, change_ok;
+
+ if ( (entryPtr->entry.validateCmd == NULL)
+ || (entryPtr->core.flags & VALIDATING)
+ || !EntryNeedsValidation(vmode, reason) )
+ {
+ return TCL_OK;
+ }
+
+ entryPtr->core.flags |= VALIDATING;
+
+ /* Run -validatecommand and check return value:
+ */
+ code = RunValidationScript(interp, entryPtr,
+ entryPtr->entry.validateCmd, "-validatecommand",
+ newValue, index, count, reason);
+ if (code != TCL_OK) {
+ goto done;
+ }
+
+ code = Tcl_GetBooleanFromObj(interp,Tcl_GetObjResult(interp), &change_ok);
+ if (code != TCL_OK) {
+ entryPtr->entry.validate = VMODE_NONE; /* Disable validation */
+ Tcl_AddErrorInfo(interp,
+ "\n(validation command did not return valid boolean)");
+ goto done;
+ }
+
+ /* Run the -invalidcommand if validation failed:
+ */
+ if (!change_ok && entryPtr->entry.invalidCmd != NULL) {
+ code = RunValidationScript(interp, entryPtr,
+ entryPtr->entry.invalidCmd, "-invalidcommand",
+ newValue, index, count, reason);
+ if (code != TCL_OK) {
+ goto done;
+ }
+ }
+
+ /* Reject the pending change if validation failed
+ * or if a validation script changed the value.
+ */
+ if (!change_ok || (entryPtr->core.flags & VALIDATION_SET_VALUE)) {
+ code = TCL_BREAK;
+ }
+
+done:
+ entryPtr->core.flags &= ~(VALIDATING|VALIDATION_SET_VALUE);
+ return code;
+}
+
+/* EntryRevalidate --
+ * Revalidate the current value of an entry widget,
+ * update the TTK_STATE_INVALID bit.
+ *
+ * Returns:
+ * TCL_OK if valid, TCL_BREAK if invalid, TCL_ERROR on error.
+ */
+static int EntryRevalidate(Tcl_Interp *interp, Entry *entryPtr, VREASON reason)
+{
+ int code = EntryValidateChange(
+ entryPtr, entryPtr->entry.string, -1,0, reason);
+
+ if (code == TCL_BREAK) {
+ TtkWidgetChangeState(&entryPtr->core, TTK_STATE_INVALID, 0);
+ } else if (code == TCL_OK) {
+ TtkWidgetChangeState(&entryPtr->core, 0, TTK_STATE_INVALID);
+ }
+
+ return code;
+}
+
+/* EntryRevalidateBG --
+ * Revalidate in the background (called from event handler).
+ */
+static void EntryRevalidateBG(Entry *entryPtr, VREASON reason)
+{
+ Tcl_Interp *interp = entryPtr->core.interp;
+ if (EntryRevalidate(interp, entryPtr, reason) == TCL_ERROR) {
+ Tcl_BackgroundError(interp);
+ }
+}
+
+/*------------------------------------------------------------------------
+ * +++ Entry widget modification.
+ */
+
+/* AdjustIndex --
+ * Adjust index to account for insertion (nChars > 0)
+ * or deletion (nChars < 0) at specified index.
+ */
+static int AdjustIndex(int i0, int index, int nChars)
+{
+ if (i0 >= index) {
+ i0 += nChars;
+ if (i0 < index) { /* index was inside deleted range */
+ i0 = index;
+ }
+ }
+ return i0;
+}
+
+/* AdjustIndices --
+ * Adjust all internal entry indexes to account for change.
+ * Note that insertPos, and selectFirst have "right gravity",
+ * while leftIndex (=xscroll.first) and selectLast have "left gravity".
+ */
+static void AdjustIndices(Entry *entryPtr, int index, int nChars)
+{
+ EntryPart *e = &entryPtr->entry;
+ int g = nChars > 0; /* left gravity adjustment */
+
+ e->insertPos = AdjustIndex(e->insertPos, index, nChars);
+ e->selectFirst = AdjustIndex(e->selectFirst, index, nChars);
+ e->selectLast = AdjustIndex(e->selectLast, index+g, nChars);
+ e->xscroll.first= AdjustIndex(e->xscroll.first, index+g, nChars);
+
+ if (e->selectLast <= e->selectFirst)
+ e->selectFirst = e->selectLast = -1;
+}
+
+/* EntryStoreValue --
+ * Replace the contents of a text entry with a given value,
+ * recompute dependent resources, and schedule a redisplay.
+ *
+ * See also: EntrySetValue().
+ */
+static void
+EntryStoreValue(Entry *entryPtr, const char *value)
+{
+ size_t numBytes = strlen(value);
+ int numChars = Tcl_NumUtfChars(value, numBytes);
+
+ if (entryPtr->core.flags & VALIDATING)
+ entryPtr->core.flags |= VALIDATION_SET_VALUE;
+
+ /* Make sure all indices remain in bounds:
+ */
+ if (numChars < entryPtr->entry.numChars)
+ AdjustIndices(entryPtr, numChars, numChars - entryPtr->entry.numChars);
+
+ /* Free old value:
+ */
+ if (entryPtr->entry.displayString != entryPtr->entry.string)
+ ckfree(entryPtr->entry.displayString);
+ ckfree(entryPtr->entry.string);
+
+ /* Store new value:
+ */
+ entryPtr->entry.string = ckalloc(numBytes + 1);
+ strcpy(entryPtr->entry.string, value);
+ entryPtr->entry.numBytes = numBytes;
+ entryPtr->entry.numChars = numChars;
+
+ entryPtr->entry.displayString
+ = entryPtr->entry.showChar
+ ? EntryDisplayString(entryPtr->entry.showChar, numChars)
+ : entryPtr->entry.string
+ ;
+
+ /* Update layout, schedule redisplay:
+ */
+ EntryUpdateTextLayout(entryPtr);
+ TtkRedisplayWidget(&entryPtr->core);
+}
+
+/* EntrySetValue --
+ * Stores a new value in the entry widget and updates the
+ * linked -textvariable, if any. The write trace on the
+ * text variable is temporarily disabled; however, other
+ * write traces may change the value of the variable.
+ * If so, the widget is updated again with the new value.
+ *
+ * Returns:
+ * TCL_OK if successful, TCL_ERROR otherwise.
+ */
+static int EntrySetValue(Entry *entryPtr, const char *value)
+{
+ EntryStoreValue(entryPtr, value);
+
+ if (entryPtr->entry.textVariableObj) {
+ const char *textVarName =
+ Tcl_GetString(entryPtr->entry.textVariableObj);
+ if (textVarName && *textVarName) {
+ entryPtr->core.flags |= SYNCING_VARIABLE;
+ value = Tcl_SetVar(entryPtr->core.interp, textVarName,
+ value, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
+ entryPtr->core.flags &= ~SYNCING_VARIABLE;
+ if (!value || WidgetDestroyed(&entryPtr->core)) {
+ return TCL_ERROR;
+ } else if (strcmp(value, entryPtr->entry.string) != 0) {
+ /* Some write trace has changed the variable value.
+ */
+ EntryStoreValue(entryPtr, value);
+ }
+ }
+ }
+
+ return TCL_OK;
+}
+
+/* EntryTextVariableTrace --
+ * Variable trace procedure for entry -textvariable
+ */
+static void EntryTextVariableTrace(void *recordPtr, const char *value)
+{
+ Entry *entryPtr = recordPtr;
+
+ if (WidgetDestroyed(&entryPtr->core)) {
+ return;
+ }
+
+ if (entryPtr->core.flags & SYNCING_VARIABLE) {
+ /* Trace was fired due to Tcl_SetVar call in EntrySetValue.
+ * Don't do anything.
+ */
+ return;
+ }
+
+ EntryStoreValue(entryPtr, value ? value : "");
+}
+
+/*------------------------------------------------------------------------
+ * +++ Insertion and deletion.
+ */
+
+/* InsertChars --
+ * Add new characters to an entry widget.
+ */
+static int
+InsertChars(
+ Entry *entryPtr, /* Entry that is to get the new elements. */
+ int index, /* Insert before this index */
+ const char *value) /* New characters to add */
+{
+ char *string = entryPtr->entry.string;
+ size_t byteIndex = Tcl_UtfAtIndex(string, index) - string;
+ size_t byteCount = strlen(value);
+ int charsAdded = Tcl_NumUtfChars(value, byteCount);
+ size_t newByteCount = entryPtr->entry.numBytes + byteCount + 1;
+ char *new;
+ int code;
+
+ if (byteCount == 0) {
+ return TCL_OK;
+ }
+
+ new = ckalloc(newByteCount);
+ memcpy(new, string, byteIndex);
+ strcpy(new + byteIndex, value);
+ strcpy(new + byteIndex + byteCount, string + byteIndex);
+
+ code = EntryValidateChange(
+ entryPtr, new, index, charsAdded, VALIDATE_INSERT);
+
+ if (code == TCL_OK) {
+ AdjustIndices(entryPtr, index, charsAdded);
+ code = EntrySetValue(entryPtr, new);
+ } else if (code == TCL_BREAK) {
+ code = TCL_OK;
+ }
+
+ ckfree(new);
+ return code;
+}
+
+/* DeleteChars --
+ * Remove one or more characters from an entry widget.
+ */
+static int
+DeleteChars(
+ Entry *entryPtr, /* Entry widget to modify. */
+ int index, /* Index of first character to delete. */
+ int count) /* How many characters to delete. */
+{
+ char *string = entryPtr->entry.string;
+ size_t byteIndex, byteCount, newByteCount;
+ char *new;
+ int code;
+
+ if (index < 0) {
+ index = 0;
+ }
+ if (count > entryPtr->entry.numChars - index) {
+ count = entryPtr->entry.numChars - index;
+ }
+ if (count <= 0) {
+ return TCL_OK;
+ }
+
+ byteIndex = Tcl_UtfAtIndex(string, index) - string;
+ byteCount = Tcl_UtfAtIndex(string+byteIndex, count) - (string+byteIndex);
+
+ newByteCount = entryPtr->entry.numBytes + 1 - byteCount;
+ new = ckalloc(newByteCount);
+ memcpy(new, string, byteIndex);
+ strcpy(new + byteIndex, string + byteIndex + byteCount);
+
+ code = EntryValidateChange(
+ entryPtr, new, index, count, VALIDATE_DELETE);
+
+ if (code == TCL_OK) {
+ AdjustIndices(entryPtr, index, -count);
+ code = EntrySetValue(entryPtr, new);
+ } else if (code == TCL_BREAK) {
+ code = TCL_OK;
+ }
+ ckfree(new);
+
+ return code;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Event handler.
+ */
+
+/* EntryEventProc --
+ * Extra event handling for entry widgets:
+ * Triggers validation on FocusIn and FocusOut events.
+ */
+#define EntryEventMask (FocusChangeMask)
+static void
+EntryEventProc(ClientData clientData, XEvent *eventPtr)
+{
+ Entry *entryPtr = (Entry *) clientData;
+
+ Tcl_Preserve(clientData);
+ switch (eventPtr->type) {
+ case DestroyNotify:
+ Tk_DeleteEventHandler(entryPtr->core.tkwin,
+ EntryEventMask, EntryEventProc, clientData);
+ break;
+ case FocusIn:
+ EntryRevalidateBG(entryPtr, VALIDATE_FOCUSIN);
+ break;
+ case FocusOut:
+ EntryRevalidateBG(entryPtr, VALIDATE_FOCUSOUT);
+ break;
+ }
+ Tcl_Release(clientData);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Initialization and cleanup.
+ */
+
+static void
+EntryInitialize(Tcl_Interp *interp, void *recordPtr)
+{
+ Entry *entryPtr = recordPtr;
+
+ Tk_CreateEventHandler(
+ entryPtr->core.tkwin, EntryEventMask, EntryEventProc, entryPtr);
+ Tk_CreateSelHandler(entryPtr->core.tkwin, XA_PRIMARY, XA_STRING,
+ EntryFetchSelection, (ClientData) entryPtr, XA_STRING);
+ TtkBlinkCursor(&entryPtr->core);
+
+ entryPtr->entry.string = ckalloc(1);
+ *entryPtr->entry.string = '\0';
+ entryPtr->entry.displayString = entryPtr->entry.string;
+ entryPtr->entry.textVariableTrace = 0;
+ entryPtr->entry.numBytes = entryPtr->entry.numChars = 0;
+
+ EntryInitStyleDefaults(&entryPtr->entry.styleDefaults);
+
+ entryPtr->entry.xscrollHandle =
+ TtkCreateScrollHandle(&entryPtr->core, &entryPtr->entry.xscroll);
+
+ entryPtr->entry.insertPos = 0;
+ entryPtr->entry.selectFirst = -1;
+ entryPtr->entry.selectLast = -1;
+}
+
+static void
+EntryCleanup(void *recordPtr)
+{
+ Entry *entryPtr = recordPtr;
+
+ if (entryPtr->entry.textVariableTrace)
+ Ttk_UntraceVariable(entryPtr->entry.textVariableTrace);
+
+ TtkFreeScrollHandle(entryPtr->entry.xscrollHandle);
+
+ EntryFreeStyleDefaults(&entryPtr->entry.styleDefaults);
+
+ Tk_DeleteSelHandler(entryPtr->core.tkwin, XA_PRIMARY, XA_STRING);
+
+ Tk_FreeTextLayout(entryPtr->entry.textLayout);
+ if (entryPtr->entry.displayString != entryPtr->entry.string)
+ ckfree(entryPtr->entry.displayString);
+ ckfree(entryPtr->entry.string);
+}
+
+/* EntryConfigure --
+ * Configure hook for Entry widgets.
+ */
+static int EntryConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Entry *entryPtr = recordPtr;
+ Tcl_Obj *textVarName = entryPtr->entry.textVariableObj;
+ Ttk_TraceHandle *vt = 0;
+
+ if (mask & TEXTVAR_CHANGED) {
+ if (textVarName && *Tcl_GetString(textVarName)) {
+ vt = Ttk_TraceVariable(interp,
+ textVarName,EntryTextVariableTrace,entryPtr);
+ if (!vt) return TCL_ERROR;
+ }
+ }
+
+ if (TtkCoreConfigure(interp, recordPtr, mask) != TCL_OK) {
+ if (vt) Ttk_UntraceVariable(vt);
+ return TCL_ERROR;
+ }
+
+ /* Update derived resources:
+ */
+ if (mask & TEXTVAR_CHANGED) {
+ if (entryPtr->entry.textVariableTrace)
+ Ttk_UntraceVariable(entryPtr->entry.textVariableTrace);
+ entryPtr->entry.textVariableTrace = vt;
+ }
+
+ /* Claim the selection, in case we've suddenly started exporting it.
+ */
+ if (entryPtr->entry.exportSelection && entryPtr->entry.selectFirst != -1) {
+ EntryOwnSelection(entryPtr);
+ }
+
+ /* Handle -state compatibility option:
+ */
+ if (mask & STATE_CHANGED) {
+ TtkCheckStateOption(&entryPtr->core, entryPtr->entry.stateObj);
+ }
+
+ /* Force scrollbar update if needed:
+ */
+ if (mask & SCROLLCMD_CHANGED) {
+ TtkScrollbarUpdateRequired(entryPtr->entry.xscrollHandle);
+ }
+
+ /* Recompute the displayString, in case showChar changed:
+ */
+ if (entryPtr->entry.displayString != entryPtr->entry.string)
+ ckfree(entryPtr->entry.displayString);
+
+ entryPtr->entry.displayString
+ = entryPtr->entry.showChar
+ ? EntryDisplayString(entryPtr->entry.showChar, entryPtr->entry.numChars)
+ : entryPtr->entry.string
+ ;
+
+ /* Update textLayout:
+ */
+ EntryUpdateTextLayout(entryPtr);
+ return TCL_OK;
+}
+
+/* EntryPostConfigure --
+ * Post-configuration hook for entry widgets.
+ */
+static int EntryPostConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Entry *entryPtr = recordPtr;
+ int status = TCL_OK;
+
+ if ((mask & TEXTVAR_CHANGED) && entryPtr->entry.textVariableTrace != NULL) {
+ status = Ttk_FireTrace(entryPtr->entry.textVariableTrace);
+ }
+
+ return status;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Layout and display.
+ */
+
+/* EntryCharPosition --
+ * Return the X coordinate of the specified character index.
+ * Precondition: textLayout and layoutX up-to-date.
+ */
+static int
+EntryCharPosition(Entry *entryPtr, int index)
+{
+ int xPos;
+ Tk_CharBbox(entryPtr->entry.textLayout, index, &xPos, NULL, NULL, NULL);
+ return xPos + entryPtr->entry.layoutX;
+}
+
+/* EntryDoLayout --
+ * Layout hook for entry widgets.
+ *
+ * Determine position of textLayout based on xscroll.first, justify,
+ * and display area.
+ *
+ * Recalculates layoutX, layoutY, and rightIndex,
+ * and updates xscroll accordingly.
+ * May adjust xscroll.first to ensure the maximum #characters are onscreen.
+ */
+static void
+EntryDoLayout(void *recordPtr)
+{
+ Entry *entryPtr = recordPtr;
+ WidgetCore *corePtr = &entryPtr->core;
+ Tk_TextLayout textLayout = entryPtr->entry.textLayout;
+ int leftIndex = entryPtr->entry.xscroll.first;
+ int rightIndex;
+ Ttk_Box textarea;
+
+ Ttk_PlaceLayout(corePtr->layout,corePtr->state,Ttk_WinBox(corePtr->tkwin));
+ textarea = Ttk_ClientRegion(corePtr->layout, "textarea");
+
+ /* Center the text vertically within the available parcel:
+ */
+ entryPtr->entry.layoutY = textarea.y +
+ (textarea.height - entryPtr->entry.layoutHeight)/2;
+
+ /* Recompute where the leftmost character on the display will
+ * be drawn (layoutX) and adjust leftIndex if necessary.
+ */
+ if (entryPtr->entry.layoutWidth <= textarea.width) {
+ /* Everything fits. Set leftIndex to zero (no need to scroll),
+ * and compute layoutX based on -justify.
+ */
+ int extraSpace = textarea.width - entryPtr->entry.layoutWidth;
+ leftIndex = 0;
+ rightIndex = entryPtr->entry.numChars;
+ entryPtr->entry.layoutX = textarea.x;
+ if (entryPtr->entry.justify == TK_JUSTIFY_RIGHT) {
+ entryPtr->entry.layoutX += extraSpace;
+ } else if (entryPtr->entry.justify == TK_JUSTIFY_CENTER) {
+ entryPtr->entry.layoutX += extraSpace / 2;
+ }
+ } else {
+ /* The whole string doesn't fit in the window.
+ * Limit leftIndex to leave at most one character's worth
+ * of empty space on the right.
+ */
+ int overflow = entryPtr->entry.layoutWidth - textarea.width;
+ int maxLeftIndex = 1 + Tk_PointToChar(textLayout, overflow, 0);
+ int leftX;
+
+ if (leftIndex > maxLeftIndex) {
+ leftIndex = maxLeftIndex;
+ }
+
+ /* Compute layoutX and rightIndex.
+ * rightIndex is set to one past the last fully-visible character.
+ */
+ Tk_CharBbox(textLayout, leftIndex, &leftX, NULL, NULL, NULL);
+ rightIndex = Tk_PointToChar(textLayout, leftX + textarea.width, 0);
+ entryPtr->entry.layoutX = textarea.x - leftX;
+ }
+
+ TtkScrolled(entryPtr->entry.xscrollHandle,
+ leftIndex, rightIndex, entryPtr->entry.numChars);
+}
+
+/* EntryGetGC -- Helper routine.
+ * Get a GC using the specified foreground color and the entry's font.
+ * Result must be freed with Tk_FreeGC().
+ */
+static GC EntryGetGC(Entry *entryPtr, Tcl_Obj *colorObj, TkRegion clip)
+{
+ Tk_Window tkwin = entryPtr->core.tkwin;
+ Tk_Font font = Tk_GetFontFromObj(tkwin, entryPtr->entry.fontObj);
+ XColor *colorPtr;
+ unsigned long mask = 0ul;
+ XGCValues gcValues;
+ GC gc;
+
+ gcValues.line_width = 1; mask |= GCLineWidth;
+ gcValues.font = Tk_FontId(font); mask |= GCFont;
+ if (colorObj != 0 && (colorPtr=Tk_GetColorFromObj(tkwin,colorObj)) != 0) {
+ gcValues.foreground = colorPtr->pixel;
+ mask |= GCForeground;
+ }
+ gc = Tk_GetGC(entryPtr->core.tkwin, mask, &gcValues);
+ if (clip != None) {
+ TkSetRegion(Tk_Display(entryPtr->core.tkwin), gc, clip);
+ }
+ return gc;
+}
+
+/* EntryDisplay --
+ * Redraws the contents of an entry window.
+ */
+static void EntryDisplay(void *clientData, Drawable d)
+{
+ Entry *entryPtr = clientData;
+ Tk_Window tkwin = entryPtr->core.tkwin;
+ int leftIndex = entryPtr->entry.xscroll.first,
+ rightIndex = entryPtr->entry.xscroll.last + 1,
+ selFirst = entryPtr->entry.selectFirst,
+ selLast = entryPtr->entry.selectLast;
+ EntryStyleData es;
+ GC gc;
+ int showSelection, showCursor;
+ Ttk_Box textarea;
+ TkRegion clipRegion;
+ XRectangle rect;
+
+ EntryInitStyleData(entryPtr, &es);
+
+ textarea = Ttk_ClientRegion(entryPtr->core.layout, "textarea");
+ showCursor =
+ (entryPtr->core.flags & CURSOR_ON) != 0
+ && EntryEditable(entryPtr)
+ && entryPtr->entry.insertPos >= leftIndex
+ && entryPtr->entry.insertPos <= rightIndex
+ ;
+ showSelection =
+ (entryPtr->core.state & TTK_STATE_DISABLED) == 0
+ && selFirst > -1
+ && selLast > leftIndex
+ && selFirst <= rightIndex
+ ;
+
+ /* Adjust selection range to keep in display bounds.
+ */
+ if (showSelection) {
+ if (selFirst < leftIndex)
+ selFirst = leftIndex;
+ if (selLast > rightIndex)
+ selLast = rightIndex;
+ }
+
+ /* Draw widget background & border
+ */
+ Ttk_DrawLayout(entryPtr->core.layout, entryPtr->core.state, d);
+
+ /* Draw selection background
+ */
+ if (showSelection && es.selBorderObj) {
+ Tk_3DBorder selBorder = Tk_Get3DBorderFromObj(tkwin, es.selBorderObj);
+ int selStartX = EntryCharPosition(entryPtr, selFirst);
+ int selEndX = EntryCharPosition(entryPtr, selLast);
+ int borderWidth = 1;
+
+ Tcl_GetIntFromObj(NULL, es.selBorderWidthObj, &borderWidth);
+
+ if (selBorder) {
+ Tk_Fill3DRectangle(tkwin, d, selBorder,
+ selStartX - borderWidth, entryPtr->entry.layoutY - borderWidth,
+ selEndX - selStartX + 2*borderWidth,
+ entryPtr->entry.layoutHeight + 2*borderWidth,
+ borderWidth, TK_RELIEF_RAISED);
+ }
+ }
+
+ /* Initialize the clip region. Note that Xft does _not_ derive its
+ * clipping area from the GC, so we have to supply that by other means.
+ */
+
+ rect.x = textarea.x;
+ rect.y = textarea.y;
+ rect.width = textarea.width;
+ rect.height = textarea.height;
+ clipRegion = TkCreateRegion();
+ TkUnionRectWithRegion(&rect, clipRegion, clipRegion);
+#ifdef HAVE_XFT
+ TkUnixSetXftClipRegion(clipRegion);
+#endif
+
+ /* Draw cursor:
+ */
+ if (showCursor) {
+ int cursorX = EntryCharPosition(entryPtr, entryPtr->entry.insertPos),
+ cursorY = entryPtr->entry.layoutY,
+ cursorHeight = entryPtr->entry.layoutHeight,
+ cursorWidth = 1;
+
+ Tcl_GetIntFromObj(NULL,es.insertWidthObj,&cursorWidth);
+ if (cursorWidth <= 0) {
+ cursorWidth = 1;
+ }
+
+ /* @@@ should: maybe: SetCaretPos even when blinked off */
+ Tk_SetCaretPos(tkwin, cursorX, cursorY, cursorHeight);
+
+ gc = EntryGetGC(entryPtr, es.insertColorObj, clipRegion);
+ XFillRectangle(Tk_Display(tkwin), d, gc,
+ cursorX-cursorWidth/2, cursorY, cursorWidth, cursorHeight);
+ XSetClipMask(Tk_Display(tkwin), gc, None);
+ Tk_FreeGC(Tk_Display(tkwin), gc);
+ }
+
+ /* Draw the text:
+ */
+ gc = EntryGetGC(entryPtr, es.foregroundObj, clipRegion);
+ Tk_DrawTextLayout(
+ Tk_Display(tkwin), d, gc, entryPtr->entry.textLayout,
+ entryPtr->entry.layoutX, entryPtr->entry.layoutY,
+ leftIndex, rightIndex);
+ XSetClipMask(Tk_Display(tkwin), gc, None);
+ Tk_FreeGC(Tk_Display(tkwin), gc);
+
+ /* Overwrite the selected portion (if any) in the -selectforeground color:
+ */
+ if (showSelection) {
+ gc = EntryGetGC(entryPtr, es.selForegroundObj, clipRegion);
+ Tk_DrawTextLayout(
+ Tk_Display(tkwin), d, gc, entryPtr->entry.textLayout,
+ entryPtr->entry.layoutX, entryPtr->entry.layoutY,
+ selFirst, selLast);
+ XSetClipMask(Tk_Display(tkwin), gc, None);
+ Tk_FreeGC(Tk_Display(tkwin), gc);
+ }
+
+ /* Drop the region. Note that we have to manually remove the reference to
+ * it from the Xft guts (if they're being used).
+ */
+#ifdef HAVE_XFT
+ TkUnixSetXftClipRegion(None);
+#endif
+ TkDestroyRegion(clipRegion);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget commands.
+ */
+
+/* EntryIndex --
+ * Parse an index into an entry and return either its value
+ * or an error.
+ *
+ * Results:
+ * A standard Tcl result. If all went well, then *indexPtr is
+ * 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 the interp's result.
+ */
+static int
+EntryIndex(
+ Tcl_Interp *interp, /* For error messages. */
+ Entry *entryPtr, /* Entry widget to query */
+ Tcl_Obj *indexObj, /* Symbolic index name */
+ int *indexPtr) /* Return value */
+{
+# define EntryWidth(e) (Tk_Width(entryPtr->core.tkwin)) /* Not Right */
+ int length;
+ const char *string = Tcl_GetStringFromObj(indexObj, &length);
+
+ if (strncmp(string, "end", length) == 0) {
+ *indexPtr = entryPtr->entry.numChars;
+ } else if (strncmp(string, "insert", length) == 0) {
+ *indexPtr = entryPtr->entry.insertPos;
+ } else if (strncmp(string, "left", length) == 0) { /* for debugging */
+ *indexPtr = entryPtr->entry.xscroll.first;
+ } else if (strncmp(string, "right", length) == 0) { /* for debugging */
+ *indexPtr = entryPtr->entry.xscroll.last;
+ } else if (strncmp(string, "sel.", 4) == 0) {
+ if (entryPtr->entry.selectFirst < 0) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "selection isn't in widget ",
+ Tk_PathName(entryPtr->core.tkwin), NULL);
+ return TCL_ERROR;
+ }
+ if (strncmp(string, "sel.first", length) == 0) {
+ *indexPtr = entryPtr->entry.selectFirst;
+ } else if (strncmp(string, "sel.last", length) == 0) {
+ *indexPtr = entryPtr->entry.selectLast;
+ } else {
+ goto badIndex;
+ }
+ } else if (string[0] == '@') {
+ int roundUp = 0;
+ int maxWidth = EntryWidth(entryPtr);
+ int x;
+
+ if (Tcl_GetInt(interp, string + 1, &x) != TCL_OK) {
+ goto badIndex;
+ }
+ if (x > maxWidth) {
+ x = maxWidth;
+ roundUp = 1;
+ }
+ *indexPtr = Tk_PointToChar(entryPtr->entry.textLayout,
+ x - entryPtr->entry.layoutX, 0);
+
+ if (*indexPtr < entryPtr->entry.xscroll.first) {
+ *indexPtr = entryPtr->entry.xscroll.first;
+ }
+
+ /*
+ * Special trick: if the x-position was off-screen to the right,
+ * round the index up to refer to the character just after the
+ * last visible one on the screen. This is needed to enable the
+ * last character to be selected, for example.
+ */
+
+ if (roundUp && (*indexPtr < entryPtr->entry.numChars)) {
+ *indexPtr += 1;
+ }
+ } else {
+ if (Tcl_GetInt(interp, string, indexPtr) != TCL_OK) {
+ goto badIndex;
+ }
+ if (*indexPtr < 0) {
+ *indexPtr = 0;
+ } else if (*indexPtr > entryPtr->entry.numChars) {
+ *indexPtr = entryPtr->entry.numChars;
+ }
+ }
+ return TCL_OK;
+
+badIndex:
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "bad entry index \"", string, "\"", NULL);
+ return TCL_ERROR;
+}
+
+/* $entry bbox $index --
+ * Return the bounding box of the character at the specified index.
+ */
+static int
+EntryBBoxCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Entry *entryPtr = recordPtr;
+ Ttk_Box b;
+ int index;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
+ return TCL_ERROR;
+ }
+ if (EntryIndex(interp, entryPtr, objv[2], &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if ((index == entryPtr->entry.numChars) && (index > 0)) {
+ index--;
+ }
+ Tk_CharBbox(entryPtr->entry.textLayout, index,
+ &b.x, &b.y, &b.width, &b.height);
+ b.x += entryPtr->entry.layoutX;
+ b.y += entryPtr->entry.layoutY;
+ Tcl_SetObjResult(interp, Ttk_NewBoxObj(b));
+ return TCL_OK;
+}
+
+/* $entry delete $from ?$to? --
+ * Delete the characters in the range [$from,$to).
+ * $to defaults to $from+1 if not specified.
+ */
+static int
+EntryDeleteCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Entry *entryPtr = recordPtr;
+ int first, last;
+
+ if ((objc < 3) || (objc > 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
+ return TCL_ERROR;
+ }
+ if (EntryIndex(interp, entryPtr, objv[2], &first) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ last = first + 1;
+ } else if (EntryIndex(interp, entryPtr, objv[3], &last) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (last >= first && EntryEditable(entryPtr)) {
+ return DeleteChars(entryPtr, first, last - first);
+ }
+ return TCL_OK;
+}
+
+/* $entry get --
+ * Return the current value of the entry widget.
+ */
+static int
+EntryGetCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Entry *entryPtr = recordPtr;
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ Tcl_SetResult(interp, entryPtr->entry.string, TCL_VOLATILE);
+ return TCL_OK;
+}
+
+/* $entry icursor $index --
+ * Set the insert cursor position.
+ */
+static int
+EntryICursorCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Entry *entryPtr = recordPtr;
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pos");
+ return TCL_ERROR;
+ }
+ if (EntryIndex(interp, entryPtr, objv[2],
+ &entryPtr->entry.insertPos) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ TtkRedisplayWidget(&entryPtr->core);
+ return TCL_OK;
+}
+
+/* $entry index $index --
+ * Return numeric value (0..numChars) of the specified index.
+ */
+static int
+EntryIndexCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Entry *entryPtr = recordPtr;
+ int index;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "string");
+ return TCL_ERROR;
+ }
+ if (EntryIndex(interp, entryPtr, objv[2], &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
+ return TCL_OK;
+}
+
+/* $entry insert $index $text --
+ * Insert $text after position $index.
+ * Silent no-op if the entry is disabled or read-only.
+ */
+static int
+EntryInsertCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Entry *entryPtr = recordPtr;
+ int index;
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index text");
+ return TCL_ERROR;
+ }
+ if (EntryIndex(interp, entryPtr, objv[2], &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (EntryEditable(entryPtr)) {
+ return InsertChars(entryPtr, index, Tcl_GetString(objv[3]));
+ }
+ return TCL_OK;
+}
+
+/* $entry selection clear --
+ * Clear selection.
+ */
+static int EntrySelectionClearCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Entry *entryPtr = recordPtr;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
+ return TCL_ERROR;
+ }
+ entryPtr->entry.selectFirst = entryPtr->entry.selectLast = -1;
+ TtkRedisplayWidget(&entryPtr->core);
+ return TCL_OK;
+}
+
+/* $entry selection present --
+ * Returns 1 if any characters are selected, 0 otherwise.
+ */
+static int EntrySelectionPresentCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Entry *entryPtr = recordPtr;
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp,
+ Tcl_NewBooleanObj(entryPtr->entry.selectFirst >= 0));
+ return TCL_OK;
+}
+
+/* $entry selection range $start $end --
+ * Explicitly set the selection range.
+ */
+static int EntrySelectionRangeCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Entry *entryPtr = recordPtr;
+ int start, end;
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "start end");
+ return TCL_ERROR;
+ }
+ if ( EntryIndex(interp, entryPtr, objv[3], &start) != TCL_OK
+ || EntryIndex(interp, entryPtr, objv[4], &end) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (entryPtr->core.state & TTK_STATE_DISABLED) {
+ return TCL_OK;
+ }
+
+ if (start >= end) {
+ entryPtr->entry.selectFirst = entryPtr->entry.selectLast = -1;
+ } else {
+ entryPtr->entry.selectFirst = start;
+ entryPtr->entry.selectLast = end;
+ EntryOwnSelection(entryPtr);
+ }
+ TtkRedisplayWidget(&entryPtr->core);
+ return TCL_OK;
+}
+
+static const Ttk_Ensemble EntrySelectionCommands[] = {
+ { "clear", EntrySelectionClearCommand,0 },
+ { "present", EntrySelectionPresentCommand,0 },
+ { "range", EntrySelectionRangeCommand,0 },
+ { 0,0,0 }
+};
+
+/* $entry set $value
+ * Sets the value of an entry widget.
+ */
+static int EntrySetCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Entry *entryPtr = recordPtr;
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "value");
+ return TCL_ERROR;
+ }
+ EntrySetValue(entryPtr, Tcl_GetString(objv[2]));
+ return TCL_OK;
+}
+
+/* $entry validate --
+ * Trigger forced validation. Returns 1/0 if validation succeeds/fails
+ * or error status from -validatecommand / -invalidcommand.
+ */
+static int EntryValidateCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Entry *entryPtr = recordPtr;
+ int code;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+
+ code = EntryRevalidate(interp, entryPtr, VALIDATE_FORCED);
+
+ if (code == TCL_ERROR)
+ return code;
+
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(code == TCL_OK));
+ return TCL_OK;
+}
+
+/* $entry xview -- horizontal scrolling interface
+ */
+static int EntryXViewCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Entry *entryPtr = recordPtr;
+ return TtkScrollviewCommand(interp, objc, objv, entryPtr->entry.xscrollHandle);
+}
+
+static const Ttk_Ensemble EntryCommands[] = {
+ { "bbox", EntryBBoxCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "delete", EntryDeleteCommand,0 },
+ { "get", EntryGetCommand,0 },
+ { "icursor", EntryICursorCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ { "index", EntryIndexCommand,0 },
+ { "insert", EntryInsertCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "selection", 0,EntrySelectionCommands },
+ { "state", TtkWidgetStateCommand,0 },
+ { "validate", EntryValidateCommand,0 },
+ { "xview", EntryXViewCommand,0 },
+ { 0,0,0 }
+};
+
+/*------------------------------------------------------------------------
+ * +++ Entry widget definition.
+ */
+
+static WidgetSpec EntryWidgetSpec = {
+ "TEntry", /* className */
+ sizeof(Entry), /* recordSize */
+ EntryOptionSpecs, /* optionSpecs */
+ EntryCommands, /* subcommands */
+ EntryInitialize, /* initializeProc */
+ EntryCleanup, /* cleanupProc */
+ EntryConfigure, /* configureProc */
+ EntryPostConfigure, /* postConfigureProc */
+ TtkWidgetGetLayout, /* getLayoutProc */
+ TtkWidgetSize, /* sizeProc */
+ EntryDoLayout, /* layoutProc */
+ EntryDisplay /* displayProc */
+};
+
+/*------------------------------------------------------------------------
+ * +++ Combobox widget record.
+ */
+
+typedef struct {
+ Tcl_Obj *postCommandObj;
+ Tcl_Obj *valuesObj;
+ Tcl_Obj *heightObj;
+ int currentIndex;
+} ComboboxPart;
+
+typedef struct {
+ WidgetCore core;
+ EntryPart entry;
+ ComboboxPart combobox;
+} Combobox;
+
+static Tk_OptionSpec ComboboxOptionSpecs[] = {
+ {TK_OPTION_STRING, "-height", "height", "Height",
+ DEF_LIST_HEIGHT, Tk_Offset(Combobox, combobox.heightObj), -1,
+ 0,0,0 },
+ {TK_OPTION_STRING, "-postcommand", "postCommand", "PostCommand",
+ "", Tk_Offset(Combobox, combobox.postCommandObj), -1,
+ 0,0,0 },
+ {TK_OPTION_STRING, "-values", "values", "Values",
+ "", Tk_Offset(Combobox, combobox.valuesObj), -1,
+ 0,0,0 },
+ WIDGET_INHERIT_OPTIONS(EntryOptionSpecs)
+};
+
+/* ComboboxInitialize --
+ * Initialization hook for combobox widgets.
+ */
+static void
+ComboboxInitialize(Tcl_Interp *interp, void *recordPtr)
+{
+ Combobox *cb = recordPtr;
+
+ cb->combobox.currentIndex = -1;
+ TtkTrackElementState(&cb->core);
+ EntryInitialize(interp, recordPtr);
+}
+
+/* ComboboxConfigure --
+ * Configuration hook for combobox widgets.
+ */
+static int
+ComboboxConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Combobox *cbPtr = recordPtr;
+ int unused;
+
+ /* Make sure -values is a valid list:
+ */
+ if (Tcl_ListObjLength(interp,cbPtr->combobox.valuesObj,&unused) != TCL_OK)
+ return TCL_ERROR;
+
+ return EntryConfigure(interp, recordPtr, mask);
+}
+
+/* $cb current ?newIndex? -- get or set current index.
+ * Setting the current index updates the combobox value,
+ * but the value and -values may be changed independently
+ * of the index. Instead of trying to keep currentIndex
+ * in sync at all times, [$cb current] double-checks
+ */
+static int ComboboxCurrentCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Combobox *cbPtr = recordPtr;
+ int currentIndex = cbPtr->combobox.currentIndex;
+ const char *currentValue = cbPtr->entry.string;
+ int nValues;
+ Tcl_Obj **values;
+
+ Tcl_ListObjGetElements(interp,cbPtr->combobox.valuesObj,&nValues,&values);
+
+ if (objc == 2) {
+ /* Check if currentIndex still valid:
+ */
+ if ( currentIndex < 0
+ || currentIndex >= nValues
+ || strcmp(currentValue,Tcl_GetString(values[currentIndex]))
+ )
+ {
+ /* Not valid. Check current value against each element in -values:
+ */
+ for (currentIndex = 0; currentIndex < nValues; ++currentIndex) {
+ if (!strcmp(currentValue,Tcl_GetString(values[currentIndex]))) {
+ break;
+ }
+ }
+ if (currentIndex >= nValues) {
+ /* Not found */
+ currentIndex = -1;
+ }
+ }
+ cbPtr->combobox.currentIndex = currentIndex;
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(currentIndex));
+ return TCL_OK;
+ } else if (objc == 3) {
+ if (Tcl_GetIntFromObj(interp, objv[2], &currentIndex) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (currentIndex < 0 || currentIndex >= nValues) {
+ Tcl_AppendResult(interp,
+ "Index ", Tcl_GetString(objv[2]), " out of range",
+ NULL);
+ return TCL_ERROR;
+ }
+
+ cbPtr->combobox.currentIndex = currentIndex;
+
+ return EntrySetValue(recordPtr, Tcl_GetString(values[currentIndex]));
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, "?newIndex?");
+ return TCL_ERROR;
+ }
+ return TCL_OK;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Combobox widget definition.
+ */
+static const Ttk_Ensemble ComboboxCommands[] = {
+ { "bbox", EntryBBoxCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "current", ComboboxCurrentCommand,0 },
+ { "delete", EntryDeleteCommand,0 },
+ { "get", EntryGetCommand,0 },
+ { "icursor", EntryICursorCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ { "index", EntryIndexCommand,0 },
+ { "insert", EntryInsertCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "selection", 0,EntrySelectionCommands },
+ { "state", TtkWidgetStateCommand,0 },
+ { "set", EntrySetCommand,0 },
+ { "validate", EntryValidateCommand,0 },
+ { "xview", EntryXViewCommand,0 },
+ { 0,0,0 }
+};
+
+static WidgetSpec ComboboxWidgetSpec = {
+ "TCombobox", /* className */
+ sizeof(Combobox), /* recordSize */
+ ComboboxOptionSpecs, /* optionSpecs */
+ ComboboxCommands, /* subcommands */
+ ComboboxInitialize, /* initializeProc */
+ EntryCleanup, /* cleanupProc */
+ ComboboxConfigure, /* configureProc */
+ EntryPostConfigure, /* postConfigureProc */
+ TtkWidgetGetLayout, /* getLayoutProc */
+ TtkWidgetSize, /* sizeProc */
+ EntryDoLayout, /* layoutProc */
+ EntryDisplay /* displayProc */
+};
+
+/*------------------------------------------------------------------------
+ * +++ Spinbox widget.
+ */
+
+typedef struct {
+ Tcl_Obj *valuesObj;
+
+ Tcl_Obj *fromObj;
+ Tcl_Obj *toObj;
+ Tcl_Obj *incrementObj;
+ Tcl_Obj *formatObj;
+
+ Tcl_Obj *wrapObj;
+ Tcl_Obj *commandObj;
+} SpinboxPart;
+
+typedef struct {
+ WidgetCore core;
+ EntryPart entry;
+ SpinboxPart spinbox;
+} Spinbox;
+
+static Tk_OptionSpec SpinboxOptionSpecs[] = {
+ {TK_OPTION_STRING, "-values", "values", "Values",
+ "", Tk_Offset(Spinbox, spinbox.valuesObj), -1,
+ 0,0,0 },
+
+ {TK_OPTION_DOUBLE, "-from", "from", "From",
+ "0", Tk_Offset(Spinbox,spinbox.fromObj), -1,
+ 0,0,0 },
+ {TK_OPTION_DOUBLE, "-to", "to", "To",
+ "0", Tk_Offset(Spinbox,spinbox.toObj), -1,
+ 0,0,0 },
+ {TK_OPTION_DOUBLE, "-increment", "increment", "Increment",
+ "1", Tk_Offset(Spinbox,spinbox.incrementObj), -1,
+ 0,0,0 },
+ {TK_OPTION_STRING, "-format", "format", "Format",
+ "", Tk_Offset(Spinbox, spinbox.formatObj), -1,
+ 0,0,0 },
+
+ {TK_OPTION_STRING, "-command", "command", "Command",
+ "", Tk_Offset(Spinbox, spinbox.commandObj), -1,
+ 0,0,0 },
+ {TK_OPTION_BOOLEAN, "-wrap", "wrap", "Wrap",
+ "0", Tk_Offset(Spinbox,spinbox.wrapObj), -1,
+ 0,0,0 },
+
+ WIDGET_INHERIT_OPTIONS(EntryOptionSpecs)
+};
+
+/* SpinboxInitialize --
+ * Initialization hook for spinbox widgets.
+ */
+static void
+SpinboxInitialize(Tcl_Interp *interp, void *recordPtr)
+{
+ Spinbox *sb = recordPtr;
+ TtkTrackElementState(&sb->core);
+ EntryInitialize(interp, recordPtr);
+}
+
+/* SpinboxConfigure --
+ * Configuration hook for spinbox widgets.
+ */
+static int
+SpinboxConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Spinbox *sb = recordPtr;
+ int unused;
+
+ /* Make sure -values is a valid list:
+ */
+ if (Tcl_ListObjLength(interp,sb->spinbox.valuesObj,&unused) != TCL_OK)
+ return TCL_ERROR;
+
+ return EntryConfigure(interp, recordPtr, mask);
+}
+
+static const Ttk_Ensemble SpinboxCommands[] = {
+ { "bbox", EntryBBoxCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "delete", EntryDeleteCommand,0 },
+ { "get", EntryGetCommand,0 },
+ { "icursor", EntryICursorCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ { "index", EntryIndexCommand,0 },
+ { "insert", EntryInsertCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "selection", 0,EntrySelectionCommands },
+ { "state", TtkWidgetStateCommand,0 },
+ { "set", EntrySetCommand,0 },
+ { "validate", EntryValidateCommand,0 },
+ { "xview", EntryXViewCommand,0 },
+ { 0,0,0 }
+};
+
+static WidgetSpec SpinboxWidgetSpec = {
+ "TSpinbox", /* className */
+ sizeof(Spinbox), /* recordSize */
+ SpinboxOptionSpecs, /* optionSpecs */
+ SpinboxCommands, /* subcommands */
+ SpinboxInitialize, /* initializeProc */
+ EntryCleanup, /* cleanupProc */
+ SpinboxConfigure, /* configureProc */
+ EntryPostConfigure, /* postConfigureProc */
+ TtkWidgetGetLayout, /* getLayoutProc */
+ TtkWidgetSize, /* sizeProc */
+ EntryDoLayout, /* layoutProc */
+ EntryDisplay /* displayProc */
+};
+
+/*------------------------------------------------------------------------
+ * +++ Textarea element.
+ *
+ * Text display area for Entry widgets.
+ * Just computes requested size; display is handled by the widget itself.
+ */
+
+typedef struct {
+ Tcl_Obj *fontObj;
+ Tcl_Obj *widthObj;
+} TextareaElement;
+
+static Ttk_ElementOptionSpec TextareaElementOptions[] = {
+ { "-font", TK_OPTION_FONT,
+ Tk_Offset(TextareaElement,fontObj), DEF_ENTRY_FONT },
+ { "-width", TK_OPTION_INT,
+ Tk_Offset(TextareaElement,widthObj), "20" },
+ { NULL, 0, 0, NULL }
+};
+
+static void TextareaElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ TextareaElement *textarea = elementRecord;
+ Tk_Font font = Tk_GetFontFromObj(tkwin, textarea->fontObj);
+ int avgWidth = Tk_TextWidth(font, "0", 1);
+ Tk_FontMetrics fm;
+ int prefWidth = 1;
+
+ Tk_GetFontMetrics(font, &fm);
+ Tcl_GetIntFromObj(NULL, textarea->widthObj, &prefWidth);
+ if (prefWidth <= 0)
+ prefWidth = 1;
+
+ *heightPtr = fm.linespace;
+ *widthPtr = prefWidth * avgWidth;
+}
+
+static Ttk_ElementSpec TextareaElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(TextareaElement),
+ TextareaElementOptions,
+ TextareaElementSize,
+ TtkNullElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Widget layouts.
+ */
+
+TTK_BEGIN_LAYOUT(EntryLayout)
+ TTK_GROUP("Entry.field", TTK_FILL_BOTH|TTK_BORDER,
+ TTK_GROUP("Entry.padding", TTK_FILL_BOTH,
+ TTK_NODE("Entry.textarea", TTK_FILL_BOTH)))
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(ComboboxLayout)
+ TTK_GROUP("Combobox.field", TTK_FILL_BOTH,
+ TTK_NODE("Combobox.downarrow", TTK_PACK_RIGHT|TTK_FILL_Y)
+ TTK_GROUP("Combobox.padding", TTK_FILL_BOTH|TTK_PACK_LEFT|TTK_EXPAND,
+ TTK_NODE("Combobox.textarea", TTK_FILL_BOTH)))
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(SpinboxLayout)
+ TTK_GROUP("Spinbox.field", TTK_PACK_TOP|TTK_FILL_X,
+ TTK_GROUP("null", TTK_PACK_RIGHT,
+ TTK_NODE("Spinbox.uparrow", TTK_PACK_TOP|TTK_STICK_E)
+ TTK_NODE("Spinbox.downarrow", TTK_PACK_BOTTOM|TTK_STICK_E))
+ TTK_GROUP("Spinbox.padding", TTK_FILL_BOTH,
+ TTK_NODE("Spinbox.textarea", TTK_FILL_BOTH)))
+TTK_END_LAYOUT
+
+/*------------------------------------------------------------------------
+ * +++ Initialization.
+ */
+MODULE_SCOPE
+void TtkEntry_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);
+
+ Ttk_RegisterElement(interp, themePtr, "textarea", &TextareaElementSpec, 0);
+
+ Ttk_RegisterLayout(themePtr, "TEntry", EntryLayout);
+ Ttk_RegisterLayout(themePtr, "TCombobox", ComboboxLayout);
+ Ttk_RegisterLayout(themePtr, "TSpinbox", SpinboxLayout);
+
+ RegisterWidget(interp, "ttk::entry", &EntryWidgetSpec);
+ RegisterWidget(interp, "ttk::combobox", &ComboboxWidgetSpec);
+ RegisterWidget(interp, "ttk::spinbox", &SpinboxWidgetSpec);
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkFrame.c b/generic/ttk/ttkFrame.c
new file mode 100644
index 0000000..7860024
--- /dev/null
+++ b/generic/ttk/ttkFrame.c
@@ -0,0 +1,654 @@
+/*
+ * Copyright (c) 2004, Joe English
+ *
+ * ttk::frame and ttk::labelframe widgets.
+ */
+
+#include <tk.h>
+
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+#include "ttkManager.h"
+
+/* ======================================================================
+ * +++ Frame widget:
+ */
+
+typedef struct {
+ Tcl_Obj *borderWidthObj;
+ Tcl_Obj *paddingObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *widthObj;
+ Tcl_Obj *heightObj;
+} FramePart;
+
+typedef struct {
+ WidgetCore core;
+ FramePart frame;
+} Frame;
+
+static Tk_OptionSpec FrameOptionSpecs[] = {
+ {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", NULL,
+ Tk_Offset(Frame,frame.borderWidthObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+ {TK_OPTION_STRING, "-padding", "padding", "Pad", NULL,
+ Tk_Offset(Frame,frame.paddingObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+ {TK_OPTION_RELIEF, "-relief", "relief", "Relief", NULL,
+ Tk_Offset(Frame,frame.reliefObj), -1,
+ TK_OPTION_NULL_OK,0,0 },
+ {TK_OPTION_PIXELS, "-width", "width", "Width", "0",
+ Tk_Offset(Frame,frame.widthObj), -1,
+ 0,0,GEOMETRY_CHANGED },
+ {TK_OPTION_PIXELS, "-height", "height", "Height", "0",
+ Tk_Offset(Frame,frame.heightObj), -1,
+ 0,0,GEOMETRY_CHANGED },
+
+ WIDGET_TAKEFOCUS_FALSE,
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
+};
+
+static const Ttk_Ensemble FrameCommands[] = {
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ { 0,0,0 }
+};
+
+/*
+ * FrameMargins --
+ * Compute internal margins for a frame widget.
+ * This includes the -borderWidth, plus any additional -padding.
+ */
+static Ttk_Padding FrameMargins(Frame *framePtr)
+{
+ Ttk_Padding margins = Ttk_UniformPadding(0);
+
+ /* Check -padding:
+ */
+ if (framePtr->frame.paddingObj) {
+ Ttk_GetPaddingFromObj(NULL,
+ framePtr->core.tkwin, framePtr->frame.paddingObj, &margins);
+ }
+
+ /* Add padding for border:
+ */
+ if (framePtr->frame.borderWidthObj) {
+ int border = 0;
+ Tk_GetPixelsFromObj(NULL,
+ framePtr->core.tkwin, framePtr->frame.borderWidthObj, &border);
+ margins = Ttk_AddPadding(margins, Ttk_UniformPadding((short)border));
+ }
+
+ return margins;
+}
+
+/* FrameSize procedure --
+ * The frame doesn't request a size of its own by default,
+ * but it does have an internal border. See also <<NOTE-SIZE>>
+ */
+static int FrameSize(void *recordPtr, int *widthPtr, int *heightPtr)
+{
+ Frame *framePtr = recordPtr;
+ Ttk_SetMargins(framePtr->core.tkwin, FrameMargins(framePtr));
+ return 0;
+}
+
+/*
+ * FrameConfigure -- configure hook.
+ * <<NOTE-SIZE>> Usually the size of a frame is controlled by
+ * a geometry manager (pack, grid); the -width and -height
+ * options are only effective if geometry propagation is turned
+ * off or if the [place] GM is used for child widgets.
+ *
+ * To avoid geometry blinking, we issue a geometry request
+ * in the Configure hook instead of the Size hook, and only
+ * if -width and/or -height is nonzero and one of them
+ * or the other size-related options (-borderwidth, -padding)
+ * has been changed.
+ */
+
+static int FrameConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Frame *framePtr = recordPtr;
+ int width, height;
+
+ /*
+ * Make sure -padding resource, if present, is correct:
+ */
+ if (framePtr->frame.paddingObj) {
+ Ttk_Padding unused;
+ if (Ttk_GetPaddingFromObj(interp,
+ framePtr->core.tkwin,
+ framePtr->frame.paddingObj,
+ &unused) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ }
+
+ /* See <<NOTE-SIZE>>
+ */
+ if ( TCL_OK != Tk_GetPixelsFromObj(
+ interp,framePtr->core.tkwin,framePtr->frame.widthObj,&width)
+ || TCL_OK != Tk_GetPixelsFromObj(
+ interp,framePtr->core.tkwin,framePtr->frame.heightObj,&height)
+ )
+ {
+ return TCL_ERROR;
+ }
+
+ if ((width > 0 || height > 0) && (mask & GEOMETRY_CHANGED)) {
+ Tk_GeometryRequest(framePtr->core.tkwin, width, height);
+ }
+
+ return TtkCoreConfigure(interp, recordPtr, mask);
+}
+
+static WidgetSpec FrameWidgetSpec = {
+ "TFrame", /* className */
+ sizeof(Frame), /* recordSize */
+ FrameOptionSpecs, /* optionSpecs */
+ FrameCommands, /* subcommands */
+ TtkNullInitialize, /* initializeProc */
+ TtkNullCleanup, /* cleanupProc */
+ FrameConfigure, /* configureProc */
+ TtkNullPostConfigure, /* postConfigureProc */
+ TtkWidgetGetLayout, /* getLayoutProc */
+ FrameSize, /* sizeProc */
+ TtkWidgetDoLayout, /* layoutProc */
+ TtkWidgetDisplay /* displayProc */
+};
+
+TTK_BEGIN_LAYOUT(FrameLayout)
+ TTK_NODE("Frame.border", TTK_FILL_BOTH)
+TTK_END_LAYOUT
+
+/* ======================================================================
+ * +++ Labelframe widget:
+ */
+
+#define DEFAULT_LABELINSET 8
+#define DEFAULT_BORDERWIDTH 2
+
+int TtkGetLabelAnchorFromObj(
+ Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_PositionSpec *anchorPtr)
+{
+ const char *string = Tcl_GetString(objPtr);
+ char c = *string++;
+ Ttk_PositionSpec flags = 0;
+
+ /* First character determines side:
+ */
+ switch (c) {
+ case 'w' : flags = TTK_PACK_LEFT; break;
+ case 'e' : flags = TTK_PACK_RIGHT; break;
+ case 'n' : flags = TTK_PACK_TOP; break;
+ case 's' : flags = TTK_PACK_BOTTOM; break;
+ default : goto error;
+ }
+
+ /* Remaining characters are as per -sticky:
+ */
+ while ((c = *string++) != '\0') {
+ switch (c) {
+ case 'w' : flags |= TTK_STICK_W; break;
+ case 'e' : flags |= TTK_STICK_E; break;
+ case 'n' : flags |= TTK_STICK_N; break;
+ case 's' : flags |= TTK_STICK_S; break;
+ default : goto error;
+ }
+ }
+
+ *anchorPtr = flags;
+ return TCL_OK;
+
+error:
+ if (interp) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ "Bad label anchor specification ", Tcl_GetString(objPtr),
+ NULL);
+ }
+ return TCL_ERROR;
+}
+
+/* LabelAnchorSide --
+ * Returns the side corresponding to a LabelAnchor value.
+ */
+static Ttk_Side LabelAnchorSide(Ttk_PositionSpec flags)
+{
+ if (flags & TTK_PACK_LEFT) return TTK_SIDE_LEFT;
+ else if (flags & TTK_PACK_RIGHT) return TTK_SIDE_RIGHT;
+ else if (flags & TTK_PACK_TOP) return TTK_SIDE_TOP;
+ else if (flags & TTK_PACK_BOTTOM) return TTK_SIDE_BOTTOM;
+ /*NOTREACHED*/
+ return TTK_SIDE_TOP;
+}
+
+/*
+ * Labelframe widget record:
+ */
+typedef struct {
+ Tcl_Obj *labelAnchorObj;
+ Tcl_Obj *textObj;
+ Tcl_Obj *underlineObj;
+ Tk_Window labelWidget;
+
+ Ttk_Manager *mgr;
+ Ttk_Layout labelLayout; /* Sublayout for label */
+ Ttk_Box labelParcel; /* Set in layoutProc */
+} LabelframePart;
+
+typedef struct {
+ WidgetCore core;
+ FramePart frame;
+ LabelframePart label;
+} Labelframe;
+
+#define LABELWIDGET_CHANGED 0x100
+
+static Tk_OptionSpec LabelframeOptionSpecs[] = {
+ {TK_OPTION_STRING, "-labelanchor", "labelAnchor", "LabelAnchor",
+ "nw", Tk_Offset(Labelframe, label.labelAnchorObj),-1,
+ 0,0,GEOMETRY_CHANGED},
+ {TK_OPTION_STRING, "-text", "text", "Text", "",
+ Tk_Offset(Labelframe,label.textObj), -1,
+ 0,0,GEOMETRY_CHANGED },
+ {TK_OPTION_INT, "-underline", "underline", "Underline",
+ "-1", Tk_Offset(Labelframe,label.underlineObj), -1,
+ 0,0,0 },
+ {TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget", NULL,
+ -1, Tk_Offset(Labelframe,label.labelWidget),
+ TK_OPTION_NULL_OK,0,LABELWIDGET_CHANGED|GEOMETRY_CHANGED },
+
+ WIDGET_INHERIT_OPTIONS(FrameOptionSpecs)
+};
+
+/*
+ * Labelframe style parameters:
+ */
+typedef struct {
+ int borderWidth; /* border width */
+ Ttk_Padding padding; /* internal padding */
+ Ttk_PositionSpec labelAnchor; /* corner/side to place label */
+ Ttk_Padding labelMargins; /* extra space around label */
+ int labelOutside; /* true=>place label outside border */
+} LabelframeStyle;
+
+static void LabelframeStyleOptions(Labelframe *lf, LabelframeStyle *style)
+{
+ Ttk_Layout layout = lf->core.layout;
+ Tcl_Obj *objPtr;
+
+ style->borderWidth = DEFAULT_BORDERWIDTH;
+ style->padding = Ttk_UniformPadding(0);
+ style->labelAnchor = TTK_PACK_TOP | TTK_STICK_W;
+ style->labelOutside = 0;
+
+ if ((objPtr = Ttk_QueryOption(layout, "-borderwidth", 0)) != NULL) {
+ Tk_GetPixelsFromObj(NULL, lf->core.tkwin, objPtr, &style->borderWidth);
+ }
+ if ((objPtr = Ttk_QueryOption(layout, "-padding", 0)) != NULL) {
+ Ttk_GetPaddingFromObj(NULL, lf->core.tkwin, objPtr, &style->padding);
+ }
+ if ((objPtr = Ttk_QueryOption(layout,"-labelanchor", 0)) != NULL) {
+ TtkGetLabelAnchorFromObj(NULL, objPtr, &style->labelAnchor);
+ }
+ if ((objPtr = Ttk_QueryOption(layout,"-labelmargins", 0)) != NULL) {
+ Ttk_GetBorderFromObj(NULL, objPtr, &style->labelMargins);
+ } else {
+ if (style->labelAnchor & (TTK_PACK_TOP|TTK_PACK_BOTTOM)) {
+ style->labelMargins =
+ Ttk_MakePadding(DEFAULT_LABELINSET,0,DEFAULT_LABELINSET,0);
+ } else {
+ style->labelMargins =
+ Ttk_MakePadding(0,DEFAULT_LABELINSET,0,DEFAULT_LABELINSET);
+ }
+ }
+ if ((objPtr = Ttk_QueryOption(layout,"-labeloutside", 0)) != NULL) {
+ Tcl_GetBooleanFromObj(NULL, objPtr, &style->labelOutside);
+ }
+
+ return;
+}
+
+/* LabelframeLabelSize --
+ * Extract the requested width and height of the labelframe's label:
+ * taken from the label widget if specified, otherwise the text label.
+ */
+static void
+LabelframeLabelSize(Labelframe *lframePtr, int *widthPtr, int *heightPtr)
+{
+ Tk_Window labelWidget = lframePtr->label.labelWidget;
+ Ttk_Layout labelLayout = lframePtr->label.labelLayout;
+
+ if (labelWidget) {
+ *widthPtr = Tk_ReqWidth(labelWidget);
+ *heightPtr = Tk_ReqHeight(labelWidget);
+ } else if (labelLayout) {
+ Ttk_LayoutSize(labelLayout, 0, widthPtr, heightPtr);
+ } else {
+ *widthPtr = *heightPtr = 0;
+ }
+}
+
+/*
+ * LabelframeSize --
+ * Like the frame, this doesn't request a size of its own
+ * but it does have internal padding and a minimum size.
+ */
+static int LabelframeSize(void *recordPtr, int *widthPtr, int *heightPtr)
+{
+ Labelframe *lframePtr = recordPtr;
+ WidgetCore *corePtr = &lframePtr->core;
+ Ttk_Padding margins;
+ LabelframeStyle style;
+ int labelWidth, labelHeight;
+
+ LabelframeStyleOptions(lframePtr, &style);
+
+ /* Compute base margins (See also: FrameMargins)
+ */
+ margins = Ttk_AddPadding(
+ style.padding, Ttk_UniformPadding((short)style.borderWidth));
+
+ /* Adjust margins based on label size and position:
+ */
+ LabelframeLabelSize(lframePtr, &labelWidth, &labelHeight);
+ labelWidth += Ttk_PaddingWidth(style.labelMargins);
+ labelHeight += Ttk_PaddingHeight(style.labelMargins);
+
+ switch (LabelAnchorSide(style.labelAnchor)) {
+ case TTK_SIDE_LEFT: margins.left += labelWidth; break;
+ case TTK_SIDE_RIGHT: margins.right += labelWidth; break;
+ case TTK_SIDE_TOP: margins.top += labelHeight; break;
+ case TTK_SIDE_BOTTOM: margins.bottom += labelHeight; break;
+ }
+
+ Ttk_SetMargins(corePtr->tkwin,margins);
+
+ /* Request minimum size based on border width and label size:
+ */
+ Tk_SetMinimumRequestSize(corePtr->tkwin,
+ labelWidth + 2*style.borderWidth,
+ labelHeight + 2*style.borderWidth);
+
+ return 0;
+}
+
+/*
+ * LabelframeGetLayout --
+ * Getlayout widget hook.
+ */
+
+static Ttk_Layout LabelframeGetLayout(
+ Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr)
+{
+ Labelframe *lf = recordPtr;
+ Ttk_Layout frameLayout = TtkWidgetGetLayout(interp, theme, recordPtr);
+ Ttk_Layout labelLayout;
+
+ if (!frameLayout) {
+ return NULL;
+ }
+
+ labelLayout = Ttk_CreateSublayout(
+ interp, theme, frameLayout, ".Label", lf->core.optionTable);
+
+ if (labelLayout) {
+ if (lf->label.labelLayout) {
+ Ttk_FreeLayout(lf->label.labelLayout);
+ }
+ Ttk_RebindSublayout(labelLayout, recordPtr);
+ lf->label.labelLayout = labelLayout;
+ }
+
+ return frameLayout;
+}
+
+/*
+ * LabelframeDoLayout --
+ * Labelframe layout hook.
+ *
+ * Side effects: Computes labelParcel.
+ */
+
+static void LabelframeDoLayout(void *recordPtr)
+{
+ Labelframe *lframePtr = recordPtr;
+ WidgetCore *corePtr = &lframePtr->core;
+ int lw, lh; /* Label width and height */
+ LabelframeStyle style;
+ Ttk_Box borderParcel = Ttk_WinBox(lframePtr->core.tkwin);
+ Ttk_Box labelParcel;
+
+ /*
+ * Compute label parcel:
+ */
+ LabelframeStyleOptions(lframePtr, &style);
+ LabelframeLabelSize(lframePtr, &lw, &lh);
+ lw += Ttk_PaddingWidth(style.labelMargins);
+ lh += Ttk_PaddingHeight(style.labelMargins);
+
+ labelParcel = Ttk_PadBox(
+ Ttk_PositionBox(&borderParcel, lw, lh, style.labelAnchor),
+ style.labelMargins);
+
+ if (!style.labelOutside) {
+ /* Move border edge so it's over label:
+ */
+ switch (LabelAnchorSide(style.labelAnchor)) {
+ case TTK_SIDE_LEFT: borderParcel.x -= lw / 2;
+ case TTK_SIDE_RIGHT: borderParcel.width += lw/2; break;
+ case TTK_SIDE_TOP: borderParcel.y -= lh / 2;
+ case TTK_SIDE_BOTTOM: borderParcel.height += lh / 2; break;
+ }
+ }
+
+ /*
+ * Place border and label:
+ */
+ Ttk_PlaceLayout(corePtr->layout, corePtr->state, borderParcel);
+ if (lframePtr->label.labelLayout) {
+ Ttk_PlaceLayout(
+ lframePtr->label.labelLayout, corePtr->state, labelParcel);
+ }
+ /* labelWidget placed in LabelframePlaceSlaves GM hook */
+ lframePtr->label.labelParcel = labelParcel;
+}
+
+static void LabelframeDisplay(void *recordPtr, Drawable d)
+{
+ Labelframe *lframePtr = recordPtr;
+ Ttk_DrawLayout(lframePtr->core.layout, lframePtr->core.state, d);
+ if (lframePtr->label.labelLayout) {
+ Ttk_DrawLayout(lframePtr->label.labelLayout, lframePtr->core.state, d);
+ }
+}
+
+/* +++ Labelframe geometry manager hooks.
+ */
+
+/* LabelframePlaceSlaves --
+ * Sets the position and size of the labelwidget.
+ */
+static void LabelframePlaceSlaves(void *recordPtr)
+{
+ Labelframe *lframe = recordPtr;
+
+ if (Ttk_NumberSlaves(lframe->label.mgr) == 1) {
+ Ttk_Box b;
+ LabelframeDoLayout(recordPtr);
+ b = lframe->label.labelParcel;
+ /* ASSERT: slave #0 is lframe->label.labelWidget */
+ Ttk_PlaceSlave(lframe->label.mgr, 0, b.x,b.y,b.width,b.height);
+ }
+}
+
+static int LabelRequest(void *managerData, int index, int width, int height)
+{
+ return 1;
+}
+
+/* LabelRemoved --
+ * Unset the -labelwidget option.
+ *
+ * <<NOTE-LABELREMOVED>>:
+ * This routine is also called when the widget voluntarily forgets
+ * the slave in LabelframeConfigure.
+ */
+static void LabelRemoved(void *managerData, int slaveIndex)
+{
+ Labelframe *lframe = managerData;
+ lframe->label.labelWidget = 0;
+}
+
+static Ttk_ManagerSpec LabelframeManagerSpec = {
+ { "labelframe", Ttk_GeometryRequestProc, Ttk_LostSlaveProc },
+ LabelframeSize,
+ LabelframePlaceSlaves,
+ LabelRequest,
+ LabelRemoved
+};
+
+/* LabelframeInitialize --
+ * Initialization hook.
+ */
+static void LabelframeInitialize(Tcl_Interp *interp, void *recordPtr)
+{
+ Labelframe *lframe = recordPtr;
+
+ lframe->label.mgr = Ttk_CreateManager(
+ &LabelframeManagerSpec, lframe, lframe->core.tkwin);
+ lframe->label.labelWidget = 0;
+ lframe->label.labelLayout = 0;
+ lframe->label.labelParcel = Ttk_MakeBox(-1,-1,-1,-1);
+}
+
+/* LabelframeCleanup --
+ * Cleanup hook.
+ */
+static void LabelframeCleanup(void *recordPtr)
+{
+ Labelframe *lframe = recordPtr;
+ Ttk_DeleteManager(lframe->label.mgr);
+ if (lframe->label.labelLayout) {
+ Ttk_FreeLayout(lframe->label.labelLayout);
+ }
+}
+
+/* RaiseLabelWidget --
+ * Raise the -labelwidget to ensure that the labelframe doesn't
+ * obscure it (if it's not a direct child), or bring it to
+ * the top of the stacking order (if it is).
+ */
+static void RaiseLabelWidget(Labelframe *lframe)
+{
+ Tk_Window parent = Tk_Parent(lframe->label.labelWidget);
+ Tk_Window sibling = NULL;
+ Tk_Window w = lframe->core.tkwin;
+
+ while (w && w != parent) {
+ sibling = w;
+ w = Tk_Parent(w);
+ }
+
+ Tk_RestackWindow(lframe->label.labelWidget, Above, sibling);
+}
+
+/* LabelframeConfigure --
+ * Configuration hook.
+ */
+static int LabelframeConfigure(Tcl_Interp *interp,void *recordPtr,int mask)
+{
+ Labelframe *lframePtr = recordPtr;
+ Tk_Window labelWidget = lframePtr->label.labelWidget;
+ Ttk_PositionSpec unused;
+
+ /* Validate options:
+ */
+ if (mask & LABELWIDGET_CHANGED && labelWidget != NULL) {
+ if (!Ttk_Maintainable(interp, labelWidget, lframePtr->core.tkwin)) {
+ return TCL_ERROR;
+ }
+ }
+
+ if (TtkGetLabelAnchorFromObj(
+ interp, lframePtr->label.labelAnchorObj, &unused) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ /* Base class configuration:
+ */
+ if (FrameConfigure(interp, recordPtr, mask) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /* Update -labelwidget changes, if any:
+ */
+ if (mask & LABELWIDGET_CHANGED) {
+ if (Ttk_NumberSlaves(lframePtr->label.mgr) == 1) {
+ Ttk_ForgetSlave(lframePtr->label.mgr, 0);
+ /* Restore labelWidget field (see <<NOTE-LABELREMOVED>>)
+ */
+ lframePtr->label.labelWidget = labelWidget;
+ }
+
+ if (labelWidget) {
+ Ttk_InsertSlave(lframePtr->label.mgr, 0, labelWidget, NULL);
+ RaiseLabelWidget(lframePtr);
+ }
+ }
+
+ if (mask & GEOMETRY_CHANGED) {
+ Ttk_ManagerSizeChanged(lframePtr->label.mgr);
+ Ttk_ManagerLayoutChanged(lframePtr->label.mgr);
+ }
+
+ return TCL_OK;
+}
+
+static WidgetSpec LabelframeWidgetSpec = {
+ "TLabelframe", /* className */
+ sizeof(Labelframe), /* recordSize */
+ LabelframeOptionSpecs, /* optionSpecs */
+ FrameCommands, /* subcommands */
+ LabelframeInitialize, /* initializeProc */
+ LabelframeCleanup, /* cleanupProc */
+ LabelframeConfigure, /* configureProc */
+ TtkNullPostConfigure, /* postConfigureProc */
+ LabelframeGetLayout, /* getLayoutProc */
+ LabelframeSize, /* sizeProc */
+ LabelframeDoLayout, /* layoutProc */
+ LabelframeDisplay /* displayProc */
+};
+
+TTK_BEGIN_LAYOUT(LabelframeLayout)
+ TTK_NODE("Labelframe.border", TTK_FILL_BOTH)
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(LabelSublayout)
+ TTK_GROUP("Label.fill", TTK_FILL_BOTH,
+ TTK_NODE("Label.text", TTK_FILL_BOTH))
+TTK_END_LAYOUT
+
+/* ======================================================================
+ * +++ Initialization.
+ */
+
+MODULE_SCOPE
+void TtkFrame_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme theme = Ttk_GetDefaultTheme(interp);
+
+ Ttk_RegisterLayout(theme, "TFrame", FrameLayout);
+ Ttk_RegisterLayout(theme, "TLabelframe", LabelframeLayout);
+ Ttk_RegisterLayout(theme, "Label", LabelSublayout);
+
+ RegisterWidget(interp, "ttk::frame", &FrameWidgetSpec);
+ RegisterWidget(interp, "ttk::labelframe", &LabelframeWidgetSpec);
+}
+
diff --git a/generic/ttk/ttkGenStubs.tcl b/generic/ttk/ttkGenStubs.tcl
new file mode 100644
index 0000000..90dea25
--- /dev/null
+++ b/generic/ttk/ttkGenStubs.tcl
@@ -0,0 +1,921 @@
+# ttkGenStubs.tcl --
+#
+# This script generates a set of stub files for a given
+# interface.
+#
+#
+# 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.
+#
+# SOURCE: tcl/tools/genStubs.tcl, revision 1.20
+#
+# CHANGES:
+# + Remove xxx_TCL_DECLARED #ifdeffery
+# + Use application-defined storage class specifier instead of "EXTERN"
+# + Add "epoch" and "revision" fields to stubs table record
+# + Remove dead code related to USE_*_STUB_PROCS (emitStubs, makeStub)
+# + Second argument to "declare" is used as a status guard
+# instead of a platform guard.
+# + Use void (*reserved$i)(void) = 0 instead of void *reserved$i = NULL
+# for unused stub entries, in case pointer-to-function and
+# pointer-to-object are different sizes.
+# + Allow trailing semicolon in function declarations
+# + stubs table is const-qualified
+#
+
+package require Tcl 8
+
+namespace eval genStubs {
+ # libraryName --
+ #
+ # The name of the entire library. This value is used to compute
+ # the USE_*_STUBS macro and the name of the init file.
+
+ variable libraryName "UNKNOWN"
+
+ # interfaces --
+ #
+ # An array indexed by interface name that is used to maintain
+ # the set of valid interfaces. The value is empty.
+
+ array set interfaces {}
+
+ # curName --
+ #
+ # The name of the interface currently being defined.
+
+ variable curName "UNKNOWN"
+
+ # scspec --
+ #
+ # Storage class specifier for external function declarations.
+ # Normally "extern", may be set to something like XYZAPI
+ #
+ variable scspec "extern"
+
+ # epoch, revision --
+ #
+ # The epoch and revision numbers of the interface currently being defined.
+ # (@@@TODO: should be an array mapping interface names -> numbers)
+ #
+
+ variable epoch 0
+ variable revision 0
+
+ # hooks --
+ #
+ # An array indexed by interface name that contains the set of
+ # subinterfaces that should be defined for a given interface.
+
+ array set hooks {}
+
+ # stubs --
+ #
+ # This three dimensional array is indexed first by interface name,
+ # second by field name, and third by a numeric offset or the
+ # constant "lastNum". The lastNum entry contains the largest
+ # numeric offset used for a given interface.
+ #
+ # Field "decl,$i" contains the C function specification that
+ # should be used for the given entry in the stub table. The spec
+ # consists of a list in the form returned by parseDecl.
+ # Other fields TBD later.
+
+ array set stubs {}
+
+ # outDir --
+ #
+ # The directory where the generated files should be placed.
+
+ variable outDir .
+}
+
+# genStubs::library --
+#
+# This function is used in the declarations file to set the name
+# of the library that the interfaces are associated with (e.g. "tcl").
+# This value will be used to define the inline conditional macro.
+#
+# Arguments:
+# name The library name.
+#
+# Results:
+# None.
+
+proc genStubs::library {name} {
+ variable libraryName $name
+}
+
+# genStubs::interface --
+#
+# This function is used in the declarations file to set the name
+# of the interface currently being defined.
+#
+# Arguments:
+# name The name of the interface.
+#
+# Results:
+# None.
+
+proc genStubs::interface {name} {
+ variable curName $name
+ variable interfaces
+ variable stubs
+
+ set interfaces($name) {}
+ set stubs($name,lastNum) 0
+ return
+}
+
+# genStubs::scspec --
+#
+# Define the storage class macro used for external function declarations.
+# Typically, this will be a macro like XYZAPI or EXTERN that
+# expands to either DLLIMPORT or DLLEXPORT, depending on whether
+# -DBUILD_XYZ has been set.
+#
+proc genStubs::scspec {value} {
+ variable scspec $value
+}
+
+# genStubs::epoch --
+#
+# Define the epoch number for this library. The epoch
+# should be incrememented when a release is made that
+# contains incompatible changes to the public API.
+#
+proc genStubs::epoch {value} {
+ variable epoch $value
+}
+
+# genStubs::hooks --
+#
+# This function defines the subinterface hooks for the current
+# interface.
+#
+# Arguments:
+# names The ordered list of interfaces that are reachable through the
+# hook vector.
+#
+# Results:
+# None.
+
+proc genStubs::hooks {names} {
+ variable curName
+ variable hooks
+
+ set hooks($curName) $names
+ return
+}
+
+# genStubs::declare --
+#
+# This function is used in the declarations file to declare a new
+# interface entry.
+#
+# Arguments:
+# index The index number of the interface.
+# status Status of the interface: one of "current",
+# "deprecated", or "obsolete".
+# decl The C function declaration, or {} for an undefined
+# entry.
+#
+proc genStubs::declare {args} {
+ variable stubs
+ variable curName
+ variable revision
+
+ incr revision
+
+ if {[llength $args] == 2} {
+ lassign $args index decl
+ set status current
+ } elseif {[llength $args] == 3} {
+ lassign $args index status decl
+ } else {
+ puts stderr "wrong # args: declare $args"
+ return
+ }
+
+ # Check for duplicate declarations, then add the declaration and
+ # bump the lastNum counter if necessary.
+
+ if {[info exists stubs($curName,decl,$index)]} {
+ puts stderr "Duplicate entry: $index"
+ }
+ regsub -all const $decl CONST decl
+ regsub -all "\[ \t\n\]+" [string trim $decl] " " decl
+ set decl [parseDecl $decl]
+
+ set stubs($curName,status,$index) $status
+ set stubs($curName,decl,$index) $decl
+
+ if {$index > $stubs($curName,lastNum)} {
+ set stubs($curName,lastNum) $index
+ }
+
+ return
+}
+
+# genStubs::rewriteFile --
+#
+# This function replaces the machine generated portion of the
+# specified file with new contents. It looks for the !BEGIN! and
+# !END! comments to determine where to place the new text.
+#
+# Arguments:
+# file The name of the file to modify.
+# text The new text to place in the file.
+#
+# Results:
+# None.
+
+proc genStubs::rewriteFile {file text} {
+ if {![file exists $file]} {
+ puts stderr "Cannot find file: $file"
+ return
+ }
+ set in [open ${file} r]
+ set out [open ${file}.new w]
+ fconfigure $out -translation lf
+
+ while {![eof $in]} {
+ set line [gets $in]
+ if {[string match "*!BEGIN!*" $line]} {
+ break
+ }
+ puts $out $line
+ }
+ puts $out "/* !BEGIN!: Do not edit below this line. */"
+ puts $out $text
+ while {![eof $in]} {
+ set line [gets $in]
+ if {[string match "*!END!*" $line]} {
+ break
+ }
+ }
+ puts $out "/* !END!: Do not edit above this line. */"
+ puts -nonewline $out [read $in]
+ close $in
+ close $out
+ file rename -force ${file}.new ${file}
+ return
+}
+
+# genStubs::addPlatformGuard --
+#
+# Wrap a string inside a platform #ifdef.
+#
+# Arguments:
+# plat Platform to test.
+#
+# Results:
+# Returns the original text inside an appropriate #ifdef.
+
+proc genStubs::addPlatformGuard {plat text} {
+ switch $plat {
+ win {
+ return "#ifdef __WIN32__\n${text}#endif /* __WIN32__ */\n"
+ }
+ unix {
+ return "#if !defined(__WIN32__) /* UNIX */\n${text}#endif /* UNIX */\n"
+ }
+ macosx {
+ return "#ifdef MAC_OSX_TCL\n${text}#endif /* MAC_OSX_TCL */\n"
+ }
+ aqua {
+ return "#ifdef MAC_OSX_TK\n${text}#endif /* MAC_OSX_TK */\n"
+ }
+ x11 {
+ return "#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */\n${text}#endif /* X11 */\n"
+ }
+ }
+ return $text
+}
+
+# genStubs::emitSlots --
+#
+# Generate the stub table slots for the given interface.
+#
+# Arguments:
+# name The name of the interface being emitted.
+# textVar The variable to use for output.
+#
+# Results:
+# None.
+
+proc genStubs::emitSlots {name textVar} {
+ upvar $textVar text
+ forAllStubs $name makeSlot noGuard text {" void (*reserved$i)(void);\n"}
+ return
+}
+
+# genStubs::parseDecl --
+#
+# Parse a C function declaration into its component parts.
+#
+# Arguments:
+# decl The function declaration.
+#
+# Results:
+# Returns a list of the form {returnType name args}. The args
+# element consists of a list of type/name pairs, or a single
+# element "void". If the function declaration is malformed
+# then an error is displayed and the return value is {}.
+
+proc genStubs::parseDecl {decl} {
+ if {![regexp {^(.*)\((.*)\);?$} $decl all prefix args]} {
+ set prefix $decl
+ set args {}
+ }
+ set prefix [string trim $prefix]
+ if {![regexp {^(.+[ ][*]*)([^ *]+)$} $prefix all rtype fname]} {
+ puts stderr "Bad return type: $decl"
+ return
+ }
+ set rtype [string trim $rtype]
+ if {$args == ""} {
+ return [list $rtype $fname {}]
+ }
+ foreach arg [split $args ,] {
+ lappend argList [string trim $arg]
+ }
+ if {![string compare [lindex $argList end] "..."]} {
+ set args TCL_VARARGS
+ foreach arg [lrange $argList 0 end-1] {
+ set argInfo [parseArg $arg]
+ if {[llength $argInfo] == 2 || [llength $argInfo] == 3} {
+ lappend args $argInfo
+ } else {
+ puts stderr "Bad argument: '$arg' in '$decl'"
+ return
+ }
+ }
+ } else {
+ set args {}
+ foreach arg $argList {
+ set argInfo [parseArg $arg]
+ if {![string compare $argInfo "void"]} {
+ lappend args "void"
+ break
+ } elseif {[llength $argInfo] == 2 || [llength $argInfo] == 3} {
+ lappend args $argInfo
+ } else {
+ puts stderr "Bad argument: '$arg' in '$decl'"
+ return
+ }
+ }
+ }
+ return [list $rtype $fname $args]
+}
+
+# genStubs::parseArg --
+#
+# This function parses a function argument into a type and name.
+#
+# Arguments:
+# arg The argument to parse.
+#
+# Results:
+# Returns a list of type and name with an optional third array
+# indicator. If the argument is malformed, returns "".
+
+proc genStubs::parseArg {arg} {
+ if {![regexp {^(.+[ ][*]*)([^][ *]+)(\[\])?$} $arg all type name array]} {
+ if {$arg == "void"} {
+ return $arg
+ } else {
+ return
+ }
+ }
+ set result [list [string trim $type] $name]
+ if {$array != ""} {
+ lappend result $array
+ }
+ return $result
+}
+
+# genStubs::makeDecl --
+#
+# Generate the prototype for a function.
+#
+# Arguments:
+# name The interface name.
+# decl The function declaration.
+# index The slot index for this function.
+#
+# Results:
+# Returns the formatted declaration string.
+
+proc genStubs::makeDecl {name decl index} {
+ variable scspec
+
+ lassign $decl rtype fname args
+
+ append text "/* $index */\n"
+ if {$rtype != "void"} {
+ regsub -all void $rtype VOID rtype
+ }
+ set line "$scspec $rtype"
+ set count [expr {2 - ([string length $line] / 8)}]
+ append line [string range "\t\t\t" 0 $count]
+ set pad [expr {24 - [string length $line]}]
+ if {$pad <= 0} {
+ append line " "
+ set pad 0
+ }
+ if {$args == ""} {
+ append line $fname
+ append text $line
+ append text ";\n"
+ return $text
+ }
+ append line $fname
+
+ regsub -all void $args VOID args
+ set arg1 [lindex $args 0]
+ switch -exact $arg1 {
+ VOID {
+ append line "(void)"
+ }
+ TCL_VARARGS {
+ set sep "("
+ foreach arg [lrange $args 1 end] {
+ append line $sep
+ set next {}
+ append next [lindex $arg 0]
+ if {[string index $next end] ne "*"} {
+ append next " "
+ }
+ append next [lindex $arg 1] [lindex $arg 2]
+ if {[string length $line] + [string length $next] \
+ + $pad > 76} {
+ append text [string trimright $line] \n
+ set line "\t\t\t\t"
+ set pad 28
+ }
+ append line $next
+ set sep ", "
+ }
+ append line ", ...)"
+ }
+ default {
+ set sep "("
+ foreach arg $args {
+ append line $sep
+ set next {}
+ append next [lindex $arg 0]
+ if {[string index $next end] ne "*"} {
+ append next " "
+ }
+ append next [lindex $arg 1] [lindex $arg 2]
+ if {[string length $line] + [string length $next] \
+ + $pad > 76} {
+ append text [string trimright $line] \n
+ set line "\t\t\t\t"
+ set pad 28
+ }
+ append line $next
+ set sep ", "
+ }
+ append line ")"
+ }
+ }
+ return "$text$line;\n"
+}
+
+# genStubs::makeMacro --
+#
+# Generate the inline macro for a function.
+#
+# Arguments:
+# name The interface name.
+# decl The function declaration.
+# index The slot index for this function.
+#
+# Results:
+# Returns the formatted macro definition.
+
+proc genStubs::makeMacro {name decl index} {
+ lassign $decl rtype fname args
+
+ set lfname [string tolower [string index $fname 0]]
+ append lfname [string range $fname 1 end]
+
+ set text "#define $fname \\\n\t("
+ if {$args == ""} {
+ append text "*"
+ }
+ append text "${name}StubsPtr->$lfname)"
+ append text " /* $index */\n"
+ return $text
+}
+
+# genStubs::makeSlot --
+#
+# Generate the stub table entry for a function.
+#
+# Arguments:
+# name The interface name.
+# decl The function declaration.
+# index The slot index for this function.
+#
+# Results:
+# Returns the formatted table entry.
+
+proc genStubs::makeSlot {name decl index} {
+ lassign $decl rtype fname args
+
+ set lfname [string tolower [string index $fname 0]]
+ append lfname [string range $fname 1 end]
+
+ set text " "
+ if {$rtype != "void"} {
+ regsub -all void $rtype VOID rtype
+ }
+ if {$args == ""} {
+ append text $rtype " *" $lfname "; /* $index */\n"
+ return $text
+ }
+ append text $rtype " (*" $lfname ") "
+
+ regsub -all void $args VOID args
+ set arg1 [lindex $args 0]
+ switch -exact $arg1 {
+ VOID {
+ append text "(void)"
+ }
+ TCL_VARARGS {
+ set sep "("
+ foreach arg [lrange $args 1 end] {
+ append text $sep [lindex $arg 0]
+ if {[string index $text end] ne "*"} {
+ append text " "
+ }
+ append text [lindex $arg 1] [lindex $arg 2]
+ set sep ", "
+ }
+ append text ", ...)"
+ }
+ default {
+ set sep "("
+ foreach arg $args {
+ append text $sep [lindex $arg 0]
+ if {[string index $text end] ne "*"} {
+ append text " "
+ }
+ append text [lindex $arg 1] [lindex $arg 2]
+ set sep ", "
+ }
+ append text ")"
+ }
+ }
+
+ append text "; /* $index */\n"
+ return $text
+}
+
+# genStubs::makeInit --
+#
+# Generate the prototype for a function.
+#
+# Arguments:
+# name The interface name.
+# decl The function declaration.
+# index The slot index for this function.
+#
+# Results:
+# Returns the formatted declaration string.
+
+proc genStubs::makeInit {name decl index} {
+ if {[lindex $decl 2] == ""} {
+ append text " &" [lindex $decl 1] ", /* " $index " */\n"
+ } else {
+ append text " " [lindex $decl 1] ", /* " $index " */\n"
+ }
+ return $text
+}
+
+# genStubs::forAllStubs --
+#
+# This function iterates over all of the slots and invokes
+# a callback for each slot. The result of the callback is then
+# placed inside appropriate guards.
+#
+# Arguments:
+# name The interface name.
+# slotProc The proc to invoke to handle the slot. It will
+# have the interface name, the declaration, and
+# the index appended.
+# guardProc The proc to invoke to add guards. It will have
+# the slot status and text appended.
+# textVar The variable to use for output.
+# skipString The string to emit if a slot is skipped. This
+# string will be subst'ed in the loop so "$i" can
+# be used to substitute the index value.
+#
+# Results:
+# None.
+
+proc genStubs::forAllStubs {name slotProc guardProc textVar
+ {skipString {"/* Slot $i is reserved */\n"}}} {
+ variable stubs
+ upvar $textVar text
+
+ set lastNum $stubs($name,lastNum)
+
+ for {set i 0} {$i <= $lastNum} {incr i} {
+ if {[info exists stubs($name,decl,$i)]} {
+ append text [$guardProc $stubs($name,status,$i) \
+ [$slotProc $name $stubs($name,decl,$i) $i]]
+ } else {
+ eval {append text} $skipString
+ }
+ }
+}
+
+proc genStubs::noGuard {status text} { return $text }
+
+proc genStubs::addGuard {status text} {
+ variable libraryName
+ set upName [string toupper $libraryName]
+
+ switch -- $status {
+ current {
+ # No change
+ }
+ deprecated {
+ set text [ifdeffed "${upName}_DEPRECATED" $text]
+ }
+ obsolete {
+ set text ""
+ }
+ default {
+ puts stderr "Unrecognized status code $status"
+ }
+ }
+ return $text
+}
+
+proc genStubs::ifdeffed {macro text} {
+ join [list "#ifdef $macro" $text "#endif" ""] \n
+}
+
+# genStubs::emitDeclarations --
+#
+# This function emits the function declarations for this interface.
+#
+# Arguments:
+# name The interface name.
+# textVar The variable to use for output.
+#
+# Results:
+# None.
+
+proc genStubs::emitDeclarations {name textVar} {
+ upvar $textVar text
+
+ append text "\n/*\n * Exported function declarations:\n */\n\n"
+ forAllStubs $name makeDecl noGuard text
+ return
+}
+
+# genStubs::emitMacros --
+#
+# This function emits the inline macros for an interface.
+#
+# Arguments:
+# name The name of the interface being emitted.
+# textVar The variable to use for output.
+#
+# Results:
+# None.
+
+proc genStubs::emitMacros {name textVar} {
+ variable libraryName
+ upvar $textVar text
+
+ set upName [string toupper $libraryName]
+ append text "\n#if defined(USE_${upName}_STUBS)\n"
+ append text "\n/*\n * Inline function declarations:\n */\n\n"
+
+ forAllStubs $name makeMacro addGuard text
+
+ append text "\n#endif /* defined(USE_${upName}_STUBS) */\n"
+ return
+}
+
+# genStubs::emitHeader --
+#
+# This function emits the body of the <name>Decls.h file for
+# the specified interface.
+#
+# Arguments:
+# name The name of the interface being emitted.
+#
+# Results:
+# None.
+
+proc genStubs::emitHeader {name} {
+ variable outDir
+ variable hooks
+ variable epoch
+ variable revision
+
+ set capName [string toupper [string index $name 0]]
+ append capName [string range $name 1 end]
+
+ set CAPName [string toupper $name]
+ append text "\n"
+ append text "#define ${CAPName}_STUBS_EPOCH $epoch\n"
+ append text "#define ${CAPName}_STUBS_REVISION $revision\n"
+
+ emitDeclarations $name text
+
+ if {[info exists hooks($name)]} {
+ append text "\ntypedef struct ${capName}StubHooks {\n"
+ foreach hook $hooks($name) {
+ set capHook [string toupper [string index $hook 0]]
+ append capHook [string range $hook 1 end]
+ append text " const struct ${capHook}Stubs *${hook}Stubs;\n"
+ }
+ append text "} ${capName}StubHooks;\n"
+ }
+ append text "\ntypedef struct ${capName}Stubs {\n"
+ append text " int magic;\n"
+ append text " int epoch;\n"
+ append text " int revision;\n"
+ append text " const struct ${capName}StubHooks *hooks;\n\n"
+
+ emitSlots $name text
+
+ append text "} ${capName}Stubs;\n\n"
+
+ append text "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"
+ append text "extern const ${capName}Stubs *${name}StubsPtr;\n"
+ append text "#ifdef __cplusplus\n}\n#endif\n"
+
+ emitMacros $name text
+
+ rewriteFile [file join $outDir ${name}Decls.h] $text
+ return
+}
+
+# genStubs::emitInit --
+#
+# Generate the table initializers for an interface.
+#
+# Arguments:
+# name The name of the interface to initialize.
+# textVar The variable to use for output.
+#
+# Results:
+# Returns the formatted output.
+
+proc genStubs::emitInit {name textVar} {
+ variable hooks
+ variable interfaces
+ variable epoch
+ variable revision
+
+ upvar $textVar text
+ set root 1
+
+ set capName [string toupper [string index $name 0]]
+ append capName [string range $name 1 end]
+ set CAPName [string toupper $name]
+
+ if {[info exists hooks($name)]} {
+ append text "\nstatic const ${capName}StubHooks ${name}StubHooks = \{\n"
+ set sep " "
+ foreach sub $hooks($name) {
+ append text $sep "&${sub}Stubs"
+ set sep ",\n "
+ }
+ append text "\n\};\n"
+ }
+ foreach intf [array names interfaces] {
+ if {[info exists hooks($intf)]} {
+ if {0<=[lsearch -exact $hooks($intf) $name]} {
+ set root 0
+ break;
+ }
+ }
+ }
+
+ if {$root} {
+ append text "\nconst ${capName}Stubs ${name}Stubs = \{\n"
+ } else {
+ append text "\nstatic const ${capName}Stubs ${name}Stubs = \{\n"
+ }
+ append text " TCL_STUB_MAGIC,\n"
+ append text " ${CAPName}_STUBS_EPOCH,\n"
+ append text " ${CAPName}_STUBS_REVISION,\n"
+ if {[info exists hooks($name)]} {
+ append text " &${name}StubHooks,\n"
+ } else {
+ append text " 0,\n"
+ }
+
+ forAllStubs $name makeInit noGuard text {" 0, /* $i */\n"}
+
+ append text "\};\n"
+ return
+}
+
+# genStubs::emitInits --
+#
+# This function emits the body of the <name>StubInit.c file for
+# the specified interface.
+#
+# Arguments:
+# name The name of the interface being emitted.
+#
+# Results:
+# None.
+
+proc genStubs::emitInits {} {
+ variable hooks
+ variable outDir
+ variable libraryName
+ variable interfaces
+
+ # Assuming that dependencies only go one level deep, we need to emit
+ # all of the leaves first to avoid needing forward declarations.
+
+ set leaves {}
+ set roots {}
+ foreach name [lsort [array names interfaces]] {
+ if {[info exists hooks($name)]} {
+ lappend roots $name
+ } else {
+ lappend leaves $name
+ }
+ }
+ foreach name $leaves {
+ emitInit $name text
+ }
+ foreach name $roots {
+ emitInit $name text
+ }
+
+ rewriteFile [file join $outDir ${libraryName}StubInit.c] $text
+}
+
+# genStubs::init --
+#
+# This is the main entry point.
+#
+# Arguments:
+# None.
+#
+# Results:
+# None.
+
+proc genStubs::init {} {
+ global argv argv0
+ variable outDir
+ variable interfaces
+
+ if {[llength $argv] < 2} {
+ puts stderr "usage: $argv0 outDir declFile ?declFile...?"
+ exit 1
+ }
+
+ set outDir [lindex $argv 0]
+
+ foreach file [lrange $argv 1 end] {
+ source $file
+ }
+
+ foreach name [lsort [array names interfaces]] {
+ puts "Emitting $name"
+ emitHeader $name
+ }
+
+ emitInits
+}
+
+# lassign --
+#
+# This function emulates the TclX lassign command.
+#
+# Arguments:
+# valueList A list containing the values to be assigned.
+# args The list of variables to be assigned.
+#
+# Results:
+# Returns any values that were not assigned to variables.
+
+if {[string length [namespace which lassign]] == 0} {
+ proc lassign {valueList args} {
+ if {[llength $args] == 0} {
+ error "wrong # args: should be \"lassign list varName ?varName ...?\""
+ }
+ uplevel [list foreach $args $valueList {break}]
+ return [lrange $valueList [llength $args] end]
+ }
+}
+
+genStubs::init
diff --git a/generic/ttk/ttkImage.c b/generic/ttk/ttkImage.c
new file mode 100644
index 0000000..2b12864
--- /dev/null
+++ b/generic/ttk/ttkImage.c
@@ -0,0 +1,415 @@
+/*
+ * Image specifications and image element factory.
+ *
+ * Copyright (C) 2004 Pat Thoyts <patthoyts@users.sf.net>
+ * Copyright (C) 2004 Joe English
+ *
+ * An imageSpec is a multi-element list; the first element
+ * is the name of the default image to use, the remainder of the
+ * list is a sequence of statespec/imagename options as per
+ * [style map].
+ */
+
+#include <string.h>
+#include <tk.h>
+#include "ttkTheme.h"
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+/*------------------------------------------------------------------------
+ * +++ ImageSpec management.
+ */
+
+struct TtkImageSpec {
+ Tk_Image baseImage; /* Base image to use */
+ int mapCount; /* #state-specific overrides */
+ Ttk_StateSpec *states; /* array[mapCount] of states ... */
+ Tk_Image *images; /* ... per-state images to use */
+};
+
+/* NullImageChanged --
+ * Do-nothing Tk_ImageChangedProc.
+ */
+static void NullImageChanged(ClientData clientData,
+ int x, int y, int width, int height, int imageWidth, int imageHeight)
+{ /* No-op */ }
+
+/* TtkGetImageSpec --
+ * Constructs a Ttk_ImageSpec * from a Tcl_Obj *.
+ * Result must be released using TtkFreeImageSpec.
+ *
+ * TODO: Need a variant of this that takes a user-specified ImageChanged proc
+ */
+Ttk_ImageSpec *
+TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr)
+{
+ Ttk_ImageSpec *imageSpec = 0;
+ int i = 0, n = 0, objc;
+ Tcl_Obj **objv;
+
+ imageSpec = (Ttk_ImageSpec *)ckalloc(sizeof(*imageSpec));
+ imageSpec->baseImage = 0;
+ imageSpec->mapCount = 0;
+ imageSpec->states = 0;
+ imageSpec->images = 0;
+
+ if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+ goto error;
+ }
+
+ if ((objc % 2) != 1) {
+ if (interp) {
+ Tcl_SetResult(interp,
+ "image specification must contain an odd number of elements",
+ TCL_STATIC);
+ }
+ goto error;
+ }
+
+ n = (objc - 1) / 2;
+ imageSpec->states = (Ttk_StateSpec*)ckalloc(n * sizeof(Ttk_StateSpec));
+ imageSpec->images = (Tk_Image*)ckalloc(n * sizeof(Tk_Image *));
+
+ /* Get base image:
+ */
+ imageSpec->baseImage = Tk_GetImage(
+ interp, tkwin, Tcl_GetString(objv[0]), NullImageChanged, NULL);
+ if (!imageSpec->baseImage) {
+ goto error;
+ }
+
+ /* Extract state and image specifications:
+ */
+ for (i = 0; i < n; ++i) {
+ Tcl_Obj *stateSpec = objv[2*i + 1];
+ const char *imageName = Tcl_GetString(objv[2*i + 2]);
+ Ttk_StateSpec state;
+
+ if (Ttk_GetStateSpecFromObj(interp, stateSpec, &state) != TCL_OK) {
+ goto error;
+ }
+ imageSpec->states[i] = state;
+
+ imageSpec->images[i] = Tk_GetImage(
+ interp, tkwin, imageName, NullImageChanged, NULL);
+ if (imageSpec->images[i] == NULL) {
+ goto error;
+ }
+ imageSpec->mapCount = i+1;
+ }
+
+ return imageSpec;
+
+error:
+ TtkFreeImageSpec(imageSpec);
+ return NULL;
+}
+
+/* TtkFreeImageSpec --
+ * Dispose of an image specification.
+ */
+void TtkFreeImageSpec(Ttk_ImageSpec *imageSpec)
+{
+ int i;
+
+ for (i=0; i < imageSpec->mapCount; ++i) {
+ Tk_FreeImage(imageSpec->images[i]);
+ }
+
+ if (imageSpec->baseImage) { Tk_FreeImage(imageSpec->baseImage); }
+ if (imageSpec->states) { ckfree((ClientData)imageSpec->states); }
+ if (imageSpec->images) { ckfree((ClientData)imageSpec->images); }
+
+ ckfree((ClientData)imageSpec);
+}
+
+/* TtkSelectImage --
+ * Return a state-specific image from an ImageSpec
+ */
+Tk_Image TtkSelectImage(Ttk_ImageSpec *imageSpec, Ttk_State state)
+{
+ int i;
+ for (i = 0; i < imageSpec->mapCount; ++i) {
+ if (Ttk_StateMatches(state, imageSpec->states+i)) {
+ return imageSpec->images[i];
+ }
+ }
+ return imageSpec->baseImage;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Drawing utilities.
+ */
+
+/* LPadding, CPadding, RPadding --
+ * Split a box+padding pair into left, center, and right boxes.
+ */
+static Ttk_Box LPadding(Ttk_Box b, Ttk_Padding p)
+ { return Ttk_MakeBox(b.x, b.y, p.left, b.height); }
+
+static Ttk_Box CPadding(Ttk_Box b, Ttk_Padding p)
+ { return Ttk_MakeBox(b.x+p.left, b.y, b.width-p.left-p.right, b.height); }
+
+static Ttk_Box RPadding(Ttk_Box b, Ttk_Padding p)
+ { return Ttk_MakeBox(b.x+b.width-p.right, b.y, p.right, b.height); }
+
+/* TPadding, MPadding, BPadding --
+ * Split a box+padding pair into top, middle, and bottom parts.
+ */
+static Ttk_Box TPadding(Ttk_Box b, Ttk_Padding p)
+ { return Ttk_MakeBox(b.x, b.y, b.width, p.top); }
+
+static Ttk_Box MPadding(Ttk_Box b, Ttk_Padding p)
+ { return Ttk_MakeBox(b.x, b.y+p.top, b.width, b.height-p.top-p.bottom); }
+
+static Ttk_Box BPadding(Ttk_Box b, Ttk_Padding p)
+ { return Ttk_MakeBox(b.x, b.y+b.height-p.bottom, b.width, p.bottom); }
+
+/* Ttk_Fill --
+ * Fill the destination area of the drawable by replicating
+ * the source area of the image.
+ */
+static void Ttk_Fill(
+ Tk_Window tkwin, Drawable d, Tk_Image image, Ttk_Box src, Ttk_Box dst)
+{
+ int dr = dst.x + dst.width;
+ int db = dst.y + dst.height;
+ int x,y;
+
+ if (!(src.width && src.height && dst.width && dst.height))
+ return;
+
+ for (x = dst.x; x < dr; x += src.width) {
+ int cw = MIN(src.width, dr - x);
+ for (y = dst.y; y <= db; y += src.height) {
+ int ch = MIN(src.height, db - y);
+ Tk_RedrawImage(image, src.x, src.y, cw, ch, d, x, y);
+ }
+ }
+}
+
+/* Ttk_Stripe --
+ * Fill a horizontal stripe of the destination drawable.
+ */
+static void Ttk_Stripe(
+ Tk_Window tkwin, Drawable d, Tk_Image image,
+ Ttk_Box src, Ttk_Box dst, Ttk_Padding p)
+{
+ Ttk_Fill(tkwin, d, image, LPadding(src,p), LPadding(dst,p));
+ Ttk_Fill(tkwin, d, image, CPadding(src,p), CPadding(dst,p));
+ Ttk_Fill(tkwin, d, image, RPadding(src,p), RPadding(dst,p));
+}
+
+/* Ttk_Tile --
+ * Fill successive horizontal stripes of the destination drawable.
+ */
+static void Ttk_Tile(
+ Tk_Window tkwin, Drawable d, Tk_Image image,
+ Ttk_Box src, Ttk_Box dst, Ttk_Padding p)
+{
+ Ttk_Stripe(tkwin, d, image, TPadding(src,p), TPadding(dst,p), p);
+ Ttk_Stripe(tkwin, d, image, MPadding(src,p), MPadding(dst,p), p);
+ Ttk_Stripe(tkwin, d, image, BPadding(src,p), BPadding(dst,p), p);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Image element definition.
+ */
+
+typedef struct { /* ClientData for image elements */
+ Ttk_ImageSpec *imageSpec; /* Image(s) to use */
+ int minWidth; /* Minimum width; overrides image width */
+ int minHeight; /* Minimum width; overrides image width */
+ Ttk_Sticky sticky; /* -stickiness specification */
+ Ttk_Padding border; /* Fixed border region */
+ Ttk_Padding padding; /* Internal padding */
+
+#if TILE_07_COMPAT
+ Ttk_ResourceCache cache; /* Resource cache for images */
+ Ttk_StateMap imageMap; /* State-based lookup table for images */
+#endif
+} ImageData;
+
+static void FreeImageData(void *clientData)
+{
+ ImageData *imageData = clientData;
+ if (imageData->imageSpec) { TtkFreeImageSpec(imageData->imageSpec); }
+#if TILE_07_COMPAT
+ if (imageData->imageMap) { Tcl_DecrRefCount(imageData->imageMap); }
+#endif
+ ckfree(clientData);
+}
+
+static void ImageElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ ImageData *imageData = clientData;
+ Tk_Image image = imageData->imageSpec->baseImage;
+
+ if (image) {
+ Tk_SizeOfImage(image, widthPtr, heightPtr);
+ }
+ if (imageData->minWidth >= 0) {
+ *widthPtr = imageData->minWidth;
+ }
+ if (imageData->minHeight >= 0) {
+ *heightPtr = imageData->minHeight;
+ }
+
+ *paddingPtr = imageData->padding;
+}
+
+static void ImageElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ ImageData *imageData = clientData;
+ Tk_Image image = 0;
+ int imgWidth, imgHeight;
+ Ttk_Box src, dst;
+
+#if TILE_07_COMPAT
+ if (imageData->imageMap) {
+ Tcl_Obj *imageObj = Ttk_StateMapLookup(NULL,imageData->imageMap,state);
+ if (imageObj) {
+ image = Ttk_UseImage(imageData->cache, tkwin, imageObj);
+ }
+ }
+ if (!image) {
+ image = TtkSelectImage(imageData->imageSpec, state);
+ }
+#else
+ image = TtkSelectImage(imageData->imageSpec, state);
+#endif
+
+ if (!image) {
+ return;
+ }
+
+ Tk_SizeOfImage(image, &imgWidth, &imgHeight);
+ src = Ttk_MakeBox(0, 0, imgWidth, imgHeight);
+ dst = Ttk_StickBox(b, imgWidth, imgHeight, imageData->sticky);
+
+ Ttk_Tile(tkwin, d, image, src, dst, imageData->border);
+}
+
+static Ttk_ElementSpec ImageElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(NullElement),
+ TtkNullElementOptions,
+ ImageElementSize,
+ ImageElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Image element factory.
+ */
+static int
+Ttk_CreateImageElement(
+ Tcl_Interp *interp,
+ void *clientData,
+ Ttk_Theme theme,
+ const char *elementName,
+ int objc, Tcl_Obj *const objv[])
+{
+ static const char *optionStrings[] =
+ { "-border","-height","-padding","-sticky","-width",NULL };
+ enum { O_BORDER, O_HEIGHT, O_PADDING, O_STICKY, O_WIDTH };
+
+ Ttk_ImageSpec *imageSpec = 0;
+ ImageData *imageData = 0;
+ int padding_specified = 0;
+ int i;
+
+ if (objc <= 0) {
+ Tcl_AppendResult(interp, "Must supply a base image", NULL);
+ return TCL_ERROR;
+ }
+
+ imageSpec = TtkGetImageSpec(interp, Tk_MainWindow(interp), objv[0]);
+ if (!imageSpec) {
+ return TCL_ERROR;
+ }
+
+ imageData = (ImageData*)ckalloc(sizeof(*imageData));
+ imageData->imageSpec = imageSpec;
+ imageData->minWidth = imageData->minHeight = -1;
+ imageData->sticky = TTK_FILL_BOTH;
+ imageData->border = imageData->padding = Ttk_UniformPadding(0);
+#if TILE_07_COMPAT
+ imageData->cache = Ttk_GetResourceCache(interp);
+ imageData->imageMap = 0;
+#endif
+
+ for (i = 1; i < objc; i += 2) {
+ int option;
+
+ if (i == objc - 1) {
+ Tcl_AppendResult(interp,
+ "Value for ", Tcl_GetString(objv[i]), " missing",
+ NULL);
+ goto error;
+ }
+
+#if TILE_07_COMPAT
+ if (!strcmp("-map", Tcl_GetString(objv[i]))) {
+ imageData->imageMap = objv[i+1];
+ Tcl_IncrRefCount(imageData->imageMap);
+ continue;
+ }
+#endif
+
+ if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings,
+ "option", 0, &option) != TCL_OK) { goto error; }
+
+ switch (option) {
+ case O_BORDER:
+ if (Ttk_GetBorderFromObj(interp, objv[i+1], &imageData->border)
+ != TCL_OK) { goto error; }
+ if (!padding_specified) {
+ imageData->padding = imageData->border;
+ }
+ break;
+ case O_PADDING:
+ if (Ttk_GetBorderFromObj(interp, objv[i+1], &imageData->padding)
+ != TCL_OK) { goto error; }
+ padding_specified = 1;
+ break;
+ case O_WIDTH:
+ if (Tcl_GetIntFromObj(interp, objv[i+1], &imageData->minWidth)
+ != TCL_OK) { goto error; }
+ break;
+ case O_HEIGHT:
+ if (Tcl_GetIntFromObj(interp, objv[i+1], &imageData->minHeight)
+ != TCL_OK) { goto error; }
+ break;
+ case O_STICKY:
+ if (Ttk_GetStickyFromObj(interp, objv[i+1], &imageData->sticky)
+ != TCL_OK) { goto error; }
+ }
+ }
+
+ if (!Ttk_RegisterElement(interp, theme, elementName, &ImageElementSpec,
+ imageData))
+ {
+ goto error;
+ }
+
+ Ttk_RegisterCleanup(interp, imageData, FreeImageData);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(elementName, -1));
+ return TCL_OK;
+
+error:
+ FreeImageData(imageData);
+ return TCL_ERROR;
+}
+
+MODULE_SCOPE
+void TtkImage_Init(Tcl_Interp *interp)
+{
+ Ttk_RegisterElementFactory(interp, "image", Ttk_CreateImageElement, NULL);
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkInit.c b/generic/ttk/ttkInit.c
new file mode 100644
index 0000000..78676c6
--- /dev/null
+++ b/generic/ttk/ttkInit.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2003, Joe English
+ *
+ * Ttk package: initialization routine and miscellaneous utilities.
+ */
+
+#include <string.h>
+#include <tk.h>
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+/*
+ * Legal values for the button -default option.
+ * See also: enum Ttk_ButtonDefaultState.
+ */
+const char *ttkDefaultStrings[] = {
+ "normal", "active", "disabled", NULL
+};
+
+int Ttk_GetButtonDefaultStateFromObj(
+ Tcl_Interp *interp, Tcl_Obj *objPtr, int *statePtr)
+{
+ *statePtr = TTK_BUTTON_DEFAULT_DISABLED;
+ return Tcl_GetIndexFromObj(interp, objPtr,
+ ttkDefaultStrings, "default state", 0, statePtr);
+}
+
+/*
+ * Legal values for the -compound option.
+ * See also: enum Ttk_Compound.
+ */
+const char *ttkCompoundStrings[] = {
+ "none", "text", "image", "center",
+ "top", "bottom", "left", "right", NULL
+};
+
+int Ttk_GetCompoundFromObj(
+ Tcl_Interp *interp, Tcl_Obj *objPtr, int *statePtr)
+{
+ *statePtr = TTK_COMPOUND_NONE;
+ return Tcl_GetIndexFromObj(interp, objPtr,
+ ttkCompoundStrings, "compound layout", 0, statePtr);
+}
+
+/*
+ * Legal values for the -orient option.
+ * See also: enum Ttk_Orient.
+ */
+const char *ttkOrientStrings[] = {
+ "horizontal", "vertical", NULL
+};
+
+int Ttk_GetOrientFromObj(
+ Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr)
+{
+ *resultPtr = TTK_ORIENT_HORIZONTAL;
+ return Tcl_GetIndexFromObj(interp, objPtr,
+ ttkOrientStrings, "orientation", 0, resultPtr);
+}
+
+/*
+ * Recognized values for the -state compatibility option.
+ * Other options are accepted and interpreted as synonyms for "normal".
+ */
+static const char *ttkStateStrings[] = {
+ "normal", "readonly", "disabled", "active", NULL
+};
+enum {
+ TTK_COMPAT_STATE_NORMAL,
+ TTK_COMPAT_STATE_READONLY,
+ TTK_COMPAT_STATE_DISABLED,
+ TTK_COMPAT_STATE_ACTIVE
+};
+
+/* TtkCheckStateOption --
+ * Handle -state compatibility option.
+ *
+ * NOTE: setting -state disabled / -state enabled affects the
+ * widget state, but the internal widget state does *not* affect
+ * the value of the -state option.
+ * This option is present for compatibility only.
+ */
+void TtkCheckStateOption(WidgetCore *corePtr, Tcl_Obj *objPtr)
+{
+ int stateOption = TTK_COMPAT_STATE_NORMAL;
+ unsigned all = TTK_STATE_DISABLED|TTK_STATE_READONLY|TTK_STATE_ACTIVE;
+# define SETFLAGS(f) TtkWidgetChangeState(corePtr, f, all^f)
+
+ (void)Tcl_GetIndexFromObj(NULL,objPtr,ttkStateStrings,"",0,&stateOption);
+ switch (stateOption) {
+ case TTK_COMPAT_STATE_NORMAL:
+ default:
+ SETFLAGS(0);
+ break;
+ case TTK_COMPAT_STATE_READONLY:
+ SETFLAGS(TTK_STATE_READONLY);
+ break;
+ case TTK_COMPAT_STATE_DISABLED:
+ SETFLAGS(TTK_STATE_DISABLED);
+ break;
+ case TTK_COMPAT_STATE_ACTIVE:
+ SETFLAGS(TTK_STATE_ACTIVE);
+ break;
+ }
+# undef SETFLAGS
+}
+
+/* TtkSendVirtualEvent --
+ * Send a virtual event notification to the specified target window.
+ * Equivalent to "event generate $tgtWindow <<$eventName>>"
+ *
+ * Note that we use Tk_QueueWindowEvent, not Tk_HandleEvent,
+ * so this routine does not reenter the interpreter.
+ */
+void TtkSendVirtualEvent(Tk_Window tgtWin, const char *eventName)
+{
+ union {XEvent general; XVirtualEvent virtual;} event;
+
+ memset(&event, 0, sizeof(event));
+ event.general.xany.type = VirtualEvent;
+ event.general.xany.serial = NextRequest(Tk_Display(tgtWin));
+ event.general.xany.send_event = False;
+ event.general.xany.window = Tk_WindowId(tgtWin);
+ event.general.xany.display = Tk_Display(tgtWin);
+ event.virtual.name = Tk_GetUid(eventName);
+
+ Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
+}
+
+/* TtkEnumerateOptions, TtkGetOptionValue --
+ * Common factors for data accessor commands.
+ */
+int TtkEnumerateOptions(
+ Tcl_Interp *interp, void *recordPtr, const Tk_OptionSpec *specPtr,
+ Tk_OptionTable optionTable, Tk_Window tkwin)
+{
+ Tcl_Obj *result = Tcl_NewListObj(0,0);
+ while (specPtr->type != TK_OPTION_END)
+ {
+ Tcl_Obj *optionName = Tcl_NewStringObj(specPtr->optionName, -1);
+ Tcl_Obj *optionValue =
+ Tk_GetOptionValue(interp,recordPtr,optionTable,optionName,tkwin);
+ if (optionValue) {
+ Tcl_ListObjAppendElement(interp, result, optionName);
+ Tcl_ListObjAppendElement(interp, result, optionValue);
+ }
+ ++specPtr;
+
+ if (specPtr->type == TK_OPTION_END && specPtr->clientData != NULL) {
+ /* Chain to next option spec array: */
+ specPtr = specPtr->clientData;
+ }
+ }
+ Tcl_SetObjResult(interp, result);
+ return TCL_OK;
+}
+
+int TtkGetOptionValue(
+ Tcl_Interp *interp, void *recordPtr, Tcl_Obj *optionName,
+ Tk_OptionTable optionTable, Tk_Window tkwin)
+{
+ Tcl_Obj *result =
+ Tk_GetOptionValue(interp,recordPtr,optionTable,optionName,tkwin);
+ if (result) {
+ Tcl_SetObjResult(interp, result);
+ return TCL_OK;
+ }
+ return TCL_ERROR;
+}
+
+
+/*------------------------------------------------------------------------
+ * Core Option specifications:
+ * type name dbName dbClass default objOffset intOffset flags clientData mask
+ */
+
+/* public */
+Tk_OptionSpec ttkCoreOptionSpecs[] =
+{
+ {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", NULL,
+ Tk_Offset(WidgetCore, cursorObj), -1, TK_OPTION_NULL_OK,0,0 },
+ {TK_OPTION_STRING, "-style", "style", "Style", "",
+ Tk_Offset(WidgetCore,styleObj), -1, 0,0,STYLE_CHANGED},
+ {TK_OPTION_STRING, "-class", "", "", NULL,
+ Tk_Offset(WidgetCore,classObj), -1, 0,0,READONLY_OPTION},
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
+};
+
+/*------------------------------------------------------------------------
+ * +++ Initialization: elements and element factories.
+ */
+
+extern void TtkElements_Init(Tcl_Interp *);
+extern void TtkLabel_Init(Tcl_Interp *);
+extern void TtkImage_Init(Tcl_Interp *);
+
+static void RegisterElements(Tcl_Interp *interp)
+{
+ TtkElements_Init(interp);
+ TtkLabel_Init(interp);
+ TtkImage_Init(interp);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Initialization: Widget definitions.
+ */
+
+extern void TtkButton_Init(Tcl_Interp *);
+extern void TtkEntry_Init(Tcl_Interp *);
+extern void TtkFrame_Init(Tcl_Interp *);
+extern void TtkNotebook_Init(Tcl_Interp *);
+extern void TtkPanedwindow_Init(Tcl_Interp *);
+extern void TtkProgressbar_Init(Tcl_Interp *);
+extern void TtkScale_Init(Tcl_Interp *);
+extern void TtkScrollbar_Init(Tcl_Interp *);
+extern void TtkSeparator_Init(Tcl_Interp *);
+extern void TtkTreeview_Init(Tcl_Interp *);
+
+#ifdef TTK_SQUARE_WIDGET
+extern int TtkSquareWidget_Init(Tcl_Interp *);
+#endif
+
+static void RegisterWidgets(Tcl_Interp *interp)
+{
+ TtkButton_Init(interp);
+ TtkEntry_Init(interp);
+ TtkFrame_Init(interp);
+ TtkNotebook_Init(interp);
+ TtkPanedwindow_Init(interp);
+ TtkProgressbar_Init(interp);
+ TtkScale_Init(interp);
+ TtkScrollbar_Init(interp);
+ TtkSeparator_Init(interp);
+ TtkTreeview_Init(interp);
+#ifdef TTK_SQUARE_WIDGET
+ TtkSquareWidget_Init(interp);
+#endif
+}
+
+/*------------------------------------------------------------------------
+ * +++ Initialization: Built-in themes.
+ */
+
+extern int TtkAltTheme_Init(Tcl_Interp *);
+extern int TtkClassicTheme_Init(Tcl_Interp *);
+extern int TtkClamTheme_Init(Tcl_Interp *);
+
+static void RegisterThemes(Tcl_Interp *interp)
+{
+
+ TtkAltTheme_Init(interp);
+ TtkClassicTheme_Init(interp);
+ TtkClamTheme_Init(interp);
+}
+
+/*
+ * Ttk initialization.
+ */
+
+extern const TtkStubs ttkStubs;
+
+MODULE_SCOPE int
+Ttk_Init(Tcl_Interp *interp)
+{
+ /*
+ * This will be run for both safe and regular interp init.
+ * Use Tcl_IsSafe if necessary to not initialize unsafe bits.
+ */
+ Ttk_StylePkgInit(interp);
+
+ RegisterElements(interp);
+ RegisterWidgets(interp);
+ RegisterThemes(interp);
+
+ Ttk_PlatformInit(interp);
+
+ Tcl_PkgProvideEx(interp, "Ttk", TTK_PATCH_LEVEL, (ClientData)&ttkStubs);
+
+ return TCL_OK;
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkLabel.c b/generic/ttk/ttkLabel.c
new file mode 100644
index 0000000..597682f
--- /dev/null
+++ b/generic/ttk/ttkLabel.c
@@ -0,0 +1,693 @@
+/*
+ * text, image, and label elements.
+ *
+ * The label element combines text and image elements,
+ * with layout determined by the "-compound" option.
+ *
+ */
+
+#include <tcl.h>
+#include <tkInt.h>
+#include "ttkTheme.h"
+
+/*----------------------------------------------------------------------
+ * +++ Text element.
+ *
+ * This element displays a textual label in the foreground color.
+ *
+ * Optionally underlines the mnemonic character if the -underline resource
+ * is present and >= 0.
+ */
+
+typedef struct {
+ /*
+ * Element options:
+ */
+ Tcl_Obj *textObj;
+ Tcl_Obj *fontObj;
+ Tcl_Obj *foregroundObj;
+ Tcl_Obj *underlineObj;
+ Tcl_Obj *widthObj;
+ Tcl_Obj *anchorObj;
+ Tcl_Obj *justifyObj;
+ Tcl_Obj *wrapLengthObj;
+ Tcl_Obj *embossedObj;
+
+ /*
+ * Computed resources:
+ */
+ Tk_Font tkfont;
+ Tk_TextLayout textLayout;
+ int width;
+ int height;
+ int embossed;
+
+} TextElement;
+
+/* Text element options table.
+ * NB: Keep in sync with label element option table.
+ */
+static Ttk_ElementOptionSpec TextElementOptions[] = {
+ { "-text", TK_OPTION_STRING,
+ Tk_Offset(TextElement,textObj), "" },
+ { "-font", TK_OPTION_FONT,
+ Tk_Offset(TextElement,fontObj), DEFAULT_FONT },
+ { "-foreground", TK_OPTION_COLOR,
+ Tk_Offset(TextElement,foregroundObj), "black" },
+ { "-underline", TK_OPTION_INT,
+ Tk_Offset(TextElement,underlineObj), "-1"},
+ { "-width", TK_OPTION_INT,
+ Tk_Offset(TextElement,widthObj), "-1"},
+ { "-anchor", TK_OPTION_ANCHOR,
+ Tk_Offset(TextElement,anchorObj), "w"},
+ { "-justify", TK_OPTION_JUSTIFY,
+ Tk_Offset(TextElement,justifyObj), "left" },
+ { "-wraplength", TK_OPTION_PIXELS,
+ Tk_Offset(TextElement,wrapLengthObj), "0" },
+ { "-embossed", TK_OPTION_INT,
+ Tk_Offset(TextElement,embossedObj), "0"},
+ { NULL, 0, 0, NULL }
+};
+
+static int TextSetup(TextElement *text, Tk_Window tkwin)
+{
+ const char *string = Tcl_GetString(text->textObj);
+ Tk_Justify justify = TK_JUSTIFY_LEFT;
+ int wrapLength = 0;
+
+ text->tkfont = Tk_GetFontFromObj(tkwin, text->fontObj);
+ Tk_GetJustifyFromObj(NULL, text->justifyObj, &justify);
+ Tk_GetPixelsFromObj(NULL, tkwin, text->wrapLengthObj, &wrapLength);
+ Tcl_GetBooleanFromObj(NULL, text->embossedObj, &text->embossed);
+
+ text->textLayout = Tk_ComputeTextLayout(
+ text->tkfont, string, -1/*numChars*/, wrapLength, justify,
+ 0/*flags*/, &text->width, &text->height);
+
+ return 1;
+}
+
+/*
+ * TextReqWidth -- compute the requested width of a text element.
+ *
+ * If -width is positive, use that as the width
+ * If -width is negative, use that as the minimum width
+ * If not specified or empty, use the natural size of the text
+ */
+
+static int TextReqWidth(TextElement *text)
+{
+ int reqWidth;
+
+ if ( text->widthObj
+ && Tcl_GetIntFromObj(NULL, text->widthObj, &reqWidth) == TCL_OK)
+ {
+ int avgWidth = Tk_TextWidth(text->tkfont, "0", 1);
+ if (reqWidth <= 0) {
+ int specWidth = avgWidth * -reqWidth;
+ if (specWidth > text->width)
+ return specWidth;
+ } else {
+ return avgWidth * reqWidth;
+ }
+ }
+ return text->width;
+}
+
+static void TextCleanup(TextElement *text)
+{
+ Tk_FreeTextLayout(text->textLayout);
+}
+
+/*
+ * TextDraw --
+ * Draw a text element.
+ * Called by TextElementDraw() and LabelElementDraw().
+ */
+static void TextDraw(TextElement *text, Tk_Window tkwin, Drawable d, Ttk_Box b)
+{
+ XColor *color = Tk_GetColorFromObj(tkwin, text->foregroundObj);
+ int underline = -1;
+ XGCValues gcValues;
+ GC gc1, gc2;
+ Tk_Anchor anchor = TK_ANCHOR_CENTER;
+ TkRegion clipRegion = NULL;
+
+ gcValues.font = Tk_FontId(text->tkfont);
+ gcValues.foreground = color->pixel;
+ gc1 = Tk_GetGC(tkwin, GCFont | GCForeground, &gcValues);
+ gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin));
+ gc2 = Tk_GetGC(tkwin, GCFont | GCForeground, &gcValues);
+
+ /*
+ * Place text according to -anchor:
+ */
+ Tk_GetAnchorFromObj(NULL, text->anchorObj, &anchor);
+ b = Ttk_AnchorBox(b, text->width, text->height, anchor);
+
+ /*
+ * Clip text if it's too wide:
+ */
+ if (b.width < text->width) {
+ XRectangle rect;
+
+ clipRegion = TkCreateRegion();
+ rect.x = b.x;
+ rect.y = b.y;
+ rect.width = b.width + (text->embossed ? 1 : 0);
+ rect.height = b.height + (text->embossed ? 1 : 0);
+ TkUnionRectWithRegion(&rect, clipRegion, clipRegion);
+ TkSetRegion(Tk_Display(tkwin), gc1, clipRegion);
+ TkSetRegion(Tk_Display(tkwin), gc2, clipRegion);
+#ifdef HAVE_XFT
+ TkUnixSetXftClipRegion(clipRegion);
+#endif
+ }
+
+ if (text->embossed) {
+ Tk_DrawTextLayout(Tk_Display(tkwin), d, gc2,
+ text->textLayout, b.x+1, b.y+1, 0/*firstChar*/, -1/*lastChar*/);
+ }
+ Tk_DrawTextLayout(Tk_Display(tkwin), d, gc1,
+ text->textLayout, b.x, b.y, 0/*firstChar*/, -1/*lastChar*/);
+
+ Tcl_GetIntFromObj(NULL, text->underlineObj, &underline);
+ if (underline >= 0) {
+ if (text->embossed) {
+ Tk_UnderlineTextLayout(Tk_Display(tkwin), d, gc2,
+ text->textLayout, b.x+1, b.y+1, underline);
+ }
+ Tk_UnderlineTextLayout(Tk_Display(tkwin), d, gc1,
+ text->textLayout, b.x, b.y, underline);
+ }
+
+ if (clipRegion != NULL) {
+#ifdef HAVE_XFT
+ TkUnixSetXftClipRegion(None);
+#endif
+ XSetClipMask(Tk_Display(tkwin), gc1, None);
+ XSetClipMask(Tk_Display(tkwin), gc2, None);
+ TkDestroyRegion(clipRegion);
+ }
+ Tk_FreeGC(Tk_Display(tkwin), gc1);
+ Tk_FreeGC(Tk_Display(tkwin), gc2);
+}
+
+static void TextElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ TextElement *text = elementRecord;
+
+ if (!TextSetup(text, tkwin))
+ return;
+
+ *heightPtr = text->height;
+ *widthPtr = TextReqWidth(text);
+
+ TextCleanup(text);
+
+ return;
+}
+
+static void TextElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, Ttk_State state)
+{
+ TextElement *text = elementRecord;
+ if (TextSetup(text, tkwin)) {
+ TextDraw(text, tkwin, d, b);
+ TextCleanup(text);
+ }
+}
+
+static Ttk_ElementSpec TextElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(TextElement),
+ TextElementOptions,
+ TextElementSize,
+ TextElementDraw
+};
+
+/*----------------------------------------------------------------------
+ * +++ Image element.
+ * Draws an image.
+ */
+
+typedef struct {
+ Tcl_Obj *imageObj;
+ Tcl_Obj *stippleObj; /* For TTK_STATE_DISABLED */
+ Tcl_Obj *backgroundObj; /* " " */
+
+ Ttk_ImageSpec *imageSpec;
+ Tk_Image tkimg;
+ int width;
+ int height;
+} ImageElement;
+
+/* ===> NB: Keep in sync with label element option table. <===
+ */
+static Ttk_ElementOptionSpec ImageElementOptions[] = {
+ { "-image", TK_OPTION_STRING,
+ Tk_Offset(ImageElement,imageObj), "" },
+ { "-stipple", TK_OPTION_STRING, /* Really: TK_OPTION_BITMAP */
+ Tk_Offset(ImageElement,stippleObj), "gray50" },
+ { "-background", TK_OPTION_COLOR,
+ Tk_Offset(ImageElement,backgroundObj), DEFAULT_BACKGROUND },
+ { NULL, 0, 0, NULL }
+};
+
+/*
+ * ImageSetup() --
+ * Look up the Tk_Image from the image element's imageObj resource.
+ * Caller must release the image with ImageCleanup().
+ *
+ * Returns:
+ * 1 if successful, 0 if there was an error (unreported)
+ * or the image resource was not specified.
+ */
+
+static int ImageSetup(
+ ImageElement *image, Tk_Window tkwin, Ttk_State state)
+{
+
+ if (!image->imageObj) {
+ return 0;
+ }
+ image->imageSpec = TtkGetImageSpec(NULL, tkwin, image->imageObj);
+ if (!image->imageSpec) {
+ return 0;
+ }
+ image->tkimg = TtkSelectImage(image->imageSpec, state);
+ if (!image->tkimg) {
+ TtkFreeImageSpec(image->imageSpec);
+ return 0;
+ }
+ Tk_SizeOfImage(image->tkimg, &image->width, &image->height);
+
+ return 1;
+}
+
+static void ImageCleanup(ImageElement *image)
+{
+ TtkFreeImageSpec(image->imageSpec);
+}
+
+/*
+ * StippleOver --
+ * Draw a stipple over the image area, to make it look "grayed-out"
+ * when TTK_STATE_DISABLED is set.
+ */
+static void StippleOver(
+ ImageElement *image, Tk_Window tkwin, Drawable d, int x, int y)
+{
+ Pixmap stipple = Tk_AllocBitmapFromObj(NULL, tkwin, image->stippleObj);
+ XColor *color = Tk_GetColorFromObj(tkwin, image->backgroundObj);
+
+ if (stipple != None) {
+ unsigned long mask = GCFillStyle | GCStipple | GCForeground;
+ XGCValues gcvalues;
+ GC gc;
+ gcvalues.foreground = color->pixel;
+ gcvalues.fill_style = FillStippled;
+ gcvalues.stipple = stipple;
+ gc = Tk_GetGC(tkwin, mask, &gcvalues);
+ XFillRectangle(Tk_Display(tkwin),d,gc,x,y,image->width,image->height);
+ Tk_FreeGC(Tk_Display(tkwin), gc);
+ Tk_FreeBitmapFromObj(tkwin, image->stippleObj);
+ }
+}
+
+static void ImageDraw(
+ ImageElement *image, Tk_Window tkwin,Drawable d,Ttk_Box b,Ttk_State state)
+{
+ int width = image->width, height = image->height;
+
+ /* Clip width and height to remain within window bounds:
+ */
+ if (b.x + width > Tk_Width(tkwin)) {
+ width = Tk_Width(tkwin) - b.x;
+ }
+ if (b.y + height > Tk_Height(tkwin)) {
+ height = Tk_Height(tkwin) - b.y;
+ }
+
+ if (height <= 0 || width <= 0) {
+ /* Completely clipped - bail out.
+ */
+ return;
+ }
+
+ Tk_RedrawImage(image->tkimg, 0,0, width, height, d, b.x, b.y);
+
+ /* If we're disabled there's no state-specific 'disabled' image,
+ * stipple the image.
+ * @@@ Possibly: Don't do disabled-stippling at all;
+ * @@@ it's ugly and out of fashion.
+ * Do not stipple at all under Aqua, just draw the image: it shows up
+ * as a white rectangle otherwise.
+ */
+ if (state & TTK_STATE_DISABLED) {
+ if (TtkSelectImage(image->imageSpec, 0ul) == image->tkimg) {
+#ifndef MAC_OSX_TK
+ StippleOver(image, tkwin, d, b.x,b.y);
+#endif
+ }
+ }
+}
+
+static void ImageElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ ImageElement *image = elementRecord;
+
+ if (ImageSetup(image, tkwin, 0)) {
+ *widthPtr = image->width;
+ *heightPtr = image->height;
+ ImageCleanup(image);
+ }
+}
+
+static void ImageElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, Ttk_State state)
+{
+ ImageElement *image = elementRecord;
+
+ if (ImageSetup(image, tkwin, state)) {
+ ImageDraw(image, tkwin, d, b, state);
+ ImageCleanup(image);
+ }
+}
+
+static Ttk_ElementSpec ImageElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(ImageElement),
+ ImageElementOptions,
+ ImageElementSize,
+ ImageElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Label element.
+ *
+ * Displays an image and/or text, as determined by the -compound option.
+ *
+ * Differences from Tk 8.4 compound elements:
+ *
+ * This adds two new values for the -compound option, "text"
+ * and "image". (This is useful for configuring toolbars to
+ * display icons, text and icons, or text only, as found in
+ * many browsers.)
+ *
+ * "-compound none" is supported, but I'd like to get rid of it;
+ * it makes the logic more complex, and the only benefit is
+ * backwards compatibility with Tk < 8.3.0 scripts.
+ *
+ * This adds a new resource, -space, for determining how much
+ * space to leave between the text and image; Tk 8.4 reuses the
+ * -padx or -pady option for this purpose.
+ *
+ * -width always specifies the length in characters of the text part;
+ * in Tk 8.4 it's either characters or pixels, depending on the
+ * value of -compound.
+ *
+ * Negative values of -width are interpreted as a minimum width
+ * on all platforms, not just on Windows.
+ *
+ * Tk 8.4 ignores -padx and -pady if -compound is set to "none".
+ * Here, padding is handled by a different element.
+ */
+
+typedef struct {
+ /*
+ * Element options:
+ */
+ Tcl_Obj *compoundObj;
+ Tcl_Obj *spaceObj;
+ TextElement text;
+ ImageElement image;
+
+ /*
+ * Computed values (see LabelSetup)
+ */
+ Ttk_Compound compound;
+ int space;
+ int totalWidth, totalHeight;
+} LabelElement;
+
+static Ttk_ElementOptionSpec LabelElementOptions[] = {
+ { "-compound", TK_OPTION_ANY,
+ Tk_Offset(LabelElement,compoundObj), "none" },
+ { "-space", TK_OPTION_PIXELS,
+ Tk_Offset(LabelElement,spaceObj), "4" },
+
+ /* Text element part:
+ * NB: Keep in sync with TextElementOptions.
+ */
+ { "-text", TK_OPTION_STRING,
+ Tk_Offset(LabelElement,text.textObj), "" },
+ { "-font", TK_OPTION_FONT,
+ Tk_Offset(LabelElement,text.fontObj), DEFAULT_FONT },
+ { "-foreground", TK_OPTION_COLOR,
+ Tk_Offset(LabelElement,text.foregroundObj), "black" },
+ { "-underline", TK_OPTION_INT,
+ Tk_Offset(LabelElement,text.underlineObj), "-1"},
+ { "-width", TK_OPTION_INT,
+ Tk_Offset(LabelElement,text.widthObj), ""},
+ { "-anchor", TK_OPTION_ANCHOR,
+ Tk_Offset(LabelElement,text.anchorObj), "w"},
+ { "-justify", TK_OPTION_JUSTIFY,
+ Tk_Offset(LabelElement,text.justifyObj), "left" },
+ { "-wraplength", TK_OPTION_PIXELS,
+ Tk_Offset(LabelElement,text.wrapLengthObj), "0" },
+ { "-embossed", TK_OPTION_INT,
+ Tk_Offset(LabelElement,text.embossedObj), "0"},
+
+ /* Image element part:
+ * NB: Keep in sync with ImageElementOptions.
+ */
+ { "-image", TK_OPTION_STRING,
+ Tk_Offset(LabelElement,image.imageObj), "" },
+ { "-stipple", TK_OPTION_STRING, /* Really: TK_OPTION_BITMAP */
+ Tk_Offset(LabelElement,image.stippleObj), "gray50" },
+ { "-background", TK_OPTION_COLOR,
+ Tk_Offset(LabelElement,image.backgroundObj), DEFAULT_BACKGROUND },
+ { NULL, 0, 0, NULL }
+};
+
+/*
+ * LabelSetup --
+ * Fills in computed fields of the label element.
+ *
+ * Calculate the text, image, and total width and height.
+ */
+
+#define MAX(a,b) ((a) > (b) ? a : b);
+static void LabelSetup(
+ LabelElement *c, Tk_Window tkwin, Ttk_State state)
+{
+ Ttk_Compound *compoundPtr = &c->compound;
+
+ Tk_GetPixelsFromObj(NULL,tkwin,c->spaceObj,&c->space);
+ Ttk_GetCompoundFromObj(NULL,c->compoundObj,(int*)compoundPtr);
+
+ /*
+ * Deal with TTK_COMPOUND_NONE.
+ */
+ if (c->compound == TTK_COMPOUND_NONE) {
+ if (ImageSetup(&c->image, tkwin, state)) {
+ c->compound = TTK_COMPOUND_IMAGE;
+ } else {
+ c->compound = TTK_COMPOUND_TEXT;
+ }
+ } else if (c->compound != TTK_COMPOUND_TEXT) {
+ if (!ImageSetup(&c->image, tkwin, state)) {
+ c->compound = TTK_COMPOUND_TEXT;
+ }
+ }
+ if (c->compound != TTK_COMPOUND_IMAGE)
+ TextSetup(&c->text, tkwin);
+
+ /*
+ * ASSERT:
+ * if c->compound != IMAGE, then TextSetup() has been called
+ * if c->compound != TEXT, then ImageSetup() has returned successfully
+ * c->compound != COMPOUND_NONE.
+ */
+
+ switch (c->compound)
+ {
+ case TTK_COMPOUND_NONE:
+ /* Can't happen */
+ break;
+ case TTK_COMPOUND_TEXT:
+ c->totalWidth = c->text.width;
+ c->totalHeight = c->text.height;
+ break;
+ case TTK_COMPOUND_IMAGE:
+ c->totalWidth = c->image.width;
+ c->totalHeight = c->image.height;
+ break;
+ case TTK_COMPOUND_CENTER:
+ c->totalWidth = MAX(c->image.width, c->text.width);
+ c->totalHeight = MAX(c->image.height, c->text.height);
+ break;
+ case TTK_COMPOUND_TOP:
+ case TTK_COMPOUND_BOTTOM:
+ c->totalWidth = MAX(c->image.width, c->text.width);
+ c->totalHeight = c->image.height + c->text.height + c->space;
+ break;
+
+ case TTK_COMPOUND_LEFT:
+ case TTK_COMPOUND_RIGHT:
+ c->totalWidth = c->image.width + c->text.width + c->space;
+ c->totalHeight = MAX(c->image.height, c->text.height);
+ break;
+ }
+}
+
+static void LabelCleanup(LabelElement *c)
+{
+ if (c->compound != TTK_COMPOUND_TEXT)
+ ImageCleanup(&c->image);
+ if (c->compound != TTK_COMPOUND_IMAGE)
+ TextCleanup(&c->text);
+}
+
+static void LabelElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ LabelElement *label = elementRecord;
+ int textReqWidth = 0;
+
+ LabelSetup(label, tkwin, 0);
+
+ *heightPtr = label->totalHeight;
+
+ /* Requested width based on -width option, not actual text width:
+ */
+ if (label->compound != TTK_COMPOUND_IMAGE)
+ textReqWidth = TextReqWidth(&label->text);
+
+ switch (label->compound)
+ {
+ case TTK_COMPOUND_TEXT:
+ *widthPtr = textReqWidth;
+ break;
+ case TTK_COMPOUND_IMAGE:
+ *widthPtr = label->image.width;
+ break;
+ case TTK_COMPOUND_TOP:
+ case TTK_COMPOUND_BOTTOM:
+ case TTK_COMPOUND_CENTER:
+ *widthPtr = MAX(label->image.width, textReqWidth);
+ break;
+ case TTK_COMPOUND_LEFT:
+ case TTK_COMPOUND_RIGHT:
+ *widthPtr = label->image.width + textReqWidth + label->space;
+ break;
+ case TTK_COMPOUND_NONE:
+ break; /* Can't happen */
+ }
+
+ LabelCleanup(label);
+}
+
+/*
+ * DrawCompound --
+ * Helper routine for LabelElementDraw;
+ * Handles layout for -compound {left,right,top,bottom}
+ */
+static void DrawCompound(
+ LabelElement *l, Ttk_Box b, Tk_Window tkwin, Drawable d, Ttk_State state,
+ int imageSide, int textSide)
+{
+ Ttk_Box imageBox =
+ Ttk_PlaceBox(&b, l->image.width, l->image.height, imageSide, 0);
+ Ttk_Box textBox =
+ Ttk_PlaceBox(&b, l->text.width, l->text.height, textSide, 0);
+ ImageDraw(&l->image,tkwin,d,imageBox,state);
+ TextDraw(&l->text,tkwin,d,textBox);
+}
+
+static void LabelElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, Ttk_State state)
+{
+ LabelElement *l = elementRecord;
+ Tk_Anchor anchor = TK_ANCHOR_CENTER;
+
+ LabelSetup(l, tkwin, state);
+
+ /*
+ * Adjust overall parcel based on -anchor:
+ */
+ Tk_GetAnchorFromObj(NULL, l->text.anchorObj, &anchor);
+ b = Ttk_AnchorBox(b, l->totalWidth, l->totalHeight, anchor);
+
+ /*
+ * Draw text and/or image parts based on -compound:
+ */
+ switch (l->compound)
+ {
+ case TTK_COMPOUND_NONE:
+ /* Can't happen */
+ break;
+ case TTK_COMPOUND_TEXT:
+ TextDraw(&l->text,tkwin,d,b);
+ break;
+ case TTK_COMPOUND_IMAGE:
+ ImageDraw(&l->image,tkwin,d,b,state);
+ break;
+ case TTK_COMPOUND_CENTER:
+ {
+ Ttk_Box pb = Ttk_AnchorBox(
+ b, l->image.width, l->image.height, TK_ANCHOR_CENTER);
+ ImageDraw(&l->image, tkwin, d, pb, state);
+ pb = Ttk_AnchorBox(
+ b, l->text.width, l->text.height, TK_ANCHOR_CENTER);
+ TextDraw(&l->text, tkwin, d, pb);
+ break;
+ }
+ case TTK_COMPOUND_TOP:
+ DrawCompound(l, b, tkwin, d, state, TTK_SIDE_TOP, TTK_SIDE_BOTTOM);
+ break;
+ case TTK_COMPOUND_BOTTOM:
+ DrawCompound(l, b, tkwin, d, state, TTK_SIDE_BOTTOM, TTK_SIDE_TOP);
+ break;
+ case TTK_COMPOUND_LEFT:
+ DrawCompound(l, b, tkwin, d, state, TTK_SIDE_LEFT, TTK_SIDE_RIGHT);
+ break;
+ case TTK_COMPOUND_RIGHT:
+ DrawCompound(l, b, tkwin, d, state, TTK_SIDE_RIGHT, TTK_SIDE_LEFT);
+ break;
+ }
+
+ LabelCleanup(l);
+}
+
+static Ttk_ElementSpec LabelElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(LabelElement),
+ LabelElementOptions,
+ LabelElementSize,
+ LabelElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Initialization.
+ */
+
+MODULE_SCOPE
+void TtkLabel_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme theme = Ttk_GetDefaultTheme(interp);
+
+ Ttk_RegisterElement(interp, theme, "text", &TextElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "image", &ImageElementSpec, NULL);
+ Ttk_RegisterElement(interp, theme, "label", &LabelElementSpec, NULL);
+}
+
diff --git a/generic/ttk/ttkLayout.c b/generic/ttk/ttkLayout.c
new file mode 100644
index 0000000..58c99eb
--- /dev/null
+++ b/generic/ttk/ttkLayout.c
@@ -0,0 +1,1252 @@
+/*
+ * ttkLayout.c --
+ *
+ * Generic layout processing.
+ *
+ * Copyright (c) 2003 Joe English. Freely redistributable.
+ */
+
+#include <string.h>
+#include <tk.h>
+#include "ttkThemeInt.h"
+
+#define MAX(a,b) (a > b ? a : b)
+#define MIN(a,b) (a < b ? a : b)
+
+/*------------------------------------------------------------------------
+ * +++ Ttk_Box and Ttk_Padding utilities:
+ */
+
+Ttk_Box
+Ttk_MakeBox(int x, int y, int width, int height)
+{
+ Ttk_Box b;
+ b.x = x; b.y = y; b.width = width; b.height = height;
+ return b;
+}
+
+int
+Ttk_BoxContains(Ttk_Box box, int x, int y)
+{
+ return box.x <= x && x < box.x + box.width
+ && box.y <= y && y < box.y + box.height;
+}
+
+Tcl_Obj *
+Ttk_NewBoxObj(Ttk_Box box)
+{
+ Tcl_Obj *result[4];
+
+ result[0] = Tcl_NewIntObj(box.x);
+ result[1] = Tcl_NewIntObj(box.y);
+ result[2] = Tcl_NewIntObj(box.width);
+ result[3] = Tcl_NewIntObj(box.height);
+
+ return Tcl_NewListObj(4, result);
+}
+
+/*
+ * packTop, packBottom, packLeft, packRight --
+ * Carve out a parcel of the specified height (resp width)
+ * from the specified cavity.
+ *
+ * Returns:
+ * The new parcel.
+ *
+ * Side effects:
+ * Adjust the cavity.
+ */
+
+static Ttk_Box packTop(Ttk_Box *cavity, int height)
+{
+ Ttk_Box parcel;
+ height = MIN(height, cavity->height);
+ parcel = Ttk_MakeBox(cavity->x, cavity->y, cavity->width, height);
+ cavity->y += height;
+ cavity->height -= height;
+ return parcel;
+}
+
+static Ttk_Box packBottom(Ttk_Box *cavity, int height)
+{
+ height = MIN(height, cavity->height);
+ cavity->height -= height;
+ return Ttk_MakeBox(
+ cavity->x, cavity->y + cavity->height,
+ cavity->width, height);
+}
+
+static Ttk_Box packLeft(Ttk_Box *cavity, int width)
+{
+ Ttk_Box parcel;
+ width = MIN(width, cavity->width);
+ parcel = Ttk_MakeBox(cavity->x, cavity->y, width,cavity->height);
+ cavity->x += width;
+ cavity->width -= width;
+ return parcel;
+}
+
+static Ttk_Box packRight(Ttk_Box *cavity, int width)
+{
+ width = MIN(width, cavity->width);
+ cavity->width -= width;
+ return Ttk_MakeBox(cavity->x + cavity->width,
+ cavity->y, width, cavity->height);
+}
+
+/*
+ * Ttk_PackBox --
+ * Carve out a parcel of the specified size on the specified side
+ * in the specified cavity.
+ *
+ * Returns:
+ * The new parcel.
+ *
+ * Side effects:
+ * Adjust the cavity.
+ */
+
+Ttk_Box Ttk_PackBox(Ttk_Box *cavity, int width, int height, Ttk_Side side)
+{
+ switch (side) {
+ default:
+ case TTK_SIDE_TOP: return packTop(cavity, height);
+ case TTK_SIDE_BOTTOM: return packBottom(cavity, height);
+ case TTK_SIDE_LEFT: return packLeft(cavity, width);
+ case TTK_SIDE_RIGHT: return packRight(cavity, width);
+ }
+}
+
+/*
+ * Ttk_PadBox --
+ * Shrink a box by the specified padding amount.
+ */
+Ttk_Box Ttk_PadBox(Ttk_Box b, Ttk_Padding p)
+{
+ b.x += p.left;
+ b.y += p.top;
+ b.width -= (p.left + p.right);
+ b.height -= (p.top + p.bottom);
+ if (b.width <= 0) b.width = 1;
+ if (b.height <= 0) b.height = 1;
+ return b;
+}
+
+/*
+ * Ttk_ExpandBox --
+ * Grow a box by the specified padding amount.
+ */
+Ttk_Box Ttk_ExpandBox(Ttk_Box b, Ttk_Padding p)
+{
+ b.x -= p.left;
+ b.y -= p.top;
+ b.width += (p.left + p.right);
+ b.height += (p.top + p.bottom);
+ return b;
+}
+
+/*
+ * Ttk_StickBox --
+ * Place a box of size w * h in the specified parcel,
+ * according to the specified sticky bits.
+ */
+Ttk_Box Ttk_StickBox(Ttk_Box parcel, int width, int height, unsigned sticky)
+{
+ int dx, dy;
+
+ if (width > parcel.width) width = parcel.width;
+ if (height > parcel.height) height = parcel.height;
+
+ dx = parcel.width - width;
+ dy = parcel.height - height;
+
+ /*
+ * X coordinate adjustment:
+ */
+ switch (sticky & (TTK_STICK_W | TTK_STICK_E))
+ {
+ case TTK_STICK_W | TTK_STICK_E:
+ /* no-op -- use entire parcel width */
+ break;
+ case TTK_STICK_W:
+ parcel.width = width;
+ break;
+ case TTK_STICK_E:
+ parcel.x += dx;
+ parcel.width = width;
+ break;
+ default :
+ parcel.x += dx / 2;
+ parcel.width = width;
+ break;
+ }
+
+ /*
+ * Y coordinate adjustment:
+ */
+ switch (sticky & (TTK_STICK_N | TTK_STICK_S))
+ {
+ case TTK_STICK_N | TTK_STICK_S:
+ /* use entire parcel height */
+ break;
+ case TTK_STICK_N:
+ parcel.height = height;
+ break;
+ case TTK_STICK_S:
+ parcel.y += dy;
+ parcel.height = height;
+ break;
+ default :
+ parcel.y += dy / 2;
+ parcel.height = height;
+ break;
+ }
+
+ return parcel;
+}
+
+/*
+ * AnchorToSticky --
+ * Convert a Tk_Anchor enum to a TTK_STICKY bitmask.
+ */
+static Ttk_Sticky AnchorToSticky(Tk_Anchor anchor)
+{
+ switch (anchor)
+ {
+ case TK_ANCHOR_N: return TTK_STICK_N;
+ case TK_ANCHOR_NE: return TTK_STICK_N | TTK_STICK_E;
+ case TK_ANCHOR_E: return TTK_STICK_E;
+ case TK_ANCHOR_SE: return TTK_STICK_S | TTK_STICK_E;
+ case TK_ANCHOR_S: return TTK_STICK_S;
+ case TK_ANCHOR_SW: return TTK_STICK_S | TTK_STICK_W;
+ case TK_ANCHOR_W: return TTK_STICK_W;
+ case TK_ANCHOR_NW: return TTK_STICK_N | TTK_STICK_W;
+ default:
+ case TK_ANCHOR_CENTER: return 0;
+ }
+}
+
+/*
+ * Ttk_AnchorBox --
+ * Place a box of size w * h in the specified parcel,
+ * according to the specified anchor.
+ */
+Ttk_Box Ttk_AnchorBox(Ttk_Box parcel, int width, int height, Tk_Anchor anchor)
+{
+ return Ttk_StickBox(parcel, width, height, AnchorToSticky(anchor));
+}
+
+/*
+ * Ttk_PlaceBox --
+ * Combine Ttk_PackBox() and Ttk_StickBox().
+ */
+Ttk_Box Ttk_PlaceBox(
+ Ttk_Box *cavity, int width, int height, Ttk_Side side, unsigned sticky)
+{
+ return Ttk_StickBox(
+ Ttk_PackBox(cavity, width, height, side), width, height, sticky);
+}
+
+/*
+ * Ttk_PositionBox --
+ * Pack and stick a box according to PositionSpec flags.
+ */
+MODULE_SCOPE Ttk_Box
+Ttk_PositionBox(Ttk_Box *cavity, int width, int height, Ttk_PositionSpec flags)
+{
+ Ttk_Box parcel;
+
+ if (flags & TTK_EXPAND) parcel = *cavity;
+ else if (flags & TTK_PACK_TOP) parcel = packTop(cavity, height);
+ else if (flags & TTK_PACK_LEFT) parcel = packLeft(cavity, width);
+ else if (flags & TTK_PACK_BOTTOM) parcel = packBottom(cavity, height);
+ else if (flags & TTK_PACK_RIGHT) parcel = packRight(cavity, width);
+ else parcel = *cavity;
+
+ return Ttk_StickBox(parcel, width, height, flags);
+}
+
+/*
+ * TTKInitPadding --
+ * Common factor of Ttk_GetPaddingFromObj and Ttk_GetBorderFromObj.
+ * Initializes Ttk_Padding record, supplying default values
+ * for missing entries.
+ */
+static void TTKInitPadding(int padc, int pixels[4], Ttk_Padding *pad)
+{
+ switch (padc)
+ {
+ case 0: pixels[0] = 0; /*FALLTHRU*/
+ case 1: pixels[1] = pixels[0]; /*FALLTHRU*/
+ case 2: pixels[2] = pixels[0]; /*FALLTHRU*/
+ case 3: pixels[3] = pixels[1]; /*FALLTHRU*/
+ }
+
+ pad->left = (short)pixels[0];
+ pad->top = (short)pixels[1];
+ pad->right = (short)pixels[2];
+ pad->bottom = (short)pixels[3];
+}
+
+/*
+ * Ttk_GetPaddingFromObj --
+ *
+ * Extract a padding specification from a Tcl_Obj * scaled
+ * to work with a particular Tk_Window.
+ *
+ * The string representation of a Ttk_Padding is a list
+ * of one to four Tk_Pixel specifications, corresponding
+ * to the left, top, right, and bottom padding.
+ *
+ * If the 'bottom' (fourth) element is missing, it defaults to 'top'.
+ * If the 'right' (third) element is missing, it defaults to 'left'.
+ * If the 'top' (second) element is missing, it defaults to 'left'.
+ *
+ * The internal representation is a Tcl_ListObj containing
+ * one to four Tk_PixelObj objects.
+ *
+ * Returns:
+ * TCL_OK or TCL_ERROR. In the latter case an error message is
+ * left in 'interp' and '*paddingPtr' is set to all-zeros.
+ * Otherwise, *paddingPtr is filled in with the padding specification.
+ *
+ */
+int Ttk_GetPaddingFromObj(
+ Tcl_Interp *interp,
+ Tk_Window tkwin,
+ Tcl_Obj *objPtr,
+ Ttk_Padding *pad)
+{
+ Tcl_Obj **padv;
+ int i, padc, pixels[4];
+
+ if (TCL_OK != Tcl_ListObjGetElements(interp, objPtr, &padc, &padv)) {
+ goto error;
+ }
+
+ if (padc > 4) {
+ if (interp) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "Wrong #elements in padding spec", NULL);
+ }
+ goto error;
+ }
+
+ for (i=0; i < padc; ++i) {
+ if (Tk_GetPixelsFromObj(interp, tkwin, padv[i], &pixels[i]) != TCL_OK) {
+ goto error;
+ }
+ }
+
+ TTKInitPadding(padc, pixels, pad);
+ return TCL_OK;
+
+error:
+ pad->left = pad->top = pad->right = pad->bottom = 0;
+ return TCL_ERROR;
+}
+
+/* Ttk_GetBorderFromObj --
+ * Same as Ttk_GetPaddingFromObj, except padding is a list of integers
+ * instead of Tk_Pixel specifications. Does not require a Tk_Window
+ * parameter.
+ *
+ */
+int Ttk_GetBorderFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Padding *pad)
+{
+ Tcl_Obj **padv;
+ int i, padc, pixels[4];
+
+ if (TCL_OK != Tcl_ListObjGetElements(interp, objPtr, &padc, &padv)) {
+ goto error;
+ }
+
+ if (padc > 4) {
+ if (interp) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "Wrong #elements in border spec", NULL);
+ }
+ goto error;
+ }
+
+ for (i=0; i < padc; ++i) {
+ if (Tcl_GetIntFromObj(interp, padv[i], &pixels[i]) != TCL_OK) {
+ goto error;
+ }
+ }
+
+ TTKInitPadding(padc, pixels, pad);
+ return TCL_OK;
+
+error:
+ pad->left = pad->top = pad->right = pad->bottom = 0;
+ return TCL_ERROR;
+}
+
+/*
+ * Ttk_MakePadding --
+ * Return an initialized Ttk_Padding structure.
+ */
+Ttk_Padding Ttk_MakePadding(short left, short top, short right, short bottom)
+{
+ Ttk_Padding pad;
+ pad.left = left;
+ pad.top = top;
+ pad.right = right;
+ pad.bottom = bottom;
+ return pad;
+}
+
+/*
+ * Ttk_UniformPadding --
+ * Returns a uniform Ttk_Padding structure, with the same
+ * border width on all sides.
+ */
+Ttk_Padding Ttk_UniformPadding(short borderWidth)
+{
+ Ttk_Padding pad;
+ pad.left = pad.top = pad.right = pad.bottom = borderWidth;
+ return pad;
+}
+
+/*
+ * Ttk_AddPadding --
+ * Combine two padding records.
+ */
+Ttk_Padding Ttk_AddPadding(Ttk_Padding p1, Ttk_Padding p2)
+{
+ p1.left += p2.left;
+ p1.top += p2.top;
+ p1.right += p2.right;
+ p1.bottom += p2.bottom;
+ return p1;
+}
+
+/* Ttk_RelievePadding --
+ * Add an extra n pixels of padding according to specified relief.
+ * This may be used in element geometry procedures to simulate
+ * a "pressed-in" look for pushbuttons.
+ */
+Ttk_Padding Ttk_RelievePadding(Ttk_Padding padding, int relief, int n)
+{
+ switch (relief)
+ {
+ case TK_RELIEF_RAISED:
+ padding.right += n;
+ padding.bottom += n;
+ break;
+ case TK_RELIEF_SUNKEN: /* shift */
+ padding.left += n;
+ padding.top += n;
+ break;
+ default:
+ {
+ int h1 = n/2, h2 = h1 + n % 2;
+ padding.left += h1;
+ padding.top += h1;
+ padding.right += h2;
+ padding.bottom += h2;
+ break;
+ }
+ }
+ return padding;
+}
+
+/*
+ * Ttk_GetStickyFromObj --
+ * Returns a stickiness specification from the specified Tcl_Obj*,
+ * consisting of any combination of n, s, e, and w.
+ *
+ * Returns: TCL_OK if objPtr holds a valid stickiness specification,
+ * otherwise TCL_ERROR. interp is used for error reporting if non-NULL.
+ *
+ */
+int Ttk_GetStickyFromObj(
+ Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Sticky *result)
+{
+ const char *string = Tcl_GetString(objPtr);
+ Ttk_Sticky sticky = 0;
+ char c;
+
+ while ((c = *string++) != '\0') {
+ switch (c) {
+ case 'w': case 'W': sticky |= TTK_STICK_W; break;
+ case 'e': case 'E': sticky |= TTK_STICK_E; break;
+ case 'n': case 'N': sticky |= TTK_STICK_N; break;
+ case 's': case 'S': sticky |= TTK_STICK_S; break;
+ default:
+ if (interp) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ "Bad -sticky specification ",
+ Tcl_GetString(objPtr),
+ NULL);
+ }
+ return TCL_ERROR;
+ }
+ }
+
+ *result = sticky;
+ return TCL_OK;
+}
+
+/* Ttk_NewStickyObj --
+ * Construct a new Tcl_Obj * containing a stickiness specification.
+ */
+Tcl_Obj *Ttk_NewStickyObj(Ttk_Sticky sticky)
+{
+ char buf[5];
+ char *p = buf;
+
+ if (sticky & TTK_STICK_N) *p++ = 'n';
+ if (sticky & TTK_STICK_S) *p++ = 's';
+ if (sticky & TTK_STICK_W) *p++ = 'w';
+ if (sticky & TTK_STICK_E) *p++ = 'e';
+
+ *p = '\0';
+ return Tcl_NewStringObj(buf, p - buf);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Layout nodes.
+ */
+
+typedef struct Ttk_LayoutNode_ Ttk_LayoutNode;
+struct Ttk_LayoutNode_
+{
+ unsigned flags; /* Packing and sticky flags */
+ Ttk_ElementClass *eclass; /* Class record */
+ Ttk_State state; /* Current state */
+ Ttk_Box parcel; /* allocated parcel */
+ Ttk_LayoutNode *next, *child;
+};
+
+static Ttk_LayoutNode *Ttk_NewLayoutNode(
+ unsigned flags, Ttk_ElementClass *elementClass)
+{
+ Ttk_LayoutNode *node = (Ttk_LayoutNode*)ckalloc(sizeof(*node));
+
+ node->flags = flags;
+ node->eclass = elementClass;
+ node->state = 0u;
+ node->next = node->child = 0;
+ node->parcel = Ttk_MakeBox(0,0,0,0);
+
+ return node;
+}
+
+static void Ttk_FreeLayoutNode(Ttk_LayoutNode *node)
+{
+ while (node) {
+ Ttk_LayoutNode *next = node->next;
+ Ttk_FreeLayoutNode(node->child);
+ ckfree((ClientData)node);
+ node = next;
+ }
+}
+
+/*------------------------------------------------------------------------
+ * +++ Layout templates.
+ */
+
+struct Ttk_TemplateNode_ {
+ char *name;
+ unsigned flags;
+ struct Ttk_TemplateNode_ *next, *child;
+};
+
+static Ttk_TemplateNode *Ttk_NewTemplateNode(const char *name, unsigned flags)
+{
+ Ttk_TemplateNode *op = (Ttk_TemplateNode*)ckalloc(sizeof(*op));
+ op->name = ckalloc(strlen(name) + 1); strcpy(op->name, name);
+ op->flags = flags;
+ op->next = op->child = 0;
+ return op;
+}
+
+void Ttk_FreeLayoutTemplate(Ttk_LayoutTemplate op)
+{
+ while (op) {
+ Ttk_LayoutTemplate next = op->next;
+ Ttk_FreeLayoutTemplate(op->child);
+ ckfree(op->name);
+ ckfree((ClientData)op);
+ op = next;
+ }
+}
+
+/* InstantiateLayout --
+ * Create a layout tree from a template.
+ */
+static Ttk_LayoutNode *
+Ttk_InstantiateLayout(Ttk_Theme theme, Ttk_TemplateNode *op)
+{
+ Ttk_ElementClass *elementClass = Ttk_GetElement(theme, op->name);
+ Ttk_LayoutNode *node = Ttk_NewLayoutNode(op->flags, elementClass);
+
+ if (op->next) {
+ node->next = Ttk_InstantiateLayout(theme,op->next);
+ }
+ if (op->child) {
+ node->child = Ttk_InstantiateLayout(theme,op->child);
+ }
+
+ return node;
+}
+
+/*
+ * Ttk_ParseLayoutTemplate --
+ * Convert a Tcl list into a layout template.
+ *
+ * Syntax:
+ * layoutSpec ::= { elementName ?-option value ...? }+
+ */
+
+/* NB: This must match bit definitions TTK_PACK_LEFT etc. */
+static const char *packSideStrings[] =
+ { "left", "right", "top", "bottom", NULL };
+
+Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(Tcl_Interp *interp, Tcl_Obj *objPtr)
+{
+ enum { OP_SIDE, OP_STICKY, OP_EXPAND, OP_BORDER, OP_UNIT, OP_CHILDREN };
+ static const char *optStrings[] = {
+ "-side", "-sticky", "-expand", "-border", "-unit", "-children", 0 };
+
+ int i = 0, objc;
+ Tcl_Obj **objv;
+ Ttk_TemplateNode *head = 0, *tail = 0;
+
+ if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK)
+ return 0;
+
+ while (i < objc) {
+ const char *elementName = Tcl_GetString(objv[i]);
+ unsigned flags = 0x0, sticky = TTK_FILL_BOTH;
+ Tcl_Obj *childSpec = 0;
+
+ /*
+ * Parse options:
+ */
+ ++i;
+ while (i < objc) {
+ const char *optName = Tcl_GetString(objv[i]);
+ int option, value;
+
+ if (optName[0] != '-')
+ break;
+
+ if (Tcl_GetIndexFromObj(
+ interp, objv[i], optStrings, "option", 0, &option)
+ != TCL_OK)
+ {
+ goto error;
+ }
+
+ if (++i >= objc) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ "Missing value for option ",Tcl_GetString(objv[i-1]),
+ NULL);
+ goto error;
+ }
+
+ switch (option) {
+ case OP_SIDE: /* <<NOTE-PACKSIDE>> */
+ if (Tcl_GetIndexFromObj(interp, objv[i], packSideStrings,
+ "side", 0, &value) != TCL_OK)
+ {
+ goto error;
+ }
+ flags |= (TTK_PACK_LEFT << value);
+
+ break;
+ case OP_STICKY:
+ if (Ttk_GetStickyFromObj(interp,objv[i],&sticky) != TCL_OK)
+ goto error;
+ break;
+ case OP_EXPAND:
+ if (Tcl_GetBooleanFromObj(interp,objv[i],&value) != TCL_OK)
+ goto error;
+ if (value)
+ flags |= TTK_EXPAND;
+ break;
+ case OP_BORDER:
+ if (Tcl_GetBooleanFromObj(interp,objv[i],&value) != TCL_OK)
+ goto error;
+ if (value)
+ flags |= TTK_BORDER;
+ break;
+ case OP_UNIT:
+ if (Tcl_GetBooleanFromObj(interp,objv[i],&value) != TCL_OK)
+ goto error;
+ if (value)
+ flags |= TTK_UNIT;
+ break;
+ case OP_CHILDREN:
+ childSpec = objv[i];
+ break;
+ }
+ ++i;
+ }
+
+ /*
+ * Build new node:
+ */
+ if (tail) {
+ tail->next = Ttk_NewTemplateNode(elementName, flags | sticky);
+ tail = tail->next;
+ } else {
+ head = tail = Ttk_NewTemplateNode(elementName, flags | sticky);
+ }
+ if (childSpec) {
+ tail->child = Ttk_ParseLayoutTemplate(interp, childSpec);
+ if (!tail->child) {
+ goto error;
+ }
+ }
+ }
+
+ return head;
+
+error:
+ Ttk_FreeLayoutTemplate(head);
+ return 0;
+}
+
+/* Ttk_BuildLayoutTemplate --
+ * Build a layout template tree from a statically defined
+ * Ttk_LayoutSpec array.
+ */
+Ttk_LayoutTemplate Ttk_BuildLayoutTemplate(Ttk_LayoutSpec spec)
+{
+ Ttk_TemplateNode *first = 0, *last = 0;
+
+ for ( ; !(spec->opcode & _TTK_LAYOUT_END) ; ++spec) {
+ if (spec->elementName) {
+ Ttk_TemplateNode *node =
+ Ttk_NewTemplateNode(spec->elementName, spec->opcode);
+
+ if (last) {
+ last->next = node;
+ } else {
+ first = node;
+ }
+ last = node;
+ }
+
+ if (spec->opcode & _TTK_CHILDREN && last) {
+ int depth = 1;
+ last->child = Ttk_BuildLayoutTemplate(spec+1);
+
+ /* Skip to end of group:
+ */
+ while (depth) {
+ ++spec;
+ if (spec->opcode & _TTK_CHILDREN) {
+ ++depth;
+ }
+ if (spec->opcode & _TTK_LAYOUT_END) {
+ --depth;
+ }
+ }
+ }
+
+ } /* for */
+
+ return first;
+}
+
+void Ttk_RegisterLayouts(Ttk_Theme theme, Ttk_LayoutSpec spec)
+{
+ while (!(spec->opcode & _TTK_LAYOUT_END)) {
+ Ttk_LayoutTemplate layoutTemplate = Ttk_BuildLayoutTemplate(spec+1);
+ Ttk_RegisterLayoutTemplate(theme, spec->elementName, layoutTemplate);
+ do {
+ ++spec;
+ } while (!(spec->opcode & _TTK_LAYOUT));
+ }
+}
+
+Tcl_Obj *Ttk_UnparseLayoutTemplate(Ttk_TemplateNode *node)
+{
+ Tcl_Obj *result = Tcl_NewListObj(0,0);
+
+# define APPENDOBJ(obj) Tcl_ListObjAppendElement(NULL, result, obj)
+# define APPENDSTR(str) APPENDOBJ(Tcl_NewStringObj(str,-1))
+
+ while (node) {
+ unsigned flags = node->flags;
+
+ APPENDSTR(node->name);
+
+ /* Back-compute -side. <<NOTE-PACKSIDE>>
+ * @@@ NOTES: Ick.
+ */
+ if (flags & TTK_EXPAND) {
+ APPENDSTR("-expand");
+ APPENDSTR("1");
+ } else {
+ if (flags & _TTK_MASK_PACK) {
+ int side = 0;
+ unsigned sideFlags = flags & _TTK_MASK_PACK;
+
+ while ((sideFlags & TTK_PACK_LEFT) == 0) {
+ ++side;
+ sideFlags >>= 1;
+ }
+ APPENDSTR("-side");
+ APPENDSTR(packSideStrings[side]);
+ }
+ }
+
+ /* In Ttk_ParseLayoutTemplate, default -sticky is "nsew",
+ * so always include this even if no sticky bits are set.
+ */
+ APPENDSTR("-sticky");
+ APPENDOBJ(Ttk_NewStickyObj(flags & _TTK_MASK_STICK));
+
+ /* @@@ Check again: are these necessary? */
+ if (flags & TTK_BORDER) { APPENDSTR("-border"); APPENDSTR("1"); }
+ if (flags & TTK_UNIT) { APPENDSTR("-unit"); APPENDSTR("1"); }
+
+ if (node->child) {
+ APPENDSTR("-children");
+ APPENDOBJ(Ttk_UnparseLayoutTemplate(node->child));
+ }
+ node = node->next;
+ }
+
+# undef APPENDOBJ
+# undef APPENDSTR
+
+ return result;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Layouts.
+ */
+struct Ttk_Layout_
+{
+ Ttk_Style style;
+ void *recordPtr;
+ Tk_OptionTable optionTable;
+ Tk_Window tkwin;
+ Ttk_LayoutNode *root;
+};
+
+static Ttk_Layout TTKNewLayout(
+ Ttk_Style style,
+ void *recordPtr,Tk_OptionTable optionTable, Tk_Window tkwin,
+ Ttk_LayoutNode *root)
+{
+ Ttk_Layout layout = (Ttk_Layout)ckalloc(sizeof(*layout));
+ layout->style = style;
+ layout->recordPtr = recordPtr;
+ layout->optionTable = optionTable;
+ layout->tkwin = tkwin;
+ layout->root = root;
+ return layout;
+}
+
+void Ttk_FreeLayout(Ttk_Layout layout)
+{
+ Ttk_FreeLayoutNode(layout->root);
+ ckfree((ClientData)layout);
+}
+
+/*
+ * Ttk_CreateLayout --
+ * Create a layout from the specified theme and style name.
+ * Returns: New layout, 0 on error.
+ * Leaves an error message in interp's result if there is an error.
+ */
+Ttk_Layout Ttk_CreateLayout(
+ Tcl_Interp *interp, /* where to leave error messages */
+ Ttk_Theme themePtr,
+ const char *styleName,
+ void *recordPtr,
+ Tk_OptionTable optionTable,
+ Tk_Window tkwin)
+{
+ Ttk_Style style = Ttk_GetStyle(themePtr, styleName);
+ Ttk_LayoutTemplate layoutTemplate =
+ Ttk_FindLayoutTemplate(themePtr,styleName);
+ Ttk_ElementClass *bgelement = Ttk_GetElement(themePtr, "background");
+ Ttk_LayoutNode *bgnode;
+
+ if (!layoutTemplate) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "Layout ", styleName, " not found", NULL);
+ return 0;
+ }
+
+ bgnode = Ttk_NewLayoutNode(TTK_FILL_BOTH, bgelement);
+ bgnode->next = Ttk_InstantiateLayout(themePtr, layoutTemplate);
+
+ return TTKNewLayout(style, recordPtr, optionTable, tkwin, bgnode);
+}
+
+/* Ttk_CreateSublayout --
+ * Creates a new sublayout.
+ *
+ * Sublayouts are used to draw subparts of a compound widget.
+ * They use the same Tk_Window, but a different option table
+ * and data record.
+ */
+Ttk_Layout
+Ttk_CreateSublayout(
+ Tcl_Interp *interp,
+ Ttk_Theme themePtr,
+ Ttk_Layout parentLayout,
+ const char *baseName,
+ Tk_OptionTable optionTable)
+{
+ Tcl_DString buf;
+ const char *styleName;
+ Ttk_Style style;
+ Ttk_LayoutTemplate layoutTemplate;
+
+ Tcl_DStringInit(&buf);
+ Tcl_DStringAppend(&buf, Ttk_StyleName(parentLayout->style), -1);
+ Tcl_DStringAppend(&buf, baseName, -1);
+ styleName = Tcl_DStringValue(&buf);
+
+ style = Ttk_GetStyle(themePtr, styleName);
+ layoutTemplate = Ttk_FindLayoutTemplate(themePtr, styleName);
+
+ if (!layoutTemplate) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "Layout ", styleName, " not found", NULL);
+ return 0;
+ }
+
+ Tcl_DStringFree(&buf);
+
+ return TTKNewLayout(
+ style, 0, optionTable, parentLayout->tkwin,
+ Ttk_InstantiateLayout(themePtr, layoutTemplate));
+}
+
+/* Ttk_RebindSublayout --
+ * Bind sublayout to new data source.
+ */
+void Ttk_RebindSublayout(Ttk_Layout layout, void *recordPtr)
+{
+ layout->recordPtr = recordPtr;
+}
+
+/*
+ * Ttk_QueryOption --
+ * Look up an option from a layout's associated option.
+ */
+Tcl_Obj *Ttk_QueryOption(
+ Ttk_Layout layout, const char *optionName, Ttk_State state)
+{
+ return Ttk_QueryStyle(
+ layout->style,layout->recordPtr,layout->optionTable,optionName,state);
+}
+
+/*
+ * Ttk_LayoutStyle --
+ * Extract Ttk_Style from Ttk_Layout.
+ */
+Ttk_Style Ttk_LayoutStyle(Ttk_Layout layout)
+{
+ return layout->style;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Size computation.
+ */
+static void Ttk_NodeListSize(
+ Ttk_Layout layout, Ttk_LayoutNode *node,
+ Ttk_State state, int *widthPtr, int *heightPtr); /* Forward */
+
+static void Ttk_NodeSize(
+ Ttk_Layout layout, Ttk_LayoutNode *node, Ttk_State state,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ int elementWidth, elementHeight, subWidth, subHeight;
+ Ttk_Padding elementPadding;
+
+ Ttk_ElementSize(node->eclass,
+ layout->style, layout->recordPtr,layout->optionTable, layout->tkwin,
+ state|node->state,
+ &elementWidth, &elementHeight, &elementPadding);
+
+ Ttk_NodeListSize(layout,node->child,state,&subWidth,&subHeight);
+ subWidth += Ttk_PaddingWidth(elementPadding);
+ subHeight += Ttk_PaddingHeight(elementPadding);
+
+ *widthPtr = MAX(elementWidth, subWidth);
+ *heightPtr = MAX(elementHeight, subHeight);
+ *paddingPtr = elementPadding;
+}
+
+static void Ttk_NodeListSize(
+ Ttk_Layout layout, Ttk_LayoutNode *node,
+ Ttk_State state, int *widthPtr, int *heightPtr)
+{
+ if (!node) {
+ *widthPtr = *heightPtr = 0;
+ } else {
+ int width, height, restWidth, restHeight;
+ Ttk_Padding unused;
+
+ Ttk_NodeSize(layout, node, state, &width, &height, &unused);
+ Ttk_NodeListSize(layout, node->next, state, &restWidth, &restHeight);
+
+ if (node->flags & (TTK_PACK_LEFT|TTK_PACK_RIGHT)) {
+ *widthPtr = width + restWidth;
+ } else {
+ *widthPtr = MAX(width, restWidth);
+ }
+
+ if (node->flags & (TTK_PACK_TOP|TTK_PACK_BOTTOM)) {
+ *heightPtr = height + restHeight;
+ } else {
+ *heightPtr = MAX(height, restHeight);
+ }
+ }
+}
+
+/*
+ * Ttk_LayoutNodeInternalPadding --
+ * Returns the internal padding of a layout node.
+ */
+Ttk_Padding Ttk_LayoutNodeInternalPadding(
+ Ttk_Layout layout, Ttk_LayoutNode *node)
+{
+ int unused;
+ Ttk_Padding padding;
+ Ttk_ElementSize(node->eclass,
+ layout->style, layout->recordPtr, layout->optionTable, layout->tkwin,
+ 0/*state*/, &unused, &unused, &padding);
+ return padding;
+}
+
+/*
+ * Ttk_LayoutNodeInternalParcel --
+ * Returns the inner area of a specified layout node,
+ * based on current parcel and element's internal padding.
+ */
+Ttk_Box Ttk_LayoutNodeInternalParcel(Ttk_Layout layout, Ttk_LayoutNode *node)
+{
+ Ttk_Padding padding = Ttk_LayoutNodeInternalPadding(layout, node);
+ return Ttk_PadBox(node->parcel, padding);
+}
+
+/* Ttk_LayoutSize --
+ * Compute requested size of a layout.
+ */
+void Ttk_LayoutSize(
+ Ttk_Layout layout, Ttk_State state, int *widthPtr, int *heightPtr)
+{
+ Ttk_NodeListSize(layout, layout->root, state, widthPtr, heightPtr);
+}
+
+void Ttk_LayoutNodeReqSize( /* @@@ Rename this */
+ Ttk_Layout layout, Ttk_LayoutNode *node, int *widthPtr, int *heightPtr)
+{
+ Ttk_Padding unused;
+ Ttk_NodeSize(layout, node, 0/*state*/, widthPtr, heightPtr, &unused);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Layout placement.
+ */
+
+/* Ttk_PlaceNodeList --
+ * Compute parcel for each node in a layout tree
+ * according to position specification and overall size.
+ */
+static void Ttk_PlaceNodeList(
+ Ttk_Layout layout, Ttk_LayoutNode *node, Ttk_State state, Ttk_Box cavity)
+{
+ for (; node; node = node->next)
+ {
+ int width, height;
+ Ttk_Padding padding;
+
+ /* Compute node size: (@@@ cache this instead?)
+ */
+ Ttk_NodeSize(layout, node, state, &width, &height, &padding);
+
+ /* Compute parcel:
+ */
+ node->parcel = Ttk_PositionBox(&cavity, width, height, node->flags);
+
+ /* Place child nodes:
+ */
+ if (node->child) {
+ Ttk_Box childBox = Ttk_PadBox(node->parcel, padding);
+ Ttk_PlaceNodeList(layout,node->child, state, childBox);
+ }
+ }
+}
+
+void Ttk_PlaceLayout(Ttk_Layout layout, Ttk_State state, Ttk_Box b)
+{
+ Ttk_PlaceNodeList(layout, layout->root, state, b);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Layout drawing.
+ */
+
+/*
+ * Ttk_DrawLayout --
+ * Draw a layout tree.
+ */
+static void Ttk_DrawNodeList(
+ Ttk_Layout layout, Ttk_State state, Ttk_LayoutNode *node, Drawable d)
+{
+ for (; node; node = node->next)
+ {
+ int border = node->flags & TTK_BORDER;
+ int substate = state;
+
+ if (node->flags & TTK_UNIT)
+ substate |= node->state;
+
+ if (node->child && border)
+ Ttk_DrawNodeList(layout, substate, node->child, d);
+
+ Ttk_DrawElement(
+ node->eclass,
+ layout->style,layout->recordPtr,layout->optionTable,layout->tkwin,
+ d, node->parcel, state | node->state);
+
+ if (node->child && !border)
+ Ttk_DrawNodeList(layout, substate, node->child, d);
+ }
+}
+
+void Ttk_DrawLayout(Ttk_Layout layout, Ttk_State state, Drawable d)
+{
+ Ttk_DrawNodeList(layout, state, layout->root, d);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Inquiry and modification.
+ */
+
+/*
+ * Ttk_IdentifyElement --
+ * Find the element at the specified x,y coordinate.
+ */
+static Ttk_Element IdentifyNode(Ttk_Element node, int x, int y)
+{
+ Ttk_Element closest = NULL;
+
+ for (; node; node = node->next) {
+ if (Ttk_BoxContains(node->parcel, x, y)) {
+ closest = node;
+ if (node->child && !(node->flags & TTK_UNIT)) {
+ Ttk_Element childNode = IdentifyNode(node->child, x,y);
+ if (childNode) {
+ closest = childNode;
+ }
+ }
+ }
+ }
+ return closest;
+}
+
+Ttk_Element Ttk_IdentifyElement(Ttk_Layout layout, int x, int y)
+{
+ return IdentifyNode(layout->root, x, y);
+}
+
+/*
+ * tail --
+ * Return the last component of an element name, e.g.,
+ * "Scrollbar.thumb" => "thumb"
+ */
+static const char *tail(const char *elementName)
+{
+ const char *dot;
+ while ((dot=strchr(elementName,'.')) != NULL)
+ elementName = dot + 1;
+ return elementName;
+}
+
+/*
+ * Ttk_FindElement --
+ * Look up an element by name
+ */
+static Ttk_Element
+FindNode(Ttk_Element node, const char *nodeName)
+{
+ for (; node ; node = node->next) {
+ if (!strcmp(tail(Ttk_ElementName(node)), nodeName))
+ return node;
+
+ if (node->child) {
+ Ttk_Element childNode = FindNode(node->child, nodeName);
+ if (childNode)
+ return childNode;
+ }
+ }
+ return 0;
+}
+
+Ttk_Element Ttk_FindElement(Ttk_Layout layout, const char *nodeName)
+{
+ return FindNode(layout->root, nodeName);
+}
+
+/*
+ * Ttk_ClientRegion --
+ * Find the internal parcel of a named element within a given layout.
+ * If the element is not present, use the entire window.
+ */
+Ttk_Box Ttk_ClientRegion(Ttk_Layout layout, const char *elementName)
+{
+ Ttk_Element element = Ttk_FindElement(layout, elementName);
+ return element
+ ? Ttk_LayoutNodeInternalParcel(layout, element)
+ : Ttk_WinBox(layout->tkwin)
+ ;
+}
+
+/*
+ * Ttk_ElementName --
+ * Return the name (class name) of the element.
+ */
+const char *Ttk_ElementName(Ttk_Element node)
+{
+ return Ttk_ElementClassName(node->eclass);
+}
+
+/*
+ * Ttk_ElementParcel --
+ * Return the element's current parcel.
+ */
+Ttk_Box Ttk_ElementParcel(Ttk_Element node)
+{
+ return node->parcel;
+}
+
+/*
+ * Ttk_PlaceElement --
+ * Explicitly specify an element's parcel.
+ */
+void Ttk_PlaceElement(Ttk_Layout layout, Ttk_Element node, Ttk_Box b)
+{
+ node->parcel = b;
+ if (node->child) {
+ Ttk_PlaceNodeList(layout, node->child, 0,
+ Ttk_PadBox(b, Ttk_LayoutNodeInternalPadding(layout, node)));
+ }
+}
+
+/*
+ * Ttk_ChangeElementState --
+ */
+void Ttk_ChangeElementState(Ttk_LayoutNode *node,unsigned set,unsigned clr)
+{
+ node->state = (node->state | set) & ~clr;
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkManager.c b/generic/ttk/ttkManager.c
new file mode 100644
index 0000000..ba9e5c0
--- /dev/null
+++ b/generic/ttk/ttkManager.c
@@ -0,0 +1,552 @@
+/*
+ * Copyright 2005, Joe English. Freely redistributable.
+ *
+ * Support routines for geometry managers.
+ */
+
+#include <string.h>
+#include <tk.h>
+#include "ttkManager.h"
+
+/*------------------------------------------------------------------------
+ * +++ The Geometry Propagation Dance.
+ *
+ * When a slave window requests a new size or some other parameter changes,
+ * the manager recomputes the required size for the master window and calls
+ * Tk_GeometryRequest(). This is scheduled as an idle handler so multiple
+ * updates can be processed as a single batch.
+ *
+ * If all goes well, the master's manager will process the request
+ * (and so on up the chain to the toplevel window), and the master
+ * window will eventually receive a <Configure> event. At this point
+ * it recomputes the size and position of all slaves and places them.
+ *
+ * If all does not go well, however, the master's request may be ignored
+ * (typically because the top-level window has a fixed, user-specified size).
+ * Tk doesn't provide any notification when this happens; to account for this,
+ * we also schedule an idle handler to call the layout procedure
+ * after making a geometry request.
+ *
+ * +++ Slave removal <<NOTE-LOSTSLAVE>>.
+ *
+ * There are three conditions under which a slave is removed:
+ *
+ * (1) Another GM claims control
+ * (2) Manager voluntarily relinquishes control
+ * (3) Slave is destroyed
+ *
+ * In case (1), Tk calls the manager's lostSlaveProc.
+ * Case (2) is performed by calling Tk_ManageGeometry(slave,NULL,0);
+ * in this case Tk does _not_ call the LostSlaveProc (documented behavior).
+ * Tk doesn't handle case (3) either; to account for that we
+ * register an event handler on the slave widget to track <Destroy> events.
+ */
+
+/* ++ Data structures.
+ */
+typedef struct
+{
+ Tk_Window slaveWindow;
+ Ttk_Manager *manager;
+ void *slaveData;
+ unsigned flags;
+} Ttk_Slave;
+
+/* slave->flags bits:
+ */
+#define SLAVE_MAPPED 0x1 /* slave to be mapped when master is */
+
+struct TtkManager_
+{
+ Ttk_ManagerSpec *managerSpec;
+ void *managerData;
+ Tk_Window masterWindow;
+ unsigned flags;
+ int nSlaves;
+ Ttk_Slave **slaves;
+};
+
+/* manager->flags bits:
+ */
+#define MGR_UPDATE_PENDING 0x1
+#define MGR_RESIZE_REQUIRED 0x2
+#define MGR_RELAYOUT_REQUIRED 0x4
+
+static void ManagerIdleProc(void *); /* forward */
+
+/* ++ ScheduleUpdate --
+ * Schedule a call to recompute the size and/or layout,
+ * depending on flags.
+ */
+static void ScheduleUpdate(Ttk_Manager *mgr, unsigned flags)
+{
+ if (!(mgr->flags & MGR_UPDATE_PENDING)) {
+ Tcl_DoWhenIdle(ManagerIdleProc, mgr);
+ mgr->flags |= MGR_UPDATE_PENDING;
+ }
+ mgr->flags |= flags;
+}
+
+/* ++ RecomputeSize --
+ * Recomputes the required size of the master window,
+ * makes geometry request.
+ */
+static void RecomputeSize(Ttk_Manager *mgr)
+{
+ int width = 1, height = 1;
+
+ if (mgr->managerSpec->RequestedSize(mgr->managerData, &width, &height)) {
+ Tk_GeometryRequest(mgr->masterWindow, width, height);
+ ScheduleUpdate(mgr, MGR_RELAYOUT_REQUIRED);
+ }
+ mgr->flags &= ~MGR_RESIZE_REQUIRED;
+}
+
+/* ++ RecomputeLayout --
+ * Recompute geometry of all slaves.
+ */
+static void RecomputeLayout(Ttk_Manager *mgr)
+{
+ mgr->managerSpec->PlaceSlaves(mgr->managerData);
+ mgr->flags &= ~MGR_RELAYOUT_REQUIRED;
+}
+
+/* ++ ManagerIdleProc --
+ * DoWhenIdle procedure for deferred updates.
+ */
+static void ManagerIdleProc(ClientData clientData)
+{
+ Ttk_Manager *mgr = clientData;
+ mgr->flags &= ~MGR_UPDATE_PENDING;
+
+ if (mgr->flags & MGR_RESIZE_REQUIRED) {
+ RecomputeSize(mgr);
+ }
+ if (mgr->flags & MGR_RELAYOUT_REQUIRED) {
+ if (mgr->flags & MGR_UPDATE_PENDING) {
+ /* RecomputeSize has scheduled another update; relayout later */
+ return;
+ }
+ RecomputeLayout(mgr);
+ }
+}
+
+/*------------------------------------------------------------------------
+ * +++ Event handlers.
+ */
+
+/* ++ ManagerEventHandler --
+ * Recompute slave layout when master widget is resized.
+ * Keep the slave's map state in sync with the master's.
+ */
+static const int ManagerEventMask = StructureNotifyMask;
+static void ManagerEventHandler(ClientData clientData, XEvent *eventPtr)
+{
+ Ttk_Manager *mgr = clientData;
+ int i;
+
+ switch (eventPtr->type)
+ {
+ case ConfigureNotify:
+ RecomputeLayout(mgr);
+ break;
+ case MapNotify:
+ for (i = 0; i < mgr->nSlaves; ++i) {
+ Ttk_Slave *slave = mgr->slaves[i];
+ if (slave->flags & SLAVE_MAPPED) {
+ Tk_MapWindow(slave->slaveWindow);
+ }
+ }
+ break;
+ case UnmapNotify:
+ for (i = 0; i < mgr->nSlaves; ++i) {
+ Ttk_Slave *slave = mgr->slaves[i];
+ Tk_UnmapWindow(slave->slaveWindow);
+ }
+ break;
+ }
+}
+
+/* ++ SlaveEventHandler --
+ * Notifies manager when a slave is destroyed
+ * (see <<NOTE-LOSTSLAVE>>).
+ */
+static const unsigned SlaveEventMask = StructureNotifyMask;
+static void SlaveEventHandler(ClientData clientData, XEvent *eventPtr)
+{
+ Ttk_Slave *slave = clientData;
+ if (eventPtr->type == DestroyNotify) {
+ slave->manager->managerSpec->tkGeomMgr.lostSlaveProc(
+ slave->manager, slave->slaveWindow);
+ }
+}
+
+/*------------------------------------------------------------------------
+ * +++ Slave initialization and cleanup.
+ */
+
+static Ttk_Slave *NewSlave(
+ Ttk_Manager *mgr, Tk_Window slaveWindow, void *slaveData)
+{
+ Ttk_Slave *slave = (Ttk_Slave*)ckalloc(sizeof(*slave));
+
+ slave->slaveWindow = slaveWindow;
+ slave->manager = mgr;
+ slave->flags = 0;
+ slave->slaveData = slaveData;
+
+ return slave;
+}
+
+static void DeleteSlave(Ttk_Slave *slave)
+{
+ ckfree((ClientData)slave);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Manager initialization and cleanup.
+ */
+
+Ttk_Manager *Ttk_CreateManager(
+ Ttk_ManagerSpec *managerSpec, void *managerData, Tk_Window masterWindow)
+{
+ Ttk_Manager *mgr = (Ttk_Manager*)ckalloc(sizeof(*mgr));
+
+ mgr->managerSpec = managerSpec;
+ mgr->managerData = managerData;
+ mgr->masterWindow = masterWindow;
+ mgr->nSlaves = 0;
+ mgr->slaves = NULL;
+ mgr->flags = 0;
+
+ Tk_CreateEventHandler(
+ mgr->masterWindow, ManagerEventMask, ManagerEventHandler, mgr);
+
+ return mgr;
+}
+
+void Ttk_DeleteManager(Ttk_Manager *mgr)
+{
+ Tk_DeleteEventHandler(
+ mgr->masterWindow, ManagerEventMask, ManagerEventHandler, mgr);
+
+ while (mgr->nSlaves > 0) {
+ Ttk_ForgetSlave(mgr, mgr->nSlaves - 1);
+ }
+ if (mgr->slaves) {
+ ckfree((ClientData)mgr->slaves);
+ }
+
+ Tk_CancelIdleCall(ManagerIdleProc, mgr);
+
+ ckfree((ClientData)mgr);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Slave management.
+ */
+
+/* ++ InsertSlave --
+ * Adds slave to the list of managed windows.
+ */
+static void InsertSlave(Ttk_Manager *mgr, Ttk_Slave *slave, int index)
+{
+ int endIndex = mgr->nSlaves++;
+ mgr->slaves = (Ttk_Slave**)ckrealloc(
+ (ClientData)mgr->slaves, mgr->nSlaves * sizeof(Ttk_Slave *));
+
+ while (endIndex > index) {
+ mgr->slaves[endIndex] = mgr->slaves[endIndex - 1];
+ --endIndex;
+ }
+
+ mgr->slaves[index] = slave;
+
+ Tk_ManageGeometry(slave->slaveWindow,
+ &mgr->managerSpec->tkGeomMgr, (ClientData)mgr);
+
+ Tk_CreateEventHandler(slave->slaveWindow,
+ SlaveEventMask, SlaveEventHandler, (ClientData)slave);
+
+ ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
+}
+
+/* RemoveSlave --
+ * Unmanage and delete the slave.
+ *
+ * NOTES/ASSUMPTIONS:
+ *
+ * [1] It's safe to call Tk_UnmapWindow / Tk_UnmaintainGeometry even if this
+ * routine is called from the slave's DestroyNotify event handler.
+ */
+static void RemoveSlave(Ttk_Manager *mgr, int index)
+{
+ Ttk_Slave *slave = mgr->slaves[index];
+ int i;
+
+ /* Notify manager:
+ */
+ mgr->managerSpec->SlaveRemoved(mgr->managerData, index);
+
+ /* Remove from array:
+ */
+ --mgr->nSlaves;
+ for (i = index ; i < mgr->nSlaves; ++i) {
+ mgr->slaves[i] = mgr->slaves[i+1];
+ }
+
+ /* Clean up:
+ */
+ Tk_DeleteEventHandler(
+ slave->slaveWindow, SlaveEventMask, SlaveEventHandler, slave);
+
+ /* Note [1] */
+ Tk_UnmaintainGeometry(slave->slaveWindow, mgr->masterWindow);
+ Tk_UnmapWindow(slave->slaveWindow);
+
+ DeleteSlave(slave);
+
+ ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Tk_GeomMgr hooks.
+ */
+
+void Ttk_GeometryRequestProc(ClientData clientData, Tk_Window slaveWindow)
+{
+ Ttk_Manager *mgr = clientData;
+ int slaveIndex = Ttk_SlaveIndex(mgr, slaveWindow);
+ int reqWidth = Tk_ReqWidth(slaveWindow);
+ int reqHeight= Tk_ReqHeight(slaveWindow);
+
+ if (mgr->managerSpec->SlaveRequest(
+ mgr->managerData, slaveIndex, reqWidth, reqHeight))
+ {
+ ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
+ }
+}
+
+void Ttk_LostSlaveProc(ClientData clientData, Tk_Window slaveWindow)
+{
+ Ttk_Manager *mgr = clientData;
+ int index = Ttk_SlaveIndex(mgr, slaveWindow);
+
+ /* ASSERT: index >= 0 */
+ RemoveSlave(mgr, index);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Public API.
+ */
+
+/* ++ Ttk_InsertSlave --
+ * Add a new slave window at the specified index.
+ */
+void Ttk_InsertSlave(
+ Ttk_Manager *mgr, int index, Tk_Window tkwin, void *slaveData)
+{
+ Ttk_Slave *slave = NewSlave(mgr, tkwin, slaveData);
+ InsertSlave(mgr, slave, index);
+}
+
+/* ++ Ttk_ForgetSlave --
+ * Unmanage the specified slave.
+ */
+void Ttk_ForgetSlave(Ttk_Manager *mgr, int slaveIndex)
+{
+ Tk_Window slaveWindow = mgr->slaves[slaveIndex]->slaveWindow;
+ RemoveSlave(mgr, slaveIndex);
+ Tk_ManageGeometry(slaveWindow, NULL, 0);
+}
+
+/* ++ Ttk_PlaceSlave --
+ * Set the position and size of the specified slave window.
+ *
+ * NOTES:
+ * Contrary to documentation, Tk_MaintainGeometry doesn't always
+ * map the slave.
+ */
+void Ttk_PlaceSlave(
+ Ttk_Manager *mgr, int slaveIndex, int x, int y, int width, int height)
+{
+ Ttk_Slave *slave = mgr->slaves[slaveIndex];
+ Tk_MaintainGeometry(slave->slaveWindow,mgr->masterWindow,x,y,width,height);
+ slave->flags |= SLAVE_MAPPED;
+ if (Tk_IsMapped(mgr->masterWindow)) {
+ Tk_MapWindow(slave->slaveWindow);
+ }
+}
+
+/* ++ Ttk_UnmapSlave --
+ * Unmap the specified slave, but leave it managed.
+ */
+void Ttk_UnmapSlave(Ttk_Manager *mgr, int slaveIndex)
+{
+ Ttk_Slave *slave = mgr->slaves[slaveIndex];
+ Tk_UnmaintainGeometry(slave->slaveWindow, mgr->masterWindow);
+ slave->flags &= ~SLAVE_MAPPED;
+ /* Contrary to documentation, Tk_UnmaintainGeometry doesn't always
+ * unmap the slave:
+ */
+ Tk_UnmapWindow(slave->slaveWindow);
+}
+
+/* LayoutChanged, SizeChanged --
+ * Schedule a relayout, resp. resize request.
+ */
+void Ttk_ManagerLayoutChanged(Ttk_Manager *mgr)
+{
+ ScheduleUpdate(mgr, MGR_RELAYOUT_REQUIRED);
+}
+
+void Ttk_ManagerSizeChanged(Ttk_Manager *mgr)
+{
+ ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
+}
+
+/* +++ Accessors.
+ */
+int Ttk_NumberSlaves(Ttk_Manager *mgr)
+{
+ return mgr->nSlaves;
+}
+void *Ttk_SlaveData(Ttk_Manager *mgr, int slaveIndex)
+{
+ return mgr->slaves[slaveIndex]->slaveData;
+}
+Tk_Window Ttk_SlaveWindow(Ttk_Manager *mgr, int slaveIndex)
+{
+ return mgr->slaves[slaveIndex]->slaveWindow;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Utility routines.
+ */
+
+/* ++ Ttk_SlaveIndex --
+ * Returns the index of specified slave window, -1 if not found.
+ */
+int Ttk_SlaveIndex(Ttk_Manager *mgr, Tk_Window slaveWindow)
+{
+ int index;
+ for (index = 0; index < mgr->nSlaves; ++index)
+ if (mgr->slaves[index]->slaveWindow == slaveWindow)
+ return index;
+ return -1;
+}
+
+/* ++ Ttk_GetSlaveIndexFromObj(interp, mgr, objPtr, indexPtr) --
+ * Return the index of the slave specified by objPtr.
+ * Slaves may be specified as an integer index or
+ * as the name of the managed window.
+ *
+ * Returns:
+ * Standard Tcl completion code. Leaves an error message in case of error.
+ */
+
+int Ttk_GetSlaveIndexFromObj(
+ Tcl_Interp *interp, Ttk_Manager *mgr, Tcl_Obj *objPtr, int *indexPtr)
+{
+ const char *string = Tcl_GetString(objPtr);
+ int slaveIndex = 0;
+ Tk_Window tkwin;
+
+ /* Try interpreting as an integer first:
+ */
+ if (Tcl_GetIntFromObj(NULL, objPtr, &slaveIndex) == TCL_OK) {
+ if (slaveIndex < 0 || slaveIndex >= mgr->nSlaves) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ "Slave index ", Tcl_GetString(objPtr), " out of bounds",
+ NULL);
+ return TCL_ERROR;
+ }
+ *indexPtr = slaveIndex;
+ return TCL_OK;
+ }
+
+ /* Try interpreting as a slave window name;
+ */
+ if ( (*string == '.')
+ && (tkwin = Tk_NameToWindow(interp, string, mgr->masterWindow)))
+ {
+ slaveIndex = Ttk_SlaveIndex(mgr, tkwin);
+ if (slaveIndex < 0) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ string, " is not managed by ", Tk_PathName(mgr->masterWindow),
+ NULL);
+ return TCL_ERROR;
+ }
+ *indexPtr = slaveIndex;
+ return TCL_OK;
+ }
+
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "Invalid slave specification ", string, NULL);
+ return TCL_ERROR;
+}
+
+/* ++ Ttk_ReorderSlave(mgr, fromIndex, toIndex) --
+ * Change slave order.
+ */
+void Ttk_ReorderSlave(Ttk_Manager *mgr, int fromIndex, int toIndex)
+{
+ Ttk_Slave *moved = mgr->slaves[fromIndex];
+
+ /* Shuffle down: */
+ while (fromIndex > toIndex) {
+ mgr->slaves[fromIndex] = mgr->slaves[fromIndex - 1];
+ --fromIndex;
+ }
+ /* Or, shuffle up: */
+ while (fromIndex < toIndex) {
+ mgr->slaves[fromIndex] = mgr->slaves[fromIndex + 1];
+ ++fromIndex;
+ }
+ /* ASSERT: fromIndex == toIndex */
+ mgr->slaves[fromIndex] = moved;
+
+ /* Schedule a relayout. In general, rearranging slaves
+ * may also change the size:
+ */
+ ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
+}
+
+/* ++ Ttk_Maintainable(interp, slave, master) --
+ * Utility routine. Verifies that 'master' may be used to maintain
+ * the geometry of 'slave' via Tk_MaintainGeometry:
+ *
+ * + 'master' is either 'slave's parent -OR-
+ * + 'master is a descendant of 'slave's parent.
+ * + 'slave' is not a toplevel window
+ * + 'slave' belongs to the same toplevel as 'master'
+ *
+ * Returns: 1 if OK; otherwise 0, leaving an error message in 'interp'.
+ */
+int Ttk_Maintainable(Tcl_Interp *interp, Tk_Window slave, Tk_Window master)
+{
+ Tk_Window ancestor = master, parent = Tk_Parent(slave);
+
+ if (Tk_IsTopLevel(slave) || slave == master) {
+ goto badWindow;
+ }
+
+ while (ancestor != parent) {
+ if (Tk_IsTopLevel(ancestor)) {
+ goto badWindow;
+ }
+ ancestor = Tk_Parent(ancestor);
+ }
+
+ return 1;
+
+badWindow:
+ Tcl_AppendResult(interp,
+ "can't add ", Tk_PathName(slave),
+ " as slave of ", Tk_PathName(master),
+ NULL);
+ return 0;
+}
+
diff --git a/generic/ttk/ttkManager.h b/generic/ttk/ttkManager.h
new file mode 100644
index 0000000..d22ff98
--- /dev/null
+++ b/generic/ttk/ttkManager.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2005, Joe English. Freely redistributable.
+ *
+ * Geometry manager utilities.
+ */
+
+#ifndef _TTKMANAGER
+#define _TTKMANAGER
+
+#include "ttkTheme.h"
+
+typedef struct TtkManager_ Ttk_Manager;
+
+/*
+ * Geometry manager specification record:
+ *
+ * RequestedSize computes the requested size of the master window.
+ *
+ * PlaceSlaves sets the position and size of all managed slaves
+ * by calling Ttk_PlaceSlave().
+ *
+ * SlaveRemoved() is called immediately before a slave is removed.
+ * NB: the associated slave window may have been destroyed when this
+ * routine is called.
+ *
+ * SlaveRequest() is called when a slave requests a size change.
+ * It should return 1 if the request should propagate, 0 otherwise.
+ */
+typedef struct { /* Manager hooks */
+ Tk_GeomMgr tkGeomMgr; /* "real" Tk Geometry Manager */
+
+ int (*RequestedSize)(void *managerData, int *widthPtr, int *heightPtr);
+ void (*PlaceSlaves)(void *managerData);
+ int (*SlaveRequest)(void *managerData, int slaveIndex, int w, int h);
+ void (*SlaveRemoved)(void *managerData, int slaveIndex);
+} Ttk_ManagerSpec;
+
+/*
+ * Default implementations for Tk_GeomMgr hooks:
+ */
+MODULE_SCOPE void Ttk_GeometryRequestProc(ClientData, Tk_Window slave);
+MODULE_SCOPE void Ttk_LostSlaveProc(ClientData, Tk_Window slave);
+
+/*
+ * Public API:
+ */
+MODULE_SCOPE Ttk_Manager *Ttk_CreateManager(
+ Ttk_ManagerSpec *, void *managerData, Tk_Window masterWindow);
+MODULE_SCOPE void Ttk_DeleteManager(Ttk_Manager *);
+
+MODULE_SCOPE void Ttk_InsertSlave(
+ Ttk_Manager *, int position, Tk_Window, void *slaveData);
+
+MODULE_SCOPE void Ttk_ForgetSlave(Ttk_Manager *, int slaveIndex);
+
+MODULE_SCOPE void Ttk_ReorderSlave(Ttk_Manager *, int fromIndex, int toIndex);
+ /* Rearrange slave positions */
+
+MODULE_SCOPE void Ttk_PlaceSlave(
+ Ttk_Manager *, int slaveIndex, int x, int y, int width, int height);
+ /* Position and map the slave */
+
+MODULE_SCOPE void Ttk_UnmapSlave(Ttk_Manager *, int slaveIndex);
+ /* Unmap the slave */
+
+MODULE_SCOPE void Ttk_ManagerSizeChanged(Ttk_Manager *);
+MODULE_SCOPE void Ttk_ManagerLayoutChanged(Ttk_Manager *);
+ /* Notify manager that size (resp. layout) needs to be recomputed */
+
+/* Utilities:
+ */
+MODULE_SCOPE int Ttk_SlaveIndex(Ttk_Manager *, Tk_Window);
+ /* Returns: index in slave array of specified window, -1 if not found */
+
+MODULE_SCOPE int Ttk_GetSlaveIndexFromObj(
+ Tcl_Interp *, Ttk_Manager *, Tcl_Obj *, int *indexPtr);
+
+/* Accessor functions:
+ */
+MODULE_SCOPE int Ttk_NumberSlaves(Ttk_Manager *);
+ /* Returns: number of managed slaves */
+
+MODULE_SCOPE void *Ttk_SlaveData(Ttk_Manager *, int slaveIndex);
+ /* Returns: client data associated with slave */
+
+MODULE_SCOPE Tk_Window Ttk_SlaveWindow(Ttk_Manager *, int slaveIndex);
+ /* Returns: slave window */
+
+MODULE_SCOPE int Ttk_Maintainable(Tcl_Interp *, Tk_Window slave, Tk_Window master);
+ /* Returns: 1 if master can manage slave; 0 otherwise leaving error msg */
+
+#endif /* _TTKMANAGER */
diff --git a/generic/ttk/ttkNotebook.c b/generic/ttk/ttkNotebook.c
new file mode 100644
index 0000000..551f4a6
--- /dev/null
+++ b/generic/ttk/ttkNotebook.c
@@ -0,0 +1,1413 @@
+/*
+ * Copyright (c) 2004, Joe English
+ */
+
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <tk.h>
+
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+#include "ttkManager.h"
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+/*------------------------------------------------------------------------
+ * +++ Tab resources.
+ */
+
+#define DEFAULT_MIN_TAB_WIDTH 24
+
+static const char *const TabStateStrings[] = { "normal", "disabled", "hidden", 0 };
+typedef enum {
+ TAB_STATE_NORMAL, TAB_STATE_DISABLED, TAB_STATE_HIDDEN
+} TAB_STATE;
+
+typedef struct
+{
+ /* Internal data:
+ */
+ int width, height; /* Requested size of tab */
+ Ttk_Box parcel; /* Tab position */
+
+ /* Tab options:
+ */
+ TAB_STATE state;
+
+ /* Child window options:
+ */
+ Tcl_Obj *paddingObj; /* Padding inside pane */
+ Ttk_Padding padding;
+ Tcl_Obj *stickyObj;
+ Ttk_Sticky sticky;
+
+ /* Label options:
+ */
+ Tcl_Obj *textObj;
+ Tcl_Obj *imageObj;
+ Tcl_Obj *compoundObj;
+ Tcl_Obj *underlineObj;
+
+} Tab;
+
+/* Two different option tables are used for tabs:
+ * TabOptionSpecs is used to draw the tab, and only includes resources
+ * relevant to the tab.
+ *
+ * PaneOptionSpecs includes additional options for child window placement
+ * and is used to configure the slave.
+ */
+static Tk_OptionSpec TabOptionSpecs[] =
+{
+ {TK_OPTION_STRING_TABLE, "-state", "", "",
+ "normal", -1,Tk_Offset(Tab,state),
+ 0,(ClientData)TabStateStrings,0 },
+ {TK_OPTION_STRING, "-text", "text", "Text", "",
+ Tk_Offset(Tab,textObj), -1, 0,0,GEOMETRY_CHANGED },
+ {TK_OPTION_STRING, "-image", "image", "Image", NULL/*default*/,
+ Tk_Offset(Tab,imageObj), -1, TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+ {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
+ "none", Tk_Offset(Tab,compoundObj), -1,
+ 0,(ClientData)ttkCompoundStrings,GEOMETRY_CHANGED },
+ {TK_OPTION_INT, "-underline", "underline", "Underline", "-1",
+ Tk_Offset(Tab,underlineObj), -1, 0,0,GEOMETRY_CHANGED },
+ {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0 }
+};
+
+static Tk_OptionSpec PaneOptionSpecs[] =
+{
+ {TK_OPTION_STRING, "-padding", "padding", "Padding", "0",
+ Tk_Offset(Tab,paddingObj), -1, 0,0,GEOMETRY_CHANGED },
+ {TK_OPTION_STRING, "-sticky", "sticky", "Sticky", "nsew",
+ Tk_Offset(Tab,stickyObj), -1, 0,0,GEOMETRY_CHANGED },
+
+ WIDGET_INHERIT_OPTIONS(TabOptionSpecs)
+};
+
+/*------------------------------------------------------------------------
+ * +++ Notebook resources.
+ */
+typedef struct
+{
+ Tcl_Obj *widthObj; /* Default width */
+ Tcl_Obj *heightObj; /* Default height */
+ Tcl_Obj *paddingObj; /* Padding around notebook */
+
+ Ttk_Manager *mgr; /* Geometry manager */
+ Tk_OptionTable tabOptionTable; /* Tab options */
+ Tk_OptionTable paneOptionTable; /* Tab+pane options */
+ int currentIndex; /* index of currently selected tab */
+ int activeIndex; /* index of currently active tab */
+ Ttk_Layout tabLayout; /* Sublayout for tabs */
+
+ Ttk_Box clientArea; /* Where to pack slave widgets */
+} NotebookPart;
+
+typedef struct
+{
+ WidgetCore core;
+ NotebookPart notebook;
+} Notebook;
+
+static Tk_OptionSpec NotebookOptionSpecs[] =
+{
+ {TK_OPTION_INT, "-width", "width", "Width", "0",
+ Tk_Offset(Notebook,notebook.widthObj),-1,
+ 0,0,GEOMETRY_CHANGED },
+ {TK_OPTION_INT, "-height", "height", "Height", "0",
+ Tk_Offset(Notebook,notebook.heightObj),-1,
+ 0,0,GEOMETRY_CHANGED },
+ {TK_OPTION_STRING, "-padding", "padding", "Padding", NULL,
+ Tk_Offset(Notebook,notebook.paddingObj),-1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+
+ WIDGET_TAKEFOCUS_TRUE,
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
+};
+
+/* Notebook style options:
+ */
+typedef struct
+{
+ Ttk_PositionSpec tabPosition; /* Where to place tabs */
+ Ttk_Padding tabMargins; /* Margins around tab row */
+ Ttk_PositionSpec tabPlacement; /* How to pack tabs within tab row */
+ Ttk_Orient tabOrient; /* ... */
+ int minTabWidth; /* Minimum tab width */
+ Ttk_Padding padding; /* External padding */
+} NotebookStyle;
+
+static void NotebookStyleOptions(Notebook *nb, NotebookStyle *nbstyle)
+{
+ Tcl_Obj *objPtr;
+
+ nbstyle->tabPosition = TTK_PACK_TOP | TTK_STICK_W;
+ if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabposition", 0)) != 0) {
+ TtkGetLabelAnchorFromObj(NULL, objPtr, &nbstyle->tabPosition);
+ }
+
+ /* Guess default tabPlacement as function of tabPosition:
+ */
+ if (nbstyle->tabPosition & TTK_PACK_LEFT) {
+ nbstyle->tabPlacement = TTK_PACK_TOP | TTK_STICK_E;
+ } else if (nbstyle->tabPosition & TTK_PACK_RIGHT) {
+ nbstyle->tabPlacement = TTK_PACK_TOP | TTK_STICK_W;
+ } else if (nbstyle->tabPosition & TTK_PACK_BOTTOM) {
+ nbstyle->tabPlacement = TTK_PACK_LEFT | TTK_STICK_N;
+ } else { /* Assume TTK_PACK_TOP */
+ nbstyle->tabPlacement = TTK_PACK_LEFT | TTK_STICK_S;
+ }
+ if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabplacement", 0)) != 0) {
+ TtkGetLabelAnchorFromObj(NULL, objPtr, &nbstyle->tabPlacement);
+ }
+
+ /* Compute tabOrient as function of tabPlacement:
+ */
+ if (nbstyle->tabPlacement & (TTK_PACK_LEFT|TTK_PACK_RIGHT)) {
+ nbstyle->tabOrient = TTK_ORIENT_HORIZONTAL;
+ } else {
+ nbstyle->tabOrient = TTK_ORIENT_VERTICAL;
+ }
+
+ nbstyle->tabMargins = Ttk_UniformPadding(0);
+ if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabmargins", 0)) != 0) {
+ Ttk_GetBorderFromObj(NULL, objPtr, &nbstyle->tabMargins);
+ }
+
+ nbstyle->padding = Ttk_UniformPadding(0);
+ if ((objPtr = Ttk_QueryOption(nb->core.layout, "-padding", 0)) != 0) {
+ Ttk_GetPaddingFromObj(NULL,nb->core.tkwin,objPtr,&nbstyle->padding);
+ }
+
+ nbstyle->minTabWidth = DEFAULT_MIN_TAB_WIDTH;
+ if ((objPtr = Ttk_QueryOption(nb->core.layout, "-mintabwidth", 0)) != 0) {
+ Tcl_GetIntFromObj(NULL, objPtr, &nbstyle->minTabWidth);
+ }
+}
+
+/*------------------------------------------------------------------------
+ * +++ Tab management.
+ */
+
+static Tab *CreateTab(Tcl_Interp *interp, Notebook *nb, Tk_Window slaveWindow)
+{
+ Tk_OptionTable optionTable = nb->notebook.paneOptionTable;
+ void *record = ckalloc(sizeof(Tab));
+ memset(record, 0, sizeof(Tab));
+
+ if (Tk_InitOptions(interp, record, optionTable, slaveWindow) != TCL_OK) {
+ ckfree(record);
+ return NULL;
+ }
+
+ return record;
+}
+
+static void DestroyTab(Notebook *nb, Tab *tab)
+{
+ void *record = tab;
+ Tk_FreeConfigOptions(record, nb->notebook.paneOptionTable, nb->core.tkwin);
+ ckfree(record);
+}
+
+static int ConfigureTab(
+ Tcl_Interp *interp, Notebook *nb, Tab *tab, Tk_Window slaveWindow,
+ int objc, Tcl_Obj *const objv[])
+{
+ Ttk_Sticky sticky = tab->sticky;
+ Ttk_Padding padding = tab->padding;
+ Tk_SavedOptions savedOptions;
+ int mask = 0;
+
+ if (Tk_SetOptions(interp, (ClientData)tab, nb->notebook.paneOptionTable,
+ objc, objv, slaveWindow, &savedOptions, &mask) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ /* Check options:
+ * @@@ TODO: validate -image option.
+ */
+ if (Ttk_GetStickyFromObj(interp, tab->stickyObj, &sticky) != TCL_OK)
+ {
+ goto error;
+ }
+ if (Ttk_GetPaddingFromObj(interp, slaveWindow, tab->paddingObj, &padding)
+ != TCL_OK)
+ {
+ goto error;
+ }
+
+ tab->sticky = sticky;
+ tab->padding = padding;
+
+ Tk_FreeSavedOptions(&savedOptions);
+ Ttk_ManagerSizeChanged(nb->notebook.mgr);
+ TtkRedisplayWidget(&nb->core);
+
+ return TCL_OK;
+error:
+ Tk_RestoreSavedOptions(&savedOptions);
+ return TCL_ERROR;
+}
+
+/*
+ * IdentifyTab --
+ * Return the index of the tab at point x,y,
+ * or -1 if no tab at that point.
+ */
+static int IdentifyTab(Notebook *nb, int x, int y)
+{
+ int index;
+ for (index = 0; index < Ttk_NumberSlaves(nb->notebook.mgr); ++index) {
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr,index);
+ if ( tab->state != TAB_STATE_HIDDEN
+ && Ttk_BoxContains(tab->parcel, x,y))
+ {
+ return index;
+ }
+ }
+ return -1;
+}
+
+/*
+ * ActivateTab --
+ * Set the active tab index, redisplay if necessary.
+ */
+static void ActivateTab(Notebook *nb, int index)
+{
+ if (index != nb->notebook.activeIndex) {
+ nb->notebook.activeIndex = index;
+ TtkRedisplayWidget(&nb->core);
+ }
+}
+
+/*
+ * TabState --
+ * Return the state of the specified tab, based on
+ * notebook state, currentIndex, activeIndex, and user-specified tab state.
+ * The USER1 bit is set for the leftmost tab, and USER2
+ * is set for the rightmost tab.
+ */
+static Ttk_State TabState(Notebook *nb, int index)
+{
+ Ttk_State state = nb->core.state;
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, index);
+
+ if (index == nb->notebook.currentIndex) {
+ state |= TTK_STATE_SELECTED;
+ } else {
+ state &= ~TTK_STATE_FOCUS;
+ }
+
+ if (index == nb->notebook.activeIndex) {
+ state |= TTK_STATE_ACTIVE;
+ }
+ if (index == 0) {
+ state |= TTK_STATE_USER1;
+ }
+ if (index == Ttk_NumberSlaves(nb->notebook.mgr) - 1) {
+ state |= TTK_STATE_USER2;
+ }
+ if (tab->state == TAB_STATE_DISABLED) {
+ state |= TTK_STATE_DISABLED;
+ }
+
+ return state;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Geometry management - size computation.
+ */
+
+/* TabrowSize --
+ * Compute max height and total width of all tabs (horizontal layouts)
+ * or total height and max width (vertical layouts).
+ *
+ * Side effects:
+ * Sets width and height fields for all tabs.
+ *
+ * Notes:
+ * Hidden tabs are included in the perpendicular computation
+ * (max height/width) but not parallel (total width/height).
+ */
+static void TabrowSize(
+ Notebook *nb, Ttk_Orient orient, int *widthPtr, int *heightPtr)
+{
+ Ttk_Layout tabLayout = nb->notebook.tabLayout;
+ int tabrowWidth = 0, tabrowHeight = 0;
+ int i;
+
+ for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) {
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
+ Ttk_State tabState = TabState(nb,i);
+
+ Ttk_RebindSublayout(tabLayout, tab);
+ Ttk_LayoutSize(tabLayout,tabState,&tab->width,&tab->height);
+
+ if (orient == TTK_ORIENT_HORIZONTAL) {
+ tabrowHeight = MAX(tabrowHeight, tab->height);
+ if (tab->state != TAB_STATE_HIDDEN) { tabrowWidth += tab->width; }
+ } else {
+ tabrowWidth = MAX(tabrowWidth, tab->width);
+ if (tab->state != TAB_STATE_HIDDEN) { tabrowHeight += tab->height; }
+ }
+ }
+
+ *widthPtr = tabrowWidth;
+ *heightPtr = tabrowHeight;
+}
+
+/* NotebookSize -- GM and widget size hook.
+ *
+ * Total height is tab height + client area height + pane internal padding
+ * Total width is max(client width, tab width) + pane internal padding
+ * Client area size determined by max size of slaves,
+ * overridden by -width and/or -height if nonzero.
+ */
+
+static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr)
+{
+ Notebook *nb = clientData;
+ NotebookStyle nbstyle;
+ Ttk_Padding padding;
+ Ttk_Element clientNode = Ttk_FindElement(nb->core.layout, "client");
+ int clientWidth = 0, clientHeight = 0,
+ reqWidth = 0, reqHeight = 0,
+ tabrowWidth = 0, tabrowHeight = 0;
+ int i;
+
+ NotebookStyleOptions(nb, &nbstyle);
+
+ /* Compute max requested size of all slaves:
+ */
+ for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) {
+ Tk_Window slaveWindow = Ttk_SlaveWindow(nb->notebook.mgr, i);
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
+ int slaveWidth
+ = Tk_ReqWidth(slaveWindow) + Ttk_PaddingWidth(tab->padding);
+ int slaveHeight
+ = Tk_ReqHeight(slaveWindow) + Ttk_PaddingHeight(tab->padding);
+
+ clientWidth = MAX(clientWidth, slaveWidth);
+ clientHeight = MAX(clientHeight, slaveHeight);
+ }
+
+ /* Client width/height overridable by widget options:
+ */
+ Tcl_GetIntFromObj(NULL, nb->notebook.widthObj,&reqWidth);
+ Tcl_GetIntFromObj(NULL, nb->notebook.heightObj,&reqHeight);
+ if (reqWidth > 0)
+ clientWidth = reqWidth;
+ if (reqHeight > 0)
+ clientHeight = reqHeight;
+
+ /* Tab row:
+ */
+ TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight);
+ tabrowHeight += Ttk_PaddingHeight(nbstyle.tabMargins);
+ tabrowWidth += Ttk_PaddingWidth(nbstyle.tabMargins);
+
+ /* Account for exterior and interior padding:
+ */
+ padding = nbstyle.padding;
+ if (clientNode) {
+ Ttk_Padding ipad =
+ Ttk_LayoutNodeInternalPadding(nb->core.layout, clientNode);
+ padding = Ttk_AddPadding(padding, ipad);
+ }
+
+ if (nbstyle.tabPosition & (TTK_PACK_TOP|TTK_PACK_BOTTOM)) {
+ *widthPtr = MAX(tabrowWidth, clientWidth) + Ttk_PaddingWidth(padding);
+ *heightPtr = tabrowHeight + clientHeight + Ttk_PaddingHeight(padding);
+ } else {
+ *widthPtr = tabrowWidth + clientWidth + Ttk_PaddingWidth(padding);
+ *heightPtr = MAX(tabrowHeight,clientHeight) + Ttk_PaddingHeight(padding);
+ }
+
+ return 1;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Geometry management - layout.
+ */
+
+/* SqueezeTabs --
+ * Squeeze or stretch tabs to fit within the tab area parcel.
+ *
+ * All tabs are adjusted by an equal amount, but will not be made
+ * smaller than the minimum width. (If all the tabs still do
+ * not fit in the available space, the rightmost ones will
+ * be further squozen by PlaceTabs()).
+ *
+ * The algorithm does not always yield an optimal layout, but does
+ * have the important property that decreasing the available width
+ * by one pixel will cause at most one tab to shrink by one pixel;
+ * this means that tabs resize "smoothly" when the window shrinks
+ * and grows.
+ *
+ * @@@ <<NOTE-TABPOSITION>> bug: only works for horizontal orientations
+ * @@@ <<NOTE-SQUEEZE-HIDDEN>> does not account for hidden tabs.
+ */
+
+static void SqueezeTabs(
+ Notebook *nb, int needed, int available, int minTabWidth)
+{
+ int nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
+
+ if (nTabs > 0) {
+ int difference = available - needed,
+ delta = difference / nTabs,
+ remainder = difference % nTabs,
+ slack = 0;
+ int i;
+
+ if (remainder < 0) { remainder += nTabs; --delta; }
+
+ for (i = 0; i < nTabs; ++i) {
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr,i);
+ int adj = delta + (i < remainder) + slack;
+
+ if (tab->width + adj >= minTabWidth) {
+ tab->width += adj;
+ slack = 0;
+ } else {
+ slack = adj - (minTabWidth - tab->width);
+ tab->width = minTabWidth;
+ }
+ }
+ }
+}
+
+/* PlaceTabs --
+ * Compute all tab parcels.
+ */
+static void PlaceTabs(
+ Notebook *nb, Ttk_Box tabrowBox, Ttk_PositionSpec tabPlacement)
+{
+ Ttk_Layout tabLayout = nb->notebook.tabLayout;
+ int nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
+ int i;
+
+ for (i = 0; i < nTabs; ++i) {
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
+ Ttk_State tabState = TabState(nb, i);
+
+ if (tab->state != TAB_STATE_HIDDEN) {
+ Ttk_Padding expand = Ttk_UniformPadding(0);
+ Tcl_Obj *expandObj = Ttk_QueryOption(tabLayout,"-expand",tabState);
+
+ if (expandObj) {
+ Ttk_GetBorderFromObj(NULL, expandObj, &expand);
+ }
+
+ tab->parcel =
+ Ttk_ExpandBox(
+ Ttk_PositionBox(&tabrowBox,
+ tab->width, tab->height, tabPlacement),
+ expand);
+ }
+ }
+}
+
+/* NotebookDoLayout --
+ * Computes notebook layout and places tabs.
+ *
+ * Side effects:
+ * Sets clientArea, used to place slave panes.
+ */
+static void NotebookDoLayout(void *recordPtr)
+{
+ Notebook *nb = recordPtr;
+ Tk_Window nbwin = nb->core.tkwin;
+ Ttk_Box cavity = Ttk_WinBox(nbwin);
+ int tabrowWidth = 0, tabrowHeight = 0;
+ Ttk_Element clientNode = Ttk_FindElement(nb->core.layout, "client");
+ Ttk_Box tabrowBox;
+ NotebookStyle nbstyle;
+
+ NotebookStyleOptions(nb, &nbstyle);
+
+ /* Notebook internal padding:
+ */
+ cavity = Ttk_PadBox(cavity, nbstyle.padding);
+
+ /* Layout for notebook background (base layout):
+ */
+ Ttk_PlaceLayout(nb->core.layout, nb->core.state, Ttk_WinBox(nbwin));
+
+ /* Place tabs:
+ */
+ TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight);
+ tabrowBox = Ttk_PadBox(
+ Ttk_PositionBox(&cavity,
+ tabrowWidth + Ttk_PaddingWidth(nbstyle.tabMargins),
+ tabrowHeight + Ttk_PaddingHeight(nbstyle.tabMargins),
+ nbstyle.tabPosition),
+ nbstyle.tabMargins);
+
+ SqueezeTabs(nb, tabrowWidth, tabrowBox.width, nbstyle.minTabWidth);
+ PlaceTabs(nb, tabrowBox, nbstyle.tabPlacement);
+
+ /* Layout for client area frame:
+ */
+ if (clientNode) {
+ Ttk_PlaceElement(nb->core.layout, clientNode, cavity);
+ cavity = Ttk_LayoutNodeInternalParcel(nb->core.layout, clientNode);
+ }
+
+ if (cavity.height <= 0) cavity.height = 1;
+ if (cavity.width <= 0) cavity.width = 1;
+
+ nb->notebook.clientArea = cavity;
+}
+
+/*
+ * NotebookPlaceSlave --
+ * Set the position and size of a child widget
+ * based on the current client area and slave options:
+ */
+static void NotebookPlaceSlave(Notebook *nb, int slaveIndex)
+{
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, slaveIndex);
+ Tk_Window slaveWindow = Ttk_SlaveWindow(nb->notebook.mgr, slaveIndex);
+ Ttk_Box slaveBox =
+ Ttk_StickBox(Ttk_PadBox(nb->notebook.clientArea, tab->padding),
+ Tk_ReqWidth(slaveWindow), Tk_ReqHeight(slaveWindow),tab->sticky);
+
+ Ttk_PlaceSlave(nb->notebook.mgr, slaveIndex,
+ slaveBox.x, slaveBox.y, slaveBox.width, slaveBox.height);
+}
+
+/* NotebookPlaceSlaves --
+ * Geometry manager hook.
+ */
+static void NotebookPlaceSlaves(void *recordPtr)
+{
+ Notebook *nb = recordPtr;
+ int currentIndex = nb->notebook.currentIndex;
+ if (currentIndex >= 0) {
+ NotebookDoLayout(nb);
+ NotebookPlaceSlave(nb, currentIndex);
+ }
+}
+
+/*
+ * SelectTab(nb, index) --
+ * Change the currently-selected tab.
+ */
+static void SelectTab(Notebook *nb, int index)
+{
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr,index);
+ int currentIndex = nb->notebook.currentIndex;
+
+ if (index == currentIndex) {
+ return;
+ }
+
+ if (TabState(nb, index) & TTK_STATE_DISABLED) {
+ return;
+ }
+
+ /* Unhide the tab if it is currently hidden and being selected.
+ */
+ if (tab->state == TAB_STATE_HIDDEN) {
+ tab->state = TAB_STATE_NORMAL;
+ }
+
+ if (currentIndex >= 0) {
+ Ttk_UnmapSlave(nb->notebook.mgr, currentIndex);
+ }
+
+ NotebookPlaceSlave(nb, index);
+
+ nb->notebook.currentIndex = index;
+ TtkRedisplayWidget(&nb->core);
+
+ TtkSendVirtualEvent(nb->core.tkwin, "NotebookTabChanged");
+}
+
+/* NextTab --
+ * Returns the index of the next tab after the specified tab
+ * in the normal state (e.g., not hidden or disabled),
+ * or -1 if all tabs are disabled or hidden.
+ */
+static int NextTab(Notebook *nb, int index)
+{
+ int nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
+ int nextIndex;
+
+ /* Scan forward for following usable tab:
+ */
+ for (nextIndex = index + 1; nextIndex < nTabs; ++nextIndex) {
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, nextIndex);
+ if (tab->state == TAB_STATE_NORMAL) {
+ return nextIndex;
+ }
+ }
+
+ /* Not found -- scan backwards.
+ */
+ for (nextIndex = index - 1; nextIndex >= 0; --nextIndex) {
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, nextIndex);
+ if (tab->state == TAB_STATE_NORMAL) {
+ return nextIndex;
+ }
+ }
+
+ /* Still nothing. Give up.
+ */
+ return -1;
+}
+
+/* SelectNearestTab --
+ * Handles the case where the current tab is forgotten, hidden,
+ * or destroyed.
+ *
+ * Unmap the current tab and schedule the next available one
+ * to be mapped at the next GM update.
+ */
+static void SelectNearestTab(Notebook *nb)
+{
+ int currentIndex = nb->notebook.currentIndex;
+ int nextIndex = NextTab(nb, currentIndex);
+
+ if (currentIndex >= 0) {
+ Ttk_UnmapSlave(nb->notebook.mgr, currentIndex);
+ }
+ if (currentIndex != nextIndex) {
+ TtkSendVirtualEvent(nb->core.tkwin, "NotebookTabChanged");
+ }
+
+ nb->notebook.currentIndex = nextIndex;
+ Ttk_ManagerLayoutChanged(nb->notebook.mgr);
+ TtkRedisplayWidget(&nb->core);
+}
+
+/* TabRemoved -- GM SlaveRemoved hook.
+ * Select the next tab if the current one is being removed.
+ * Adjust currentIndex to account for removed slave.
+ */
+static void TabRemoved(void *managerData, int index)
+{
+ Notebook *nb = managerData;
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, index);
+
+ if (index == nb->notebook.currentIndex) {
+ SelectNearestTab(nb);
+ }
+
+ if (index < nb->notebook.currentIndex) {
+ --nb->notebook.currentIndex;
+ }
+
+ DestroyTab(nb, tab);
+
+ TtkRedisplayWidget(&nb->core);
+}
+
+static int TabRequest(void *managerData, int index, int width, int height)
+{
+ return 1;
+}
+
+/* AddTab --
+ * Add new tab at specified index.
+ */
+static int AddTab(
+ Tcl_Interp *interp, Notebook *nb,
+ int destIndex, Tk_Window slaveWindow,
+ int objc, Tcl_Obj *const objv[])
+{
+ Tab *tab;
+ if (!Ttk_Maintainable(interp, slaveWindow, nb->core.tkwin)) {
+ return TCL_ERROR;
+ }
+#if 0 /* can't happen */
+ if (Ttk_SlaveIndex(nb->notebook.mgr, slaveWindow) >= 0) {
+ Tcl_AppendResult(interp,
+ Tk_PathName(slaveWindow), " already added",
+ NULL);
+ return TCL_ERROR;
+ }
+#endif
+
+ /* Create and insert tab.
+ */
+ tab = CreateTab(interp, nb, slaveWindow);
+ if (!tab) {
+ return TCL_ERROR;
+ }
+ if (ConfigureTab(interp, nb, tab, slaveWindow, objc, objv) != TCL_OK) {
+ DestroyTab(nb, tab);
+ return TCL_ERROR;
+ }
+
+ Ttk_InsertSlave(nb->notebook.mgr, destIndex, slaveWindow, tab);
+
+ /* Adjust indices and/or autoselect first tab:
+ */
+ if (nb->notebook.currentIndex < 0) {
+ SelectTab(nb, destIndex);
+ } else if (nb->notebook.currentIndex >= destIndex) {
+ ++nb->notebook.currentIndex;
+ }
+
+ return TCL_OK;
+}
+
+static Ttk_ManagerSpec NotebookManagerSpec = {
+ { "notebook", Ttk_GeometryRequestProc, Ttk_LostSlaveProc },
+ NotebookSize,
+ NotebookPlaceSlaves,
+ TabRequest,
+ TabRemoved
+};
+
+/*------------------------------------------------------------------------
+ * +++ Event handlers.
+ */
+
+/* NotebookEventHandler --
+ * Tracks the active tab.
+ */
+static const int NotebookEventMask
+ = StructureNotifyMask
+ | PointerMotionMask
+ | LeaveWindowMask
+ ;
+static void NotebookEventHandler(ClientData clientData, XEvent *eventPtr)
+{
+ Notebook *nb = clientData;
+
+ if (eventPtr->type == DestroyNotify) { /* Remove self */
+ Tk_DeleteEventHandler(nb->core.tkwin,
+ NotebookEventMask, NotebookEventHandler, clientData);
+ } else if (eventPtr->type == MotionNotify) {
+ int index = IdentifyTab(nb, eventPtr->xmotion.x, eventPtr->xmotion.y);
+ ActivateTab(nb, index);
+ } else if (eventPtr->type == LeaveNotify) {
+ ActivateTab(nb, -1);
+ }
+}
+
+/*------------------------------------------------------------------------
+ * +++ Utilities.
+ */
+
+/* FindTabIndex --
+ * Find the index of the specified tab.
+ * Tab identifiers are one of:
+ *
+ * + positional specifications @x,y,
+ * + "current",
+ * + numeric indices [0..nTabs],
+ * + slave window names
+ *
+ * Stores index of specified tab in *index_rtn, -1 if not found.
+ *
+ * Returns TCL_ERROR and leaves an error message in interp->result
+ * if the tab identifier was incorrect.
+ *
+ * See also: GetTabIndex.
+ */
+static int FindTabIndex(
+ Tcl_Interp *interp, Notebook *nb, Tcl_Obj *objPtr, int *index_rtn)
+{
+ const char *string = Tcl_GetString(objPtr);
+ int x, y;
+
+ *index_rtn = -1;
+
+ /* Check for @x,y ...
+ */
+ if (string[0] == '@' && sscanf(string, "@%d,%d",&x,&y) == 2) {
+ *index_rtn = IdentifyTab(nb, x, y);
+ return TCL_OK;
+ }
+
+ /* ... or "current" ...
+ */
+ if (!strcmp(string, "current")) {
+ *index_rtn = nb->notebook.currentIndex;
+ return TCL_OK;
+ }
+
+ /* ... or integer index or slave window name:
+ */
+ if (Ttk_GetSlaveIndexFromObj(
+ interp, nb->notebook.mgr, objPtr, index_rtn) == TCL_OK)
+ {
+ return TCL_OK;
+ }
+
+ /* Nothing matched; Ttk_GetSlaveIndexFromObj will have left error message.
+ */
+ return TCL_ERROR;
+}
+
+/* GetTabIndex --
+ * Get the index of an existing tab.
+ * Tab identifiers are as per FindTabIndex.
+ * Returns TCL_ERROR if the tab does not exist.
+ */
+static int GetTabIndex(
+ Tcl_Interp *interp, Notebook *nb, Tcl_Obj *objPtr, int *index_rtn)
+{
+ int status = FindTabIndex(interp, nb, objPtr, index_rtn);
+
+ if (status == TCL_OK && *index_rtn < 0) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ "tab '", Tcl_GetString(objPtr), "' not found",
+ NULL);
+ status = TCL_ERROR;
+ }
+ return status;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget command routines.
+ */
+
+/* $nb add window ?options ... ?
+ */
+static int NotebookAddCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Notebook *nb = recordPtr;
+ int index = Ttk_NumberSlaves(nb->notebook.mgr);
+ Tk_Window slaveWindow;
+ int slaveIndex;
+ Tab *tab;
+
+ if (objc <= 2 || objc % 2 != 1) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?");
+ return TCL_ERROR;
+ }
+
+ slaveWindow = Tk_NameToWindow(interp,Tcl_GetString(objv[2]),nb->core.tkwin);
+ if (!slaveWindow) {
+ return TCL_ERROR;
+ }
+ slaveIndex = Ttk_SlaveIndex(nb->notebook.mgr, slaveWindow);
+
+ if (slaveIndex < 0) { /* New tab */
+ return AddTab(interp, nb, index, slaveWindow, objc-3,objv+3);
+ }
+
+ tab = Ttk_SlaveData(nb->notebook.mgr, slaveIndex);
+ if (tab->state == TAB_STATE_HIDDEN) {
+ tab->state = TAB_STATE_NORMAL;
+ }
+ if (ConfigureTab(interp, nb, tab, slaveWindow, objc-4,objv+4) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ TtkRedisplayWidget(&nb->core);
+
+ return TCL_OK;
+}
+
+/* $nb insert $index $tab ?-option value ...?
+ * Insert new tab, or move existing one.
+ */
+static int NotebookInsertCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Notebook *nb = recordPtr;
+ int current = nb->notebook.currentIndex;
+ int nSlaves = Ttk_NumberSlaves(nb->notebook.mgr);
+ int srcIndex, destIndex;
+
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 2,objv, "index slave ?-option value ...?");
+ return TCL_ERROR;
+ }
+
+ if (!strcmp(Tcl_GetString(objv[2]), "end")) {
+ destIndex = Ttk_NumberSlaves(nb->notebook.mgr);
+ } else if (TCL_OK != Ttk_GetSlaveIndexFromObj(
+ interp, nb->notebook.mgr, objv[2], &destIndex)) {
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetString(objv[3])[0] == '.') {
+ /* Window name -- could be new or existing slave.
+ */
+ Tk_Window slaveWindow =
+ Tk_NameToWindow(interp,Tcl_GetString(objv[3]),nb->core.tkwin);
+
+ if (!slaveWindow) {
+ return TCL_ERROR;
+ }
+
+ srcIndex = Ttk_SlaveIndex(nb->notebook.mgr, slaveWindow);
+ if (srcIndex < 0) { /* New slave */
+ return AddTab(interp, nb, destIndex, slaveWindow, objc-4,objv+4);
+ }
+ } else if (Ttk_GetSlaveIndexFromObj(
+ interp, nb->notebook.mgr, objv[3], &srcIndex) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ /* Move existing slave:
+ */
+ if (ConfigureTab(interp, nb,
+ Ttk_SlaveData(nb->notebook.mgr,srcIndex),
+ Ttk_SlaveWindow(nb->notebook.mgr,srcIndex),
+ objc-4,objv+4) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ if (destIndex >= nSlaves) {
+ destIndex = nSlaves - 1;
+ }
+ Ttk_ReorderSlave(nb->notebook.mgr, srcIndex, destIndex);
+
+ /* Adjust internal indexes:
+ */
+ nb->notebook.activeIndex = -1;
+ if (current == srcIndex) {
+ nb->notebook.currentIndex = destIndex;
+ } else if (destIndex <= current && current < srcIndex) {
+ ++nb->notebook.currentIndex;
+ } else if (srcIndex < current && current <= destIndex) {
+ --nb->notebook.currentIndex;
+ }
+
+ TtkRedisplayWidget(&nb->core);
+
+ return TCL_OK;
+}
+
+/* $nb forget $tab --
+ * Removes the specified tab.
+ */
+static int NotebookForgetCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Notebook *nb = recordPtr;
+ int index;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "tab");
+ return TCL_ERROR;
+ }
+
+ if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ Ttk_ForgetSlave(nb->notebook.mgr, index);
+ TtkRedisplayWidget(&nb->core);
+
+ return TCL_OK;
+}
+
+/* $nb hide $tab --
+ * Hides the specified tab.
+ */
+static int NotebookHideCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Notebook *nb = recordPtr;
+ int index;
+ Tab *tab;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "tab");
+ return TCL_ERROR;
+ }
+
+ if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ tab = Ttk_SlaveData(nb->notebook.mgr, index);
+ tab->state = TAB_STATE_HIDDEN;
+ if (index == nb->notebook.currentIndex) {
+ SelectNearestTab(nb);
+ }
+
+ TtkRedisplayWidget(&nb->core);
+
+ return TCL_OK;
+}
+
+/* $nb identify $x $y --
+ * Returns name of tab element at $x,$y; empty string if none.
+ */
+static int NotebookIdentifyCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ static const char *whatTable[] = { "element", "tab", NULL };
+ enum { IDENTIFY_ELEMENT, IDENTIFY_TAB };
+ int what = IDENTIFY_ELEMENT;
+ Notebook *nb = recordPtr;
+ Ttk_Element element = NULL;
+ int x, y, tabIndex;
+
+ if (objc < 4 || objc > 5) {
+ Tcl_WrongNumArgs(interp, 2,objv, "?what? x y");
+ return TCL_ERROR;
+ }
+
+ if ( Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK
+ || Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK
+ || (objc == 5 &&
+ Tcl_GetIndexFromObj(interp, objv[2], whatTable, "option", 0, &what)
+ != TCL_OK)
+ ) {
+ return TCL_ERROR;
+ }
+
+ tabIndex = IdentifyTab(nb, x, y);
+ if (tabIndex >= 0) {
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, tabIndex);
+ Ttk_State state = TabState(nb, tabIndex);
+ Ttk_Layout tabLayout = nb->notebook.tabLayout;
+
+ Ttk_RebindSublayout(tabLayout, tab);
+ Ttk_PlaceLayout(tabLayout, state, tab->parcel);
+
+ element = Ttk_IdentifyElement(tabLayout, x, y);
+ }
+
+ switch (what) {
+ case IDENTIFY_ELEMENT:
+ if (element) {
+ const char *elementName = Ttk_ElementName(element);
+ Tcl_SetObjResult(interp,Tcl_NewStringObj(elementName,-1));
+ }
+ break;
+ case IDENTIFY_TAB:
+ if (tabIndex >= 0) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(tabIndex));
+ }
+ break;
+ }
+ return TCL_OK;
+}
+
+/* $nb index $item --
+ * Returns the integer index of the tab specified by $item,
+ * the empty string if $item does not identify a tab.
+ * See above for valid item formats.
+ */
+static int NotebookIndexCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Notebook *nb = recordPtr;
+ int index, status;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "tab");
+ return TCL_ERROR;
+ }
+
+ /*
+ * Special-case for "end":
+ */
+ if (!strcmp("end", Tcl_GetString(objv[2]))) {
+ int nSlaves = Ttk_NumberSlaves(nb->notebook.mgr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(nSlaves));
+ return TCL_OK;
+ }
+
+ status = FindTabIndex(interp, nb, objv[2], &index);
+ if (status == TCL_OK && index >= 0) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
+ }
+
+ return status;
+}
+
+/* $nb select ?$item? --
+ * Select the specified tab, or return the widget path of
+ * the currently-selected pane.
+ */
+static int NotebookSelectCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Notebook *nb = recordPtr;
+
+ if (objc == 2) {
+ if (nb->notebook.currentIndex >= 0) {
+ Tk_Window pane = Ttk_SlaveWindow(
+ nb->notebook.mgr, nb->notebook.currentIndex);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(pane), -1));
+ }
+ return TCL_OK;
+ } else if (objc == 3) {
+ int index, status = GetTabIndex(interp, nb, objv[2], &index);
+ if (status == TCL_OK) {
+ SelectTab(nb, index);
+ }
+ return status;
+ } /*else*/
+ Tcl_WrongNumArgs(interp, 2, objv, "?tab?");
+ return TCL_ERROR;
+}
+
+/* $nb tabs --
+ * Return list of tabs.
+ */
+static int NotebookTabsCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Notebook *nb = recordPtr;
+ Ttk_Manager *mgr = nb->notebook.mgr;
+ Tcl_Obj *result;
+ int i;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "");
+ return TCL_ERROR;
+ }
+
+ result = Tcl_NewListObj(0, NULL);
+ for (i = 0; i < Ttk_NumberSlaves(mgr); ++i) {
+ const char *pathName = Tk_PathName(Ttk_SlaveWindow(mgr,i));
+ Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(pathName,-1));
+ }
+ Tcl_SetObjResult(interp, result);
+
+ return TCL_OK;
+}
+
+/* $nb tab $tab ?-option ?value -option value...??
+ */
+static int NotebookTabCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Notebook *nb = recordPtr;
+ Ttk_Manager *mgr = nb->notebook.mgr;
+ int index;
+ Tk_Window slaveWindow;
+ Tab *tab;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "tab ?-option ?value??...");
+ return TCL_ERROR;
+ }
+
+ if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ tab = Ttk_SlaveData(mgr, index);
+ slaveWindow = Ttk_SlaveWindow(mgr, index);
+
+ if (objc == 3) {
+ return TtkEnumerateOptions(interp, tab,
+ PaneOptionSpecs, nb->notebook.paneOptionTable, slaveWindow);
+ } else if (objc == 4) {
+ return TtkGetOptionValue(interp, tab, objv[3],
+ nb->notebook.paneOptionTable, slaveWindow);
+ } /* else */
+
+ if (ConfigureTab(interp, nb, tab, slaveWindow, objc-3,objv+3) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /* If the current tab has become disabled or hidden,
+ * select the next nondisabled, unhidden one:
+ */
+ if (index == nb->notebook.currentIndex && tab->state != TAB_STATE_NORMAL) {
+ SelectNearestTab(nb);
+ }
+
+ return TCL_OK;
+}
+
+/* Subcommand table:
+ */
+static const Ttk_Ensemble NotebookCommands[] = {
+ { "add", NotebookAddCommand,0 },
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "forget", NotebookForgetCommand,0 },
+ { "hide", NotebookHideCommand,0 },
+ { "identify", NotebookIdentifyCommand,0 },
+ { "index", NotebookIndexCommand,0 },
+ { "insert", NotebookInsertCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "select", NotebookSelectCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { "tab", NotebookTabCommand,0 },
+ { "tabs", NotebookTabsCommand,0 },
+ { 0,0,0 }
+};
+
+/*------------------------------------------------------------------------
+ * +++ Widget class hooks.
+ */
+
+static void NotebookInitialize(Tcl_Interp *interp, void *recordPtr)
+{
+ Notebook *nb = recordPtr;
+
+ nb->notebook.mgr = Ttk_CreateManager(
+ &NotebookManagerSpec, recordPtr, nb->core.tkwin);
+
+ nb->notebook.tabOptionTable = Tk_CreateOptionTable(interp,TabOptionSpecs);
+ nb->notebook.paneOptionTable = Tk_CreateOptionTable(interp,PaneOptionSpecs);
+
+ nb->notebook.currentIndex = -1;
+ nb->notebook.activeIndex = -1;
+ nb->notebook.tabLayout = 0;
+
+ nb->notebook.clientArea = Ttk_MakeBox(0,0,1,1);
+
+ Tk_CreateEventHandler(
+ nb->core.tkwin, NotebookEventMask, NotebookEventHandler, recordPtr);
+}
+
+static void NotebookCleanup(void *recordPtr)
+{
+ Notebook *nb = recordPtr;
+
+ Ttk_DeleteManager(nb->notebook.mgr);
+ if (nb->notebook.tabLayout)
+ Ttk_FreeLayout(nb->notebook.tabLayout);
+}
+
+static int NotebookConfigure(Tcl_Interp *interp, void *clientData, int mask)
+{
+ Notebook *nb = clientData;
+
+ /*
+ * Error-checks:
+ */
+ if (nb->notebook.paddingObj) {
+ /* Check for valid -padding: */
+ Ttk_Padding unused;
+ if (Ttk_GetPaddingFromObj(
+ interp, nb->core.tkwin, nb->notebook.paddingObj, &unused)
+ != TCL_OK) {
+ return TCL_ERROR;
+ }
+ }
+
+ return TtkCoreConfigure(interp, clientData, mask);
+}
+
+/* NotebookGetLayout --
+ * GetLayout widget hook.
+ */
+static Ttk_Layout NotebookGetLayout(
+ Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr)
+{
+ Notebook *nb = recordPtr;
+ Ttk_Layout notebookLayout = TtkWidgetGetLayout(interp, theme, recordPtr);
+ Ttk_Layout tabLayout;
+
+ if (!notebookLayout) {
+ return NULL;
+ }
+
+ tabLayout = Ttk_CreateSublayout(
+ interp, theme, notebookLayout, ".Tab", nb->notebook.tabOptionTable);
+
+ if (tabLayout) {
+ if (nb->notebook.tabLayout) {
+ Ttk_FreeLayout(nb->notebook.tabLayout);
+ }
+ nb->notebook.tabLayout = tabLayout;
+ }
+
+ return notebookLayout;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Display routines.
+ */
+
+static void DisplayTab(Notebook *nb, int index, Drawable d)
+{
+ Ttk_Layout tabLayout = nb->notebook.tabLayout;
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, index);
+ Ttk_State state = TabState(nb, index);
+
+ if (tab->state != TAB_STATE_HIDDEN) {
+ Ttk_RebindSublayout(tabLayout, tab);
+ Ttk_PlaceLayout(tabLayout, state, tab->parcel);
+ Ttk_DrawLayout(tabLayout, state, d);
+ }
+}
+
+static void NotebookDisplay(void *clientData, Drawable d)
+{
+ Notebook *nb = clientData;
+ int nSlaves = Ttk_NumberSlaves(nb->notebook.mgr);
+ int index;
+
+ /* Draw notebook background (base layout):
+ */
+ Ttk_DrawLayout(nb->core.layout, nb->core.state, d);
+
+ /* Draw tabs from left to right, but draw the current tab last
+ * so it will overwrite its neighbors.
+ */
+ for (index = 0; index < nSlaves; ++index) {
+ if (index != nb->notebook.currentIndex) {
+ DisplayTab(nb, index, d);
+ }
+ }
+ if (nb->notebook.currentIndex >= 0) {
+ DisplayTab(nb, nb->notebook.currentIndex, d);
+ }
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget specification and layout definitions.
+ */
+
+static WidgetSpec NotebookWidgetSpec =
+{
+ "TNotebook", /* className */
+ sizeof(Notebook), /* recordSize */
+ NotebookOptionSpecs, /* optionSpecs */
+ NotebookCommands, /* subcommands */
+ NotebookInitialize, /* initializeProc */
+ NotebookCleanup, /* cleanupProc */
+ NotebookConfigure, /* configureProc */
+ TtkNullPostConfigure, /* postConfigureProc */
+ NotebookGetLayout, /* getLayoutProc */
+ NotebookSize, /* geometryProc */
+ NotebookDoLayout, /* layoutProc */
+ NotebookDisplay /* displayProc */
+};
+
+TTK_BEGIN_LAYOUT(NotebookLayout)
+ TTK_NODE("Notebook.client", TTK_FILL_BOTH)
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(TabLayout)
+ TTK_GROUP("Notebook.tab", TTK_FILL_BOTH,
+ TTK_GROUP("Notebook.padding", TTK_PACK_TOP|TTK_FILL_BOTH,
+ TTK_GROUP("Notebook.focus", TTK_PACK_TOP|TTK_FILL_BOTH,
+ TTK_NODE("Notebook.label", TTK_PACK_TOP))))
+TTK_END_LAYOUT
+
+/*------------------------------------------------------------------------
+ * +++ Initialization.
+ */
+
+MODULE_SCOPE
+void TtkNotebook_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);
+
+ Ttk_RegisterLayout(themePtr, "Tab", TabLayout);
+ Ttk_RegisterLayout(themePtr, "TNotebook", NotebookLayout);
+
+ RegisterWidget(interp, "ttk::notebook", &NotebookWidgetSpec);
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkPanedwindow.c b/generic/ttk/ttkPanedwindow.c
new file mode 100644
index 0000000..b301372
--- /dev/null
+++ b/generic/ttk/ttkPanedwindow.c
@@ -0,0 +1,975 @@
+/*
+ * Copyright (c) 2005, Joe English. Freely redistributable.
+ *
+ * ttk::panedwindow widget implementation.
+ *
+ * TODO: track active/pressed sash.
+ */
+
+#include <string.h>
+#include <tk.h>
+#include "ttkManager.h"
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+/*------------------------------------------------------------------------
+ * +++ Layout algorithm.
+ *
+ * (pos=x/y, size=width/height, depending on -orient=horizontal/vertical)
+ *
+ * Each pane carries two pieces of state: the request size and the
+ * position of the following sash. (The final pane has no sash,
+ * its sash position is used as a sentinel value).
+ *
+ * Pane geometry is determined by the sash positions.
+ * When resizing, sash positions are computed from the request sizes,
+ * the available space, and pane weights (see PlaceSashes()).
+ * This ensures continuous resize behavior (that is: changing
+ * the size by X pixels then changing the size by Y pixels
+ * gives the same result as changing the size by X+Y pixels
+ * in one step).
+ *
+ * The request size is initially set to the slave window's requested size.
+ * When the user drags a sash, each pane's request size is set to its
+ * actual size. This ensures that panes "stay put" on the next resize.
+ *
+ * If reqSize == 0, use 0 for the weight as well. This ensures that
+ * "collapsed" panes stay collapsed during a resize, regardless of
+ * their nominal -weight.
+ *
+ * +++ Invariants.
+ *
+ * #sash = #pane - 1
+ * pos(pane[0]) = 0
+ * pos(sash[i]) = pos(pane[i]) + size(pane[i]), 0 <= i <= #sash
+ * pos(pane[i+1]) = pos(sash[i]) + size(sash[i]), 0 <= i < #sash
+ * pos(sash[#sash]) = size(pw) // sentinel value, constraint
+ *
+ * size(pw) = sum(size(pane(0..#pane))) + sum(size(sash(0..#sash)))
+ * size(pane[i]) >= 0, for 0 <= i < #pane
+ * size(sash[i]) >= 0, for 0 <= i < #sash
+ * ==> pos(pane[i]) <= pos(sash[i]) <= pos(pane[i+1]), for 0 <= i < #sash
+ *
+ * Assumption: all sashes are the same size.
+ */
+
+/*------------------------------------------------------------------------
+ * +++ Widget record.
+ */
+
+typedef struct {
+ Tcl_Obj *orientObj;
+ int orient;
+ int width;
+ int height;
+ Ttk_Manager *mgr;
+ Tk_OptionTable paneOptionTable;
+ Ttk_Layout sashLayout;
+ int sashThickness;
+} PanedPart;
+
+typedef struct {
+ WidgetCore core;
+ PanedPart paned;
+} Paned;
+
+/* @@@ NOTE: -orient is readonly 'cause dynamic oriention changes NYI
+ */
+static Tk_OptionSpec PanedOptionSpecs[] = {
+ {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "vertical",
+ Tk_Offset(Paned,paned.orientObj), Tk_Offset(Paned,paned.orient),
+ 0,(ClientData)ttkOrientStrings,READONLY_OPTION|STYLE_CHANGED },
+ {TK_OPTION_INT, "-width", "width", "Width", "0",
+ -1,Tk_Offset(Paned,paned.width),
+ 0,0,GEOMETRY_CHANGED },
+ {TK_OPTION_INT, "-height", "height", "Height", "0",
+ -1,Tk_Offset(Paned,paned.height),
+ 0,0,GEOMETRY_CHANGED },
+
+ WIDGET_TAKEFOCUS_FALSE,
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
+};
+
+/*------------------------------------------------------------------------
+ * +++ Slave pane record.
+ */
+typedef struct {
+ int reqSize; /* Pane request size */
+ int sashPos; /* Folowing sash position */
+ int weight; /* Pane -weight, for resizing */
+} Pane;
+
+static Tk_OptionSpec PaneOptionSpecs[] = {
+ {TK_OPTION_INT, "-weight", "weight", "Weight", "0",
+ -1,Tk_Offset(Pane,weight), 0,0,GEOMETRY_CHANGED },
+ {TK_OPTION_END, 0,0,0, NULL, -1,-1, 0,0,0}
+};
+
+/* CreatePane --
+ * Create a new pane record.
+ */
+static Pane *CreatePane(Tcl_Interp *interp, Paned *pw, Tk_Window slaveWindow)
+{
+ Tk_OptionTable optionTable = pw->paned.paneOptionTable;
+ void *record = ckalloc(sizeof(Pane));
+ Pane *pane = record;
+
+ memset(record, 0, sizeof(Pane));
+ if (Tk_InitOptions(interp, record, optionTable, slaveWindow) != TCL_OK) {
+ ckfree(record);
+ return NULL;
+ }
+
+ pane->reqSize
+ = pw->paned.orient == TTK_ORIENT_HORIZONTAL
+ ? Tk_ReqWidth(slaveWindow) : Tk_ReqHeight(slaveWindow);
+
+ return pane;
+}
+
+/* DestroyPane --
+ * Free pane record.
+ */
+static void DestroyPane(Paned *pw, Pane *pane)
+{
+ void *record = pane;
+ Tk_FreeConfigOptions(record, pw->paned.paneOptionTable, pw->core.tkwin);
+ ckfree(record);
+}
+
+/* ConfigurePane --
+ * Set pane options.
+ */
+static int ConfigurePane(
+ Tcl_Interp *interp, Paned *pw, Pane *pane, Tk_Window slaveWindow,
+ int objc, Tcl_Obj *const objv[])
+{
+ Ttk_Manager *mgr = pw->paned.mgr;
+ Tk_SavedOptions savedOptions;
+ int mask = 0;
+
+ if (Tk_SetOptions(interp, (void*)pane, pw->paned.paneOptionTable,
+ objc, objv, slaveWindow, &savedOptions, &mask) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ /* Sanity-check:
+ */
+ if (pane->weight < 0) {
+ Tcl_AppendResult(interp, "-weight must be nonnegative", NULL);
+ goto error;
+ }
+
+ /* Done.
+ */
+ Tk_FreeSavedOptions(&savedOptions);
+ Ttk_ManagerSizeChanged(mgr);
+ return TCL_OK;
+
+error:
+ Tk_RestoreSavedOptions(&savedOptions);
+ return TCL_ERROR;
+}
+
+
+/*------------------------------------------------------------------------
+ * +++ Sash adjustment.
+ */
+
+/* ShoveUp --
+ * Place sash i at specified position, recursively shoving
+ * previous sashes upwards as needed, until hitting the top
+ * of the window. If that happens, shove back down.
+ *
+ * Returns: final position of sash i.
+ */
+
+static int ShoveUp(Paned *pw, int i, int pos)
+{
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, i);
+ int sashThickness = pw->paned.sashThickness;
+
+ if (i == 0) {
+ if (pos < 0)
+ pos = 0;
+ } else {
+ Pane *prevPane = Ttk_SlaveData(pw->paned.mgr, i-1);
+ if (pos < prevPane->sashPos + sashThickness)
+ pos = ShoveUp(pw, i-1, pos - sashThickness) + sashThickness;
+ }
+ return pane->sashPos = pos;
+}
+
+/* ShoveDown --
+ * Same as ShoveUp, but going in the opposite direction
+ * and stopping at the sentinel sash.
+ */
+static int ShoveDown(Paned *pw, int i, int pos)
+{
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr,i);
+ int sashThickness = pw->paned.sashThickness;
+
+ if (i == Ttk_NumberSlaves(pw->paned.mgr) - 1) {
+ pos = pane->sashPos; /* Sentinel value == master window size */
+ } else {
+ Pane *nextPane = Ttk_SlaveData(pw->paned.mgr,i+1);
+ if (pos + sashThickness > nextPane->sashPos)
+ pos = ShoveDown(pw, i+1, pos + sashThickness) - sashThickness;
+ }
+ return pane->sashPos = pos;
+}
+
+/* PanedSize --
+ * Compute the requested size of the paned widget
+ * from the individual pane request sizes.
+ *
+ * Used as the WidgetSpec sizeProc and the ManagerSpec sizeProc.
+ */
+static int PanedSize(void *recordPtr, int *widthPtr, int *heightPtr)
+{
+ Paned *pw = recordPtr;
+ int nPanes = Ttk_NumberSlaves(pw->paned.mgr);
+ int nSashes = nPanes - 1;
+ int sashThickness = pw->paned.sashThickness;
+ int width = 0, height = 0;
+ int index;
+
+ if (pw->paned.orient == TTK_ORIENT_HORIZONTAL) {
+ for (index = 0; index < nPanes; ++index) {
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
+ Tk_Window slaveWindow = Ttk_SlaveWindow(pw->paned.mgr, index);
+
+ if (height < Tk_ReqHeight(slaveWindow))
+ height = Tk_ReqHeight(slaveWindow);
+ width += pane->reqSize;
+ }
+ width += nSashes * sashThickness;
+ } else {
+ for (index = 0; index < nPanes; ++index) {
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
+ Tk_Window slaveWindow = Ttk_SlaveWindow(pw->paned.mgr, index);
+
+ if (width < Tk_ReqWidth(slaveWindow))
+ width = Tk_ReqWidth(slaveWindow);
+ height += pane->reqSize;
+ }
+ height += nSashes * sashThickness;
+ }
+
+ *widthPtr = pw->paned.width > 0 ? pw->paned.width : width;
+ *heightPtr = pw->paned.height > 0 ? pw->paned.height : height;
+ return 1;
+}
+
+/* AdjustPanes --
+ * Set pane request sizes from sash positions.
+ *
+ * NOTE:
+ * AdjustPanes followed by PlaceSashes (called during relayout)
+ * will leave the sashes in the same place, as long as available size
+ * remains contant.
+ */
+static void AdjustPanes(Paned *pw)
+{
+ int sashThickness = pw->paned.sashThickness;
+ int pos = 0;
+ int index;
+
+ for (index = 0; index < Ttk_NumberSlaves(pw->paned.mgr); ++index) {
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
+ int size = pane->sashPos - pos;
+ pane->reqSize = size >= 0 ? size : 0;
+ pos = pane->sashPos + sashThickness;
+ }
+}
+
+/* PlaceSashes --
+ * Set sash positions from pane request sizes and available space.
+ * The sentinel sash position is set to the available space.
+ *
+ * Allocate pane->reqSize pixels to each pane, and distribute
+ * the difference = available size - requested size according
+ * to pane->weight.
+ *
+ * If there's still some left over, squeeze panes from the bottom up
+ * (This can happen if all weights are zero, or if one or more panes
+ * are too small to absorb the required shrinkage).
+ *
+ * Notes:
+ * This doesn't distribute the remainder pixels as evenly as it could
+ * when more than one pane has weight > 1.
+ */
+static void PlaceSashes(Paned *pw, int width, int height)
+{
+ Ttk_Manager *mgr = pw->paned.mgr;
+ int nPanes = Ttk_NumberSlaves(mgr);
+ int sashThickness = pw->paned.sashThickness;
+ int available = pw->paned.orient == TTK_ORIENT_HORIZONTAL ? width : height;
+ int reqSize = 0, totalWeight = 0;
+ int difference, delta, remainder, pos, i;
+
+ if (nPanes == 0)
+ return;
+
+ /* Compute total required size and total available weight:
+ */
+ for (i = 0; i < nPanes; ++i) {
+ Pane *pane = Ttk_SlaveData(mgr, i);
+ reqSize += pane->reqSize;
+ totalWeight += pane->weight * (pane->reqSize != 0);
+ }
+
+ /* Compute difference to be redistributed:
+ */
+ difference = available - reqSize - sashThickness*(nPanes-1);
+ if (totalWeight != 0) {
+ delta = difference / totalWeight;
+ remainder = difference % totalWeight;
+ if (remainder < 0) {
+ --delta;
+ remainder += totalWeight;
+ }
+ } else {
+ delta = remainder = 0;
+ }
+ /* ASSERT: 0 <= remainder < totalWeight */
+
+ /* Place sashes:
+ */
+ pos = 0;
+ for (i = 0; i < nPanes; ++i) {
+ Pane *pane = Ttk_SlaveData(mgr, i);
+ int weight = pane->weight * (pane->reqSize != 0);
+ int size = pane->reqSize + delta * weight;
+
+ if (weight > remainder)
+ weight = remainder;
+ remainder -= weight;
+ size += weight;
+
+ if (size < 0)
+ size = 0;
+
+ pane->sashPos = (pos += size);
+ pos += sashThickness;
+ }
+
+ /* Handle emergency shrink/emergency stretch:
+ * Set sentinel sash position to end of widget,
+ * shove preceding sashes up.
+ */
+ ShoveUp(pw, nPanes - 1, available);
+}
+
+/* PlacePanes --
+ * Places slave panes based on sash positions.
+ */
+static void PlacePanes(Paned *pw)
+{
+ int horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL;
+ int width = Tk_Width(pw->core.tkwin), height = Tk_Height(pw->core.tkwin);
+ int sashThickness = pw->paned.sashThickness;
+ int pos = 0;
+ int index;
+
+ for (index = 0; index < Ttk_NumberSlaves(pw->paned.mgr); ++index) {
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
+ int size = pane->sashPos - pos;
+
+ if (size > 0) {
+ if (horizontal) {
+ Ttk_PlaceSlave(pw->paned.mgr, index, pos, 0, size, height);
+ } else {
+ Ttk_PlaceSlave(pw->paned.mgr, index, 0, pos, width, size);
+ }
+ } else {
+ Ttk_UnmapSlave(pw->paned.mgr, index);
+ }
+
+ pos = pane->sashPos + sashThickness;
+ }
+}
+
+/*------------------------------------------------------------------------
+ * +++ Manager specification.
+ */
+
+static void PanedPlaceSlaves(void *managerData)
+{
+ Paned *pw = managerData;
+ PlaceSashes(pw, Tk_Width(pw->core.tkwin), Tk_Height(pw->core.tkwin));
+ PlacePanes(pw);
+}
+
+static void PaneRemoved(void *managerData, int index)
+{
+ Paned *pw = managerData;
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
+ DestroyPane(pw, pane);
+}
+
+static int AddPane(
+ Tcl_Interp *interp, Paned *pw,
+ int destIndex, Tk_Window slaveWindow,
+ int objc, Tcl_Obj *const objv[])
+{
+ Pane *pane;
+ if (!Ttk_Maintainable(interp, slaveWindow, pw->core.tkwin)) {
+ return TCL_ERROR;
+ }
+ if (Ttk_SlaveIndex(pw->paned.mgr, slaveWindow) >= 0) {
+ Tcl_AppendResult(interp,
+ Tk_PathName(slaveWindow), " already added",
+ NULL);
+ return TCL_ERROR;
+ }
+
+ pane = CreatePane(interp, pw, slaveWindow);
+ if (!pane) {
+ return TCL_ERROR;
+ }
+ if (ConfigurePane(interp, pw, pane, slaveWindow, objc, objv) != TCL_OK) {
+ DestroyPane(pw, pane);
+ return TCL_ERROR;
+ }
+
+ Ttk_InsertSlave(pw->paned.mgr, destIndex, slaveWindow, pane);
+ return TCL_OK;
+}
+
+/* PaneRequest --
+ * Only update pane request size if slave is currently unmapped.
+ * Geometry requests from mapped slaves are not directly honored
+ * in order to avoid unexpected pane resizes (esp. while the
+ * user is dragging a sash [#1325286]).
+ */
+static int PaneRequest(void *managerData, int index, int width, int height)
+{
+ Paned *pw = managerData;
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
+ Tk_Window slaveWindow = Ttk_SlaveWindow(pw->paned.mgr, index);
+ int horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL;
+
+ if (!Tk_IsMapped(slaveWindow)) {
+ pane->reqSize = horizontal ? width : height;
+ }
+ return 1;
+}
+
+static Ttk_ManagerSpec PanedManagerSpec = {
+ { "panedwindow", Ttk_GeometryRequestProc, Ttk_LostSlaveProc },
+ PanedSize,
+ PanedPlaceSlaves,
+ PaneRequest,
+ PaneRemoved
+};
+
+/*------------------------------------------------------------------------
+ * +++ Event handler.
+ *
+ * <<NOTE-PW-LEAVE-NOTIFYINFERIOR>>
+ * Tk does not execute binding scripts for <Leave> events when
+ * the pointer crosses from a parent to a child. This widget
+ * needs to know when that happens, though, so it can reset
+ * the cursor.
+ *
+ * This event handler generates an <<EnteredChild>> virtual event
+ * on LeaveNotify/NotifyInferior.
+ */
+
+static const unsigned PanedEventMask = LeaveWindowMask;
+static void PanedEventProc(ClientData clientData, XEvent *eventPtr)
+{
+ WidgetCore *corePtr = clientData;
+ if ( eventPtr->type == LeaveNotify
+ && eventPtr->xcrossing.detail == NotifyInferior)
+ {
+ TtkSendVirtualEvent(corePtr->tkwin, "EnteredChild");
+ }
+}
+
+/*------------------------------------------------------------------------
+ * +++ Initialization and cleanup hooks.
+ */
+
+static void PanedInitialize(Tcl_Interp *interp, void *recordPtr)
+{
+ Paned *pw = recordPtr;
+
+ Tk_CreateEventHandler(pw->core.tkwin,
+ PanedEventMask, PanedEventProc, recordPtr);
+ pw->paned.mgr = Ttk_CreateManager(&PanedManagerSpec, pw, pw->core.tkwin);
+ pw->paned.paneOptionTable = Tk_CreateOptionTable(interp,PaneOptionSpecs);
+ pw->paned.sashLayout = 0;
+ pw->paned.sashThickness = 1;
+}
+
+static void PanedCleanup(void *recordPtr)
+{
+ Paned *pw = recordPtr;
+
+ if (pw->paned.sashLayout)
+ Ttk_FreeLayout(pw->paned.sashLayout);
+ Tk_DeleteEventHandler(pw->core.tkwin,
+ PanedEventMask, PanedEventProc, recordPtr);
+ Ttk_DeleteManager(pw->paned.mgr);
+}
+
+/* Post-configuration hook.
+ */
+static int PanedPostConfigure(Tcl_Interp *interp, void *clientData, int mask)
+{
+ Paned *pw = clientData;
+
+ if (mask & GEOMETRY_CHANGED) {
+ /* User has changed -width or -height.
+ * Recalculate sash positions based on requested size.
+ */
+ Tk_Window tkwin = pw->core.tkwin;
+ PlaceSashes(pw,
+ pw->paned.width > 0 ? pw->paned.width : Tk_Width(tkwin),
+ pw->paned.height > 0 ? pw->paned.height : Tk_Height(tkwin));
+ }
+
+ return TCL_OK;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Layout management hooks.
+ */
+static Ttk_Layout PanedGetLayout(
+ Tcl_Interp *interp, Ttk_Theme themePtr, void *recordPtr)
+{
+ Paned *pw = recordPtr;
+ Ttk_Layout panedLayout = TtkWidgetGetLayout(interp, themePtr, recordPtr);
+
+ if (panedLayout) {
+ int horizontal = pw->paned.orient == TTK_ORIENT_HORIZONTAL;
+ const char *layoutName =
+ horizontal ? ".Vertical.Sash" : ".Horizontal.Sash";
+ Ttk_Layout sashLayout = Ttk_CreateSublayout(
+ interp, themePtr, panedLayout, layoutName, pw->core.optionTable);
+
+ if (sashLayout) {
+ int sashWidth, sashHeight;
+
+ Ttk_LayoutSize(sashLayout, 0, &sashWidth, &sashHeight);
+ pw->paned.sashThickness = horizontal ? sashWidth : sashHeight;
+
+ if (pw->paned.sashLayout)
+ Ttk_FreeLayout(pw->paned.sashLayout);
+ pw->paned.sashLayout = sashLayout;
+ } else {
+ Ttk_FreeLayout(panedLayout);
+ return 0;
+ }
+ }
+
+ return panedLayout;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Drawing routines.
+ */
+
+/* SashLayout --
+ * Place the sash sublayout after the specified pane,
+ * in preparation for drawing.
+ */
+static Ttk_Layout SashLayout(Paned *pw, int index)
+{
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
+ int thickness = pw->paned.sashThickness,
+ height = Tk_Height(pw->core.tkwin),
+ width = Tk_Width(pw->core.tkwin),
+ sashPos = pane->sashPos;
+
+ Ttk_PlaceLayout(
+ pw->paned.sashLayout, pw->core.state,
+ pw->paned.orient == TTK_ORIENT_HORIZONTAL
+ ? Ttk_MakeBox(sashPos, 0, thickness, height)
+ : Ttk_MakeBox(0, sashPos, width, thickness));
+
+ return pw->paned.sashLayout;
+}
+
+static void DrawSash(Paned *pw, int index, Drawable d)
+{
+ Ttk_DrawLayout(SashLayout(pw, index), pw->core.state, d);
+}
+
+static void PanedDisplay(void *recordPtr, Drawable d)
+{
+ Paned *pw = recordPtr;
+ int i, nSashes = Ttk_NumberSlaves(pw->paned.mgr) - 1;
+
+ TtkWidgetDisplay(recordPtr, d);
+ for (i = 0; i < nSashes; ++i) {
+ DrawSash(pw, i, d);
+ }
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget commands.
+ */
+
+/* $pw add window [ options ... ]
+ */
+static int PanedAddCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Paned *pw = recordPtr;
+ Tk_Window slaveWindow;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window");
+ return TCL_ERROR;
+ }
+
+ slaveWindow = Tk_NameToWindow(
+ interp, Tcl_GetString(objv[2]), pw->core.tkwin);
+
+ if (!slaveWindow) {
+ return TCL_ERROR;
+ }
+
+ return AddPane(interp, pw, Ttk_NumberSlaves(pw->paned.mgr), slaveWindow,
+ objc - 3, objv + 3);
+}
+
+/* $pw insert $index $slave ?-option value ...?
+ * Insert new slave, or move existing one.
+ */
+static int PanedInsertCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Paned *pw = recordPtr;
+ int nSlaves = Ttk_NumberSlaves(pw->paned.mgr);
+ int srcIndex, destIndex;
+ Tk_Window slaveWindow;
+
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 2,objv, "index slave ?-option value ...?");
+ return TCL_ERROR;
+ }
+
+ slaveWindow = Tk_NameToWindow(
+ interp, Tcl_GetString(objv[3]), pw->core.tkwin);
+ if (!slaveWindow) {
+ return TCL_ERROR;
+ }
+
+ if (!strcmp(Tcl_GetString(objv[2]), "end")) {
+ destIndex = Ttk_NumberSlaves(pw->paned.mgr);
+ } else if (TCL_OK != Ttk_GetSlaveIndexFromObj(
+ interp,pw->paned.mgr,objv[2],&destIndex))
+ {
+ return TCL_ERROR;
+ }
+
+ srcIndex = Ttk_SlaveIndex(pw->paned.mgr, slaveWindow);
+ if (srcIndex < 0) { /* New slave: */
+ return AddPane(interp, pw, destIndex, slaveWindow, objc-4, objv+4);
+ } /* else -- move existing slave: */
+
+ if (destIndex >= nSlaves)
+ destIndex = nSlaves - 1;
+ Ttk_ReorderSlave(pw->paned.mgr, srcIndex, destIndex);
+
+ return objc == 4 ? TCL_OK :
+ ConfigurePane(interp, pw,
+ Ttk_SlaveData(pw->paned.mgr, destIndex),
+ Ttk_SlaveWindow(pw->paned.mgr, destIndex),
+ objc-4,objv+4);
+}
+
+/* $pw forget $pane
+ */
+static int PanedForgetCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Paned *pw = recordPtr;
+ int paneIndex;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2,objv, "pane");
+ return TCL_ERROR;
+ }
+
+ if (TCL_OK != Ttk_GetSlaveIndexFromObj(
+ interp, pw->paned.mgr, objv[2], &paneIndex))
+ {
+ return TCL_ERROR;
+ }
+ Ttk_ForgetSlave(pw->paned.mgr, paneIndex);
+
+ return TCL_OK;
+}
+
+/* $pw identify ?what? $x $y --
+ * Return index of sash at $x,$y
+ */
+static int PanedIdentifyCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ static const char *whatTable[] = { "element", "sash", NULL };
+ enum { IDENTIFY_ELEMENT, IDENTIFY_SASH };
+ int what = IDENTIFY_SASH;
+ Paned *pw = recordPtr;
+ int sashThickness = pw->paned.sashThickness;
+ int nSashes = Ttk_NumberSlaves(pw->paned.mgr) - 1;
+ int x, y, pos;
+ int index;
+
+ if (objc < 4 || objc > 5) {
+ Tcl_WrongNumArgs(interp, 2,objv, "?what? x y");
+ return TCL_ERROR;
+ }
+
+ if ( Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK
+ || Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK
+ || (objc == 5 &&
+ Tcl_GetIndexFromObj(interp, objv[2], whatTable, "option", 0, &what)
+ != TCL_OK)
+ ) {
+ return TCL_ERROR;
+ }
+
+ pos = pw->paned.orient == TTK_ORIENT_HORIZONTAL ? x : y;
+ for (index = 0; index < nSashes; ++index) {
+ Pane *pane = Ttk_SlaveData(pw->paned.mgr, index);
+ if (pane->sashPos <= pos && pos <= pane->sashPos + sashThickness) {
+ /* Found it. */
+ switch (what) {
+ case IDENTIFY_SASH:
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
+ return TCL_OK;
+ case IDENTIFY_ELEMENT:
+ {
+ Ttk_Element element =
+ Ttk_IdentifyElement(SashLayout(pw, index), x, y);
+ if (element) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj(Ttk_ElementName(element), -1));
+ }
+ return TCL_OK;
+ }
+ }
+ }
+ }
+
+ return TCL_OK; /* nothing found - return empty string */
+}
+
+/* $pw pane $pane ?-option ?value -option value ...??
+ * Query/modify pane options.
+ */
+static int PanedPaneCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Paned *pw = recordPtr;
+ int paneIndex;
+ Tk_Window slaveWindow;
+ Pane *pane;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2,objv, "pane ?-option value ...?");
+ return TCL_ERROR;
+ }
+
+ if (TCL_OK != Ttk_GetSlaveIndexFromObj(
+ interp,pw->paned.mgr,objv[2],&paneIndex))
+ {
+ return TCL_ERROR;
+ }
+
+ pane = Ttk_SlaveData(pw->paned.mgr, paneIndex);
+ slaveWindow = Ttk_SlaveWindow(pw->paned.mgr, paneIndex);
+
+ switch (objc) {
+ case 3:
+ return TtkEnumerateOptions(interp, pane, PaneOptionSpecs,
+ pw->paned.paneOptionTable, slaveWindow);
+ case 4:
+ return TtkGetOptionValue(interp, pane, objv[3],
+ pw->paned.paneOptionTable, slaveWindow);
+ default:
+ return ConfigurePane(interp, pw, pane, slaveWindow, objc-3,objv+3);
+ }
+}
+
+/* $pw panes --
+ * Return list of managed panes.
+ */
+static int PanedPanesCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Paned *pw = recordPtr;
+ Ttk_Manager *mgr = pw->paned.mgr;
+ Tcl_Obj *panes;
+ int i;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "");
+ return TCL_ERROR;
+ }
+
+ panes = Tcl_NewListObj(0, NULL);
+ for (i = 0; i < Ttk_NumberSlaves(mgr); ++i) {
+ const char *pathName = Tk_PathName(Ttk_SlaveWindow(mgr,i));
+ Tcl_ListObjAppendElement(interp, panes, Tcl_NewStringObj(pathName,-1));
+ }
+ Tcl_SetObjResult(interp, panes);
+
+ return TCL_OK;
+}
+
+
+/* $pw sashpos $index ?$newpos?
+ * Query or modify sash position.
+ */
+static int PanedSashposCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Paned *pw = recordPtr;
+ int sashIndex, position = -1;
+ Pane *pane;
+
+ if (objc < 3 || objc > 4) {
+ Tcl_WrongNumArgs(interp, 2,objv, "index ?newpos?");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIntFromObj(interp, objv[2], &sashIndex) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (sashIndex < 0 || sashIndex >= Ttk_NumberSlaves(pw->paned.mgr) - 1) {
+ Tcl_AppendResult(interp,
+ "sash index ", Tcl_GetString(objv[2]), " out of range",
+ NULL);
+ return TCL_ERROR;
+ }
+
+ pane = Ttk_SlaveData(pw->paned.mgr, sashIndex);
+
+ if (objc == 3) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(pane->sashPos));
+ return TCL_OK;
+ }
+ /* else -- set new sash position */
+
+ if (Tcl_GetIntFromObj(interp, objv[3], &position) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (position < pane->sashPos) {
+ ShoveUp(pw, sashIndex, position);
+ } else {
+ ShoveDown(pw, sashIndex, position);
+ }
+
+ AdjustPanes(pw);
+ Ttk_ManagerLayoutChanged(pw->paned.mgr);
+
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(pane->sashPos));
+ return TCL_OK;
+}
+
+static const Ttk_Ensemble PanedCommands[] = {
+ { "add", PanedAddCommand,0 },
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "forget", PanedForgetCommand,0 },
+ { "identify", PanedIdentifyCommand,0 },
+ { "insert", PanedInsertCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "pane", PanedPaneCommand,0 },
+ { "panes", PanedPanesCommand,0 },
+ { "sashpos", PanedSashposCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { 0,0,0 }
+};
+
+/*------------------------------------------------------------------------
+ * +++ Widget specification.
+ */
+
+static WidgetSpec PanedWidgetSpec =
+{
+ "TPanedwindow", /* className */
+ sizeof(Paned), /* recordSize */
+ PanedOptionSpecs, /* optionSpecs */
+ PanedCommands, /* subcommands */
+ PanedInitialize, /* initializeProc */
+ PanedCleanup, /* cleanupProc */
+ TtkCoreConfigure, /* configureProc */
+ PanedPostConfigure, /* postConfigureProc */
+ PanedGetLayout, /* getLayoutProc */
+ PanedSize, /* sizeProc */
+ TtkWidgetDoLayout, /* layoutProc */
+ PanedDisplay /* displayProc */
+};
+
+/*------------------------------------------------------------------------
+ * +++ Elements and layouts.
+ */
+
+static const int DEFAULT_SASH_THICKNESS = 5;
+
+typedef struct {
+ Tcl_Obj *thicknessObj;
+} SashElement;
+
+static Ttk_ElementOptionSpec SashElementOptions[] = {
+ { "-sashthickness", TK_OPTION_INT,
+ Tk_Offset(SashElement,thicknessObj), "5" },
+ { NULL, 0, 0, NULL }
+};
+
+static void SashElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ SashElement *sash = elementRecord;
+ int thickness = DEFAULT_SASH_THICKNESS;
+ Tcl_GetIntFromObj(NULL, sash->thicknessObj, &thickness);
+ *widthPtr = *heightPtr = thickness;
+}
+
+static Ttk_ElementSpec SashElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(SashElement),
+ SashElementOptions,
+ SashElementSize,
+ TtkNullElementDraw
+};
+
+TTK_BEGIN_LAYOUT(PanedLayout)
+ TTK_NODE("Panedwindow.background", 0)/* @@@ BUG: empty layouts don't work */
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(HorizontalSashLayout)
+ TTK_NODE("Sash.hsash", TTK_FILL_X)
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(VerticalSashLayout)
+ TTK_NODE("Sash.vsash", TTK_FILL_Y)
+TTK_END_LAYOUT
+
+/*------------------------------------------------------------------------
+ * +++ Registration routine.
+ */
+MODULE_SCOPE
+void TtkPanedwindow_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);
+ RegisterWidget(interp, "ttk::panedwindow", &PanedWidgetSpec);
+
+ Ttk_RegisterElement(interp, themePtr, "hsash", &SashElementSpec, 0);
+ Ttk_RegisterElement(interp, themePtr, "vsash", &SashElementSpec, 0);
+
+ Ttk_RegisterLayout(themePtr, "TPanedwindow", PanedLayout);
+ Ttk_RegisterLayout(themePtr, "Horizontal.Sash", HorizontalSashLayout);
+ Ttk_RegisterLayout(themePtr, "Vertical.Sash", VerticalSashLayout);
+}
+
diff --git a/generic/ttk/ttkProgress.c b/generic/ttk/ttkProgress.c
new file mode 100644
index 0000000..4dc50a2
--- /dev/null
+++ b/generic/ttk/ttkProgress.c
@@ -0,0 +1,545 @@
+/*
+ * Copyright (c) Joe English, Pat Thoyts, Michael Kirkham
+ *
+ * ttk::progressbar widget.
+ */
+
+#include <math.h>
+#include <tk.h>
+
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+/*------------------------------------------------------------------------
+ * +++ Widget record:
+ */
+
+#define DEF_PROGRESSBAR_LENGTH "100"
+enum {
+ TTK_PROGRESSBAR_DETERMINATE, TTK_PROGRESSBAR_INDETERMINATE
+};
+static const char *const ProgressbarModeStrings[] = {
+ "determinate", "indeterminate", NULL
+};
+
+typedef struct {
+ Tcl_Obj *orientObj;
+ Tcl_Obj *lengthObj;
+ Tcl_Obj *modeObj;
+ Tcl_Obj *variableObj;
+ Tcl_Obj *maximumObj;
+ Tcl_Obj *valueObj;
+ Tcl_Obj *phaseObj;
+
+ int mode;
+ Ttk_TraceHandle *variableTrace; /* Trace handle for -variable option */
+ int period; /* Animation period */
+ int maxPhase; /* Max animation phase */
+ Tcl_TimerToken timer; /* Animation timer */
+
+} ProgressbarPart;
+
+typedef struct {
+ WidgetCore core;
+ ProgressbarPart progress;
+} Progressbar;
+
+static Tk_OptionSpec ProgressbarOptionSpecs[] =
+{
+ {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
+ "horizontal", Tk_Offset(Progressbar,progress.orientObj), -1,
+ 0, (ClientData)ttkOrientStrings, STYLE_CHANGED },
+ {TK_OPTION_PIXELS, "-length", "length", "Length",
+ DEF_PROGRESSBAR_LENGTH, Tk_Offset(Progressbar,progress.lengthObj), -1,
+ 0, 0, GEOMETRY_CHANGED },
+ {TK_OPTION_STRING_TABLE, "-mode", "mode", "ProgressMode", "determinate",
+ Tk_Offset(Progressbar,progress.modeObj),
+ Tk_Offset(Progressbar,progress.mode),
+ 0, (ClientData)ProgressbarModeStrings, 0 },
+ {TK_OPTION_DOUBLE, "-maximum", "maximum", "Maximum",
+ "100", Tk_Offset(Progressbar,progress.maximumObj), -1,
+ 0, 0, 0 },
+ {TK_OPTION_STRING, "-variable", "variable", "Variable",
+ NULL, Tk_Offset(Progressbar,progress.variableObj), -1,
+ TK_OPTION_NULL_OK, 0, 0 },
+ {TK_OPTION_DOUBLE, "-value", "value", "Value",
+ "0.0", Tk_Offset(Progressbar,progress.valueObj), -1,
+ 0, 0, 0 },
+ {TK_OPTION_INT, "-phase", "phase", "Phase",
+ "0", Tk_Offset(Progressbar,progress.phaseObj), -1,
+ 0, 0, 0 },
+
+ WIDGET_TAKEFOCUS_FALSE,
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
+};
+
+/*------------------------------------------------------------------------
+ * +++ Animation procedures:
+ */
+
+/* AnimationEnabled --
+ * Returns 1 if animation should be active, 0 otherwise.
+ */
+static int AnimationEnabled(Progressbar *pb)
+{
+ double maximum = 100, value = 0;
+
+ Tcl_GetDoubleFromObj(NULL, pb->progress.maximumObj, &maximum);
+ Tcl_GetDoubleFromObj(NULL, pb->progress.valueObj, &value);
+
+ return pb->progress.period > 0
+ && value > 0.0
+ && ( value < maximum
+ || pb->progress.mode == TTK_PROGRESSBAR_INDETERMINATE);
+}
+
+/* AnimateProgressProc --
+ * Timer callback for progress bar animation.
+ * Increments the -phase option, redisplays the widget,
+ * and reschedules itself if animation still enabled.
+ */
+static void AnimateProgressProc(ClientData clientData)
+{
+ Progressbar *pb = clientData;
+
+ pb->progress.timer = 0;
+
+ if (AnimationEnabled(pb)) {
+ int phase = 0;
+ Tcl_GetIntFromObj(NULL, pb->progress.phaseObj, &phase);
+
+ /*
+ * Update -phase:
+ */
+ ++phase;
+ if (pb->progress.maxPhase)
+ phase %= pb->progress.maxPhase;
+ Tcl_DecrRefCount(pb->progress.phaseObj);
+ pb->progress.phaseObj = Tcl_NewIntObj(phase);
+ Tcl_IncrRefCount(pb->progress.phaseObj);
+
+ /*
+ * Reschedule:
+ */
+ pb->progress.timer = Tcl_CreateTimerHandler(
+ pb->progress.period, AnimateProgressProc, clientData);
+
+ TtkRedisplayWidget(&pb->core);
+ }
+}
+
+/* CheckAnimation --
+ * If animation is enabled and not scheduled, schedule it.
+ * If animation is disabled but scheduled, cancel it.
+ */
+static void CheckAnimation(Progressbar *pb)
+{
+ if (AnimationEnabled(pb)) {
+ if (pb->progress.timer == 0) {
+ pb->progress.timer = Tcl_CreateTimerHandler(
+ pb->progress.period, AnimateProgressProc, (ClientData)pb);
+ }
+ } else {
+ if (pb->progress.timer != 0) {
+ Tcl_DeleteTimerHandler(pb->progress.timer);
+ pb->progress.timer = 0;
+ }
+ }
+}
+
+/*------------------------------------------------------------------------
+ * +++ Trace hook for progressbar -variable option:
+ */
+
+static void VariableChanged(void *recordPtr, const char *value)
+{
+ Progressbar *pb = recordPtr;
+ Tcl_Obj *newValue;
+ double scratch;
+
+ if (WidgetDestroyed(&pb->core)) {
+ return;
+ }
+
+ if (!value) {
+ /* Linked variable is unset -- disable widget */
+ TtkWidgetChangeState(&pb->core, TTK_STATE_DISABLED, 0);
+ return;
+ }
+ TtkWidgetChangeState(&pb->core, 0, TTK_STATE_DISABLED);
+
+ newValue = Tcl_NewStringObj(value, -1);
+ Tcl_IncrRefCount(newValue);
+ if (Tcl_GetDoubleFromObj(NULL, newValue, &scratch) != TCL_OK) {
+ TtkWidgetChangeState(&pb->core, TTK_STATE_INVALID, 0);
+ return;
+ }
+ TtkWidgetChangeState(&pb->core, 0, TTK_STATE_INVALID);
+ Tcl_DecrRefCount(pb->progress.valueObj);
+ pb->progress.valueObj = newValue;
+
+ CheckAnimation(pb);
+ TtkRedisplayWidget(&pb->core);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget class methods:
+ */
+
+static void ProgressbarInitialize(Tcl_Interp *interp, void *recordPtr)
+{
+ Progressbar *pb = recordPtr;
+ pb->progress.variableTrace = 0;
+ pb->progress.timer = 0;
+}
+
+static void ProgressbarCleanup(void *recordPtr)
+{
+ Progressbar *pb = recordPtr;
+ if (pb->progress.variableTrace)
+ Ttk_UntraceVariable(pb->progress.variableTrace);
+ if (pb->progress.timer)
+ Tcl_DeleteTimerHandler(pb->progress.timer);
+}
+
+/*
+ * Configure hook:
+ *
+ * @@@ TODO: deal with [$pb configure -value ... -variable ...]
+ */
+static int ProgressbarConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Progressbar *pb = recordPtr;
+ Tcl_Obj *varName = pb->progress.variableObj;
+ Ttk_TraceHandle *vt = 0;
+
+ if (varName != NULL && *Tcl_GetString(varName) != '\0') {
+ vt = Ttk_TraceVariable(interp, varName, VariableChanged, recordPtr);
+ if (!vt) return TCL_ERROR;
+ }
+
+ if (TtkCoreConfigure(interp, recordPtr, mask) != TCL_OK) {
+ if (vt) Ttk_UntraceVariable(vt);
+ return TCL_ERROR;
+ }
+
+ if (pb->progress.variableTrace) {
+ Ttk_UntraceVariable(pb->progress.variableTrace);
+ }
+ pb->progress.variableTrace = vt;
+
+ return TCL_OK;
+}
+
+/*
+ * Post-configuration hook:
+ */
+static int ProgressbarPostConfigure(
+ Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Progressbar *pb = recordPtr;
+ int status = TCL_OK;
+
+ if (pb->progress.variableTrace) {
+ status = Ttk_FireTrace(pb->progress.variableTrace);
+ if (WidgetDestroyed(&pb->core)) {
+ return TCL_ERROR;
+ }
+ if (status != TCL_OK) {
+ /* Unset -variable: */
+ Ttk_UntraceVariable(pb->progress.variableTrace);
+ Tcl_DecrRefCount(pb->progress.variableObj);
+ pb->progress.variableTrace = 0;
+ pb->progress.variableObj = NULL;
+ return TCL_ERROR;
+ }
+ }
+
+ CheckAnimation(pb);
+
+ return status;
+}
+
+/*
+ * Size hook:
+ * Compute base layout size, overrid
+ */
+static int ProgressbarSize(void *recordPtr, int *widthPtr, int *heightPtr)
+{
+ Progressbar *pb = recordPtr;
+ int length = 100, orient = TTK_ORIENT_HORIZONTAL;
+
+ TtkWidgetSize(recordPtr, widthPtr, heightPtr);
+
+ /* Override requested width (height) based on -length and -orient
+ */
+ Tk_GetPixelsFromObj(NULL, pb->core.tkwin, pb->progress.lengthObj, &length);
+ Ttk_GetOrientFromObj(NULL, pb->progress.orientObj, &orient);
+
+ if (orient == TTK_ORIENT_HORIZONTAL) {
+ *widthPtr = length;
+ } else {
+ *heightPtr = length;
+ }
+
+ return 1;
+}
+
+/*
+ * Layout hook:
+ * Adjust size and position of pbar element, if present.
+ */
+
+static void ProgressbarDeterminateLayout(
+ Progressbar *pb,
+ Ttk_Element pbar,
+ Ttk_Box parcel,
+ double fraction,
+ Ttk_Orient orient)
+{
+ if (fraction < 0.0) fraction = 0.0;
+ if (fraction > 1.0) fraction = 1.0;
+
+ if (orient == TTK_ORIENT_HORIZONTAL) {
+ parcel.width = (int)(parcel.width * fraction);
+ } else {
+ int newHeight = (int)(parcel.height * fraction);
+ parcel.y += (parcel.height - newHeight);
+ parcel.height = newHeight;
+ }
+ Ttk_PlaceElement(pb->core.layout, pbar, parcel);
+}
+
+static void ProgressbarIndeterminateLayout(
+ Progressbar *pb,
+ Ttk_Element pbar,
+ Ttk_Box parcel,
+ double fraction,
+ Ttk_Orient orient)
+{
+ Ttk_Box pbarBox = Ttk_ElementParcel(pbar);
+
+ fraction = fmod(fabs(fraction), 2.0);
+ if (fraction > 1.0) {
+ fraction = 2.0 - fraction;
+ }
+
+ if (orient == TTK_ORIENT_HORIZONTAL) {
+ pbarBox.x = parcel.x + (int)(fraction * (parcel.width-pbarBox.width));
+ } else {
+ pbarBox.y = parcel.y + (int)(fraction * (parcel.height-pbarBox.height));
+ }
+ Ttk_PlaceElement(pb->core.layout, pbar, pbarBox);
+}
+
+static void ProgressbarDoLayout(void *recordPtr)
+{
+ Progressbar *pb = recordPtr;
+ WidgetCore *corePtr = &pb->core;
+ Ttk_Element pbar = Ttk_FindElement(corePtr->layout, "pbar");
+ double value = 0.0, maximum = 100.0;
+ int orient = TTK_ORIENT_HORIZONTAL;
+
+ Ttk_PlaceLayout(corePtr->layout,corePtr->state,Ttk_WinBox(corePtr->tkwin));
+
+ /* Adjust the bar size:
+ */
+
+ Tcl_GetDoubleFromObj(NULL, pb->progress.valueObj, &value);
+ Tcl_GetDoubleFromObj(NULL, pb->progress.maximumObj, &maximum);
+ Ttk_GetOrientFromObj(NULL, pb->progress.orientObj, &orient);
+
+ if (pbar) {
+ double fraction = value / maximum;
+ Ttk_Box parcel = Ttk_ClientRegion(corePtr->layout, "trough");
+
+ if (pb->progress.mode == TTK_PROGRESSBAR_DETERMINATE) {
+ ProgressbarDeterminateLayout(
+ pb, pbar, parcel, fraction, orient);
+ } else {
+ ProgressbarIndeterminateLayout(
+ pb, pbar, parcel, fraction, orient);
+ }
+ }
+}
+
+static Ttk_Layout ProgressbarGetLayout(
+ Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr)
+{
+ Progressbar *pb = recordPtr;
+ Ttk_Layout layout = TtkWidgetGetOrientedLayout(
+ interp, theme, recordPtr, pb->progress.orientObj);
+
+ /*
+ * Check if the style supports animation:
+ */
+ pb->progress.period = 0;
+ pb->progress.maxPhase = 0;
+ if (layout) {
+ Tcl_Obj *periodObj = Ttk_QueryOption(layout,"-period", 0);
+ Tcl_Obj *maxPhaseObj = Ttk_QueryOption(layout,"-maxphase", 0);
+ if (periodObj)
+ Tcl_GetIntFromObj(NULL, periodObj, &pb->progress.period);
+ if (maxPhaseObj)
+ Tcl_GetIntFromObj(NULL, maxPhaseObj, &pb->progress.maxPhase);
+ }
+
+ return layout;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget commands:
+ */
+
+/* $sb step ?amount?
+ */
+static int ProgressbarStepCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Progressbar *pb = recordPtr;
+ double value = 0.0, stepAmount = 1.0;
+ Tcl_Obj *newValueObj;
+
+ if (objc == 3) {
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &stepAmount) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ } else if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2,objv, "?stepAmount?");
+ return TCL_ERROR;
+ }
+
+ (void)Tcl_GetDoubleFromObj(NULL, pb->progress.valueObj, &value);
+ value += stepAmount;
+
+ /* In determinate mode, wrap around if value exceeds maximum:
+ */
+ if (pb->progress.mode == TTK_PROGRESSBAR_DETERMINATE) {
+ double maximum = 100.0;
+ (void)Tcl_GetDoubleFromObj(NULL, pb->progress.maximumObj, &maximum);
+ value = fmod(value, maximum);
+ }
+
+ newValueObj = Tcl_NewDoubleObj(value);
+
+ TtkRedisplayWidget(&pb->core);
+
+ /* Update value by setting the linked -variable, if there is one:
+ */
+ if (pb->progress.variableTrace) {
+ return Tcl_ObjSetVar2(
+ interp, pb->progress.variableObj, 0, newValueObj,
+ TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG)
+ ? TCL_OK : TCL_ERROR;
+ }
+
+ /* Otherwise, change the -value directly:
+ */
+ Tcl_IncrRefCount(newValueObj);
+ Tcl_DecrRefCount(pb->progress.valueObj);
+ pb->progress.valueObj = newValueObj;
+ CheckAnimation(pb);
+
+ return TCL_OK;
+}
+
+/* $sb start|stop ?args? --
+ * Change [$sb $cmd ...] to [ttk::progressbar::$cmd ...]
+ * and pass to interpreter.
+ */
+static int ProgressbarStartStopCommand(
+ Tcl_Interp *interp, const char *cmdName, int objc, Tcl_Obj *const objv[])
+{
+ Tcl_Obj *cmd = Tcl_NewListObj(objc, objv);
+ Tcl_Obj *prefix[2];
+ int status;
+
+ /* ASSERT: objc >= 2 */
+
+ prefix[0] = Tcl_NewStringObj(cmdName, -1);
+ prefix[1] = objv[0];
+ Tcl_ListObjReplace(interp, cmd, 0,2, 2,prefix);
+
+ Tcl_IncrRefCount(cmd);
+ status = Tcl_EvalObjEx(interp, cmd, 0);
+ Tcl_DecrRefCount(cmd);
+
+ return status;
+}
+
+static int ProgressbarStartCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ return ProgressbarStartStopCommand(
+ interp, "::ttk::progressbar::start", objc, objv);
+}
+
+static int ProgressbarStopCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ return ProgressbarStartStopCommand(
+ interp, "::ttk::progressbar::stop", objc, objv);
+}
+
+static const Ttk_Ensemble ProgressbarCommands[] = {
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "start", ProgressbarStartCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { "step", ProgressbarStepCommand,0 },
+ { "stop", ProgressbarStopCommand,0 },
+ { 0,0,0 }
+};
+
+/*
+ * Widget specification:
+ */
+static WidgetSpec ProgressbarWidgetSpec =
+{
+ "TProgressbar", /* className */
+ sizeof(Progressbar), /* recordSize */
+ ProgressbarOptionSpecs, /* optionSpecs */
+ ProgressbarCommands, /* subcommands */
+ ProgressbarInitialize, /* initializeProc */
+ ProgressbarCleanup, /* cleanupProc */
+ ProgressbarConfigure, /* configureProc */
+ ProgressbarPostConfigure, /* postConfigureProc */
+ ProgressbarGetLayout, /* getLayoutProc */
+ ProgressbarSize, /* sizeProc */
+ ProgressbarDoLayout, /* layoutProc */
+ TtkWidgetDisplay /* displayProc */
+};
+
+/*
+ * Layouts:
+ */
+TTK_BEGIN_LAYOUT(VerticalProgressbarLayout)
+ TTK_GROUP("Vertical.Progressbar.trough", TTK_FILL_BOTH,
+ TTK_NODE("Vertical.Progressbar.pbar", TTK_PACK_BOTTOM|TTK_FILL_X))
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(HorizontalProgressbarLayout)
+ TTK_GROUP("Horizontal.Progressbar.trough", TTK_FILL_BOTH,
+ TTK_NODE("Horizontal.Progressbar.pbar", TTK_PACK_LEFT|TTK_FILL_Y))
+TTK_END_LAYOUT
+
+/*
+ * Initialization:
+ */
+
+MODULE_SCOPE
+void TtkProgressbar_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);
+
+ Ttk_RegisterLayout(themePtr,
+ "Vertical.TProgressbar", VerticalProgressbarLayout);
+ Ttk_RegisterLayout(themePtr,
+ "Horizontal.TProgressbar", HorizontalProgressbarLayout);
+
+ RegisterWidget(interp, "ttk::progressbar", &ProgressbarWidgetSpec);
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkScale.c b/generic/ttk/ttkScale.c
new file mode 100644
index 0000000..69753d1
--- /dev/null
+++ b/generic/ttk/ttkScale.c
@@ -0,0 +1,515 @@
+/*
+ * Copyright (C) 2004 Pat Thoyts <patthoyts@users.sourceforge.net>
+ *
+ * ttk::scale widget.
+ */
+
+#include <tk.h>
+#include <string.h>
+#include <stdio.h>
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+#define DEF_SCALE_LENGTH "100"
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+/*
+ * Scale widget record
+ */
+typedef struct
+{
+ /* slider element options */
+ Tcl_Obj *fromObj; /* minimum value */
+ Tcl_Obj *toObj; /* maximum value */
+ Tcl_Obj *valueObj; /* current value */
+ Tcl_Obj *lengthObj; /* length of the long axis of the scale */
+ Tcl_Obj *orientObj; /* widget orientation */
+ int orient;
+
+ /* widget options */
+ Tcl_Obj *commandObj;
+ Tcl_Obj *variableObj;
+
+ /* internal state */
+ Ttk_TraceHandle *variableTrace;
+
+} ScalePart;
+
+typedef struct
+{
+ WidgetCore core;
+ ScalePart scale;
+} Scale;
+
+static Tk_OptionSpec ScaleOptionSpecs[] =
+{
+ {TK_OPTION_STRING, "-command", "command", "Command", "",
+ Tk_Offset(Scale,scale.commandObj), -1,
+ TK_OPTION_NULL_OK,0,0},
+ {TK_OPTION_STRING, "-variable", "variable", "Variable", "",
+ Tk_Offset(Scale,scale.variableObj), -1,
+ 0,0,0},
+ {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "horizontal",
+ Tk_Offset(Scale,scale.orientObj),
+ Tk_Offset(Scale,scale.orient), 0,
+ (ClientData)ttkOrientStrings, STYLE_CHANGED },
+
+ {TK_OPTION_DOUBLE, "-from", "from", "From", "0",
+ Tk_Offset(Scale,scale.fromObj), -1, 0, 0, 0},
+ {TK_OPTION_DOUBLE, "-to", "to", "To", "1.0",
+ Tk_Offset(Scale,scale.toObj), -1, 0, 0, 0},
+ {TK_OPTION_DOUBLE, "-value", "value", "Value", "0",
+ Tk_Offset(Scale,scale.valueObj), -1, 0, 0, 0},
+ {TK_OPTION_PIXELS, "-length", "length", "Length",
+ DEF_SCALE_LENGTH, Tk_Offset(Scale,scale.lengthObj), -1, 0, 0,
+ GEOMETRY_CHANGED},
+
+ WIDGET_TAKEFOCUS_TRUE,
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
+};
+
+static XPoint ValueToPoint(Scale *scalePtr, double value);
+static double PointToValue(Scale *scalePtr, int x, int y);
+
+/* ScaleVariableChanged --
+ * Variable trace procedure for scale -variable;
+ * Updates the scale's value.
+ * If the linked variable is not a valid double,
+ * sets the 'invalid' state.
+ */
+static void ScaleVariableChanged(void *recordPtr, const char *value)
+{
+ Scale *scale = recordPtr;
+ double v;
+
+ if (value == NULL || Tcl_GetDouble(0, value, &v) != TCL_OK) {
+ TtkWidgetChangeState(&scale->core, TTK_STATE_INVALID, 0);
+ } else {
+ Tcl_Obj *valueObj = Tcl_NewDoubleObj(v);
+ Tcl_IncrRefCount(valueObj);
+ Tcl_DecrRefCount(scale->scale.valueObj);
+ scale->scale.valueObj = valueObj;
+ TtkWidgetChangeState(&scale->core, 0, TTK_STATE_INVALID);
+ }
+ TtkRedisplayWidget(&scale->core);
+}
+
+/* ScaleInitialize --
+ * Scale widget initialization hook.
+ */
+static void ScaleInitialize(Tcl_Interp *interp, void *recordPtr)
+{
+ Scale *scalePtr = recordPtr;
+ TtkTrackElementState(&scalePtr->core);
+}
+
+static void ScaleCleanup(void *recordPtr)
+{
+ Scale *scale = recordPtr;
+
+ if (scale->scale.variableTrace) {
+ Ttk_UntraceVariable(scale->scale.variableTrace);
+ scale->scale.variableTrace = 0;
+ }
+}
+
+/* ScaleConfigure --
+ * Configuration hook.
+ */
+static int ScaleConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Scale *scale = recordPtr;
+ Tcl_Obj *varName = scale->scale.variableObj;
+ Ttk_TraceHandle *vt = 0;
+
+ if (varName != NULL && *Tcl_GetString(varName) != '\0') {
+ vt = Ttk_TraceVariable(interp,varName, ScaleVariableChanged,recordPtr);
+ if (!vt) return TCL_ERROR;
+ }
+
+ if (TtkCoreConfigure(interp, recordPtr, mask) != TCL_OK) {
+ if (vt) Ttk_UntraceVariable(vt);
+ return TCL_ERROR;
+ }
+
+ if (scale->scale.variableTrace) {
+ Ttk_UntraceVariable(scale->scale.variableTrace);
+ }
+ scale->scale.variableTrace = vt;
+
+ return TCL_OK;
+}
+
+/* ScalePostConfigure --
+ * Post-configuration hook.
+ */
+static int ScalePostConfigure(
+ Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Scale *scale = recordPtr;
+ int status = TCL_OK;
+
+ if (scale->scale.variableTrace) {
+ status = Ttk_FireTrace(scale->scale.variableTrace);
+ if (WidgetDestroyed(&scale->core)) {
+ return TCL_ERROR;
+ }
+ if (status != TCL_OK) {
+ /* Unset -variable: */
+ Ttk_UntraceVariable(scale->scale.variableTrace);
+ Tcl_DecrRefCount(scale->scale.variableObj);
+ scale->scale.variableTrace = 0;
+ scale->scale.variableObj = NULL;
+ status = TCL_ERROR;
+ }
+ }
+
+ return status;
+}
+
+/* ScaleGetLayout --
+ * getLayout hook.
+ */
+static Ttk_Layout
+ScaleGetLayout(Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr)
+{
+ Scale *scalePtr = recordPtr;
+ return TtkWidgetGetOrientedLayout(
+ interp, theme, recordPtr, scalePtr->scale.orientObj);
+}
+
+/*
+ * TroughBox --
+ * Returns the inner area of the trough element.
+ */
+static Ttk_Box TroughBox(Scale *scalePtr)
+{
+ return Ttk_ClientRegion(scalePtr->core.layout, "trough");
+}
+
+/*
+ * TroughRange --
+ * Return the value area of the trough element, adjusted
+ * for slider size.
+ */
+static Ttk_Box TroughRange(Scale *scalePtr)
+{
+ Ttk_Box troughBox = TroughBox(scalePtr);
+ Ttk_Element slider = Ttk_FindElement(scalePtr->core.layout,"slider");
+
+ /*
+ * If this is a scale widget, adjust range for slider:
+ */
+ if (slider) {
+ Ttk_Box sliderBox = Ttk_ElementParcel(slider);
+ if (scalePtr->scale.orient == TTK_ORIENT_HORIZONTAL) {
+ troughBox.x += sliderBox.width / 2;
+ troughBox.width -= sliderBox.width;
+ } else {
+ troughBox.y += sliderBox.height / 2;
+ troughBox.height -= sliderBox.height;
+ }
+ }
+
+ return troughBox;
+}
+
+/*
+ * ScaleFraction --
+ */
+static double ScaleFraction(Scale *scalePtr, double value)
+{
+ double from = 0, to = 1, fraction;
+
+ Tcl_GetDoubleFromObj(NULL, scalePtr->scale.fromObj, &from);
+ Tcl_GetDoubleFromObj(NULL, scalePtr->scale.toObj, &to);
+
+ if (from == to) {
+ return 1.0;
+ }
+
+ fraction = (value - from) / (to - from);
+
+ return fraction < 0 ? 0 : fraction > 1 ? 1 : fraction;
+}
+
+/* $scale get ?x y? --
+ * Returns the current value of the scale widget, or if $x and
+ * $y are specified, the value represented by point @x,y.
+ */
+static int
+ScaleGetCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Scale *scalePtr = recordPtr;
+ int x, y, r = TCL_OK;
+ double value = 0;
+
+ if ((objc != 2) && (objc != 4)) {
+ Tcl_WrongNumArgs(interp, 1, objv, "get ?x y?");
+ return TCL_ERROR;
+ }
+ if (objc == 2) {
+ Tcl_SetObjResult(interp, scalePtr->scale.valueObj);
+ } else {
+ r = Tcl_GetIntFromObj(interp, objv[2], &x);
+ if (r == TCL_OK)
+ r = Tcl_GetIntFromObj(interp, objv[3], &y);
+ if (r == TCL_OK) {
+ value = PointToValue(scalePtr, x, y);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(value));
+ }
+ }
+ return r;
+}
+
+/* $scale set $newValue
+ */
+static int
+ScaleSetCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Scale *scalePtr = recordPtr;
+ double from = 0.0, to = 1.0, value;
+ int result = TCL_OK;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "set value");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &value) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (scalePtr->core.state & TTK_STATE_DISABLED) {
+ return TCL_OK;
+ }
+
+ /* ASSERT: fromObj and toObj are valid doubles.
+ */
+ Tcl_GetDoubleFromObj(interp, scalePtr->scale.fromObj, &from);
+ Tcl_GetDoubleFromObj(interp, scalePtr->scale.toObj, &to);
+
+ /* Limit new value to between 'from' and 'to':
+ */
+ if (from < to) {
+ value = value < from ? from : value > to ? to : value;
+ } else {
+ value = value < to ? to : value > from ? from : value;
+ }
+
+ /*
+ * Set value:
+ */
+ Tcl_DecrRefCount(scalePtr->scale.valueObj);
+ scalePtr->scale.valueObj = Tcl_NewDoubleObj(value);
+ Tcl_IncrRefCount(scalePtr->scale.valueObj);
+ TtkRedisplayWidget(&scalePtr->core);
+
+ /*
+ * Set attached variable, if any:
+ */
+ if (scalePtr->scale.variableObj != NULL) {
+ Tcl_ObjSetVar2(interp, scalePtr->scale.variableObj, NULL,
+ scalePtr->scale.valueObj, TCL_GLOBAL_ONLY);
+ }
+ if (WidgetDestroyed(&scalePtr->core)) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Invoke -command, if any:
+ */
+ if (scalePtr->scale.commandObj != NULL) {
+ Tcl_Obj *cmdObj = Tcl_DuplicateObj(scalePtr->scale.commandObj);
+ Tcl_IncrRefCount(cmdObj);
+ Tcl_AppendToObj(cmdObj, " ", 1);
+ Tcl_AppendObjToObj(cmdObj, scalePtr->scale.valueObj);
+ result = Tcl_EvalObjEx(interp, cmdObj, TCL_EVAL_GLOBAL);
+ Tcl_DecrRefCount(cmdObj);
+ }
+
+ return result;
+}
+
+static int
+ScaleCoordsCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Scale *scalePtr = recordPtr;
+ double value;
+ int r = TCL_OK;
+
+ if (objc < 2 || objc > 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "coords ?value?");
+ return TCL_ERROR;
+ }
+
+ if (objc == 3) {
+ r = Tcl_GetDoubleFromObj(interp, objv[2], &value);
+ } else {
+ r = Tcl_GetDoubleFromObj(interp, scalePtr->scale.valueObj, &value);
+ }
+
+ if (r == TCL_OK) {
+ Tcl_Obj *point[2];
+ XPoint pt = ValueToPoint(scalePtr, value);
+ point[0] = Tcl_NewIntObj(pt.x);
+ point[1] = Tcl_NewIntObj(pt.y);
+ Tcl_SetObjResult(interp, Tcl_NewListObj(2, point));
+ }
+ return r;
+}
+
+static void ScaleDoLayout(void *clientData)
+{
+ WidgetCore *corePtr = clientData;
+ Ttk_Element slider = Ttk_FindElement(corePtr->layout, "slider");
+
+ Ttk_PlaceLayout(corePtr->layout,corePtr->state,Ttk_WinBox(corePtr->tkwin));
+
+ /* Adjust the slider position:
+ */
+ if (slider) {
+ Scale *scalePtr = clientData;
+ Ttk_Box troughBox = TroughBox(scalePtr);
+ Ttk_Box sliderBox = Ttk_ElementParcel(slider);
+ double value = 0.0;
+ double fraction;
+ int range;
+
+ Tcl_GetDoubleFromObj(NULL, scalePtr->scale.valueObj, &value);
+ fraction = ScaleFraction(scalePtr, value);
+
+ if (scalePtr->scale.orient == TTK_ORIENT_HORIZONTAL) {
+ range = troughBox.width - sliderBox.width;
+ sliderBox.x += (int)(fraction * range);
+ } else {
+ range = troughBox.height - sliderBox.height;
+ sliderBox.y += (int)(fraction * range);
+ }
+ Ttk_PlaceElement(corePtr->layout, slider, sliderBox);
+ }
+}
+
+/*
+ * ScaleSize --
+ * Compute requested size of scale.
+ */
+static int ScaleSize(void *clientData, int *widthPtr, int *heightPtr)
+{
+ WidgetCore *corePtr = clientData;
+ Scale *scalePtr = clientData;
+ int length;
+
+ Ttk_LayoutSize(corePtr->layout, corePtr->state, widthPtr, heightPtr);
+
+ /* Assert the -length configuration option */
+ Tk_GetPixelsFromObj(NULL, corePtr->tkwin,
+ scalePtr->scale.lengthObj, &length);
+ if (scalePtr->scale.orient == TTK_ORIENT_VERTICAL) {
+ *heightPtr = MAX(*heightPtr, length);
+ } else {
+ *widthPtr = MAX(*widthPtr, length);
+ }
+
+ return 1;
+}
+
+static double
+PointToValue(Scale *scalePtr, int x, int y)
+{
+ Ttk_Box troughBox = TroughRange(scalePtr);
+ double from = 0, to = 1, fraction;
+
+ Tcl_GetDoubleFromObj(NULL, scalePtr->scale.fromObj, &from);
+ Tcl_GetDoubleFromObj(NULL, scalePtr->scale.toObj, &to);
+
+ if (scalePtr->scale.orient == TTK_ORIENT_HORIZONTAL) {
+ fraction = (double)(x - troughBox.x) / (double)troughBox.width;
+ } else {
+ fraction = (double)(y - troughBox.y) / (double)troughBox.height;
+ }
+
+ fraction = fraction < 0 ? 0 : fraction > 1 ? 1 : fraction;
+
+ return from + fraction * (to-from);
+}
+
+/*
+ * Return the center point in the widget corresponding to the given
+ * value. This point can be used to center the slider.
+ */
+
+static XPoint
+ValueToPoint(Scale *scalePtr, double value)
+{
+ Ttk_Box troughBox = TroughRange(scalePtr);
+ double fraction = ScaleFraction(scalePtr, value);
+ XPoint pt = {0, 0};
+
+ if (scalePtr->scale.orient == TTK_ORIENT_HORIZONTAL) {
+ pt.x = troughBox.x + (int)(fraction * troughBox.width);
+ pt.y = troughBox.y + troughBox.height / 2;
+ } else {
+ pt.x = troughBox.x + troughBox.width / 2;
+ pt.y = troughBox.y + (int)(fraction * troughBox.height);
+ }
+ return pt;
+}
+
+static const Ttk_Ensemble ScaleCommands[] = {
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ { "set", ScaleSetCommand,0 },
+ { "get", ScaleGetCommand,0 },
+ { "coords", ScaleCoordsCommand,0 },
+ { 0,0,0 }
+};
+
+static WidgetSpec ScaleWidgetSpec =
+{
+ "TScale", /* Class name */
+ sizeof(Scale), /* record size */
+ ScaleOptionSpecs, /* option specs */
+ ScaleCommands, /* widget commands */
+ ScaleInitialize, /* initialization proc */
+ ScaleCleanup, /* cleanup proc */
+ ScaleConfigure, /* configure proc */
+ ScalePostConfigure, /* postConfigure */
+ ScaleGetLayout, /* getLayoutProc */
+ ScaleSize, /* sizeProc */
+ ScaleDoLayout, /* layoutProc */
+ TtkWidgetDisplay /* displayProc */
+};
+
+TTK_BEGIN_LAYOUT(VerticalScaleLayout)
+ TTK_GROUP("Vertical.Scale.trough", TTK_FILL_BOTH,
+ TTK_NODE("Vertical.Scale.slider", TTK_PACK_TOP) )
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(HorizontalScaleLayout)
+ TTK_GROUP("Horizontal.Scale.trough", TTK_FILL_BOTH,
+ TTK_NODE("Horizontal.Scale.slider", TTK_PACK_LEFT) )
+TTK_END_LAYOUT
+
+/*
+ * Initialization.
+ */
+MODULE_SCOPE
+void TtkScale_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme theme = Ttk_GetDefaultTheme(interp);
+
+ Ttk_RegisterLayout(theme, "Vertical.TScale", VerticalScaleLayout);
+ Ttk_RegisterLayout(theme, "Horizontal.TScale", HorizontalScaleLayout);
+
+ RegisterWidget(interp, "ttk::scale", &ScaleWidgetSpec);
+}
+
diff --git a/generic/ttk/ttkScroll.c b/generic/ttk/ttkScroll.c
new file mode 100644
index 0000000..defe05a
--- /dev/null
+++ b/generic/ttk/ttkScroll.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2004, Joe English
+ *
+ * Support routines for scrollable widgets.
+ *
+ * (This is sort of half-baked; needs some work)
+ *
+ * Scrollable interface:
+ *
+ * + 'first' is controlled by [xy]view widget command
+ * and other scrolling commands like 'see';
+ * + 'total' depends on widget contents;
+ * + 'last' depends on first, total, and widget size.
+ *
+ * Choreography (typical usage):
+ *
+ * 1. User adjusts scrollbar, scrollbar widget calls its -command
+ * 2. Scrollbar -command invokes the scrollee [xy]view widget method
+ * 3. TtkScrollviewCommand calls TtkScrollTo(), which updates
+ * 'first' and schedules a redisplay.
+ * 4. Once the scrollee knows 'total' and 'last' (typically in
+ * the LayoutProc), call TtkScrolled(h,first,last,total) to
+ * synchronize the scrollbar.
+ * 5. The scrollee -[xy]scrollcommand is called (in an idle callback)
+ * 6. Which calls the scrollbar 'set' method and redisplays the scrollbar.
+ *
+ * If the scrollee has internal scrolling (e.g., a 'see' method),
+ * it should TtkScrollTo() directly (step 2).
+ *
+ * If the widget value changes, it should call TtkScrolled() (step 4).
+ * (This usually happens automatically when the widget is redisplayed).
+ *
+ * If the scrollee's -[xy]scrollcommand changes, it should call
+ * TtkScrollbarUpdateRequired, which will invoke step (5) (@@@ Fix this)
+ */
+
+#include <tk.h>
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+/* Private data:
+ */
+#define SCROLL_UPDATE_PENDING (0x1)
+#define SCROLL_UPDATE_REQUIRED (0x2)
+
+struct ScrollHandleRec
+{
+ unsigned flags;
+ WidgetCore *corePtr;
+ Scrollable *scrollPtr;
+};
+
+/* TtkCreateScrollHandle --
+ * Initialize scroll handle.
+ */
+ScrollHandle TtkCreateScrollHandle(WidgetCore *corePtr, Scrollable *scrollPtr)
+{
+ ScrollHandle h = (ScrollHandle)ckalloc(sizeof(*h));
+
+ h->flags = 0;
+ h->corePtr = corePtr;
+ h->scrollPtr = scrollPtr;
+
+ scrollPtr->first = 0;
+ scrollPtr->last = 1;
+ scrollPtr->total = 1;
+ return h;
+}
+
+/* UpdateScrollbar --
+ * Call the -scrollcommand callback to sync the scrollbar.
+ * Returns: Whatever the -scrollcommand does.
+ */
+static int UpdateScrollbar(Tcl_Interp *interp, ScrollHandle h)
+{
+ Scrollable *s = h->scrollPtr;
+ WidgetCore *corePtr = h->corePtr;
+ char arg1[TCL_DOUBLE_SPACE + 2];
+ char arg2[TCL_DOUBLE_SPACE + 2];
+ int code;
+
+ h->flags &= ~SCROLL_UPDATE_REQUIRED;
+
+ if (s->scrollCmd == NULL) {
+ return TCL_OK;
+ }
+
+ arg1[0] = arg2[0] = ' ';
+ Tcl_PrintDouble(interp, (double)s->first / s->total, arg1+1);
+ Tcl_PrintDouble(interp, (double)s->last / s->total, arg2+1);
+
+ Tcl_Preserve(corePtr);
+ code = Tcl_VarEval(interp, s->scrollCmd, arg1, arg2, NULL);
+ if (WidgetDestroyed(corePtr)) {
+ Tcl_Release(corePtr);
+ return TCL_ERROR;
+ }
+ Tcl_Release(corePtr);
+
+ if (code != TCL_OK && !Tcl_InterpDeleted(interp)) {
+ /* Disable the -scrollcommand, add to stack trace:
+ */
+ ckfree(s->scrollCmd);
+ s->scrollCmd = 0;
+
+ Tcl_AddErrorInfo(interp, /* @@@ "horizontal" / "vertical" */
+ "\n (scrolling command executed by ");
+ Tcl_AddErrorInfo(interp, Tk_PathName(h->corePtr->tkwin));
+ Tcl_AddErrorInfo(interp, ")");
+ }
+ return code;
+}
+
+/* UpdateScrollbarBG --
+ * Idle handler to update the scrollbar.
+ */
+static void UpdateScrollbarBG(ClientData clientData)
+{
+ ScrollHandle h = (ScrollHandle)clientData;
+ Tcl_Interp *interp = h->corePtr->interp;
+ int code;
+
+ h->flags &= ~SCROLL_UPDATE_PENDING;
+ Tcl_Preserve((ClientData) interp);
+ code = UpdateScrollbar(interp, h);
+ if (code == TCL_ERROR && !Tcl_InterpDeleted(interp)) {
+ Tcl_BackgroundError(interp);
+ }
+ Tcl_Release((ClientData) interp);
+}
+
+/* TtkScrolled --
+ * Update scroll info, schedule scrollbar update.
+ */
+void TtkScrolled(ScrollHandle h, int first, int last, int total)
+{
+ Scrollable *s = h->scrollPtr;
+
+ /* Sanity-check inputs:
+ */
+ if (total <= 0) {
+ first = 0;
+ last = 1;
+ total = 1;
+ }
+
+ if (last > total) {
+ first -= (last - total);
+ if (first < 0) first = 0;
+ last = total;
+ }
+
+ if (s->first != first || s->last != last || s->total != total
+ || (h->flags & SCROLL_UPDATE_REQUIRED))
+ {
+ s->first = first;
+ s->last = last;
+ s->total = total;
+
+ if (!(h->flags & SCROLL_UPDATE_PENDING)) {
+ Tcl_DoWhenIdle(UpdateScrollbarBG, (ClientData)h);
+ h->flags |= SCROLL_UPDATE_PENDING;
+ }
+ }
+}
+
+/* TtkScrollbarUpdateRequired --
+ * Force a scrollbar update at the next call to TtkScrolled(),
+ * even if scroll parameters haven't changed (e.g., if
+ * -yscrollcommand has changed).
+ */
+
+void TtkScrollbarUpdateRequired(ScrollHandle h)
+{
+ h->flags |= SCROLL_UPDATE_REQUIRED;
+}
+
+/* TtkScrollviewCommand --
+ * Widget [xy]view command implementation.
+ *
+ * $w [xy]view -- return current view region
+ * $w [xy]view $index -- set topmost item
+ * $w [xy]view moveto $fraction
+ * $w [xy]view scroll $number $what -- scrollbar interface
+ */
+int TtkScrollviewCommand(
+ Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], ScrollHandle h)
+{
+ Scrollable *s = h->scrollPtr;
+ int newFirst = s->first;
+
+ if (objc == 2) {
+ Tcl_Obj *result[2];
+ result[0] = Tcl_NewDoubleObj((double)s->first / s->total);
+ result[1] = Tcl_NewDoubleObj((double)s->last / s->total);
+ Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
+ return TCL_OK;
+ } else if (objc == 3) {
+ if (Tcl_GetIntFromObj(interp, objv[2], &newFirst) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ } else {
+ double fraction;
+ int count;
+
+ switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) {
+ case TK_SCROLL_ERROR:
+ return TCL_ERROR;
+ case TK_SCROLL_MOVETO:
+ newFirst = (int) ((fraction * s->total) + 0.5);
+ break;
+ case TK_SCROLL_UNITS:
+ newFirst = s->first + count;
+ break;
+ case TK_SCROLL_PAGES: {
+ int perPage = s->last - s->first; /* @@@ */
+ newFirst = s->first + count * perPage;
+ break;
+ }
+ }
+ }
+
+ TtkScrollTo(h, newFirst);
+
+ return TCL_OK;
+}
+
+void TtkScrollTo(ScrollHandle h, int newFirst)
+{
+ Scrollable *s = h->scrollPtr;
+
+ if (newFirst >= s->total)
+ newFirst = s->total - 1;
+ if (newFirst > s->first && s->last >= s->total) /* don't scroll past end */
+ newFirst = s->first;
+ if (newFirst < 0)
+ newFirst = 0;
+
+ if (newFirst != s->first) {
+ s->first = newFirst;
+ TtkRedisplayWidget(h->corePtr);
+ }
+}
+
+void TtkFreeScrollHandle(ScrollHandle h)
+{
+ if (h->flags & SCROLL_UPDATE_PENDING) {
+ Tcl_CancelIdleCall(UpdateScrollbarBG, (ClientData)h);
+ }
+ ckfree((ClientData)h);
+}
+
diff --git a/generic/ttk/ttkScrollbar.c b/generic/ttk/ttkScrollbar.c
new file mode 100644
index 0000000..5b0c212
--- /dev/null
+++ b/generic/ttk/ttkScrollbar.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 2003, Joe English
+ *
+ * ttk::scrollbar widget.
+ */
+
+#include <tk.h>
+
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+/*------------------------------------------------------------------------
+ * +++ Scrollbar widget record.
+ */
+typedef struct
+{
+ Tcl_Obj *commandObj;
+
+ int orient;
+ Tcl_Obj *orientObj;
+
+ double first; /* top fraction */
+ double last; /* bottom fraction */
+
+ Ttk_Box troughBox; /* trough parcel */
+ int minSize; /* minimum size of thumb */
+} ScrollbarPart;
+
+typedef struct
+{
+ WidgetCore core;
+ ScrollbarPart scrollbar;
+} Scrollbar;
+
+static Tk_OptionSpec ScrollbarOptionSpecs[] =
+{
+ {TK_OPTION_STRING, "-command", "command", "Command", "",
+ Tk_Offset(Scrollbar,scrollbar.commandObj), -1, 0,0,0},
+
+ {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "vertical",
+ Tk_Offset(Scrollbar,scrollbar.orientObj),
+ Tk_Offset(Scrollbar,scrollbar.orient),
+ 0,(ClientData)ttkOrientStrings,STYLE_CHANGED },
+
+ WIDGET_TAKEFOCUS_FALSE,
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
+};
+
+/*------------------------------------------------------------------------
+ * +++ Widget hooks.
+ */
+
+static void
+ScrollbarInitialize(Tcl_Interp *interp, void *recordPtr)
+{
+ Scrollbar *sb = recordPtr;
+ sb->scrollbar.first = 0.0;
+ sb->scrollbar.last = 1.0;
+
+ TtkTrackElementState(&sb->core);
+}
+
+static Ttk_Layout ScrollbarGetLayout(
+ Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr)
+{
+ Scrollbar *sb = recordPtr;
+ return TtkWidgetGetOrientedLayout(
+ interp, theme, recordPtr, sb->scrollbar.orientObj);
+}
+
+/*
+ * ScrollbarDoLayout --
+ * Layout hook. Adjusts the position of the scrollbar thumb.
+ *
+ * Side effects:
+ * Sets sb->troughBox and sb->minSize.
+ */
+static void ScrollbarDoLayout(void *recordPtr)
+{
+ Scrollbar *sb = recordPtr;
+ WidgetCore *corePtr = &sb->core;
+ Ttk_Element thumb;
+ Ttk_Box thumbBox;
+ int thumbWidth, thumbHeight;
+ double first, last, size;
+ int minSize;
+
+ /*
+ * Use generic layout manager to compute initial layout:
+ */
+ Ttk_PlaceLayout(corePtr->layout,corePtr->state,Ttk_WinBox(corePtr->tkwin));
+
+ /*
+ * Locate thumb element, extract parcel and requested minimum size:
+ */
+ thumb = Ttk_FindElement(corePtr->layout, "thumb");
+ if (!thumb) /* Something has gone wrong -- bail */
+ return;
+
+ sb->scrollbar.troughBox = thumbBox = Ttk_ElementParcel(thumb);
+ Ttk_LayoutNodeReqSize(
+ corePtr->layout, thumb, &thumbWidth,&thumbHeight);
+
+ /*
+ * Adjust thumb element parcel:
+ */
+ first = sb->scrollbar.first;
+ last = sb->scrollbar.last;
+
+ if (sb->scrollbar.orient == TTK_ORIENT_VERTICAL) {
+ minSize = thumbHeight;
+ size = thumbBox.height - minSize;
+ thumbBox.y += (int)(size * first);
+ thumbBox.height = (int)(size * last) + minSize - (int)(size * first);
+ } else {
+ minSize = thumbWidth;
+ size = thumbBox.width - minSize;
+ thumbBox.x += (int)(size * first);
+ thumbBox.width = (int)(size * last) + minSize - (int)(size * first);
+ }
+ sb->scrollbar.minSize = minSize;
+ Ttk_PlaceElement(corePtr->layout, thumb, thumbBox);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget commands.
+ */
+
+/* $sb set $first $last --
+ * Set the position of the scrollbar.
+ */
+static int
+ScrollbarSetCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Scrollbar *scrollbar = recordPtr;
+ Tcl_Obj *firstObj, *lastObj;
+ double first, last;
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "first last");
+ return TCL_ERROR;
+ }
+
+ firstObj = objv[2];
+ lastObj = objv[3];
+ if (Tcl_GetDoubleFromObj(interp, firstObj, &first) != TCL_OK
+ || Tcl_GetDoubleFromObj(interp, lastObj, &last) != TCL_OK)
+ return TCL_ERROR;
+
+ /* Range-checks:
+ */
+ if (first < 0.0) {
+ first = 0.0;
+ } else if (first > 1.0) {
+ first = 1.0;
+ }
+
+ if (last < first) {
+ last = first;
+ } else if (last > 1.0) {
+ last = 1.0;
+ }
+
+ /* ASSERT: 0.0 <= first <= last <= 1.0 */
+
+ scrollbar->scrollbar.first = first;
+ scrollbar->scrollbar.last = last;
+ if (first <= 0.0 && last >= 1.0) {
+ scrollbar->core.state |= TTK_STATE_DISABLED;
+ } else {
+ scrollbar->core.state &= ~TTK_STATE_DISABLED;
+ }
+
+ TtkRedisplayWidget(&scrollbar->core);
+
+ return TCL_OK;
+}
+
+/* $sb get --
+ * Returns the last thing passed to 'set'.
+ */
+static int
+ScrollbarGetCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Scrollbar *scrollbar = recordPtr;
+ Tcl_Obj *result[2];
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "");
+ return TCL_ERROR;
+ }
+
+ result[0] = Tcl_NewDoubleObj(scrollbar->scrollbar.first);
+ result[1] = Tcl_NewDoubleObj(scrollbar->scrollbar.last);
+ Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
+
+ return TCL_OK;
+}
+
+/* $sb delta $dx $dy --
+ * Returns the percentage change corresponding to a mouse movement
+ * of $dx, $dy.
+ */
+static int
+ScrollbarDeltaCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Scrollbar *sb = recordPtr;
+ double dx, dy;
+ double delta = 0.0;
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "dx dy");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &dx) != TCL_OK
+ || Tcl_GetDoubleFromObj(interp, objv[3], &dy) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ delta = 0.0;
+ if (sb->scrollbar.orient == TTK_ORIENT_VERTICAL) {
+ int size = sb->scrollbar.troughBox.height - sb->scrollbar.minSize;
+ if (size > 0) {
+ delta = (double)dy / (double)size;
+ }
+ } else {
+ int size = sb->scrollbar.troughBox.width - sb->scrollbar.minSize;
+ if (size > 0) {
+ delta = (double)dx / (double)size;
+ }
+ }
+
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(delta));
+ return TCL_OK;
+}
+
+/* $sb fraction $x $y --
+ * Returns a real number between 0 and 1 indicating where the
+ * point given by x and y lies in the trough area of the scrollbar.
+ */
+static int
+ScrollbarFractionCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Scrollbar *sb = recordPtr;
+ Ttk_Box b = sb->scrollbar.troughBox;
+ int minSize = sb->scrollbar.minSize;
+ double x, y;
+ double fraction = 0.0;
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &x) != TCL_OK
+ || Tcl_GetDoubleFromObj(interp, objv[3], &y) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ fraction = 0.0;
+ if (sb->scrollbar.orient == TTK_ORIENT_VERTICAL) {
+ if (b.height > minSize) {
+ fraction = (double)(y - b.y) / (double)(b.height - minSize);
+ }
+ } else {
+ if (b.width > minSize) {
+ fraction = (double)(x - b.x) / (double)(b.width - minSize);
+ }
+ }
+
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(fraction));
+ return TCL_OK;
+}
+
+static const Ttk_Ensemble ScrollbarCommands[] = {
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "delta", ScrollbarDeltaCommand,0 },
+ { "fraction", ScrollbarFractionCommand,0 },
+ { "get", ScrollbarGetCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "set", ScrollbarSetCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { 0,0,0 }
+};
+
+/*------------------------------------------------------------------------
+ * +++ Widget specification.
+ */
+static WidgetSpec ScrollbarWidgetSpec =
+{
+ "TScrollbar", /* className */
+ sizeof(Scrollbar), /* recordSize */
+ ScrollbarOptionSpecs, /* optionSpecs */
+ ScrollbarCommands, /* subcommands */
+ ScrollbarInitialize, /* initializeProc */
+ TtkNullCleanup, /* cleanupProc */
+ TtkCoreConfigure, /* configureProc */
+ TtkNullPostConfigure, /* postConfigureProc */
+ ScrollbarGetLayout, /* getLayoutProc */
+ TtkWidgetSize, /* sizeProc */
+ ScrollbarDoLayout, /* layoutProc */
+ TtkWidgetDisplay /* displayProc */
+};
+
+TTK_BEGIN_LAYOUT(VerticalScrollbarLayout)
+ TTK_GROUP("Vertical.Scrollbar.trough", TTK_FILL_Y,
+ TTK_NODE("Vertical.Scrollbar.uparrow", TTK_PACK_TOP)
+ TTK_NODE("Vertical.Scrollbar.downarrow", TTK_PACK_BOTTOM)
+ TTK_NODE(
+ "Vertical.Scrollbar.thumb", TTK_PACK_TOP|TTK_EXPAND|TTK_FILL_BOTH))
+TTK_END_LAYOUT
+
+TTK_BEGIN_LAYOUT(HorizontalScrollbarLayout)
+ TTK_GROUP("Horizontal.Scrollbar.trough", TTK_FILL_X,
+ TTK_NODE("Horizontal.Scrollbar.leftarrow", TTK_PACK_LEFT)
+ TTK_NODE("Horizontal.Scrollbar.rightarrow", TTK_PACK_RIGHT)
+ TTK_NODE(
+ "Horizontal.Scrollbar.thumb", TTK_PACK_LEFT|TTK_EXPAND|TTK_FILL_BOTH))
+TTK_END_LAYOUT
+
+/*------------------------------------------------------------------------
+ * +++ Initialization.
+ */
+
+MODULE_SCOPE
+void TtkScrollbar_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme theme = Ttk_GetDefaultTheme(interp);
+
+ Ttk_RegisterLayout(theme,"Vertical.TScrollbar",VerticalScrollbarLayout);
+ Ttk_RegisterLayout(theme,"Horizontal.TScrollbar",HorizontalScrollbarLayout);
+
+ RegisterWidget(interp, "ttk::scrollbar", &ScrollbarWidgetSpec);
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkSeparator.c b/generic/ttk/ttkSeparator.c
new file mode 100644
index 0000000..b52e6f4
--- /dev/null
+++ b/generic/ttk/ttkSeparator.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2004, Joe English
+ *
+ * ttk::separator and ttk::sizegrip widgets.
+ */
+
+#include <tk.h>
+
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+/* +++ Separator widget record:
+ */
+typedef struct
+{
+ Tcl_Obj *orientObj;
+ int orient;
+} SeparatorPart;
+
+typedef struct
+{
+ WidgetCore core;
+ SeparatorPart separator;
+} Separator;
+
+static Tk_OptionSpec SeparatorOptionSpecs[] = {
+ {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "horizontal",
+ Tk_Offset(Separator,separator.orientObj),
+ Tk_Offset(Separator,separator.orient),
+ 0,(ClientData)ttkOrientStrings,STYLE_CHANGED },
+
+ WIDGET_TAKEFOCUS_FALSE,
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
+};
+
+/*
+ * GetLayout hook --
+ * Choose layout based on -orient option.
+ */
+static Ttk_Layout SeparatorGetLayout(
+ Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr)
+{
+ Separator *sep = recordPtr;
+ return TtkWidgetGetOrientedLayout(
+ interp, theme, recordPtr, sep->separator.orientObj);
+}
+
+/*
+ * Widget commands:
+ */
+static const Ttk_Ensemble SeparatorCommands[] = {
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { 0,0,0 }
+};
+
+/*
+ * Widget specification:
+ */
+static WidgetSpec SeparatorWidgetSpec =
+{
+ "TSeparator", /* className */
+ sizeof(Separator), /* recordSize */
+ SeparatorOptionSpecs, /* optionSpecs */
+ SeparatorCommands, /* subcommands */
+ TtkNullInitialize, /* initializeProc */
+ TtkNullCleanup, /* cleanupProc */
+ TtkCoreConfigure, /* configureProc */
+ TtkNullPostConfigure, /* postConfigureProc */
+ SeparatorGetLayout, /* getLayoutProc */
+ TtkWidgetSize, /* sizeProc */
+ TtkWidgetDoLayout, /* layoutProc */
+ TtkWidgetDisplay /* displayProc */
+};
+
+TTK_BEGIN_LAYOUT(SeparatorLayout)
+ TTK_NODE("Separator.separator", TTK_FILL_BOTH)
+TTK_END_LAYOUT
+
+/* +++ Sizegrip widget:
+ * Has no options or methods other than the standard ones.
+ */
+
+static Tk_OptionSpec SizegripOptionSpecs[] = {
+ WIDGET_TAKEFOCUS_FALSE,
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
+};
+
+static const Ttk_Ensemble SizegripCommands[] = {
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { 0,0,0 }
+};
+
+static WidgetSpec SizegripWidgetSpec =
+{
+ "TSizegrip", /* className */
+ sizeof(WidgetCore), /* recordSize */
+ SizegripOptionSpecs, /* optionSpecs */
+ SizegripCommands, /* subcommands */
+ TtkNullInitialize, /* initializeProc */
+ TtkNullCleanup, /* cleanupProc */
+ TtkCoreConfigure, /* configureProc */
+ TtkNullPostConfigure, /* postConfigureProc */
+ TtkWidgetGetLayout, /* getLayoutProc */
+ TtkWidgetSize, /* sizeProc */
+ TtkWidgetDoLayout, /* layoutProc */
+ TtkWidgetDisplay /* displayProc */
+};
+
+TTK_BEGIN_LAYOUT(SizegripLayout)
+ TTK_NODE("Sizegrip.sizegrip", TTK_PACK_BOTTOM|TTK_STICK_S|TTK_STICK_E)
+TTK_END_LAYOUT
+
+/* +++ Initialization:
+ */
+
+MODULE_SCOPE
+void TtkSeparator_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme theme = Ttk_GetDefaultTheme(interp);
+
+ Ttk_RegisterLayout(theme, "TSeparator", SeparatorLayout);
+ Ttk_RegisterLayout(theme, "TSizegrip", SizegripLayout);
+
+ RegisterWidget(interp, "ttk::separator", &SeparatorWidgetSpec);
+ RegisterWidget(interp, "ttk::sizegrip", &SizegripWidgetSpec);
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkSquare.c b/generic/ttk/ttkSquare.c
new file mode 100644
index 0000000..d002f2f
--- /dev/null
+++ b/generic/ttk/ttkSquare.c
@@ -0,0 +1,301 @@
+/* square.c - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sourceforge.net>
+ *
+ * Minimal sample ttk widget.
+ */
+
+#include <tk.h>
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+#if defined(TTK_SQUARE_WIDGET) || 1
+
+#ifndef DEFAULT_BORDERWIDTH
+#define DEFAULT_BORDERWIDTH "2"
+#endif
+
+/*
+ * First, we setup the widget record. The Ttk package provides a structure
+ * that contains standard widget data so it is only necessary to define
+ * a structure that holds the data required for our widget. We do this by
+ * defining a widget part and then specifying the widget record as the
+ * concatenation of the two structures.
+ */
+
+typedef struct
+{
+ Tcl_Obj *widthObj;
+ Tcl_Obj *heightObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *borderWidthObj;
+ Tcl_Obj *foregroundObj;
+ Tcl_Obj *paddingObj;
+ Tcl_Obj *anchorObj;
+} SquarePart;
+
+typedef struct
+{
+ WidgetCore core;
+ SquarePart square;
+} Square;
+
+/*
+ * Widget options.
+ *
+ * This structure is the same as the option specification structure used
+ * for Tk widgets. For each option we provide the type, name and options
+ * database name and class name and the position in the structure and
+ * default values. At the bottom we bring in the standard widget option
+ * defined for all widgets.
+ */
+
+static Tk_OptionSpec SquareOptionSpecs[] =
+{
+ {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
+ DEFAULT_BORDERWIDTH, Tk_Offset(Square,square.borderWidthObj), -1,
+ 0,0,GEOMETRY_CHANGED },
+ {TK_OPTION_BORDER, "-foreground", "foreground", "Foreground",
+ DEFAULT_BACKGROUND, Tk_Offset(Square,square.foregroundObj),
+ -1, 0, 0, 0},
+
+ {TK_OPTION_PIXELS, "-width", "width", "Width",
+ "50", Tk_Offset(Square,square.widthObj), -1, 0, 0,
+ GEOMETRY_CHANGED},
+ {TK_OPTION_PIXELS, "-height", "height", "Height",
+ "50", Tk_Offset(Square,square.heightObj), -1, 0, 0,
+ GEOMETRY_CHANGED},
+
+ {TK_OPTION_STRING, "-padding", "padding", "Pad", NULL,
+ Tk_Offset(Square,square.paddingObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+
+ {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
+ NULL, Tk_Offset(Square,square.reliefObj), -1, TK_OPTION_NULL_OK, 0, 0},
+
+ {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
+ NULL, Tk_Offset(Square,square.anchorObj), -1, TK_OPTION_NULL_OK, 0, 0},
+
+ WIDGET_TAKEFOCUS_TRUE,
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
+};
+
+/*
+ * Almost all of the widget functionality is handled by the default Ttk
+ * widget code and the contained element. The one thing that we must handle
+ * is the -anchor option which positions the square element within the parcel
+ * of space available for the widget.
+ * To do this we must find out the layout preferences for the square
+ * element and adjust its position within our region.
+ *
+ * Note that if we do not have a "square" elememt then just the default
+ * layout will be done. So if someone places a label element into the
+ * widget layout it will still be handled but the -anchor option will be
+ * passed onto the label element instead of handled here.
+ */
+
+static void
+SquareDoLayout(void *clientData)
+{
+ WidgetCore *corePtr = (WidgetCore *)clientData;
+ Ttk_Box winBox;
+ Ttk_Element squareNode;
+
+ squareNode = Ttk_FindElement(corePtr->layout, "square");
+ winBox = Ttk_WinBox(corePtr->tkwin);
+ Ttk_PlaceLayout(corePtr->layout, corePtr->state, winBox);
+
+ /*
+ * Adjust the position of the square element within the widget according
+ * to the -anchor option.
+ */
+
+ if (squareNode) {
+ Square *squarePtr = clientData;
+ Tk_Anchor anchor = TK_ANCHOR_CENTER;
+ Ttk_Box b;
+
+ b = Ttk_ElementParcel(squareNode);
+ if (squarePtr->square.anchorObj != NULL)
+ Tk_GetAnchorFromObj(NULL, squarePtr->square.anchorObj, &anchor);
+ b = Ttk_AnchorBox(winBox, b.width, b.height, anchor);
+
+ Ttk_PlaceElement(corePtr->layout, squareNode, b);
+ }
+}
+
+/*
+ * Widget commands. A widget is impelemented as an ensemble and the
+ * subcommands are listed here. Ttk provides default implementations
+ * that are sufficient for our needs.
+ */
+
+static const Ttk_Ensemble SquareCommands[] = {
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "identify", TtkWidgetIdentifyCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { 0,0,0 }
+};
+
+/*
+ * The Widget specification structure holds all the implementation
+ * information about this widget and this is what must be registered
+ * with Tk in the package initialization code (see bottom).
+ */
+
+static WidgetSpec SquareWidgetSpec =
+{
+ "TSquare", /* className */
+ sizeof(Square), /* recordSize */
+ SquareOptionSpecs, /* optionSpecs */
+ SquareCommands, /* subcommands */
+ TtkNullInitialize, /* initializeProc */
+ TtkNullCleanup, /* cleanupProc */
+ TtkCoreConfigure, /* configureProc */
+ TtkNullPostConfigure, /* postConfigureProc */
+ TtkWidgetGetLayout, /* getLayoutProc */
+ TtkWidgetSize, /* sizeProc */
+ SquareDoLayout, /* layoutProc */
+ TtkWidgetDisplay /* displayProc */
+};
+
+/* ----------------------------------------------------------------------
+ * Square element
+ *
+ * In this section we demonstrate what is required to create a new themed
+ * element.
+ */
+
+typedef struct
+{
+ Tcl_Obj *borderObj;
+ Tcl_Obj *foregroundObj;
+ Tcl_Obj *borderWidthObj;
+ Tcl_Obj *reliefObj;
+ Tcl_Obj *widthObj;
+ Tcl_Obj *heightObj;
+} SquareElement;
+
+static Ttk_ElementOptionSpec SquareElementOptions[] =
+{
+ { "-background", TK_OPTION_BORDER, Tk_Offset(SquareElement,borderObj),
+ DEFAULT_BACKGROUND },
+ { "-foreground", TK_OPTION_BORDER, Tk_Offset(SquareElement,foregroundObj),
+ DEFAULT_BACKGROUND },
+ { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(SquareElement,borderWidthObj),
+ DEFAULT_BORDERWIDTH },
+ { "-relief", TK_OPTION_RELIEF, Tk_Offset(SquareElement,reliefObj),
+ "raised" },
+ { "-width", TK_OPTION_PIXELS, Tk_Offset(SquareElement,widthObj), "20"},
+ { "-height", TK_OPTION_PIXELS, Tk_Offset(SquareElement,heightObj), "20"},
+ { NULL, 0, 0, NULL }
+};
+
+/*
+ * The element geometry function is called when the layout code wishes to
+ * find out how big this element wants to be. We must return our preferred
+ * size and padding information
+ */
+
+static void SquareElementSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ SquareElement *square = elementRecord;
+ int borderWidth = 0;
+
+ Tcl_GetIntFromObj(NULL, square->borderWidthObj, &borderWidth);
+ *paddingPtr = Ttk_UniformPadding((short)borderWidth);
+ Tk_GetPixelsFromObj(NULL, tkwin, square->widthObj, widthPtr);
+ Tk_GetPixelsFromObj(NULL, tkwin, square->heightObj, heightPtr);
+}
+
+/*
+ * Draw the element in the box provided.
+ */
+
+static void SquareElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, unsigned int state)
+{
+ SquareElement *square = elementRecord;
+ Tk_3DBorder foreground = NULL;
+ int borderWidth = 1, relief = TK_RELIEF_FLAT;
+
+ foreground = Tk_Get3DBorderFromObj(tkwin, square->foregroundObj);
+ Tcl_GetIntFromObj(NULL, square->borderWidthObj, &borderWidth);
+ Tk_GetReliefFromObj(NULL, square->reliefObj, &relief);
+
+ Tk_Fill3DRectangle(tkwin, d, foreground,
+ b.x, b.y, b.width, b.height, borderWidth, relief);
+}
+
+static Ttk_ElementSpec SquareElementSpec =
+{
+ TK_STYLE_VERSION_2,
+ sizeof(SquareElement),
+ SquareElementOptions,
+ SquareElementSize,
+ SquareElementDraw
+};
+
+/* ----------------------------------------------------------------------
+ *
+ * Layout section.
+ *
+ * Every widget class needs a layout style that specifies which elements
+ * are part of the widget and how they should be placed. The element layout
+ * engine is similar to the Tk pack geometry manager. Read the documentation
+ * for the details. In this example we just need to have the square element
+ * that has been defined for this widget placed on a background. We will
+ * also need some padding to keep it away from the edges.
+ */
+
+TTK_BEGIN_LAYOUT(SquareLayout)
+ TTK_NODE("Square.background", TTK_FILL_BOTH)
+ TTK_GROUP("Square.padding", TTK_FILL_BOTH,
+ TTK_NODE("Square.square", 0))
+TTK_END_LAYOUT
+
+/* ----------------------------------------------------------------------
+ *
+ * Widget initialization.
+ *
+ * This file defines a new element and a new widget. We need to register
+ * the element with the themes that will need it. In this case we will
+ * register with the default theme that is the root of the theme inheritance
+ * tree. This means all themes will find this element.
+ * We then need to register the widget class style. This is the layout
+ * specification. If a different theme requires an alternative layout, we
+ * could register that here. For instance, in some themes the scrollbars have
+ * one uparrow, in other themes there are two uparrow elements.
+ * Finally we register the widget itself. This step creates a tcl command so
+ * that we can actually create an instance of this class. The widget is
+ * linked to a particular style by the widget class name. This is important
+ * to realise as the programmer may change the classname when creating a
+ * new instance. If this is done, a new layout will need to be created (which
+ * can be done at script level). Some widgets may require particular elements
+ * to be present but we try to avoid this where possible. In this widget's C
+ * code, no reference is made to any particular elements. The programmer is
+ * free to specify a new style using completely different elements.
+ */
+
+/* public */ MODULE_SCOPE int
+TtkSquareWidget_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme theme = Ttk_GetDefaultTheme(interp);
+
+ /* register the new elements for this theme engine */
+ Ttk_RegisterElement(interp, theme, "square", &SquareElementSpec, NULL);
+
+ /* register the layout for this theme */
+ Ttk_RegisterLayout(theme, "TSquare", SquareLayout);
+
+ /* register the widget */
+ RegisterWidget(interp, "ttk::square", &SquareWidgetSpec);
+
+ return TCL_OK;
+}
+
+#endif /* TTK_SQUARE_WIDGET */
+
diff --git a/generic/ttk/ttkState.c b/generic/ttk/ttkState.c
new file mode 100644
index 0000000..a71ae21
--- /dev/null
+++ b/generic/ttk/ttkState.c
@@ -0,0 +1,273 @@
+/*
+ * Tk widget state utilities.
+ *
+ * Copyright (c) 2003 Joe English. Freely redistributable.
+ *
+ */
+
+#include <string.h>
+
+#include <tk.h>
+#include "ttkTheme.h"
+
+/*
+ * Table of state names. Must be kept in sync with TTK_STATE_*
+ * #defines in ttkTheme.h.
+ */
+static const char *const stateNames[] =
+{
+ "active", /* Mouse cursor is over widget or element */
+ "disabled", /* Widget is disabled */
+ "focus", /* Widget has keyboard focus */
+ "pressed", /* Pressed or "armed" */
+ "selected", /* "on", "true", "current", etc. */
+ "background", /* Top-level window lost focus (Mac,Win "inactive") */
+ "alternate", /* Widget-specific alternate display style */
+ "invalid", /* Bad value */
+ "readonly", /* Editing/modification disabled */
+ "hover", /* Mouse cursor is over widget */
+ "reserved1", /* Reserved for future extension */
+ "reserved2", /* Reserved for future extension */
+ "reserved3", /* Reserved for future extension */
+ "user3", /* User-definable state */
+ "user2", /* User-definable state */
+ "user1", /* User-definable state */
+ NULL
+};
+
+/*------------------------------------------------------------------------
+ * +++ StateSpec object type:
+ *
+ * The string representation consists of a list of state names,
+ * each optionally prefixed by an exclamation point (!).
+ *
+ * The internal representation uses the upper half of the longValue
+ * to store the on bits and the lower half to store the off bits.
+ * If we ever get more than 16 states, this will need to be reconsidered...
+ */
+
+static int StateSpecSetFromAny(Tcl_Interp *interp, Tcl_Obj *obj);
+/* static void StateSpecFreeIntRep(Tcl_Obj *); */
+#define StateSpecFreeIntRep 0 /* not needed */
+static void StateSpecDupIntRep(Tcl_Obj *, Tcl_Obj *);
+static void StateSpecUpdateString(Tcl_Obj *);
+
+static
+struct Tcl_ObjType StateSpecObjType =
+{
+ "StateSpec",
+ StateSpecFreeIntRep,
+ StateSpecDupIntRep,
+ StateSpecUpdateString,
+ StateSpecSetFromAny
+};
+
+static void StateSpecDupIntRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr)
+{
+ copyPtr->internalRep.longValue = srcPtr->internalRep.longValue;
+ copyPtr->typePtr = &StateSpecObjType;
+}
+
+static int StateSpecSetFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr)
+{
+ int status;
+ int objc;
+ Tcl_Obj **objv;
+ int i;
+ unsigned int onbits = 0, offbits = 0;
+
+ status = Tcl_ListObjGetElements(interp, objPtr, &objc, &objv);
+ if (status != TCL_OK)
+ return status;
+
+ for (i = 0; i < objc; ++i) {
+ const char *stateName = Tcl_GetString(objv[i]);
+ int on, j;
+
+ if (*stateName == '!') {
+ ++stateName;
+ on = 0;
+ } else {
+ on = 1;
+ }
+
+ for (j = 0; stateNames[j] != 0; ++j) {
+ if (strcmp(stateName, stateNames[j]) == 0)
+ break;
+ }
+
+ if (stateNames[j] == 0) {
+ if (interp) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "Invalid state name ", stateName,NULL);
+ }
+ return TCL_ERROR;
+ }
+
+ if (on) {
+ onbits |= (1<<j);
+ } else {
+ offbits |= (1<<j);
+ }
+ }
+
+ /* Invalidate old intrep:
+ */
+ if (objPtr->typePtr && objPtr->typePtr->freeIntRepProc) {
+ objPtr->typePtr->freeIntRepProc(objPtr);
+ }
+
+ objPtr->typePtr = &StateSpecObjType;
+ objPtr->internalRep.longValue = (onbits << 16) | offbits;
+
+ return TCL_OK;
+}
+
+static void StateSpecUpdateString(Tcl_Obj *objPtr)
+{
+ unsigned int onbits = (objPtr->internalRep.longValue & 0xFFFF0000) >> 16;
+ unsigned int offbits = objPtr->internalRep.longValue & 0x0000FFFF;
+ unsigned int mask = onbits | offbits;
+ Tcl_DString result;
+ int i, len;
+
+ Tcl_DStringInit(&result);
+
+ for (i=0; stateNames[i] != NULL; ++i) {
+ if (mask & (1<<i)) {
+ if (offbits & (1<<i))
+ Tcl_DStringAppend(&result, "!", 1);
+ Tcl_DStringAppend(&result, stateNames[i], -1);
+ Tcl_DStringAppend(&result, " ", 1);
+ }
+ }
+
+ len = Tcl_DStringLength(&result);
+ if (len) {
+ /* 'len' includes extra trailing ' ' */
+ objPtr->bytes = Tcl_Alloc((unsigned)len);
+ objPtr->length = len-1;
+ strncpy(objPtr->bytes, Tcl_DStringValue(&result), (size_t)len-1);
+ objPtr->bytes[len-1] = '\0';
+ } else {
+ /* empty string */
+ objPtr->length = 0;
+ objPtr->bytes = Tcl_Alloc(1);
+ *objPtr->bytes = '\0';
+ }
+
+ Tcl_DStringFree(&result);
+}
+
+Tcl_Obj *Ttk_NewStateSpecObj(unsigned int onbits, unsigned int offbits)
+{
+ Tcl_Obj *objPtr = Tcl_NewObj();
+
+ Tcl_InvalidateStringRep(objPtr);
+ objPtr->typePtr = &StateSpecObjType;
+ objPtr->internalRep.longValue = (onbits << 16) | offbits;
+
+ return objPtr;
+}
+
+int Ttk_GetStateSpecFromObj(
+ Tcl_Interp *interp,
+ Tcl_Obj *objPtr,
+ Ttk_StateSpec *spec)
+{
+ if (objPtr->typePtr != &StateSpecObjType) {
+ int status = StateSpecSetFromAny(interp, objPtr);
+ if (status != TCL_OK)
+ return status;
+ }
+
+ spec->onbits = (objPtr->internalRep.longValue & 0xFFFF0000) >> 16;
+ spec->offbits = objPtr->internalRep.longValue & 0x0000FFFF;
+ return TCL_OK;
+}
+
+
+/*
+ * Tk_StateMapLookup --
+ *
+ * A state map is a paired list of StateSpec / value pairs.
+ * Returns the value corresponding to the first matching state
+ * specification, or NULL if not found or an error occurs.
+ */
+Tcl_Obj *Ttk_StateMapLookup(
+ Tcl_Interp *interp, /* Where to leave error messages; may be NULL */
+ Ttk_StateMap map, /* State map */
+ Ttk_State state) /* State to look up */
+{
+ Tcl_Obj **specs;
+ int nSpecs;
+ int j, status;
+
+ status = Tcl_ListObjGetElements(interp, map, &nSpecs, &specs);
+ if (status != TCL_OK)
+ return NULL;
+
+ for (j = 0; j < nSpecs; j += 2) {
+ Ttk_StateSpec spec;
+ status = Ttk_GetStateSpecFromObj(interp, specs[j], &spec);
+ if (status != TCL_OK)
+ return NULL;
+ if (Ttk_StateMatches(state, &spec))
+ return specs[j+1];
+ }
+ if (interp) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "No match in state map", NULL);
+ }
+ return NULL;
+}
+
+/* Ttk_GetStateMapFromObj --
+ * Returns a Ttk_StateMap from a Tcl_Obj*.
+ * Since a Ttk_StateMap is just a specially-formatted Tcl_Obj,
+ * this basically just checks for errors.
+ */
+Ttk_StateMap Ttk_GetStateMapFromObj(
+ Tcl_Interp *interp, /* Where to leave error messages; may be NULL */
+ Tcl_Obj *mapObj) /* State map */
+{
+ Tcl_Obj **specs;
+ int nSpecs;
+ int j, status;
+
+ status = Tcl_ListObjGetElements(interp, mapObj, &nSpecs, &specs);
+ if (status != TCL_OK)
+ return NULL;
+
+ if (nSpecs % 2 != 0) {
+ if (interp)
+ Tcl_SetResult(interp,
+ "State map must have an even number of elements",
+ TCL_STATIC);
+ return 0;
+ }
+
+ for (j = 0; j < nSpecs; j += 2) {
+ Ttk_StateSpec spec;
+ if (Ttk_GetStateSpecFromObj(interp, specs[j], &spec) != TCL_OK)
+ return NULL;
+ }
+
+ return mapObj;
+}
+
+/*
+ * Ttk_StateTableLooup --
+ * Look up an index from a statically allocated state table.
+ */
+int Ttk_StateTableLookup(Ttk_StateTable *map, unsigned int state)
+{
+ while ((state & map->onBits) != map->onBits
+ || (~state & map->offBits) != map->offBits)
+ {
+ ++map;
+ }
+ return map->index;
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkStubInit.c b/generic/ttk/ttkStubInit.c
new file mode 100644
index 0000000..87b33dc
--- /dev/null
+++ b/generic/ttk/ttkStubInit.c
@@ -0,0 +1,61 @@
+/*
+ * This file is (mostly) automatically generated from ttk.decls.
+ * It is compiled and linked in with the ttk package proper.
+ */
+
+#include "tk.h"
+#include "ttkTheme.h"
+
+MODULE_SCOPE const TtkStubs ttkStubs;
+
+/* !BEGIN!: Do not edit below this line. */
+
+const TtkStubs ttkStubs = {
+ TCL_STUB_MAGIC,
+ TTK_STUBS_EPOCH,
+ TTK_STUBS_REVISION,
+ 0,
+ Ttk_GetTheme, /* 0 */
+ Ttk_GetDefaultTheme, /* 1 */
+ Ttk_GetCurrentTheme, /* 2 */
+ Ttk_CreateTheme, /* 3 */
+ Ttk_RegisterCleanup, /* 4 */
+ Ttk_RegisterElementSpec, /* 5 */
+ Ttk_RegisterElement, /* 6 */
+ Ttk_RegisterElementFactory, /* 7 */
+ Ttk_RegisterLayout, /* 8 */
+ 0, /* 9 */
+ Ttk_GetStateSpecFromObj, /* 10 */
+ Ttk_NewStateSpecObj, /* 11 */
+ Ttk_GetStateMapFromObj, /* 12 */
+ Ttk_StateMapLookup, /* 13 */
+ Ttk_StateTableLookup, /* 14 */
+ 0, /* 15 */
+ 0, /* 16 */
+ 0, /* 17 */
+ 0, /* 18 */
+ 0, /* 19 */
+ Ttk_GetPaddingFromObj, /* 20 */
+ Ttk_GetBorderFromObj, /* 21 */
+ Ttk_GetStickyFromObj, /* 22 */
+ Ttk_MakePadding, /* 23 */
+ Ttk_UniformPadding, /* 24 */
+ Ttk_AddPadding, /* 25 */
+ Ttk_RelievePadding, /* 26 */
+ Ttk_MakeBox, /* 27 */
+ Ttk_BoxContains, /* 28 */
+ Ttk_PackBox, /* 29 */
+ Ttk_StickBox, /* 30 */
+ Ttk_AnchorBox, /* 31 */
+ Ttk_PadBox, /* 32 */
+ Ttk_ExpandBox, /* 33 */
+ Ttk_PlaceBox, /* 34 */
+ Ttk_NewBoxObj, /* 35 */
+ 0, /* 36 */
+ 0, /* 37 */
+ 0, /* 38 */
+ 0, /* 39 */
+ Ttk_GetOrientFromObj, /* 40 */
+};
+
+/* !END!: Do not edit above this line. */
diff --git a/generic/ttk/ttkStubLib.c b/generic/ttk/ttkStubLib.c
new file mode 100644
index 0000000..2c07b9d
--- /dev/null
+++ b/generic/ttk/ttkStubLib.c
@@ -0,0 +1,74 @@
+/*
+ * We need to ensure that we use the tcl stub macros so that this file
+ * contains no references to any of the tcl stub functions.
+ */
+
+#undef USE_TCL_STUBS
+#define USE_TCL_STUBS
+
+#include "tk.h"
+
+#define USE_TTK_STUBS 1
+#include "ttkTheme.h"
+
+MODULE_SCOPE const TtkStubs *ttkStubsPtr;
+const TtkStubs *ttkStubsPtr = NULL;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TtkInitializeStubs --
+ * Load the Ttk package, initialize stub table pointer.
+ * Do not call this function directly, use Ttk_InitStubs() macro instead.
+ *
+ * Results:
+ * The actual version of the package that satisfies the request, or
+ * NULL to indicate that an error occurred.
+ *
+ * Side effects:
+ * Sets the stub table pointer.
+ *
+ */
+MODULE_SCOPE const char *
+TtkInitializeStubs(
+ Tcl_Interp *interp, const char *version, int epoch, int revision)
+{
+ int exact = 0;
+ const char *packageName = "Ttk";
+ const char *errMsg = NULL;
+ ClientData pkgClientData = NULL;
+ const char *actualVersion = Tcl_PkgRequireEx(
+ interp, packageName, version, exact, &pkgClientData);
+ const TtkStubs *stubsPtr = pkgClientData;
+
+ if (!actualVersion) {
+ return NULL;
+ }
+
+ if (!stubsPtr) {
+ errMsg = "missing stub table pointer";
+ goto error;
+ }
+ if (stubsPtr->epoch != epoch) {
+ errMsg = "epoch number mismatch";
+ goto error;
+ }
+ if (stubsPtr->revision < revision) {
+ errMsg = "require later revision";
+ goto error;
+ }
+
+ ttkStubsPtr = stubsPtr;
+ return actualVersion;
+
+error:
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ "Error loading ", packageName, " package",
+ " (requested version '", version,
+ "', loaded version '", actualVersion, "'): ",
+ errMsg,
+ NULL);
+ return NULL;
+}
+
diff --git a/generic/ttk/ttkTagSet.c b/generic/ttk/ttkTagSet.c
new file mode 100644
index 0000000..9f2a87b
--- /dev/null
+++ b/generic/ttk/ttkTagSet.c
@@ -0,0 +1,306 @@
+/*
+ * Tag tables. 3/4-baked, work in progress.
+ *
+ * Copyright (C) 2005, Joe English. Freely redistributable.
+ */
+
+#include <string.h> /* for memset() */
+#include <tcl.h>
+#include <tk.h>
+
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+/*------------------------------------------------------------------------
+ * +++ Internal data structures.
+ */
+struct TtkTag {
+ int priority; /* 1=>highest */
+ const char *tagName; /* Back-pointer to hash table entry */
+ void *tagRecord; /* User data */
+};
+
+struct TtkTagTable {
+ Tk_Window tkwin; /* owner window */
+ Tk_OptionSpec *optionSpecs; /* ... */
+ Tk_OptionTable optionTable; /* ... */
+ int recordSize; /* size of tag record */
+ int nTags; /* #tags defined so far */
+ Tcl_HashTable tags; /* defined tags */
+};
+
+/*------------------------------------------------------------------------
+ * +++ Tags.
+ */
+static Ttk_Tag NewTag(Ttk_TagTable tagTable, const char *tagName)
+{
+ Ttk_Tag tag = (Ttk_Tag)ckalloc(sizeof(*tag));
+ tag->tagRecord = ckalloc(tagTable->recordSize);
+ memset(tag->tagRecord, 0, tagTable->recordSize);
+ /* Don't need Tk_InitOptions() here, all defaults should be NULL. */
+ tag->priority = ++tagTable->nTags;
+ tag->tagName = tagName;
+ return tag;
+}
+
+static void DeleteTag(Ttk_TagTable tagTable, Ttk_Tag tag)
+{
+ Tk_FreeConfigOptions(tag->tagRecord,tagTable->optionTable,tagTable->tkwin);
+ ckfree(tag->tagRecord);
+ ckfree((void*)tag);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Tag tables.
+ */
+
+Ttk_TagTable Ttk_CreateTagTable(
+ Tcl_Interp *interp, Tk_Window tkwin,
+ Tk_OptionSpec optionSpecs[], int recordSize)
+{
+ Ttk_TagTable tagTable = (Ttk_TagTable)ckalloc(sizeof(*tagTable));
+ tagTable->tkwin = tkwin;
+ tagTable->optionSpecs = optionSpecs;
+ tagTable->optionTable = Tk_CreateOptionTable(interp, optionSpecs);
+ tagTable->recordSize = recordSize;
+ tagTable->nTags = 0;
+ Tcl_InitHashTable(&tagTable->tags, TCL_STRING_KEYS);
+ return tagTable;
+}
+
+void Ttk_DeleteTagTable(Ttk_TagTable tagTable)
+{
+ Tcl_HashSearch search;
+ Tcl_HashEntry *entryPtr;
+
+ entryPtr = Tcl_FirstHashEntry(&tagTable->tags, &search);
+ while (entryPtr != NULL) {
+ DeleteTag(tagTable, Tcl_GetHashValue(entryPtr));
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+
+ Tcl_DeleteHashTable(&tagTable->tags);
+ ckfree((void*)tagTable);
+}
+
+Ttk_Tag Ttk_GetTag(Ttk_TagTable tagTable, const char *tagName)
+{
+ int isNew = 0;
+ Tcl_HashEntry *entryPtr = Tcl_CreateHashEntry(
+ &tagTable->tags, tagName, &isNew);
+
+ if (isNew) {
+ tagName = Tcl_GetHashKey(&tagTable->tags, entryPtr);
+ Tcl_SetHashValue(entryPtr, NewTag(tagTable,tagName));
+ }
+ return Tcl_GetHashValue(entryPtr);
+}
+
+Ttk_Tag Ttk_GetTagFromObj(Ttk_TagTable tagTable, Tcl_Obj *objPtr)
+{
+ return Ttk_GetTag(tagTable, Tcl_GetString(objPtr));
+}
+
+/*------------------------------------------------------------------------
+ * +++ Tag sets.
+ */
+
+/* Ttk_GetTagSetFromObj --
+ * Extract an array of pointers to Ttk_Tags from a Tcl_Obj.
+ * objPtr may be NULL, in which case a new empty tag set is returned.
+ *
+ * Returns NULL and leaves an error message in interp->result on error.
+ *
+ * Non-NULL results must be passed to Ttk_FreeTagSet().
+ */
+Ttk_TagSet Ttk_GetTagSetFromObj(
+ Tcl_Interp *interp, Ttk_TagTable tagTable, Tcl_Obj *objPtr)
+{
+ Ttk_TagSet tagset = (Ttk_TagSet)(ckalloc(sizeof *tagset));
+ Tcl_Obj **objv;
+ int i, objc;
+
+ if (objPtr == NULL) {
+ tagset->tags = NULL;
+ tagset->nTags = 0;
+ return tagset;
+ }
+
+ if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+ ckfree((ClientData)tagset);
+ return NULL;
+ }
+
+ tagset->tags = (Ttk_Tag*)ckalloc((objc+1) * sizeof(Ttk_Tag));
+ for (i=0; i<objc; ++i) {
+ tagset->tags[i] = Ttk_GetTagFromObj(tagTable, objv[i]);
+ }
+ tagset->tags[i] = NULL;
+ tagset->nTags = objc;
+
+ return tagset;
+}
+
+/* Ttk_NewTagSetObj --
+ * Construct a fresh Tcl_Obj * from a tag set.
+ */
+Tcl_Obj *Ttk_NewTagSetObj(Ttk_TagSet tagset)
+{
+ Tcl_Obj *result = Tcl_NewListObj(0,0);
+ int i;
+
+ for (i = 0; i < tagset->nTags; ++i) {
+ Tcl_ListObjAppendElement(
+ NULL, result, Tcl_NewStringObj(tagset->tags[i]->tagName, -1));
+ }
+ return result;
+}
+
+void Ttk_FreeTagSet(Ttk_TagSet tagset)
+{
+ ckfree((ClientData)tagset->tags);
+ ckfree((ClientData)tagset);
+}
+
+/* Ttk_TagSetContains -- test if tag set contains a tag.
+ */
+int Ttk_TagSetContains(Ttk_TagSet tagset, Ttk_Tag tag)
+{
+ int i;
+ for (i = 0; i < tagset->nTags; ++i) {
+ if (tagset->tags[i] == tag) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Ttk_TagSetAdd -- add a tag to a tag set.
+ *
+ * Returns: 0 if tagset already contained tag,
+ * 1 if tagset was modified.
+ */
+int Ttk_TagSetAdd(Ttk_TagSet tagset, Ttk_Tag tag)
+{
+ int i;
+ for (i = 0; i < tagset->nTags; ++i) {
+ if (tagset->tags[i] == tag) {
+ return 0;
+ }
+ }
+ tagset->tags = (void*)ckrealloc((void*)tagset->tags,
+ (tagset->nTags+1)*sizeof(tagset->tags[0]));
+ tagset->tags[tagset->nTags++] = tag;
+ return 1;
+}
+
+/* Ttk_TagSetRemove -- remove a tag from a tag set.
+ *
+ * Returns: 0 if tagset did not contain tag,
+ * 1 if tagset was modified.
+ */
+int Ttk_TagSetRemove(Ttk_TagSet tagset, Ttk_Tag tag)
+{
+ int i = 0, j = 0;
+ while (i < tagset->nTags) {
+ if ((tagset->tags[j] = tagset->tags[i]) != tag) {
+ ++j;
+ }
+ ++i;
+ }
+ tagset->nTags = j;
+ return j != i;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Utilities for widget commands.
+ */
+
+/* Ttk_EnumerateTags -- implements [$w tag names]
+ */
+int Ttk_EnumerateTags(
+ Tcl_Interp *interp, Ttk_TagTable tagTable)
+{
+ return TtkEnumerateHashTable(interp, &tagTable->tags);
+}
+
+/* Ttk_EnumerateTagOptions -- implements [$w tag configure $tag]
+ */
+int Ttk_EnumerateTagOptions(
+ Tcl_Interp *interp, Ttk_TagTable tagTable, Ttk_Tag tag)
+{
+ return TtkEnumerateOptions(interp, tag->tagRecord,
+ tagTable->optionSpecs, tagTable->optionTable, tagTable->tkwin);
+}
+
+/* Ttk_TagOptionValue -- implements [$w tag configure $tag -option]
+ */
+Tcl_Obj *Ttk_TagOptionValue(
+ Tcl_Interp *interp,
+ Ttk_TagTable tagTable,
+ Ttk_Tag tag,
+ Tcl_Obj *optionName)
+{
+ return Tk_GetOptionValue(interp,
+ tag->tagRecord, tagTable->optionTable, optionName, tagTable->tkwin);
+}
+
+/* Ttk_ConfigureTag -- implements [$w tag configure $tag -option value...]
+ */
+int Ttk_ConfigureTag(
+ Tcl_Interp *interp,
+ Ttk_TagTable tagTable,
+ Ttk_Tag tag,
+ int objc, Tcl_Obj *const objv[])
+{
+ return Tk_SetOptions(
+ interp, tag->tagRecord, tagTable->optionTable,
+ objc, objv, tagTable->tkwin, NULL/*savedOptions*/, NULL/*mask*/);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Tag values.
+ */
+
+#define OBJ_AT(record, offset) (*(Tcl_Obj**)(((char*)record)+offset))
+
+void Ttk_TagSetValues(Ttk_TagTable tagTable, Ttk_TagSet tagSet, void *record)
+{
+ const int LOWEST_PRIORITY = 0x7FFFFFFF;
+ int i, j;
+
+ memset(record, 0, tagTable->recordSize);
+
+ for (i = 0; tagTable->optionSpecs[i].type != TK_OPTION_END; ++i) {
+ Tk_OptionSpec *optionSpec = tagTable->optionSpecs + i;
+ int offset = optionSpec->objOffset;
+ int prio = LOWEST_PRIORITY;
+
+ for (j = 0; j < tagSet->nTags; ++j) {
+ Ttk_Tag tag = tagSet->tags[j];
+ if (OBJ_AT(tag->tagRecord, offset) != 0 && tag->priority < prio) {
+ OBJ_AT(record, offset) = OBJ_AT(tag->tagRecord, offset);
+ prio = tag->priority;
+ }
+ }
+ }
+}
+
+void Ttk_TagSetApplyStyle(
+ Ttk_TagTable tagTable, Ttk_Style style, Ttk_State state, void *record)
+{
+ Tk_OptionSpec *optionSpec = tagTable->optionSpecs;
+
+ while (optionSpec->type != TK_OPTION_END) {
+ int offset = optionSpec->objOffset;
+ const char *optionName = optionSpec->optionName;
+ Tcl_Obj *val = Ttk_StyleMap(style, optionName, state);
+ if (val) {
+ OBJ_AT(record, offset) = val;
+ } else if (OBJ_AT(record, offset) == 0) {
+ OBJ_AT(record, offset) = Ttk_StyleDefault(style, optionName);
+ }
+ ++optionSpec;
+ }
+}
+
diff --git a/generic/ttk/ttkTheme.c b/generic/ttk/ttkTheme.c
new file mode 100644
index 0000000..a2c51c0
--- /dev/null
+++ b/generic/ttk/ttkTheme.c
@@ -0,0 +1,1737 @@
+/*
+ * ttkTheme.c --
+ *
+ * This file implements the widget styles and themes support.
+ *
+ * Copyright (c) 2002 Frederic Bonnet
+ * Copyright (c) 2003 Joe English
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <tk.h>
+#include <tkInt.h>
+#include "ttkThemeInt.h"
+
+#define PKG_ASSOC_KEY "Ttk"
+
+/*------------------------------------------------------------------------
+ * +++ Styles.
+ *
+ * Invariants:
+ * If styleName contains a dot, parentStyle->styleName is everything
+ * after the first dot; otherwise, parentStyle is the theme's root
+ * style ".". The root style's parentStyle is NULL.
+ *
+ */
+
+typedef struct Ttk_Style_
+{
+ const char *styleName; /* points to hash table key */
+ Tcl_HashTable settingsTable; /* KEY: string; VALUE: StateMap */
+ Tcl_HashTable defaultsTable; /* KEY: string; VALUE: resource */
+ Ttk_LayoutTemplate layoutTemplate; /* Layout template for style, or NULL */
+ Ttk_Style parentStyle; /* Previous style in chain */
+ Ttk_ResourceCache cache; /* Back-pointer to resource cache */
+} Style;
+
+static Style *NewStyle()
+{
+ Style *stylePtr = (Style*)ckalloc(sizeof(Style));
+
+ stylePtr->styleName = NULL;
+ stylePtr->parentStyle = NULL;
+ stylePtr->layoutTemplate = NULL;
+ stylePtr->cache = NULL;
+ Tcl_InitHashTable(&stylePtr->settingsTable, TCL_STRING_KEYS);
+ Tcl_InitHashTable(&stylePtr->defaultsTable, TCL_STRING_KEYS);
+
+ return stylePtr;
+}
+
+static void FreeStyle(Style *stylePtr)
+{
+ Tcl_HashSearch search;
+ Tcl_HashEntry *entryPtr;
+
+ entryPtr = Tcl_FirstHashEntry(&stylePtr->settingsTable, &search);
+ while (entryPtr != NULL) {
+ Ttk_StateMap stateMap = Tcl_GetHashValue(entryPtr);
+ Tcl_DecrRefCount(stateMap);
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+ Tcl_DeleteHashTable(&stylePtr->settingsTable);
+
+ entryPtr = Tcl_FirstHashEntry(&stylePtr->defaultsTable, &search);
+ while (entryPtr != NULL) {
+ Tcl_Obj *defaultValue = Tcl_GetHashValue(entryPtr);
+ Tcl_DecrRefCount(defaultValue);
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+ Tcl_DeleteHashTable(&stylePtr->defaultsTable);
+
+ Ttk_FreeLayoutTemplate(stylePtr->layoutTemplate);
+
+ ckfree((ClientData)stylePtr);
+}
+
+/*
+ * Ttk_StyleMap --
+ * Look up state-specific option value from specified style.
+ */
+Tcl_Obj *Ttk_StyleMap(Ttk_Style style, const char *optionName, Ttk_State state)
+{
+ while (style) {
+ Tcl_HashEntry *entryPtr =
+ Tcl_FindHashEntry(&style->settingsTable, optionName);
+ if (entryPtr) {
+ Ttk_StateMap stateMap = Tcl_GetHashValue(entryPtr);
+ return Ttk_StateMapLookup(NULL, stateMap, state);
+ }
+ style = style->parentStyle;
+ }
+ return 0;
+}
+
+/*
+ * Ttk_StyleDefault --
+ * Look up default resource setting the in the specified style.
+ */
+Tcl_Obj *Ttk_StyleDefault(Ttk_Style style, const char *optionName)
+{
+ while (style) {
+ Tcl_HashEntry *entryPtr =
+ Tcl_FindHashEntry(&style->defaultsTable, optionName);
+ if (entryPtr)
+ return Tcl_GetHashValue(entryPtr);
+ style= style->parentStyle;
+ }
+ return 0;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Elements.
+ */
+typedef const Tk_OptionSpec **OptionMap;
+ /* array of Tk_OptionSpecs mapping widget options to element options */
+
+struct Ttk_ElementClass_ {
+ const char *name; /* Points to hash table key */
+ Ttk_ElementSpec *specPtr; /* Template provided during registration. */
+ void *clientData; /* Client data passed in at registration time */
+ void *elementRecord; /* Scratch buffer for element record storage */
+ int nResources; /* #Element options */
+ Tcl_Obj **defaultValues; /* Array of option default values */
+ Tcl_HashTable optMapCache; /* Map: Tk_OptionTable * -> OptionMap */
+};
+
+/* TTKGetOptionSpec --
+ * Look up a Tk_OptionSpec by name from a Tk_OptionTable,
+ * and verify that it's compatible with the specified Tk_OptionType,
+ * along with other constraints (see below).
+ */
+static const Tk_OptionSpec *TTKGetOptionSpec(
+ const char *optionName,
+ Tk_OptionTable optionTable,
+ Tk_OptionType optionType)
+{
+ const Tk_OptionSpec *optionSpec = TkGetOptionSpec(optionName, optionTable);
+
+ if (!optionSpec)
+ return 0;
+
+ /* Make sure widget option has a Tcl_Obj* entry:
+ */
+ if (optionSpec->objOffset < 0) {
+ return 0;
+ }
+
+ /* Grrr. Ignore accidental mismatches caused by prefix-matching:
+ */
+ if (strcmp(optionSpec->optionName, optionName)) {
+ return 0;
+ }
+
+ /* Ensure that the widget option type is compatible with
+ * the element option type.
+ *
+ * TK_OPTION_STRING element options are compatible with anything.
+ * As a workaround for the workaround for Bug #967209,
+ * TK_OPTION_STRING widget options are also compatible with anything
+ * (see <<NOTE-NULLOPTIONS>>).
+ */
+ if ( optionType != TK_OPTION_STRING
+ && optionSpec->type != TK_OPTION_STRING
+ && optionType != optionSpec->type)
+ {
+ return 0;
+ }
+
+ return optionSpec;
+}
+
+/* BuildOptionMap --
+ * Construct the mapping from element options to widget options.
+ */
+static OptionMap
+BuildOptionMap(Ttk_ElementClass *elementClass, Tk_OptionTable optionTable)
+{
+ OptionMap optionMap = (OptionMap)ckalloc(
+ sizeof(const Tk_OptionSpec) * elementClass->nResources + 1);
+ int i;
+
+ for (i = 0; i < elementClass->nResources; ++i) {
+ Ttk_ElementOptionSpec *e = elementClass->specPtr->options+i;
+ optionMap[i] = TTKGetOptionSpec(e->optionName, optionTable, e->type);
+ }
+
+ return optionMap;
+}
+
+/* GetOptionMap --
+ * Return a cached OptionMap matching the specified optionTable
+ * for the specified element, creating it if necessary.
+ */
+static OptionMap
+GetOptionMap(Ttk_ElementClass *elementClass, Tk_OptionTable optionTable)
+{
+ OptionMap optionMap;
+ int isNew;
+ Tcl_HashEntry *entryPtr = Tcl_CreateHashEntry(
+ &elementClass->optMapCache, (void*)optionTable, &isNew);
+
+ if (isNew) {
+ optionMap = BuildOptionMap(elementClass, optionTable);
+ Tcl_SetHashValue(entryPtr, optionMap);
+ } else {
+ optionMap = Tcl_GetHashValue(entryPtr);
+ }
+
+ return optionMap;
+}
+
+/*
+ * NewElementClass --
+ * Allocate and initialize an element class record
+ * from the specified element specification.
+ */
+static Ttk_ElementClass *
+NewElementClass(const char *name, Ttk_ElementSpec *specPtr,void *clientData)
+{
+ Ttk_ElementClass *elementClass =
+ (Ttk_ElementClass*)ckalloc(sizeof(Ttk_ElementClass));
+ int i;
+
+ elementClass->name = name;
+ elementClass->specPtr = specPtr;
+ elementClass->clientData = clientData;
+ elementClass->elementRecord = ckalloc(specPtr->elementSize);
+
+ /* Count #element resources:
+ */
+ for (i = 0; specPtr->options[i].optionName != 0; ++i)
+ continue;
+ elementClass->nResources = i;
+
+ /* Initialize default values:
+ */
+ elementClass->defaultValues = (Tcl_Obj**)
+ ckalloc(elementClass->nResources * sizeof(Tcl_Obj *) + 1);
+ for (i=0; i < elementClass->nResources; ++i) {
+ const char *defaultValue = specPtr->options[i].defaultValue;
+ if (defaultValue) {
+ elementClass->defaultValues[i] = Tcl_NewStringObj(defaultValue,-1);
+ Tcl_IncrRefCount(elementClass->defaultValues[i]);
+ } else {
+ elementClass->defaultValues[i] = 0;
+ }
+ }
+
+ /* Initialize option map cache:
+ */
+ Tcl_InitHashTable(&elementClass->optMapCache, TCL_ONE_WORD_KEYS);
+
+ return elementClass;
+}
+
+/*
+ * FreeElementClass --
+ * Release resources associated with an element class record.
+ */
+static void FreeElementClass(Ttk_ElementClass *elementClass)
+{
+ Tcl_HashSearch search;
+ Tcl_HashEntry *entryPtr;
+ int i;
+
+ /*
+ * Free default values:
+ */
+ for (i = 0; i < elementClass->nResources; ++i) {
+ if (elementClass->defaultValues[i]) {
+ Tcl_DecrRefCount(elementClass->defaultValues[i]);
+ }
+ }
+ ckfree((ClientData)elementClass->defaultValues);
+
+ /*
+ * Free option map cache:
+ */
+ entryPtr = Tcl_FirstHashEntry(&elementClass->optMapCache, &search);
+ while (entryPtr != NULL) {
+ ckfree(Tcl_GetHashValue(entryPtr));
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+ Tcl_DeleteHashTable(&elementClass->optMapCache);
+
+ ckfree(elementClass->elementRecord);
+ ckfree((ClientData)elementClass);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Themes.
+ */
+
+static int ThemeEnabled(Ttk_Theme theme, void *clientData) { return 1; }
+ /* Default ThemeEnabledProc -- always return true */
+
+typedef struct Ttk_Theme_
+{
+ Ttk_Theme parentPtr; /* Parent theme. */
+ Tcl_HashTable elementTable; /* Map element names to class records */
+ Tcl_HashTable styleTable; /* Map style names to Styles */
+ Ttk_Style rootStyle; /* "." style, root of chain */
+ Ttk_ThemeEnabledProc *enabledProc; /* Function called by SetTheme */
+ void *enabledData; /* ClientData for enabledProc */
+ Ttk_ResourceCache cache; /* Back-pointer to resource cache */
+} Theme;
+
+static Theme *NewTheme(Ttk_ResourceCache cache, Ttk_Theme parent)
+{
+ Theme *themePtr = (Theme*)ckalloc(sizeof(Theme));
+ Tcl_HashEntry *entryPtr;
+ int unused;
+
+ themePtr->parentPtr = parent;
+ themePtr->enabledProc = ThemeEnabled;
+ themePtr->enabledData = NULL;
+ themePtr->cache = cache;
+ Tcl_InitHashTable(&themePtr->elementTable, TCL_STRING_KEYS);
+ Tcl_InitHashTable(&themePtr->styleTable, TCL_STRING_KEYS);
+
+ /*
+ * Create root style "."
+ */
+ entryPtr = Tcl_CreateHashEntry(&themePtr->styleTable, ".", &unused);
+ themePtr->rootStyle = NewStyle();
+ themePtr->rootStyle->styleName =
+ Tcl_GetHashKey(&themePtr->styleTable, entryPtr);
+ themePtr->rootStyle->cache = themePtr->cache;
+ Tcl_SetHashValue(entryPtr, themePtr->rootStyle);
+
+ return themePtr;
+}
+
+static void FreeTheme(Theme *themePtr)
+{
+ Tcl_HashSearch search;
+ Tcl_HashEntry *entryPtr;
+
+ /*
+ * Free element table:
+ */
+ entryPtr = Tcl_FirstHashEntry(&themePtr->elementTable, &search);
+ while (entryPtr != NULL) {
+ Ttk_ElementClass *elementClass = Tcl_GetHashValue(entryPtr);
+ FreeElementClass(elementClass);
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+ Tcl_DeleteHashTable(&themePtr->elementTable);
+
+ /*
+ * Free style table:
+ */
+ entryPtr = Tcl_FirstHashEntry(&themePtr->styleTable, &search);
+ while (entryPtr != NULL) {
+ Style *stylePtr = Tcl_GetHashValue(entryPtr);
+ FreeStyle(stylePtr);
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+ Tcl_DeleteHashTable(&themePtr->styleTable);
+
+ /*
+ * Free theme record:
+ */
+ ckfree((ClientData)themePtr);
+
+ return;
+}
+
+/*
+ * Element constructors.
+ */
+typedef struct {
+ Ttk_ElementFactory factory;
+ void *clientData;
+} FactoryRec;
+
+/*
+ * Cleanup records:
+ */
+typedef struct CleanupStruct {
+ void *clientData;
+ Ttk_CleanupProc *cleanupProc;
+ struct CleanupStruct *next;
+} Cleanup;
+
+/*------------------------------------------------------------------------
+ * +++ Master style package data structure.
+ */
+typedef struct
+{
+ Tcl_Interp *interp; /* Owner interp */
+ Tcl_HashTable themeTable; /* KEY: name; VALUE: Theme pointer */
+ Tcl_HashTable factoryTable; /* KEY: name; VALUE: FactoryRec ptr */
+ Theme *defaultTheme; /* Default theme; global fallback*/
+ Theme *currentTheme; /* Currently-selected theme */
+ Cleanup *cleanupList; /* Cleanup records */
+ Ttk_ResourceCache cache; /* Resource cache */
+ int themeChangePending; /* scheduled ThemeChangedProc call? */
+} StylePackageData;
+
+static void ThemeChangedProc(ClientData); /* Forward */
+
+/* Ttk_StylePkgFree --
+ * Cleanup procedure for StylePackageData.
+ */
+static void Ttk_StylePkgFree(ClientData clientData, Tcl_Interp *interp)
+{
+ StylePackageData *pkgPtr = clientData;
+ Tcl_HashSearch search;
+ Tcl_HashEntry *entryPtr;
+ Cleanup *cleanup;
+
+ /*
+ * Cancel any pending ThemeChanged calls:
+ */
+ if (pkgPtr->themeChangePending) {
+ Tcl_CancelIdleCall(ThemeChangedProc, pkgPtr);
+ }
+
+ /*
+ * Free themes.
+ */
+ entryPtr = Tcl_FirstHashEntry(&pkgPtr->themeTable, &search);
+ while (entryPtr != NULL) {
+ Theme *themePtr = Tcl_GetHashValue(entryPtr);
+ FreeTheme(themePtr);
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+ Tcl_DeleteHashTable(&pkgPtr->themeTable);
+
+ /*
+ * Free element constructor table:
+ */
+ entryPtr = Tcl_FirstHashEntry(&pkgPtr->factoryTable, &search);
+ while (entryPtr != NULL) {
+ ckfree(Tcl_GetHashValue(entryPtr));
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+ Tcl_DeleteHashTable(&pkgPtr->factoryTable);
+
+ /*
+ * Release cache:
+ */
+ Ttk_FreeResourceCache(pkgPtr->cache);
+
+ /*
+ * Call all registered cleanup procedures:
+ */
+ cleanup = pkgPtr->cleanupList;
+ while (cleanup) {
+ Cleanup *next = cleanup->next;
+ cleanup->cleanupProc(cleanup->clientData);
+ ckfree((ClientData)cleanup);
+ cleanup = next;
+ }
+
+ ckfree((ClientData)pkgPtr);
+}
+
+/*
+ * GetStylePackageData --
+ * Look up the package data registered with the interp.
+ */
+
+static StylePackageData *GetStylePackageData(Tcl_Interp *interp)
+{
+ return Tcl_GetAssocData(interp, PKG_ASSOC_KEY, NULL);
+}
+
+/*
+ * Ttk_RegisterCleanup --
+ *
+ * Register a function to be called when a theme engine is deleted.
+ * (This only happens when the main interp is destroyed). The cleanup
+ * function is called with the current Tcl interpreter and the client
+ * data provided here.
+ *
+ */
+void Ttk_RegisterCleanup(
+ Tcl_Interp *interp, ClientData clientData, Ttk_CleanupProc *cleanupProc)
+{
+ StylePackageData *pkgPtr = GetStylePackageData(interp);
+ Cleanup *cleanup = (Cleanup*)ckalloc(sizeof(*cleanup));
+
+ cleanup->clientData = clientData;
+ cleanup->cleanupProc = cleanupProc;
+ cleanup->next = pkgPtr->cleanupList;
+ pkgPtr->cleanupList = cleanup;
+}
+
+/* ThemeChangedProc --
+ * Notify all widgets that the theme has been changed.
+ * Scheduled as an idle callback; clientData is a StylePackageData *.
+ *
+ * Sends a <<ThemeChanged>> event to every widget in the hierarchy.
+ * Widgets respond to this by calling the WorldChanged class proc,
+ * which in turn recreates the layout.
+ *
+ * The Tk C API doesn't doesn't provide an easy way to traverse
+ * the widget hierarchy, so this is done by evaluating a Tcl script.
+ */
+
+static void ThemeChangedProc(ClientData clientData)
+{
+ static char ThemeChangedScript[] = "ttk::ThemeChanged";
+ StylePackageData *pkgPtr = clientData;
+
+ if (Tcl_EvalEx(pkgPtr->interp, ThemeChangedScript, -1, TCL_EVAL_GLOBAL) != TCL_OK) {
+ Tcl_BackgroundError(pkgPtr->interp);
+ }
+ pkgPtr->themeChangePending = 0;
+}
+
+/*
+ * ThemeChanged --
+ * Schedule a call to ThemeChanged if one is not already pending.
+ */
+static void ThemeChanged(StylePackageData *pkgPtr)
+{
+ if (!pkgPtr->themeChangePending) {
+ Tcl_DoWhenIdle(ThemeChangedProc, pkgPtr);
+ pkgPtr->themeChangePending = 1;
+ }
+}
+
+/*
+ * Ttk_CreateTheme --
+ * Create a new theme and register it in the global theme table.
+ *
+ * Returns:
+ * Pointer to new Theme structure; NULL if named theme already exists.
+ * Leaves an error message in interp's result on error.
+ */
+
+Ttk_Theme
+Ttk_CreateTheme(
+ Tcl_Interp *interp, /* Interpreter in which to create theme */
+ const char *name, /* Name of the theme to create. */
+ Ttk_Theme parent) /* Parent/fallback theme, NULL for default */
+{
+ StylePackageData *pkgPtr = GetStylePackageData(interp);
+ Tcl_HashEntry *entryPtr;
+ int newEntry;
+ Theme *themePtr;
+
+ entryPtr = Tcl_CreateHashEntry(&pkgPtr->themeTable, name, &newEntry);
+ if (!newEntry) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "Theme ", name, " already exists", NULL);
+ return NULL;
+ }
+
+ /*
+ * Initialize new theme:
+ */
+ if (!parent) parent = pkgPtr->defaultTheme;
+
+ themePtr = NewTheme(pkgPtr->cache, parent);
+ Tcl_SetHashValue(entryPtr, themePtr);
+
+ return themePtr;
+}
+
+/*
+ * Ttk_SetThemeEnabledProc --
+ * Sets a procedure that is used to check that this theme is available.
+ */
+
+void Ttk_SetThemeEnabledProc(
+ Ttk_Theme theme, Ttk_ThemeEnabledProc enabledProc, void *enabledData)
+{
+ theme->enabledProc = enabledProc;
+ theme->enabledData = enabledData;
+}
+
+/*
+ * LookupTheme --
+ * Retrieve a registered theme by name. If not found,
+ * returns NULL and leaves an error message in interp's result.
+ */
+
+static Ttk_Theme LookupTheme(
+ Tcl_Interp *interp, /* where to leave error messages */
+ StylePackageData *pkgPtr, /* style package master record */
+ const char *name) /* theme name */
+{
+ Tcl_HashEntry *entryPtr;
+
+ entryPtr = Tcl_FindHashEntry(&pkgPtr->themeTable, name);
+ if (!entryPtr) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "theme \"", name, "\" doesn't exist", NULL);
+ return NULL;
+ }
+
+ return Tcl_GetHashValue(entryPtr);
+}
+
+/*
+ * Ttk_GetTheme --
+ * Public interface to LookupTheme.
+ */
+Ttk_Theme Ttk_GetTheme(Tcl_Interp *interp, const char *themeName)
+{
+ StylePackageData *pkgPtr = GetStylePackageData(interp);
+
+ return LookupTheme(interp, pkgPtr, themeName);
+}
+
+Ttk_Theme Ttk_GetCurrentTheme(Tcl_Interp *interp)
+{
+ StylePackageData *pkgPtr = GetStylePackageData(interp);
+ return pkgPtr->currentTheme;
+}
+
+Ttk_Theme Ttk_GetDefaultTheme(Tcl_Interp *interp)
+{
+ StylePackageData *pkgPtr = GetStylePackageData(interp);
+ return pkgPtr->defaultTheme;
+}
+
+/*
+ * Ttk_UseTheme --
+ * Set the current theme, notify all widgets that the theme has changed.
+ */
+int Ttk_UseTheme(Tcl_Interp *interp, Ttk_Theme theme)
+{
+ StylePackageData *pkgPtr = GetStylePackageData(interp);
+
+ /*
+ * Check if selected theme is enabled:
+ */
+ while (theme && !theme->enabledProc(theme, theme->enabledData)) {
+ theme = theme->parentPtr;
+ }
+ if (!theme) {
+ /* This shouldn't happen -- default theme should always work */
+ Tcl_Panic("No themes available?");
+ return TCL_ERROR;
+ }
+
+ pkgPtr->currentTheme = theme;
+ ThemeChanged(pkgPtr);
+ return TCL_OK;
+}
+
+/*
+ * Ttk_GetResourceCache --
+ * Return the resource cache associated with 'interp'
+ */
+Ttk_ResourceCache
+Ttk_GetResourceCache(Tcl_Interp *interp)
+{
+ StylePackageData *pkgPtr = GetStylePackageData(interp);
+ return pkgPtr->cache;
+}
+
+/*
+ * Register a new layout specification with a style.
+ * @@@ TODO: Make sure layoutName is not ".", root style must not have a layout
+ */
+MODULE_SCOPE
+void Ttk_RegisterLayoutTemplate(
+ Ttk_Theme theme, /* Target theme */
+ const char *layoutName, /* Name of new layout */
+ Ttk_LayoutTemplate layoutTemplate) /* Template */
+{
+ Ttk_Style style = Ttk_GetStyle(theme, layoutName);
+ if (style->layoutTemplate) {
+ Ttk_FreeLayoutTemplate(style->layoutTemplate);
+ }
+ style->layoutTemplate = layoutTemplate;
+}
+
+void Ttk_RegisterLayout(
+ Ttk_Theme themePtr, /* Target theme */
+ const char *layoutName, /* Name of new layout */
+ Ttk_LayoutSpec specPtr) /* Static layout information */
+{
+ Ttk_LayoutTemplate layoutTemplate = Ttk_BuildLayoutTemplate(specPtr);
+ Ttk_RegisterLayoutTemplate(themePtr, layoutName, layoutTemplate);
+}
+
+/*
+ * Ttk_GetStyle --
+ * Look up a Style from a Theme, create new style if not found.
+ */
+Ttk_Style Ttk_GetStyle(Ttk_Theme themePtr, const char *styleName)
+{
+ Tcl_HashEntry *entryPtr;
+ int newStyle;
+
+ entryPtr = Tcl_CreateHashEntry(&themePtr->styleTable, styleName, &newStyle);
+ if (newStyle) {
+ Ttk_Style stylePtr = NewStyle();
+ const char *dot = strchr(styleName, '.');
+
+ if (dot) {
+ stylePtr->parentStyle = Ttk_GetStyle(themePtr, dot + 1);
+ } else {
+ stylePtr->parentStyle = themePtr->rootStyle;
+ }
+
+ stylePtr->styleName = Tcl_GetHashKey(&themePtr->styleTable, entryPtr);
+ stylePtr->cache = stylePtr->parentStyle->cache;
+ Tcl_SetHashValue(entryPtr, stylePtr);
+ return stylePtr;
+ }
+ return Tcl_GetHashValue(entryPtr);
+}
+
+/* FindLayoutTemplate --
+ * Locate a layout template in the layout table, checking
+ * generic names to specific names first, then looking for
+ * the full name in the parent theme.
+ */
+Ttk_LayoutTemplate
+Ttk_FindLayoutTemplate(Ttk_Theme themePtr, const char *layoutName)
+{
+ while (themePtr) {
+ Ttk_Style stylePtr = Ttk_GetStyle(themePtr, layoutName);
+ while (stylePtr) {
+ if (stylePtr->layoutTemplate) {
+ return stylePtr->layoutTemplate;
+ }
+ stylePtr = stylePtr->parentStyle;
+ }
+ themePtr = themePtr->parentPtr;
+ }
+ return NULL;
+}
+
+const char *Ttk_StyleName(Ttk_Style stylePtr)
+{
+ return stylePtr->styleName;
+}
+
+/*
+ * Ttk_GetElement --
+ * Look up an element class by name in a given theme.
+ * If not found, try generic element names in this theme, then
+ * repeat the lookups in the parent theme.
+ * If not found, return the null element.
+ */
+Ttk_ElementClass *Ttk_GetElement(Ttk_Theme themePtr, const char *elementName)
+{
+ Tcl_HashEntry *entryPtr;
+ const char *dot = elementName;
+
+ /*
+ * Check if element has already been registered:
+ */
+ entryPtr = Tcl_FindHashEntry(&themePtr->elementTable, elementName);
+ if (entryPtr) {
+ return Tcl_GetHashValue(entryPtr);
+ }
+
+ /*
+ * Check generic names:
+ */
+ while (!entryPtr && ((dot = strchr(dot, '.')) != NULL)) {
+ dot++;
+ entryPtr = Tcl_FindHashEntry(&themePtr->elementTable, dot);
+ }
+ if (entryPtr) {
+ return Tcl_GetHashValue(entryPtr);
+ }
+
+ /*
+ * Check parent theme:
+ */
+ if (themePtr->parentPtr) {
+ return Ttk_GetElement(themePtr->parentPtr, elementName);
+ }
+
+ /*
+ * Not found, and this is the root theme; return null element, "".
+ * (@@@ SHOULD: signal a background error)
+ */
+ entryPtr = Tcl_FindHashEntry(&themePtr->elementTable, "");
+ /* ASSERT: entryPtr != 0 */
+ return Tcl_GetHashValue(entryPtr);
+}
+
+const char *Ttk_ElementClassName(Ttk_ElementClass *elementClass)
+{
+ return elementClass->name;
+}
+
+/*
+ * Ttk_RegisterElementFactory --
+ * Register a new element factory.
+ */
+int Ttk_RegisterElementFactory(
+ Tcl_Interp *interp, const char *name,
+ Ttk_ElementFactory factory, void *clientData)
+{
+ StylePackageData *pkgPtr = GetStylePackageData(interp);
+ FactoryRec *recPtr = (FactoryRec*)ckalloc(sizeof(*recPtr));
+ Tcl_HashEntry *entryPtr;
+ int newEntry;
+
+ recPtr->factory = factory;
+ recPtr->clientData = clientData;
+
+ entryPtr = Tcl_CreateHashEntry(&pkgPtr->factoryTable, name, &newEntry);
+ if (!newEntry) {
+ /* Free old factory: */
+ ckfree(Tcl_GetHashValue(entryPtr));
+ }
+ Tcl_SetHashValue(entryPtr, recPtr);
+
+ return TCL_OK;
+}
+
+/* Ttk_CloneElement -- element factory procedure.
+ * (style element create $name) "from" $theme ?$element?
+ */
+static int Ttk_CloneElement(
+ Tcl_Interp *interp, void *clientData,
+ Ttk_Theme theme, const char *elementName,
+ int objc, Tcl_Obj *const objv[])
+{
+ Ttk_Theme fromTheme;
+ Ttk_ElementClass *fromElement;
+
+ if (objc <= 0 || objc > 2) {
+ Tcl_WrongNumArgs(interp, 0, objv, "theme ?element?");
+ return TCL_ERROR;
+ }
+
+ fromTheme = Ttk_GetTheme(interp, Tcl_GetString(objv[0]));
+ if (!fromTheme) {
+ return TCL_ERROR;
+ }
+
+ if (objc == 2) {
+ fromElement = Ttk_GetElement(fromTheme, Tcl_GetString(objv[1]));
+ } else {
+ fromElement = Ttk_GetElement(fromTheme, elementName);
+ }
+ if (!fromElement) {
+ return TCL_ERROR;
+ }
+
+ if (Ttk_RegisterElement(interp, theme, elementName,
+ fromElement->specPtr, fromElement->clientData) == NULL)
+ {
+ return TCL_ERROR;
+ }
+ return TCL_OK;
+}
+
+/* Ttk_RegisterElement--
+ * Register an element in the given theme.
+ * Returns: Element handle if successful, NULL otherwise.
+ * On failure, leaves an error message in interp's result
+ * if interp is non-NULL.
+ */
+
+Ttk_ElementClass *Ttk_RegisterElement(
+ Tcl_Interp *interp, /* Where to leave error messages */
+ Ttk_Theme theme, /* Style engine providing the implementation. */
+ const char *name, /* Name of new element */
+ Ttk_ElementSpec *specPtr, /* Static template information */
+ void *clientData) /* application-specific data */
+{
+ Ttk_ElementClass *elementClass;
+ Tcl_HashEntry *entryPtr;
+ int newEntry;
+
+ if (specPtr->version != TK_STYLE_VERSION_2) {
+ /* Version mismatch */
+ if (interp) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "Internal error: Ttk_RegisterElement (",
+ name, "): invalid version",
+ NULL);
+ }
+ return 0;
+ }
+
+ entryPtr = Tcl_CreateHashEntry(&theme->elementTable, name, &newEntry);
+ if (!newEntry) {
+ if (interp) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "Duplicate element ", name, NULL);
+ }
+ return 0;
+ }
+
+ name = Tcl_GetHashKey(&theme->elementTable, entryPtr);
+ elementClass = NewElementClass(name, specPtr, clientData);
+ Tcl_SetHashValue(entryPtr, elementClass);
+
+ return elementClass;
+}
+
+/* Ttk_RegisterElementSpec (deprecated) --
+ * Register a new element.
+ */
+int Ttk_RegisterElementSpec(Ttk_Theme theme,
+ const char *name, Ttk_ElementSpec *specPtr, void *clientData)
+{
+ return Ttk_RegisterElement(NULL, theme, name, specPtr, clientData)
+ ? TCL_OK : TCL_ERROR;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Element record initialization.
+ */
+
+/*
+ * AllocateResource --
+ * Extra initialization for element options like TK_OPTION_COLOR, etc.
+ *
+ * Returns: 1 if OK, 0 on failure.
+ *
+ * Note: if resource allocation fails at this point (just prior
+ * to drawing an element), there's really no good place to
+ * report the error. Instead we just silently fail.
+ */
+
+static int AllocateResource(
+ Ttk_ResourceCache cache,
+ Tk_Window tkwin,
+ Tcl_Obj **destPtr,
+ int optionType)
+{
+ Tcl_Obj *resource = *destPtr;
+
+ switch (optionType)
+ {
+ case TK_OPTION_FONT:
+ return (*destPtr = Ttk_UseFont(cache, tkwin, resource)) != NULL;
+ case TK_OPTION_COLOR:
+ return (*destPtr = Ttk_UseColor(cache, tkwin, resource)) != NULL;
+ case TK_OPTION_BORDER:
+ return (*destPtr = Ttk_UseBorder(cache, tkwin, resource)) != NULL;
+ default:
+ /* no-op; always succeeds */
+ return 1;
+ }
+}
+
+/*
+ * InitializeElementRecord --
+ *
+ * Fill in the element record based on the element's option table.
+ * Resources are initialized from:
+ * the corresponding widget option if present and non-NULL,
+ * otherwise the dynamic state map if specified,
+ * otherwise from the corresponding widget resource if present,
+ * otherwise the default value specified at registration time.
+ *
+ * Returns:
+ * 1 if OK, 0 if an error is detected.
+ *
+ * NOTES:
+ * Tcl_Obj * reference counts are _NOT_ adjusted.
+ */
+
+static
+int InitializeElementRecord(
+ Ttk_ElementClass *eclass, /* Element instance to initialize */
+ Ttk_Style style, /* Style table */
+ char *widgetRecord, /* Source of widget option values */
+ Tk_OptionTable optionTable, /* Option table describing widget record */
+ Tk_Window tkwin, /* Corresponding window */
+ Ttk_State state) /* Widget or element state */
+{
+ char *elementRecord = eclass->elementRecord;
+ OptionMap optionMap = GetOptionMap(eclass,optionTable);
+ int nResources = eclass->nResources;
+ Ttk_ResourceCache cache = style->cache;
+ Ttk_ElementOptionSpec *elementOption = eclass->specPtr->options;
+
+ int i;
+ for (i=0; i<nResources; ++i, ++elementOption) {
+ Tcl_Obj **dest = (Tcl_Obj **)
+ (elementRecord + elementOption->offset);
+ const char *optionName = elementOption->optionName;
+ Tcl_Obj *dynamicSetting = Ttk_StyleMap(style, optionName, state);
+ Tcl_Obj *widgetValue = 0;
+ Tcl_Obj *elementDefault = eclass->defaultValues[i];
+
+ if (optionMap[i]) {
+ widgetValue = *(Tcl_Obj **)
+ (widgetRecord + optionMap[i]->objOffset);
+ }
+
+ if (widgetValue) {
+ *dest = widgetValue;
+ } else if (dynamicSetting) {
+ *dest = dynamicSetting;
+ } else {
+ Tcl_Obj *styleDefault = Ttk_StyleDefault(style, optionName);
+ *dest = styleDefault ? styleDefault : elementDefault;
+ }
+
+ if (!AllocateResource(cache, tkwin, dest, elementOption->type)) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Public API.
+ */
+
+/*
+ * Ttk_QueryStyle --
+ * Look up a style option based on the current state.
+ */
+Tcl_Obj *Ttk_QueryStyle(
+ Ttk_Style style, /* Style to query */
+ void *recordPtr, /* Widget record */
+ Tk_OptionTable optionTable, /* Option table describing widget record */
+ const char *optionName, /* Option name */
+ Ttk_State state) /* Current state */
+{
+ const Tk_OptionSpec *optionSpec;
+ Tcl_Obj *result;
+
+ /*
+ * Check widget record:
+ */
+ optionSpec = TTKGetOptionSpec(optionName, optionTable, TK_OPTION_ANY);
+ if (optionSpec) {
+ result = *(Tcl_Obj**)(((char*)recordPtr) + optionSpec->objOffset);
+ if (result) {
+ return result;
+ }
+ }
+
+ /*
+ * Check dynamic settings:
+ */
+ result = Ttk_StyleMap(style, optionName, state);
+ if (result) {
+ return result;
+ }
+
+ /*
+ * Use style default:
+ */
+ return Ttk_StyleDefault(style, optionName);
+}
+
+/*
+ * Ttk_ElementSize --
+ * Compute the requested size of the given element.
+ */
+
+void
+Ttk_ElementSize(
+ Ttk_ElementClass *eclass, /* Element to query */
+ Ttk_Style style, /* Style settings */
+ char *recordPtr, /* The widget record. */
+ Tk_OptionTable optionTable, /* Description of widget record */
+ Tk_Window tkwin, /* The widget window. */
+ Ttk_State state, /* Current widget state */
+ int *widthPtr, /* Requested width */
+ int *heightPtr, /* Reqested height */
+ Ttk_Padding *paddingPtr) /* Requested inner border */
+{
+ paddingPtr->left = paddingPtr->right = paddingPtr->top = paddingPtr->bottom
+ = *widthPtr = *heightPtr = 0;
+
+ if (!InitializeElementRecord(
+ eclass, style, recordPtr, optionTable, tkwin, state))
+ {
+ return;
+ }
+ eclass->specPtr->size(
+ eclass->clientData, eclass->elementRecord,
+ tkwin, widthPtr, heightPtr, paddingPtr);
+}
+
+/*
+ * Ttk_DrawElement --
+ * Draw the given widget element in a given drawable area.
+ */
+
+void
+Ttk_DrawElement(
+ Ttk_ElementClass *eclass, /* Element instance */
+ Ttk_Style style, /* Style settings */
+ char *recordPtr, /* The widget record. */
+ Tk_OptionTable optionTable, /* Description of option table */
+ Tk_Window tkwin, /* The widget window. */
+ Drawable d, /* Where to draw element. */
+ Ttk_Box b, /* Element area */
+ Ttk_State state) /* Widget or element state flags. */
+{
+ if (b.width <= 0 || b.height <= 0)
+ return;
+ if (!InitializeElementRecord(
+ eclass, style, recordPtr, optionTable, tkwin, state))
+ {
+ return;
+ }
+ eclass->specPtr->draw(
+ eclass->clientData, eclass->elementRecord,
+ tkwin, d, b, state);
+}
+
+/*------------------------------------------------------------------------
+ * +++ 'style' command ensemble procedures.
+ */
+
+/*
+ * TtkEnumerateHashTable --
+ * Helper routine. Sets interp's result to the list of all keys
+ * in the hash table.
+ *
+ * Returns: TCL_OK.
+ * Side effects: Sets interp's result.
+ */
+
+MODULE_SCOPE
+int TtkEnumerateHashTable(Tcl_Interp *interp, Tcl_HashTable *ht)
+{
+ Tcl_HashSearch search;
+ Tcl_Obj *result = Tcl_NewListObj(0, NULL);
+ Tcl_HashEntry *entryPtr = Tcl_FirstHashEntry(ht, &search);
+
+ while (entryPtr != NULL) {
+ Tcl_Obj *nameObj = Tcl_NewStringObj(Tcl_GetHashKey(ht, entryPtr),-1);
+ Tcl_ListObjAppendElement(interp, result, nameObj);
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+
+ Tcl_SetObjResult(interp, result);
+ return TCL_OK;
+}
+
+/* HashTableToDict --
+ * Helper routine. Converts a TCL_STRING_KEYS Tcl_HashTable
+ * with Tcl_Obj * entries into a dictionary.
+ */
+static Tcl_Obj* HashTableToDict(Tcl_HashTable *ht)
+{
+ Tcl_HashSearch search;
+ Tcl_Obj *result = Tcl_NewListObj(0, NULL);
+ Tcl_HashEntry *entryPtr = Tcl_FirstHashEntry(ht, &search);
+
+ while (entryPtr != NULL) {
+ Tcl_Obj *nameObj = Tcl_NewStringObj(Tcl_GetHashKey(ht, entryPtr),-1);
+ Tcl_Obj *valueObj = Tcl_GetHashValue(entryPtr);
+ Tcl_ListObjAppendElement(NULL, result, nameObj);
+ Tcl_ListObjAppendElement(NULL, result, valueObj);
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+
+ return result;
+}
+
+/* + style map $style ? -resource statemap ... ?
+ *
+ * Note that resource names are unconstrained; the Style
+ * doesn't know what resources individual elements may use.
+ */
+static int
+StyleMapCmd(
+ ClientData clientData, /* Master StylePackageData pointer */
+ Tcl_Interp *interp, /* Current interpreter */
+ int objc, /* Number of arguments */
+ Tcl_Obj *const objv[]) /* Argument objects */
+{
+ StylePackageData *pkgPtr = clientData;
+ Ttk_Theme theme = pkgPtr->currentTheme;
+ const char *styleName;
+ Style *stylePtr;
+ int i;
+
+ if (objc < 3) {
+usage:
+ Tcl_WrongNumArgs(interp,2,objv,"style ?-option ?value...??");
+ return TCL_ERROR;
+ }
+
+ styleName = Tcl_GetString(objv[2]);
+ stylePtr = Ttk_GetStyle(theme, styleName);
+
+ /* NOTE: StateMaps are actually Tcl_Obj *s, so HashTableToDict works
+ * for settingsTable.
+ */
+ if (objc == 3) { /* style map $styleName */
+ Tcl_SetObjResult(interp, HashTableToDict(&stylePtr->settingsTable));
+ return TCL_OK;
+ } else if (objc == 4) { /* style map $styleName -option */
+ const char *optionName = Tcl_GetString(objv[3]);
+ Tcl_HashEntry *entryPtr =
+ Tcl_FindHashEntry(&stylePtr->settingsTable, optionName);
+ if (entryPtr) {
+ Tcl_SetObjResult(interp, (Tcl_Obj*)Tcl_GetHashValue(entryPtr));
+ }
+ return TCL_OK;
+ } else if (objc % 2 != 1) {
+ goto usage;
+ }
+
+ for (i = 3; i < objc; i += 2) {
+ const char *optionName = Tcl_GetString(objv[i]);
+ Tcl_Obj *stateMap = objv[i+1];
+ Tcl_HashEntry *entryPtr;
+ int newEntry;
+
+ /* Make sure 'stateMap' is legal:
+ * (@@@ SHOULD: check for valid resource values as well,
+ * but we don't know what types they should be at this level.)
+ */
+ if (!Ttk_GetStateMapFromObj(interp, stateMap))
+ return TCL_ERROR;
+
+ entryPtr = Tcl_CreateHashEntry(
+ &stylePtr->settingsTable,optionName,&newEntry);
+
+ Tcl_IncrRefCount(stateMap);
+ if (!newEntry) {
+ Tcl_DecrRefCount((Tcl_Obj*)Tcl_GetHashValue(entryPtr));
+ }
+ Tcl_SetHashValue(entryPtr, stateMap);
+ }
+ ThemeChanged(pkgPtr);
+ return TCL_OK;
+}
+
+/* + style configure $style -option ?value...
+ */
+static int StyleConfigureCmd(
+ ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ StylePackageData *pkgPtr = clientData;
+ Ttk_Theme theme = pkgPtr->currentTheme;
+ const char *styleName;
+ Style *stylePtr;
+ int i;
+
+ if (objc < 3) {
+usage:
+ Tcl_WrongNumArgs(interp,2,objv,"style ?-option ?value...??");
+ return TCL_ERROR;
+ }
+
+ styleName = Tcl_GetString(objv[2]);
+ stylePtr = Ttk_GetStyle(theme, styleName);
+
+ if (objc == 3) { /* style default $styleName */
+ Tcl_SetObjResult(interp, HashTableToDict(&stylePtr->defaultsTable));
+ return TCL_OK;
+ } else if (objc == 4) { /* style default $styleName -option */
+ const char *optionName = Tcl_GetString(objv[3]);
+ Tcl_HashEntry *entryPtr =
+ Tcl_FindHashEntry(&stylePtr->defaultsTable, optionName);
+ if (entryPtr) {
+ Tcl_SetObjResult(interp, (Tcl_Obj*)Tcl_GetHashValue(entryPtr));
+ }
+ return TCL_OK;
+ } else if (objc % 2 != 1) {
+ goto usage;
+ }
+
+ for (i = 3; i < objc; i += 2) {
+ const char *optionName = Tcl_GetString(objv[i]);
+ Tcl_Obj *value = objv[i+1];
+ Tcl_HashEntry *entryPtr;
+ int newEntry;
+
+ entryPtr = Tcl_CreateHashEntry(
+ &stylePtr->defaultsTable,optionName,&newEntry);
+
+ Tcl_IncrRefCount(value);
+ if (!newEntry) {
+ Tcl_DecrRefCount((Tcl_Obj*)Tcl_GetHashValue(entryPtr));
+ }
+ Tcl_SetHashValue(entryPtr, value);
+ }
+
+ ThemeChanged(pkgPtr);
+ return TCL_OK;
+}
+
+/* + style lookup $style -option ?statespec? ?defaultValue?
+ */
+static int StyleLookupCmd(
+ ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ StylePackageData *pkgPtr = clientData;
+ Ttk_Theme theme = pkgPtr->currentTheme;
+ Ttk_Style style = NULL;
+ const char *optionName;
+ Ttk_State state = 0ul;
+ Tcl_Obj *result;
+
+ if (objc < 4 || objc > 6) {
+ Tcl_WrongNumArgs(interp, 2, objv, "style -option ?state? ?default?");
+ return TCL_ERROR;
+ }
+
+ style = Ttk_GetStyle(theme, Tcl_GetString(objv[2]));
+ if (!style) {
+ return TCL_ERROR;
+ }
+ optionName = Tcl_GetString(objv[3]);
+
+ if (objc >= 5) {
+ Ttk_StateSpec stateSpec;
+ /* @@@ SB: Ttk_GetStateFromObj(); 'offbits' spec is ignored */
+ if (Ttk_GetStateSpecFromObj(interp, objv[4], &stateSpec) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ state = stateSpec.onbits;
+ }
+
+ result = Ttk_QueryStyle(style, NULL,NULL, optionName, state);
+ if (result == NULL && objc >= 6) { /* Use caller-supplied fallback */
+ result = objv[5];
+ }
+
+ if (result) {
+ Tcl_SetObjResult(interp, result);
+ }
+
+ return TCL_OK;
+}
+
+static int StyleThemeCurrentCmd(
+ ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[])
+{
+ StylePackageData *pkgPtr = clientData;
+ Tcl_HashSearch search;
+ Tcl_HashEntry *entryPtr = NULL;
+ const char *name = NULL;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, "");
+ return TCL_ERROR;
+ }
+
+ entryPtr = Tcl_FirstHashEntry(&pkgPtr->themeTable, &search);
+ while (entryPtr != NULL) {
+ Theme *ptr = Tcl_GetHashValue(entryPtr);
+ if (ptr == pkgPtr->currentTheme) {
+ name = Tcl_GetHashKey(&pkgPtr->themeTable, entryPtr);
+ break;
+ }
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+
+ if (name == NULL) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj("error: failed to get theme name", -1));
+ return TCL_ERROR;
+ }
+
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
+ return TCL_OK;
+}
+
+/* + style theme create name ?-parent $theme? ?-settings { script }?
+ */
+static int StyleThemeCreateCmd(
+ ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ StylePackageData *pkgPtr = clientData;
+ static const char *optStrings[] =
+ { "-parent", "-settings", NULL };
+ enum { OP_PARENT, OP_SETTINGS };
+ Ttk_Theme parentTheme = pkgPtr->defaultTheme, newTheme;
+ Tcl_Obj *settingsScript = NULL;
+ const char *themeName;
+ int i;
+
+ if (objc < 4 || objc % 2 != 0) {
+ Tcl_WrongNumArgs(interp, 3, objv, "name ?-option value ...?");
+ return TCL_ERROR;
+ }
+
+ themeName = Tcl_GetString(objv[3]);
+
+ for (i=4; i < objc; i +=2) {
+ int option;
+ if (Tcl_GetIndexFromObj(
+ interp, objv[i], optStrings, "option", 0, &option) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ switch (option) {
+ case OP_PARENT:
+ parentTheme = LookupTheme(
+ interp, pkgPtr, Tcl_GetString(objv[i+1]));
+ if (!parentTheme)
+ return TCL_ERROR;
+ break;
+ case OP_SETTINGS:
+ settingsScript = objv[i+1];
+ break;
+ }
+ }
+
+ newTheme = Ttk_CreateTheme(interp, themeName, parentTheme);
+ if (!newTheme) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Evaluate the -settings script, if supplied:
+ */
+ if (settingsScript) {
+ Ttk_Theme oldTheme = pkgPtr->currentTheme;
+ int status;
+
+ pkgPtr->currentTheme = newTheme;
+ status = Tcl_EvalObjEx(interp, settingsScript, 0);
+ pkgPtr->currentTheme = oldTheme;
+ return status;
+ } else {
+ return TCL_OK;
+ }
+}
+
+/* + style theme names --
+ * Return list of registered themes.
+ */
+static int StyleThemeNamesCmd(
+ ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ StylePackageData *pkgPtr = clientData;
+ return TtkEnumerateHashTable(interp, &pkgPtr->themeTable);
+}
+
+/* + style theme settings $theme $script
+ *
+ * Temporarily sets the current theme to $themeName,
+ * evaluates $script, then restores the old theme.
+ */
+static int
+StyleThemeSettingsCmd(
+ ClientData clientData, /* Master StylePackageData pointer */
+ Tcl_Interp *interp, /* Current interpreter */
+ int objc, /* Number of arguments */
+ Tcl_Obj *const objv[]) /* Argument objects */
+{
+ StylePackageData *pkgPtr = clientData;
+ Ttk_Theme oldTheme = pkgPtr->currentTheme;
+ Ttk_Theme newTheme;
+ int status;
+
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "theme script");
+ return TCL_ERROR;
+ }
+
+ newTheme = LookupTheme(interp, pkgPtr, Tcl_GetString(objv[3]));
+ if (!newTheme)
+ return TCL_ERROR;
+
+ pkgPtr->currentTheme = newTheme;
+ status = Tcl_EvalObjEx(interp, objv[4], 0);
+ pkgPtr->currentTheme = oldTheme;
+
+ return status;
+}
+
+/* + style element create name type ? ...args ?
+ */
+static int StyleElementCreateCmd(
+ ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ StylePackageData *pkgPtr = clientData;
+ Ttk_Theme theme = pkgPtr->currentTheme;
+ const char *elementName, *factoryName;
+ Tcl_HashEntry *entryPtr;
+ FactoryRec *recPtr;
+
+ if (objc < 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "name type ?-option value ...?");
+ return TCL_ERROR;
+ }
+
+ elementName = Tcl_GetString(objv[3]);
+ factoryName = Tcl_GetString(objv[4]);
+
+ entryPtr = Tcl_FindHashEntry(&pkgPtr->factoryTable, factoryName);
+ if (!entryPtr) {
+ Tcl_AppendResult(interp, "No such element type ", factoryName, NULL);
+ return TCL_ERROR;
+ }
+
+ recPtr = Tcl_GetHashValue(entryPtr);
+
+ return recPtr->factory(interp, recPtr->clientData,
+ theme, elementName, objc - 5, objv + 5);
+}
+
+/* + style element names --
+ * Return a list of elements defined in the current theme.
+ */
+static int StyleElementNamesCmd(
+ ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ StylePackageData *pkgPtr = clientData;
+ Ttk_Theme theme = pkgPtr->currentTheme;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
+ return TCL_ERROR;
+ }
+ return TtkEnumerateHashTable(interp, &theme->elementTable);
+}
+
+/* + style element options $element --
+ * Return list of element options for specified element
+ */
+static int StyleElementOptionsCmd(
+ ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ StylePackageData *pkgPtr = clientData;
+ Ttk_Theme theme = pkgPtr->currentTheme;
+ const char *elementName;
+ Ttk_ElementClass *elementClass;
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "element");
+ return TCL_ERROR;
+ }
+
+ elementName = Tcl_GetString(objv[3]);
+ elementClass = Ttk_GetElement(theme, elementName);
+ if (elementClass) {
+ Ttk_ElementSpec *specPtr = elementClass->specPtr;
+ Ttk_ElementOptionSpec *option = specPtr->options;
+ Tcl_Obj *result = Tcl_NewListObj(0,0);
+
+ while (option->optionName) {
+ Tcl_ListObjAppendElement(
+ interp, result, Tcl_NewStringObj(option->optionName,-1));
+ ++option;
+ }
+
+ Tcl_SetObjResult(interp, result);
+ return TCL_OK;
+ }
+
+ Tcl_AppendResult(interp, "element ", elementName, " not found", NULL);
+ return TCL_ERROR;
+}
+
+/* + style layout name ?spec?
+ */
+static int StyleLayoutCmd(
+ ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ StylePackageData *pkgPtr = clientData;
+ Ttk_Theme theme = pkgPtr->currentTheme;
+ const char *layoutName;
+ Ttk_LayoutTemplate layoutTemplate;
+
+ if (objc < 3 || objc > 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name ?spec?");
+ return TCL_ERROR;
+ }
+
+ layoutName = Tcl_GetString(objv[2]);
+
+ if (objc == 3) {
+ layoutTemplate = Ttk_FindLayoutTemplate(theme, layoutName);
+ if (!layoutTemplate) {
+ Tcl_AppendResult(interp, "Layout ", layoutName, " not found", NULL);
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, Ttk_UnparseLayoutTemplate(layoutTemplate));
+ } else {
+ layoutTemplate = Ttk_ParseLayoutTemplate(interp, objv[3]);
+ if (!layoutTemplate) {
+ return TCL_ERROR;
+ }
+ Ttk_RegisterLayoutTemplate(theme, layoutName, layoutTemplate);
+ ThemeChanged(pkgPtr);
+ }
+ return TCL_OK;
+}
+
+/* + style theme use $theme --
+ * Sets the current theme to $theme
+ */
+static int
+StyleThemeUseCmd(
+ ClientData clientData, /* Master StylePackageData pointer */
+ Tcl_Interp *interp, /* Current interpreter */
+ int objc, /* Number of arguments */
+ Tcl_Obj *const objv[]) /* Argument objects */
+{
+ StylePackageData *pkgPtr = clientData;
+ Ttk_Theme theme;
+
+ if (objc < 3 || objc > 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "?theme?");
+ return TCL_ERROR;
+ }
+
+ if (objc == 3) {
+ return StyleThemeCurrentCmd(clientData, interp, objc, objv);
+ }
+
+ theme = LookupTheme(interp, pkgPtr, Tcl_GetString(objv[3]));
+ if (!theme) {
+ return TCL_ERROR;
+ }
+
+ return Ttk_UseTheme(interp, theme);
+}
+
+/*
+ * StyleObjCmd --
+ * Implementation of the [style] command.
+ */
+
+static const Ttk_Ensemble StyleThemeEnsemble[] = {
+ { "create", StyleThemeCreateCmd, 0 },
+ { "names", StyleThemeNamesCmd, 0 },
+ { "settings", StyleThemeSettingsCmd, 0 },
+ { "use", StyleThemeUseCmd, 0 },
+ { NULL, 0, 0 }
+};
+
+static const Ttk_Ensemble StyleElementEnsemble[] = {
+ { "create", StyleElementCreateCmd, 0 },
+ { "names", StyleElementNamesCmd, 0 },
+ { "options", StyleElementOptionsCmd, 0 },
+ { NULL, 0, 0 }
+};
+
+static const Ttk_Ensemble StyleEnsemble[] = {
+ { "configure", StyleConfigureCmd, 0 },
+ { "map", StyleMapCmd, 0 },
+ { "lookup", StyleLookupCmd, 0 },
+ { "layout", StyleLayoutCmd, 0 },
+ { "theme", 0, StyleThemeEnsemble },
+ { "element", 0, StyleElementEnsemble },
+ { NULL, 0, 0 }
+};
+
+static int
+StyleObjCmd(
+ ClientData clientData, /* Master StylePackageData pointer */
+ Tcl_Interp *interp, /* Current interpreter */
+ int objc, /* Number of arguments */
+ Tcl_Obj *const objv[]) /* Argument objects */
+{
+ return Ttk_InvokeEnsemble(StyleEnsemble, 1, clientData,interp,objc,objv);
+}
+
+MODULE_SCOPE
+int Ttk_InvokeEnsemble( /* Run an ensemble command */
+ const Ttk_Ensemble *ensemble, int cmdIndex,
+ void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ while (cmdIndex < objc) {
+ int index;
+ if (Tcl_GetIndexFromObjStruct(interp,
+ objv[cmdIndex], ensemble, sizeof(ensemble[0]),
+ "command", 0, &index)
+ != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ if (ensemble[index].command) {
+ return ensemble[index].command(clientData, interp, objc, objv);
+ }
+ ensemble = ensemble[index].ensemble;
+ ++cmdIndex;
+ }
+ Tcl_WrongNumArgs(interp, cmdIndex, objv, "option ?arg ...?");
+ return TCL_ERROR;
+}
+
+/*
+ * Ttk_StylePkgInit --
+ * Initializes all the structures that are used by the style
+ * package on a per-interp basis.
+ */
+
+void Ttk_StylePkgInit(Tcl_Interp *interp)
+{
+ Tcl_Namespace *nsPtr;
+
+ StylePackageData *pkgPtr = (StylePackageData *)
+ ckalloc(sizeof(StylePackageData));
+
+ pkgPtr->interp = interp;
+ Tcl_InitHashTable(&pkgPtr->themeTable, TCL_STRING_KEYS);
+ Tcl_InitHashTable(&pkgPtr->factoryTable, TCL_STRING_KEYS);
+ pkgPtr->cleanupList = NULL;
+ pkgPtr->cache = Ttk_CreateResourceCache(interp);
+ pkgPtr->themeChangePending = 0;
+
+ Tcl_SetAssocData(interp, PKG_ASSOC_KEY, Ttk_StylePkgFree, pkgPtr);
+
+ /*
+ * Create the default system theme:
+ *
+ * pkgPtr->defaultTheme must be initialized to 0 before
+ * calling Ttk_CreateTheme for the first time, since it's used
+ * as the parent theme.
+ */
+ pkgPtr->defaultTheme = 0;
+ pkgPtr->defaultTheme = pkgPtr->currentTheme =
+ Ttk_CreateTheme(interp, "default", NULL);
+
+ /*
+ * Register null element, used as a last-resort fallback:
+ */
+ Ttk_RegisterElement(interp, pkgPtr->defaultTheme, "", &ttkNullElementSpec, 0);
+
+ /*
+ * Register commands:
+ */
+ Tcl_CreateObjCommand(interp, "::ttk::style", StyleObjCmd, pkgPtr, 0);
+
+ nsPtr = Tcl_FindNamespace(interp, "::ttk", NULL, TCL_LEAVE_ERR_MSG);
+ Tcl_Export(interp, nsPtr, "style", 0 /* dontResetList */);
+
+ Ttk_RegisterElementFactory(interp, "from", Ttk_CloneElement, 0);
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkTheme.h b/generic/ttk/ttkTheme.h
new file mode 100644
index 0000000..7bf2a7f
--- /dev/null
+++ b/generic/ttk/ttkTheme.h
@@ -0,0 +1,444 @@
+/*
+ * Copyright (c) 2003 Joe English. Freely redistributable.
+ *
+ * Declarations for Tk theme engine.
+ */
+
+#ifndef _TTKTHEME
+#define _TTKTHEME
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MODULE_SCOPE
+# ifdef __cplusplus
+# define MODULE_SCOPE extern "C"
+# else
+# define MODULE_SCOPE extern
+# endif
+#endif
+
+#define TTKAPI MODULE_SCOPE
+
+/* Ttk syncs to the Tk version & patchlevel */
+#define TTK_VERSION TK_VERSION
+#define TTK_PATCH_LEVEL TK_PATCH_LEVEL
+
+/*------------------------------------------------------------------------
+ * +++ Defaults for element option specifications.
+ */
+#define DEFAULT_FONT "TkDefaultFont"
+#define DEFAULT_BACKGROUND "#d9d9d9"
+#define DEFAULT_FOREGROUND "black"
+
+/*------------------------------------------------------------------------
+ * +++ Widget states.
+ * Keep in sync with stateNames[] in tkstate.c.
+ */
+
+typedef unsigned int Ttk_State;
+
+#define TTK_STATE_ACTIVE (1<<0)
+#define TTK_STATE_DISABLED (1<<1)
+#define TTK_STATE_FOCUS (1<<2)
+#define TTK_STATE_PRESSED (1<<3)
+#define TTK_STATE_SELECTED (1<<4)
+#define TTK_STATE_BACKGROUND (1<<5)
+#define TTK_STATE_ALTERNATE (1<<6)
+#define TTK_STATE_INVALID (1<<7)
+#define TTK_STATE_READONLY (1<<8)
+#define TTK_STATE_HOVER (1<<9)
+#define TTK_STATE_USER6 (1<<10)
+#define TTK_STATE_USER5 (1<<11)
+#define TTK_STATE_USER4 (1<<12)
+#define TTK_STATE_USER3 (1<<13)
+#define TTK_STATE_USER2 (1<<14)
+#define TTK_STATE_USER1 (1<<15)
+
+/* Maintenance note: if you get all the way to "USER1",
+ * see tkstate.c
+ */
+typedef struct
+{
+ unsigned int onbits; /* bits to turn on */
+ unsigned int offbits; /* bits to turn off */
+} Ttk_StateSpec;
+
+#define Ttk_StateMatches(state, spec) \
+ (((state) & ((spec)->onbits|(spec)->offbits)) == (spec)->onbits)
+
+#define Ttk_ModifyState(state, spec) \
+ (((state) & ~(spec)->offbits) | (spec)->onbits)
+
+TTKAPI int Ttk_GetStateSpecFromObj(Tcl_Interp *, Tcl_Obj *, Ttk_StateSpec *);
+TTKAPI Tcl_Obj *Ttk_NewStateSpecObj(unsigned int onbits,unsigned int offbits);
+
+/*------------------------------------------------------------------------
+ * +++ State maps and state tables.
+ */
+typedef Tcl_Obj *Ttk_StateMap;
+
+TTKAPI Ttk_StateMap Ttk_GetStateMapFromObj(Tcl_Interp *, Tcl_Obj *);
+TTKAPI Tcl_Obj *Ttk_StateMapLookup(Tcl_Interp*, Ttk_StateMap, Ttk_State);
+
+/*
+ * Table for looking up an integer index based on widget state:
+ */
+typedef struct
+{
+ int index; /* Value to return if this entry matches */
+ unsigned int onBits; /* Bits which must be set */
+ unsigned int offBits; /* Bits which must be cleared */
+} Ttk_StateTable;
+
+TTKAPI int Ttk_StateTableLookup(Ttk_StateTable map[], Ttk_State);
+
+/*------------------------------------------------------------------------
+ * +++ Padding.
+ * Used to represent internal padding and borders.
+ */
+typedef struct
+{
+ short left;
+ short top;
+ short right;
+ short bottom;
+} Ttk_Padding;
+
+TTKAPI int Ttk_GetPaddingFromObj(Tcl_Interp*,Tk_Window,Tcl_Obj*,Ttk_Padding*);
+TTKAPI int Ttk_GetBorderFromObj(Tcl_Interp*,Tcl_Obj*,Ttk_Padding*);
+
+TTKAPI Ttk_Padding Ttk_MakePadding(short l, short t, short r, short b);
+TTKAPI Ttk_Padding Ttk_UniformPadding(short borderWidth);
+TTKAPI Ttk_Padding Ttk_AddPadding(Ttk_Padding, Ttk_Padding);
+TTKAPI Ttk_Padding Ttk_RelievePadding(Ttk_Padding, int relief, int n);
+
+#define Ttk_PaddingWidth(p) ((p).left + (p).right)
+#define Ttk_PaddingHeight(p) ((p).top + (p).bottom)
+
+#define Ttk_SetMargins(tkwin, pad) \
+ Tk_SetInternalBorderEx(tkwin, pad.left, pad.right, pad.top, pad.bottom)
+
+/*------------------------------------------------------------------------
+ * +++ Boxes.
+ * Used to represent rectangular regions
+ */
+typedef struct /* Hey, this is an XRectangle! */
+{
+ int x;
+ int y;
+ int width;
+ int height;
+} Ttk_Box;
+
+TTKAPI Ttk_Box Ttk_MakeBox(int x, int y, int width, int height);
+TTKAPI int Ttk_BoxContains(Ttk_Box, int x, int y);
+
+#define Ttk_WinBox(tkwin) Ttk_MakeBox(0,0,Tk_Width(tkwin),Tk_Height(tkwin))
+
+/*------------------------------------------------------------------------
+ * +++ Layout utilities.
+ */
+typedef enum {
+ TTK_SIDE_LEFT, TTK_SIDE_TOP, TTK_SIDE_RIGHT, TTK_SIDE_BOTTOM
+} Ttk_Side;
+
+typedef unsigned int Ttk_Sticky;
+
+/*
+ * -sticky bits for Ttk_StickBox:
+ */
+#define TTK_STICK_W (0x1)
+#define TTK_STICK_E (0x2)
+#define TTK_STICK_N (0x4)
+#define TTK_STICK_S (0x8)
+
+/*
+ * Aliases and useful combinations:
+ */
+#define TTK_FILL_X (0x3) /* -sticky ew */
+#define TTK_FILL_Y (0xC) /* -sticky ns */
+#define TTK_FILL_BOTH (0xF) /* -sticky nswe */
+
+TTKAPI int Ttk_GetStickyFromObj(Tcl_Interp *, Tcl_Obj *, Ttk_Sticky *);
+TTKAPI Tcl_Obj *Ttk_NewStickyObj(Ttk_Sticky);
+
+/*
+ * Extra bits for position specifications (combine -side and -sticky)
+ */
+
+typedef unsigned int Ttk_PositionSpec; /* See below */
+
+#define TTK_PACK_LEFT (0x10) /* pack at left of current parcel */
+#define TTK_PACK_RIGHT (0x20) /* pack at right of current parcel */
+#define TTK_PACK_TOP (0x40) /* pack at top of current parcel */
+#define TTK_PACK_BOTTOM (0x80) /* pack at bottom of current parcel */
+#define TTK_EXPAND (0x100) /* use entire parcel */
+#define TTK_BORDER (0x200) /* draw this element after children */
+#define TTK_UNIT (0x400) /* treat descendants as a part of element */
+
+/*
+ * Extra bits for layout specifications
+ */
+#define _TTK_CHILDREN (0x1000)/* for LayoutSpecs -- children follow */
+#define _TTK_LAYOUT_END (0x2000)/* for LayoutSpecs -- end of child list */
+#define _TTK_LAYOUT (0x4000)/* for LayoutSpec tables -- define layout */
+
+#define _TTK_MASK_STICK (0x0F) /* See Ttk_UnparseLayout() */
+#define _TTK_MASK_PACK (0xF0) /* See Ttk_UnparseLayout(), packStrings */
+
+TTKAPI Ttk_Box Ttk_PackBox(Ttk_Box *cavity, int w, int h, Ttk_Side side);
+TTKAPI Ttk_Box Ttk_StickBox(Ttk_Box parcel, int w, int h, Ttk_Sticky sticky);
+TTKAPI Ttk_Box Ttk_AnchorBox(Ttk_Box parcel, int w, int h, Tk_Anchor anchor);
+TTKAPI Ttk_Box Ttk_PadBox(Ttk_Box b, Ttk_Padding p);
+TTKAPI Ttk_Box Ttk_ExpandBox(Ttk_Box b, Ttk_Padding p);
+TTKAPI Ttk_Box Ttk_PlaceBox(Ttk_Box *cavity, int w,int h, Ttk_Side,Ttk_Sticky);
+TTKAPI Ttk_Box Ttk_PositionBox(Ttk_Box *cavity, int w, int h, Ttk_PositionSpec);
+
+/*------------------------------------------------------------------------
+ * +++ Themes.
+ */
+MODULE_SCOPE void Ttk_StylePkgInit(Tcl_Interp *);
+
+typedef struct Ttk_Theme_ *Ttk_Theme;
+typedef struct Ttk_ElementClass_ Ttk_ElementClass;
+typedef struct Ttk_Layout_ *Ttk_Layout;
+typedef struct Ttk_LayoutNode_ *Ttk_Element;
+typedef struct Ttk_Style_ *Ttk_Style;
+
+TTKAPI Ttk_Theme Ttk_GetTheme(Tcl_Interp *interp, const char *name);
+TTKAPI Ttk_Theme Ttk_GetDefaultTheme(Tcl_Interp *interp);
+TTKAPI Ttk_Theme Ttk_GetCurrentTheme(Tcl_Interp *interp);
+
+TTKAPI Ttk_Theme Ttk_CreateTheme(
+ Tcl_Interp *interp, const char *name, Ttk_Theme parent);
+
+typedef int (Ttk_ThemeEnabledProc)(Ttk_Theme theme, void *clientData);
+MODULE_SCOPE void Ttk_SetThemeEnabledProc(Ttk_Theme, Ttk_ThemeEnabledProc, void *);
+
+MODULE_SCOPE int Ttk_UseTheme(Tcl_Interp *, Ttk_Theme);
+
+typedef void (Ttk_CleanupProc)(void *clientData);
+TTKAPI void Ttk_RegisterCleanup(
+ Tcl_Interp *interp, void *deleteData, Ttk_CleanupProc *cleanupProc);
+
+/*------------------------------------------------------------------------
+ * +++ Elements.
+ */
+
+enum TTKStyleVersion2 { TK_STYLE_VERSION_2 = 2 };
+
+typedef void (Ttk_ElementSizeProc)(void *clientData, void *elementRecord,
+ Tk_Window tkwin, int *widthPtr, int *heightPtr, Ttk_Padding*);
+typedef void (Ttk_ElementDrawProc)(void *clientData, void *elementRecord,
+ Tk_Window tkwin, Drawable d, Ttk_Box b, Ttk_State state);
+
+typedef struct Ttk_ElementOptionSpec
+{
+ const char *optionName; /* Command-line name of the widget option */
+ Tk_OptionType type; /* Accepted option types */
+ int offset; /* Offset of Tcl_Obj* field in element record */
+ const char *defaultValue; /* Default value to used if resource missing */
+} Ttk_ElementOptionSpec;
+
+#define TK_OPTION_ANY TK_OPTION_STRING
+
+typedef struct Ttk_ElementSpec {
+ enum TTKStyleVersion2 version; /* Version of the style support. */
+ size_t elementSize; /* Size of element record */
+ Ttk_ElementOptionSpec *options; /* List of options, NULL-terminated */
+ Ttk_ElementSizeProc *size; /* Compute min size and padding */
+ Ttk_ElementDrawProc *draw; /* Draw the element */
+} Ttk_ElementSpec;
+
+TTKAPI Ttk_ElementClass *Ttk_RegisterElement(
+ Tcl_Interp *interp, Ttk_Theme theme, const char *elementName,
+ Ttk_ElementSpec *, void *clientData);
+
+typedef int (*Ttk_ElementFactory)
+ (Tcl_Interp *, void *clientData,
+ Ttk_Theme, const char *elementName, int objc, Tcl_Obj *const objv[]);
+
+TTKAPI int Ttk_RegisterElementFactory(
+ Tcl_Interp *, const char *name, Ttk_ElementFactory, void *clientData);
+
+/*
+ * Null element implementation:
+ * has no geometry or layout; may be used as a stub or placeholder.
+ */
+
+typedef struct {
+ Tcl_Obj *unused;
+} NullElement;
+
+MODULE_SCOPE void TtkNullElementSize
+ (void *, void *, Tk_Window, int *, int *, Ttk_Padding *);
+MODULE_SCOPE void TtkNullElementDraw
+ (void *, void *, Tk_Window, Drawable, Ttk_Box, Ttk_State);
+MODULE_SCOPE Ttk_ElementOptionSpec TtkNullElementOptions[];
+MODULE_SCOPE Ttk_ElementSpec ttkNullElementSpec;
+
+/*------------------------------------------------------------------------
+ * +++ Layout templates.
+ */
+typedef struct {
+ const char * elementName;
+ unsigned opcode;
+} TTKLayoutInstruction, *Ttk_LayoutSpec;
+
+#define TTK_BEGIN_LAYOUT_TABLE(name) \
+ static TTKLayoutInstruction name[] = {
+#define TTK_LAYOUT(name, content) \
+ { name, _TTK_CHILDREN|_TTK_LAYOUT }, \
+ content \
+ { 0, _TTK_LAYOUT_END },
+#define TTK_GROUP(name, flags, children) \
+ { name, flags | _TTK_CHILDREN }, \
+ children \
+ { 0, _TTK_LAYOUT_END },
+#define TTK_NODE(name, flags) { name, flags },
+#define TTK_END_LAYOUT_TABLE { 0, _TTK_LAYOUT | _TTK_LAYOUT_END } };
+
+#define TTK_BEGIN_LAYOUT(name) static TTKLayoutInstruction name[] = {
+#define TTK_END_LAYOUT { 0, _TTK_LAYOUT_END } };
+
+TTKAPI void Ttk_RegisterLayout(
+ Ttk_Theme theme, const char *className, Ttk_LayoutSpec layoutSpec);
+
+TTKAPI void Ttk_RegisterLayouts(
+ Ttk_Theme theme, Ttk_LayoutSpec layoutTable);
+
+/*------------------------------------------------------------------------
+ * +++ Layout instances.
+ */
+
+MODULE_SCOPE Ttk_Layout Ttk_CreateLayout(
+ Tcl_Interp *, Ttk_Theme, const char *name,
+ void *recordPtr, Tk_OptionTable, Tk_Window tkwin);
+
+MODULE_SCOPE Ttk_Layout Ttk_CreateSublayout(
+ Tcl_Interp *, Ttk_Theme, Ttk_Layout, const char *name, Tk_OptionTable);
+
+MODULE_SCOPE void Ttk_FreeLayout(Ttk_Layout);
+
+MODULE_SCOPE void Ttk_LayoutSize(Ttk_Layout,Ttk_State,int *widthPtr,int *heightPtr);
+MODULE_SCOPE void Ttk_PlaceLayout(Ttk_Layout, Ttk_State, Ttk_Box);
+MODULE_SCOPE void Ttk_DrawLayout(Ttk_Layout, Ttk_State, Drawable);
+
+MODULE_SCOPE void Ttk_RebindSublayout(Ttk_Layout, void *recordPtr);
+
+MODULE_SCOPE Ttk_Element Ttk_IdentifyElement(Ttk_Layout, int x, int y);
+MODULE_SCOPE Ttk_Element Ttk_FindElement(Ttk_Layout, const char *nodeName);
+
+MODULE_SCOPE const char *Ttk_ElementName(Ttk_Element);
+MODULE_SCOPE Ttk_Box Ttk_ElementParcel(Ttk_Element);
+
+MODULE_SCOPE Ttk_Box Ttk_ClientRegion(Ttk_Layout, const char *elementName);
+
+MODULE_SCOPE Ttk_Box Ttk_LayoutNodeInternalParcel(Ttk_Layout,Ttk_Element);
+MODULE_SCOPE Ttk_Padding Ttk_LayoutNodeInternalPadding(Ttk_Layout,Ttk_Element);
+MODULE_SCOPE void Ttk_LayoutNodeReqSize(Ttk_Layout, Ttk_Element, int *w, int *h);
+
+MODULE_SCOPE void Ttk_PlaceElement(Ttk_Layout, Ttk_Element, Ttk_Box);
+MODULE_SCOPE void Ttk_ChangeElementState(Ttk_Element,unsigned set,unsigned clr);
+
+MODULE_SCOPE Tcl_Obj *Ttk_QueryOption(Ttk_Layout, const char *, Ttk_State);
+
+TTKAPI Ttk_Style Ttk_LayoutStyle(Ttk_Layout);
+TTKAPI Tcl_Obj *Ttk_StyleDefault(Ttk_Style, const char *optionName);
+TTKAPI Tcl_Obj *Ttk_StyleMap(Ttk_Style, const char *optionName, Ttk_State);
+
+/*------------------------------------------------------------------------
+ * +++ Resource cache.
+ * See resource.c for explanation.
+ */
+
+typedef struct Ttk_ResourceCache_ *Ttk_ResourceCache;
+MODULE_SCOPE Ttk_ResourceCache Ttk_CreateResourceCache(Tcl_Interp *);
+MODULE_SCOPE void Ttk_FreeResourceCache(Ttk_ResourceCache);
+
+MODULE_SCOPE Ttk_ResourceCache Ttk_GetResourceCache(Tcl_Interp*);
+MODULE_SCOPE Tcl_Obj *Ttk_UseFont(Ttk_ResourceCache, Tk_Window, Tcl_Obj *);
+MODULE_SCOPE Tcl_Obj *Ttk_UseColor(Ttk_ResourceCache, Tk_Window, Tcl_Obj *);
+MODULE_SCOPE Tcl_Obj *Ttk_UseBorder(Ttk_ResourceCache, Tk_Window, Tcl_Obj *);
+MODULE_SCOPE Tk_Image Ttk_UseImage(Ttk_ResourceCache, Tk_Window, Tcl_Obj *);
+
+MODULE_SCOPE void Ttk_RegisterNamedColor(Ttk_ResourceCache, const char *, XColor *);
+
+/*------------------------------------------------------------------------
+ * +++ Image specifications.
+ */
+
+typedef struct TtkImageSpec Ttk_ImageSpec;
+TTKAPI Ttk_ImageSpec *TtkGetImageSpec(Tcl_Interp *, Tk_Window, Tcl_Obj *);
+TTKAPI void TtkFreeImageSpec(Ttk_ImageSpec *);
+TTKAPI Tk_Image TtkSelectImage(Ttk_ImageSpec *, Ttk_State);
+
+/*------------------------------------------------------------------------
+ * +++ Miscellaneous enumerations.
+ * Other stuff that element implementations need to know about.
+ */
+typedef enum /* -default option values */
+{
+ TTK_BUTTON_DEFAULT_NORMAL, /* widget defaultable */
+ TTK_BUTTON_DEFAULT_ACTIVE, /* currently the default widget */
+ TTK_BUTTON_DEFAULT_DISABLED /* not defaultable */
+} Ttk_ButtonDefaultState;
+
+TTKAPI int Ttk_GetButtonDefaultStateFromObj(Tcl_Interp *, Tcl_Obj *, int *);
+
+typedef enum /* -compound option values */
+{
+ TTK_COMPOUND_NONE, /* image if specified, otherwise text */
+ TTK_COMPOUND_TEXT, /* text only */
+ TTK_COMPOUND_IMAGE, /* image only */
+ TTK_COMPOUND_CENTER, /* text overlays image */
+ TTK_COMPOUND_TOP, /* image above text */
+ TTK_COMPOUND_BOTTOM, /* image below text */
+ TTK_COMPOUND_LEFT, /* image to left of text */
+ TTK_COMPOUND_RIGHT /* image to right of text */
+} Ttk_Compound;
+
+TTKAPI int Ttk_GetCompoundFromObj(Tcl_Interp *, Tcl_Obj *, int *);
+
+typedef enum { /* -orient option values */
+ TTK_ORIENT_HORIZONTAL,
+ TTK_ORIENT_VERTICAL
+} Ttk_Orient;
+
+/*------------------------------------------------------------------------
+ * +++ Utilities.
+ */
+
+typedef struct TtkEnsemble {
+ const char *name; /* subcommand name */
+ Tcl_ObjCmdProc *command; /* subcommand implementation, OR: */
+ const struct TtkEnsemble *ensemble; /* subcommand ensemble */
+} Ttk_Ensemble;
+
+MODULE_SCOPE int Ttk_InvokeEnsemble( /* Run an ensemble command */
+ const Ttk_Ensemble *commands, int cmdIndex,
+ void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
+
+MODULE_SCOPE int TtkEnumerateHashTable(Tcl_Interp *, Tcl_HashTable *);
+
+/*------------------------------------------------------------------------
+ * +++ Stub table declarations.
+ */
+
+#include "ttkDecls.h"
+
+/*
+ * Drawing utilities for theme code:
+ * (@@@ find a better home for this)
+ */
+typedef enum { ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT } ArrowDirection;
+MODULE_SCOPE void TtkArrowSize(int h, ArrowDirection, int *widthPtr, int *heightPtr);
+MODULE_SCOPE void TtkDrawArrow(Display *, Drawable, GC, Ttk_Box, ArrowDirection);
+MODULE_SCOPE void TtkFillArrow(Display *, Drawable, GC, Ttk_Box, ArrowDirection);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _TTKTHEME */
diff --git a/generic/ttk/ttkThemeInt.h b/generic/ttk/ttkThemeInt.h
new file mode 100644
index 0000000..3aaada8
--- /dev/null
+++ b/generic/ttk/ttkThemeInt.h
@@ -0,0 +1,42 @@
+/*
+ * Theme engine: private definitions.
+ *
+ * Copyright (c) 2004 Joe English. Freely redistributable.
+ */
+
+#ifndef _TTKTHEMEINT
+#define _TTKTHEMEINT
+
+#include "ttkTheme.h"
+
+typedef struct Ttk_TemplateNode_ Ttk_TemplateNode, *Ttk_LayoutTemplate;
+
+MODULE_SCOPE Ttk_ElementClass *Ttk_GetElement(Ttk_Theme, const char *name);
+MODULE_SCOPE const char *Ttk_ElementClassName(Ttk_ElementClass *);
+
+MODULE_SCOPE void Ttk_ElementSize(
+ Ttk_ElementClass *, Ttk_Style, char *recordPtr, Tk_OptionTable,
+ Tk_Window tkwin, Ttk_State state,
+ int *widthPtr, int *heightPtr, Ttk_Padding*);
+MODULE_SCOPE void Ttk_DrawElement(
+ Ttk_ElementClass *, Ttk_Style, char *recordPtr, Tk_OptionTable,
+ Tk_Window tkwin, Drawable d, Ttk_Box b, Ttk_State state);
+
+MODULE_SCOPE Tcl_Obj *Ttk_QueryStyle(
+ Ttk_Style, void *, Tk_OptionTable, const char *, Ttk_State state);
+
+MODULE_SCOPE Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(
+ Tcl_Interp *, Tcl_Obj *);
+MODULE_SCOPE Tcl_Obj *Ttk_UnparseLayoutTemplate(Ttk_LayoutTemplate);
+MODULE_SCOPE Ttk_LayoutTemplate Ttk_BuildLayoutTemplate(Ttk_LayoutSpec);
+MODULE_SCOPE void Ttk_FreeLayoutTemplate(Ttk_LayoutTemplate);
+MODULE_SCOPE void Ttk_RegisterLayoutTemplate(
+ Ttk_Theme theme, const char *layoutName, Ttk_LayoutTemplate);
+
+MODULE_SCOPE Ttk_Style Ttk_GetStyle(Ttk_Theme themePtr, const char *styleName);
+MODULE_SCOPE Ttk_LayoutTemplate Ttk_FindLayoutTemplate(
+ Ttk_Theme themePtr, const char *layoutName);
+
+MODULE_SCOPE const char *Ttk_StyleName(Ttk_Style);
+
+#endif /* _TTKTHEMEINT */
diff --git a/generic/ttk/ttkTrace.c b/generic/ttk/ttkTrace.c
new file mode 100644
index 0000000..8bc8519
--- /dev/null
+++ b/generic/ttk/ttkTrace.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2003, Joe English
+ *
+ * Simplified interface to Tcl_TraceVariable.
+ *
+ * PROBLEM: Can't distinguish "variable does not exist" (which is OK)
+ * from other errors (which are not).
+ */
+
+#include <tk.h>
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+struct TtkTraceHandle_
+{
+ Tcl_Interp *interp; /* Containing interpreter */
+ Tcl_Obj *varnameObj; /* Name of variable being traced */
+ Ttk_TraceProc callback; /* Callback procedure */
+ void *clientData; /* Data to pass to callback */
+};
+
+/*
+ * Tcl_VarTraceProc for trace handles.
+ */
+static char *
+VarTraceProc(
+ ClientData clientData, /* Widget record pointer */
+ Tcl_Interp *interp, /* Interpreter containing variable. */
+ const char *name1, /* (unused) */
+ const char *name2, /* (unused) */
+ int flags) /* Information about what happened. */
+{
+ Ttk_TraceHandle *tracePtr = clientData;
+ const char *name, *value;
+ Tcl_Obj *valuePtr;
+
+ if (flags & TCL_INTERP_DESTROYED) {
+ return NULL;
+ }
+
+ name = Tcl_GetString(tracePtr->varnameObj);
+
+ /*
+ * If the variable is being unset, then re-establish the trace:
+ */
+ if (flags & TCL_TRACE_DESTROYED) {
+ /*
+ * If a prior call to Ttk_UntraceVariable() left behind an
+ * indicator that we wanted this handler to be deleted (see below),
+ * cleanup the ClientData bits and exit.
+ */
+ if (tracePtr->interp == NULL) {
+ Tcl_DecrRefCount(tracePtr->varnameObj);
+ ckfree((ClientData)tracePtr);
+ return NULL;
+ }
+ Tcl_TraceVar(interp, name,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ VarTraceProc, clientData);
+ tracePtr->callback(tracePtr->clientData, NULL);
+ return NULL;
+ }
+
+ /*
+ * Call the callback:
+ */
+ valuePtr = Tcl_GetVar2Ex(interp, name, NULL, TCL_GLOBAL_ONLY);
+ value = valuePtr ? Tcl_GetString(valuePtr) : NULL;
+ tracePtr->callback(tracePtr->clientData, value);
+
+ return NULL;
+}
+
+/* Ttk_TraceVariable(interp, varNameObj, callback, clientdata) --
+ * Attach a write trace to the specified variable,
+ * which will pass the variable's value to 'callback'
+ * whenever the variable is set.
+ *
+ * When the variable is unset, passes NULL to the callback
+ * and reattaches the trace.
+ */
+Ttk_TraceHandle *Ttk_TraceVariable(
+ Tcl_Interp *interp,
+ Tcl_Obj *varnameObj,
+ Ttk_TraceProc callback,
+ void *clientData)
+{
+ Ttk_TraceHandle *h = (Ttk_TraceHandle*)ckalloc(sizeof(*h));
+ int status;
+
+ h->interp = interp;
+ h->varnameObj = Tcl_DuplicateObj(varnameObj);
+ Tcl_IncrRefCount(h->varnameObj);
+ h->clientData = clientData;
+ h->callback = callback;
+
+ status = Tcl_TraceVar(interp, Tcl_GetString(varnameObj),
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ VarTraceProc, (ClientData)h);
+
+ if (status != TCL_OK) {
+ Tcl_DecrRefCount(h->varnameObj);
+ ckfree((ClientData)h);
+ return NULL;
+ }
+
+ return h;
+}
+
+/*
+ * Ttk_UntraceVariable --
+ * Remove previously-registered trace and free the handle.
+ */
+void Ttk_UntraceVariable(Ttk_TraceHandle *h)
+{
+ if (h) {
+ ClientData cd = NULL;
+
+ /*
+ * Workaround for Tcl Bug 3062331. The trace design problem is
+ * that when variable unset traces fire, Tcl documents that the
+ * traced variable has already been unset. It's already gone.
+ * So from within an unset trace, if you try to call
+ * Tcl_UntraceVar() on that variable, it will do nothing, because
+ * the variable by that name can no longer be found. It's gone.
+ * This means callers of Tcl_UntraceVar() that might be running
+ * in response to an unset trace have to handle the possibility
+ * that their Tcl_UntraceVar() call will do nothing. In this case,
+ * we have to support the possibility that Tcl_UntraceVar() will
+ * leave the trace in place, so we need to leave the ClientData
+ * untouched so when that trace does fire it will not crash.
+ */
+
+ /*
+ * Search the traces on the variable to see if the one we are tasked
+ * with removing is present.
+ */
+ while ((cd = Tcl_VarTraceInfo(h->interp, Tcl_GetString(h->varnameObj),
+ TCL_GLOBAL_ONLY, VarTraceProc, cd)) != NULL) {
+ if (cd == (ClientData) h) {
+ break;
+ }
+ }
+ /*
+ * If the trace we wish to delete is not visible, Tcl_UntraceVar
+ * will do nothing, so don't try to call it. Instead set an
+ * indicator in the Ttk_TraceHandle that we need to cleanup later.
+ */
+ if (cd == NULL) {
+ h->interp = NULL;
+ return;
+ }
+ Tcl_UntraceVar(h->interp, Tcl_GetString(h->varnameObj),
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ VarTraceProc, (ClientData)h);
+ Tcl_DecrRefCount(h->varnameObj);
+ ckfree((ClientData)h);
+ }
+}
+
+/*
+ * Ttk_FireTrace --
+ * Executes a trace handle as if the variable has been written.
+ *
+ * Note: may reenter the interpreter.
+ */
+int Ttk_FireTrace(Ttk_TraceHandle *tracePtr)
+{
+ Tcl_Interp *interp = tracePtr->interp;
+ void *clientData = tracePtr->clientData;
+ const char *name = Tcl_GetString(tracePtr->varnameObj);
+ Ttk_TraceProc callback = tracePtr->callback;
+ Tcl_Obj *valuePtr;
+ const char *value;
+
+ /* Read the variable.
+ * Note that this can reenter the interpreter, and anything can happen --
+ * including the current trace handle being freed!
+ */
+ valuePtr = Tcl_GetVar2Ex(interp, name, NULL, TCL_GLOBAL_ONLY);
+ value = valuePtr ? Tcl_GetString(valuePtr) : NULL;
+
+ /* Call callback.
+ */
+ callback(clientData, value);
+
+ return TCL_OK;
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkTrack.c b/generic/ttk/ttkTrack.c
new file mode 100644
index 0000000..9cf8267
--- /dev/null
+++ b/generic/ttk/ttkTrack.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2004, Joe English
+ *
+ * TtkTrackElementState() -- helper routine for widgets
+ * like scrollbars in which individual elements may
+ * be active or pressed instead of the widget as a whole.
+ *
+ * Usage:
+ * TtkTrackElementState(&recordPtr->core);
+ *
+ * Registers an event handler on the widget that tracks pointer
+ * events and updates the state of the element under the
+ * mouse cursor.
+ *
+ * The "active" element is the one under the mouse cursor,
+ * and is normally set to the ACTIVE state unless another element
+ * is currently being pressed.
+ *
+ * The active element becomes "pressed" on <ButtonPress> events,
+ * and remains "active" and "pressed" until the corresponding
+ * <ButtonRelease> event.
+ *
+ * TODO: Handle "chords" properly (e.g., <B1-ButtonPress-2>)
+ */
+
+#include <tk.h>
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+typedef struct {
+ WidgetCore *corePtr; /* widget to track */
+ Ttk_Layout tracking; /* current layout being tracked */
+ Ttk_Element activeElement; /* element under the mouse cursor */
+ Ttk_Element pressedElement; /* currently pressed element */
+} ElementStateTracker;
+
+/*
+ * ActivateElement(es, node) --
+ * Make 'node' the active element if non-NULL.
+ * Deactivates the currently active element if different.
+ *
+ * The active element has TTK_STATE_ACTIVE set _unless_
+ * another element is 'pressed'
+ */
+static void ActivateElement(ElementStateTracker *es, Ttk_Element element)
+{
+ if (es->activeElement == element) {
+ /* No change */
+ return;
+ }
+
+ if (!es->pressedElement) {
+ if (es->activeElement) {
+ /* Deactivate old element */
+ Ttk_ChangeElementState(es->activeElement, 0,TTK_STATE_ACTIVE);
+ }
+ if (element) {
+ /* Activate new element */
+ Ttk_ChangeElementState(element, TTK_STATE_ACTIVE,0);
+ }
+ TtkRedisplayWidget(es->corePtr);
+ }
+
+ es->activeElement = element;
+}
+
+/* ReleaseElement --
+ * Releases the currently pressed element, if any.
+ */
+static void ReleaseElement(ElementStateTracker *es)
+{
+ if (!es->pressedElement)
+ return;
+
+ Ttk_ChangeElementState(
+ es->pressedElement, 0,TTK_STATE_PRESSED|TTK_STATE_ACTIVE);
+ es->pressedElement = 0;
+
+ /* Reactivate element under the mouse cursor:
+ */
+ if (es->activeElement)
+ Ttk_ChangeElementState(es->activeElement, TTK_STATE_ACTIVE,0);
+
+ TtkRedisplayWidget(es->corePtr);
+}
+
+/* PressElement --
+ * Presses the specified element.
+ */
+static void PressElement(ElementStateTracker *es, Ttk_Element element)
+{
+ if (es->pressedElement) {
+ ReleaseElement(es);
+ }
+
+ if (element) {
+ Ttk_ChangeElementState(
+ element, TTK_STATE_PRESSED|TTK_STATE_ACTIVE, 0);
+ }
+
+ es->pressedElement = element;
+ TtkRedisplayWidget(es->corePtr);
+}
+
+/* ElementStateEventProc --
+ * Event handler for tracking element states.
+ */
+
+static const unsigned ElementStateMask =
+ ButtonPressMask
+ | ButtonReleaseMask
+ | PointerMotionMask
+ | LeaveWindowMask
+ | EnterWindowMask
+ | StructureNotifyMask
+ ;
+
+static void
+ElementStateEventProc(ClientData clientData, XEvent *ev)
+{
+ ElementStateTracker *es = clientData;
+ Ttk_Layout layout = es->corePtr->layout;
+ Ttk_Element element;
+
+ /* Guard against dangling pointers [#2431428]
+ */
+ if (es->tracking != layout) {
+ es->pressedElement = es->activeElement = 0;
+ es->tracking = layout;
+ }
+
+ switch (ev->type)
+ {
+ case MotionNotify :
+ element = Ttk_IdentifyElement(
+ layout, ev->xmotion.x, ev->xmotion.y);
+ ActivateElement(es, element);
+ break;
+ case LeaveNotify:
+ ActivateElement(es, 0);
+ if (ev->xcrossing.mode == NotifyGrab)
+ PressElement(es, 0);
+ break;
+ case EnterNotify:
+ element = Ttk_IdentifyElement(
+ layout, ev->xcrossing.x, ev->xcrossing.y);
+ ActivateElement(es, element);
+ break;
+ case ButtonPress:
+ element = Ttk_IdentifyElement(
+ layout, ev->xbutton.x, ev->xbutton.y);
+ if (element)
+ PressElement(es, element);
+ break;
+ case ButtonRelease:
+ ReleaseElement(es);
+ break;
+ case DestroyNotify:
+ /* Unregister this event handler and free client data.
+ */
+ Tk_DeleteEventHandler(es->corePtr->tkwin,
+ ElementStateMask, ElementStateEventProc, es);
+ ckfree(clientData);
+ break;
+ }
+}
+
+/*
+ * TtkTrackElementState --
+ * Register an event handler to manage the 'pressed'
+ * and 'active' states of individual widget elements.
+ */
+
+void TtkTrackElementState(WidgetCore *corePtr)
+{
+ ElementStateTracker *es = (ElementStateTracker*)ckalloc(sizeof(*es));
+ es->corePtr = corePtr;
+ es->tracking = 0;
+ es->activeElement = es->pressedElement = 0;
+ Tk_CreateEventHandler(corePtr->tkwin,
+ ElementStateMask,ElementStateEventProc,es);
+}
+
diff --git a/generic/ttk/ttkTreeview.c b/generic/ttk/ttkTreeview.c
new file mode 100644
index 0000000..862c7f6
--- /dev/null
+++ b/generic/ttk/ttkTreeview.c
@@ -0,0 +1,3442 @@
+/*
+ * Copyright (c) 2004, Joe English
+ *
+ * ttk::treeview widget implementation.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <tk.h>
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+#define DEF_TREE_ROWS "10"
+#define DEF_COLWIDTH "200"
+#define DEF_MINWIDTH "20"
+
+static const int DEFAULT_ROWHEIGHT = 20;
+static const int DEFAULT_INDENT = 20;
+static const int HALO = 4; /* separator */
+
+#define TTK_STATE_OPEN TTK_STATE_USER1
+#define TTK_STATE_LEAF TTK_STATE_USER2
+
+#define STATE_CHANGED (0x100) /* item state option changed */
+
+/*------------------------------------------------------------------------
+ * +++ Tree items.
+ *
+ * INVARIANTS:
+ * item->children ==> item->children->parent == item
+ * item->next ==> item->next->parent == item->parent
+ * item->next ==> item->next->prev == item
+ * item->prev ==> item->prev->next == item
+ */
+
+typedef struct TreeItemRec TreeItem;
+struct TreeItemRec {
+ Tcl_HashEntry *entryPtr; /* Back-pointer to hash table entry */
+ TreeItem *parent; /* Parent item */
+ TreeItem *children; /* Linked list of child items */
+ TreeItem *next; /* Next sibling */
+ TreeItem *prev; /* Previous sibling */
+
+ /*
+ * Options and instance data:
+ */
+ Ttk_State state;
+ Tcl_Obj *textObj;
+ Tcl_Obj *imageObj;
+ Tcl_Obj *valuesObj;
+ Tcl_Obj *openObj;
+ Tcl_Obj *tagsObj;
+
+ /*
+ * Derived resources:
+ */
+ Ttk_TagSet tagset;
+ Ttk_ImageSpec *imagespec;
+};
+
+#define ITEM_OPTION_TAGS_CHANGED 0x100
+#define ITEM_OPTION_IMAGE_CHANGED 0x200
+
+static Tk_OptionSpec ItemOptionSpecs[] = {
+ {TK_OPTION_STRING, "-text", "text", "Text",
+ "", Tk_Offset(TreeItem,textObj), -1,
+ 0,0,0 },
+ {TK_OPTION_STRING, "-image", "image", "Image",
+ NULL, Tk_Offset(TreeItem,imageObj), -1,
+ TK_OPTION_NULL_OK,0,ITEM_OPTION_IMAGE_CHANGED },
+ {TK_OPTION_STRING, "-values", "values", "Values",
+ NULL, Tk_Offset(TreeItem,valuesObj), -1,
+ TK_OPTION_NULL_OK,0,0 },
+ {TK_OPTION_BOOLEAN, "-open", "open", "Open",
+ "0", Tk_Offset(TreeItem,openObj), -1,
+ 0,0,0 },
+ {TK_OPTION_STRING, "-tags", "tags", "Tags",
+ NULL, Tk_Offset(TreeItem,tagsObj), -1,
+ TK_OPTION_NULL_OK,0,ITEM_OPTION_TAGS_CHANGED },
+
+ {TK_OPTION_END, 0,0,0, NULL, -1,-1, 0,0,0}
+};
+
+/* + NewItem --
+ * Allocate a new, uninitialized, unlinked item
+ */
+static TreeItem *NewItem(void)
+{
+ TreeItem *item = (TreeItem*)ckalloc(sizeof(*item));
+
+ item->entryPtr = 0;
+ item->parent = item->children = item->next = item->prev = NULL;
+
+ item->state = 0ul;
+ item->textObj = NULL;
+ item->imageObj = NULL;
+ item->valuesObj = NULL;
+ item->openObj = NULL;
+ item->tagsObj = NULL;
+
+ item->tagset = NULL;
+ item->imagespec = NULL;
+
+ return item;
+}
+
+/* + FreeItem --
+ * Destroy an item
+ */
+static void FreeItem(TreeItem *item)
+{
+ if (item->textObj) { Tcl_DecrRefCount(item->textObj); }
+ if (item->imageObj) { Tcl_DecrRefCount(item->imageObj); }
+ if (item->valuesObj) { Tcl_DecrRefCount(item->valuesObj); }
+ if (item->openObj) { Tcl_DecrRefCount(item->openObj); }
+ if (item->tagsObj) { Tcl_DecrRefCount(item->tagsObj); }
+
+ if (item->tagset) { Ttk_FreeTagSet(item->tagset); }
+ if (item->imagespec) { TtkFreeImageSpec(item->imagespec); }
+
+ ckfree((ClientData)item);
+}
+
+static void FreeItemCB(void *clientData) { FreeItem(clientData); }
+
+/* + DetachItem --
+ * Unlink an item from the tree.
+ */
+static void DetachItem(TreeItem *item)
+{
+ if (item->parent && item->parent->children == item)
+ item->parent->children = item->next;
+ if (item->prev)
+ item->prev->next = item->next;
+ if (item->next)
+ item->next->prev = item->prev;
+ item->next = item->prev = item->parent = NULL;
+}
+
+/* + InsertItem --
+ * Insert an item into the tree after the specified item.
+ *
+ * Preconditions:
+ * + item is currently detached
+ * + prev != NULL ==> prev->parent == parent.
+ */
+static void InsertItem(TreeItem *parent, TreeItem *prev, TreeItem *item)
+{
+ item->parent = parent;
+ item->prev = prev;
+ if (prev) {
+ item->next = prev->next;
+ prev->next = item;
+ } else {
+ item->next = parent->children;
+ parent->children = item;
+ }
+ if (item->next) {
+ item->next->prev = item;
+ }
+}
+
+/* + NextPreorder --
+ * Return the next item in preorder traversal order.
+ */
+
+static TreeItem *NextPreorder(TreeItem *item)
+{
+ if (item->children)
+ return item->children;
+ while (!item->next) {
+ item = item->parent;
+ if (!item)
+ return 0;
+ }
+ return item->next;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Display items and tag options.
+ */
+
+typedef struct {
+ Tcl_Obj *textObj; /* taken from item / data cell */
+ Tcl_Obj *imageObj; /* taken from item */
+ Tcl_Obj *anchorObj; /* from column <<NOTE-ANCHOR>> */
+ Tcl_Obj *backgroundObj; /* remainder from tag */
+ Tcl_Obj *foregroundObj;
+ Tcl_Obj *fontObj;
+} DisplayItem;
+
+static Tk_OptionSpec TagOptionSpecs[] = {
+ {TK_OPTION_STRING, "-text", "text", "Text",
+ NULL, Tk_Offset(DisplayItem,textObj), -1,
+ TK_OPTION_NULL_OK,0,0 },
+ {TK_OPTION_STRING, "-image", "image", "Image",
+ NULL, Tk_Offset(DisplayItem,imageObj), -1,
+ TK_OPTION_NULL_OK,0,0 },
+ {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
+ NULL, Tk_Offset(DisplayItem,anchorObj), -1,
+ TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED}, /* <<NOTE-ANCHOR>> */
+ {TK_OPTION_COLOR, "-background", "windowColor", "WindowColor",
+ NULL, Tk_Offset(DisplayItem,backgroundObj), -1,
+ TK_OPTION_NULL_OK,0,0 },
+ {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
+ NULL, Tk_Offset(DisplayItem,foregroundObj), -1,
+ TK_OPTION_NULL_OK,0,0 },
+ {TK_OPTION_FONT, "-font", "font", "Font",
+ NULL, Tk_Offset(DisplayItem,fontObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+
+ {TK_OPTION_END, 0,0,0, NULL, -1,-1, 0,0,0}
+};
+
+/*------------------------------------------------------------------------
+ * +++ Columns.
+ *
+ * There are separate option tables associated with the column record:
+ * ColumnOptionSpecs is for configuring the column,
+ * and HeadingOptionSpecs is for drawing headings.
+ */
+typedef struct {
+ int width; /* Column width, in pixels */
+ int minWidth; /* Minimum column width, in pixels */
+ int stretch; /* Should column stretch while resizing? */
+ Tcl_Obj *idObj; /* Column identifier, from -columns option */
+
+ Tcl_Obj *anchorObj; /* -anchor for cell data <<NOTE-ANCHOR>> */
+
+ /* Column heading data:
+ */
+ Tcl_Obj *headingObj; /* Heading label */
+ Tcl_Obj *headingImageObj; /* Heading image */
+ Tcl_Obj *headingAnchorObj; /* -anchor for heading label */
+ Tcl_Obj *headingCommandObj; /* Command to execute */
+ Tcl_Obj *headingStateObj; /* @@@ testing ... */
+ Ttk_State headingState; /* ... */
+
+ /* Temporary storage for cell data
+ */
+ Tcl_Obj *data;
+} TreeColumn;
+
+static void InitColumn(TreeColumn *column)
+{
+ column->width = 200;
+ column->minWidth = 20;
+ column->stretch = 1;
+ column->idObj = 0;
+ column->anchorObj = 0;
+
+ column->headingState = 0;
+ column->headingObj = 0;
+ column->headingImageObj = 0;
+ column->headingAnchorObj = 0;
+ column->headingStateObj = 0;
+ column->headingCommandObj = 0;
+
+ column->data = 0;
+}
+
+static void FreeColumn(TreeColumn *column)
+{
+ if (column->idObj) { Tcl_DecrRefCount(column->idObj); }
+ if (column->anchorObj) { Tcl_DecrRefCount(column->anchorObj); }
+
+ if (column->headingObj) { Tcl_DecrRefCount(column->headingObj); }
+ if (column->headingImageObj) { Tcl_DecrRefCount(column->headingImageObj); }
+ if (column->headingAnchorObj) { Tcl_DecrRefCount(column->headingAnchorObj); }
+ if (column->headingStateObj) { Tcl_DecrRefCount(column->headingStateObj); }
+ if (column->headingCommandObj) { Tcl_DecrRefCount(column->headingCommandObj); }
+
+ /* Don't touch column->data, it's scratch storage */
+}
+
+static Tk_OptionSpec ColumnOptionSpecs[] = {
+ {TK_OPTION_INT, "-width", "width", "Width",
+ DEF_COLWIDTH, -1, Tk_Offset(TreeColumn,width),
+ 0,0,GEOMETRY_CHANGED },
+ {TK_OPTION_INT, "-minwidth", "minWidth", "MinWidth",
+ DEF_MINWIDTH, -1, Tk_Offset(TreeColumn,minWidth),
+ 0,0,0 },
+ {TK_OPTION_BOOLEAN, "-stretch", "stretch", "Stretch",
+ "1", -1, Tk_Offset(TreeColumn,stretch),
+ 0,0,0 },
+ {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
+ "w", Tk_Offset(TreeColumn,anchorObj), -1, /* <<NOTE-ANCHOR>> */
+ 0,0,0 },
+ {TK_OPTION_STRING, "-id", "id", "ID",
+ NULL, Tk_Offset(TreeColumn,idObj), -1,
+ TK_OPTION_NULL_OK,0,READONLY_OPTION },
+ {TK_OPTION_END, 0,0,0, NULL, -1,-1, 0,0,0}
+};
+
+static Tk_OptionSpec HeadingOptionSpecs[] = {
+ {TK_OPTION_STRING, "-text", "text", "Text",
+ "", Tk_Offset(TreeColumn,headingObj), -1,
+ 0,0,0 },
+ {TK_OPTION_STRING, "-image", "image", "Image",
+ "", Tk_Offset(TreeColumn,headingImageObj), -1,
+ 0,0,0 },
+ {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
+ "center", Tk_Offset(TreeColumn,headingAnchorObj), -1,
+ 0,0,0 },
+ {TK_OPTION_STRING, "-command", "", "",
+ "", Tk_Offset(TreeColumn,headingCommandObj), -1,
+ TK_OPTION_NULL_OK,0,0 },
+ {TK_OPTION_STRING, "state", "", "",
+ "", Tk_Offset(TreeColumn,headingStateObj), -1,
+ 0,0,STATE_CHANGED },
+ {TK_OPTION_END, 0,0,0, NULL, -1,-1, 0,0,0}
+};
+
+/*------------------------------------------------------------------------
+ * +++ -show option:
+ * TODO: Implement SHOW_BRANCHES.
+ */
+
+#define SHOW_TREE (0x1) /* Show tree column? */
+#define SHOW_HEADINGS (0x2) /* Show heading row? */
+
+#define DEFAULT_SHOW "tree headings"
+
+static const char *showStrings[] = {
+ "tree", "headings", NULL
+};
+
+static int GetEnumSetFromObj(
+ Tcl_Interp *interp,
+ Tcl_Obj *objPtr,
+ const char *table[],
+ unsigned *resultPtr)
+{
+ unsigned result = 0;
+ int i, objc;
+ Tcl_Obj **objv;
+
+ if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK)
+ return TCL_ERROR;
+
+ for (i = 0; i < objc; ++i) {
+ int index;
+ if (TCL_OK != Tcl_GetIndexFromObj(
+ interp, objv[i], table, "value", TCL_EXACT, &index))
+ {
+ return TCL_ERROR;
+ }
+ result |= (1 << index);
+ }
+
+ *resultPtr = result;
+ return TCL_OK;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Treeview widget record.
+ *
+ * Dependencies:
+ * columns, columnNames: -columns
+ * displayColumns: -columns, -displaycolumns
+ * headingHeight: [layout]
+ * rowHeight, indent: style
+ */
+typedef struct {
+ /* Resources acquired at initialization-time:
+ */
+ Tk_OptionTable itemOptionTable;
+ Tk_OptionTable columnOptionTable;
+ Tk_OptionTable headingOptionTable;
+ Tk_OptionTable tagOptionTable;
+ Tk_BindingTable bindingTable;
+ Ttk_TagTable tagTable;
+
+ /* Acquired in GetLayout hook:
+ */
+ Ttk_Layout itemLayout;
+ Ttk_Layout cellLayout;
+ Ttk_Layout headingLayout;
+ Ttk_Layout rowLayout;
+
+ int headingHeight; /* Space for headings */
+ int rowHeight; /* Height of each item */
+ int indent; /* #pixels horizontal offset for child items */
+
+ /* Tree data:
+ */
+ Tcl_HashTable items; /* Map: item name -> item */
+ int serial; /* Next item # for autogenerated names */
+ TreeItem *root; /* Root item */
+
+ TreeColumn column0; /* Column options for display column #0 */
+ TreeColumn *columns; /* Array of column options for data columns */
+
+ TreeItem *focus; /* Current focus item */
+ TreeItem *endPtr; /* See EndPosition() */
+
+ /* Widget options:
+ */
+ Tcl_Obj *columnsObj; /* List of symbolic column names */
+ Tcl_Obj *displayColumnsObj; /* List of columns to display */
+
+ Tcl_Obj *heightObj; /* height (rows) */
+ Tcl_Obj *paddingObj; /* internal padding */
+
+ Tcl_Obj *showObj; /* -show list */
+ Tcl_Obj *selectModeObj; /* -selectmode option */
+
+ Scrollable xscroll;
+ ScrollHandle xscrollHandle;
+ Scrollable yscroll;
+ ScrollHandle yscrollHandle;
+
+ /* Derived resources:
+ */
+ Tcl_HashTable columnNames; /* Map: column name -> column table entry */
+ int nColumns; /* #columns */
+ unsigned showFlags; /* bitmask of subparts to display */
+
+ TreeColumn **displayColumns; /* List of columns for display (incl tree) */
+ int nDisplayColumns; /* #display columns */
+ Ttk_Box headingArea; /* Display area for column headings */
+ Ttk_Box treeArea; /* Display area for tree */
+ int slack; /* Slack space (see Resizing section) */
+
+} TreePart;
+
+typedef struct {
+ WidgetCore core;
+ TreePart tree;
+} Treeview;
+
+#define USER_MASK 0x0100
+#define COLUMNS_CHANGED (USER_MASK)
+#define DCOLUMNS_CHANGED (USER_MASK<<1)
+#define SCROLLCMD_CHANGED (USER_MASK<<2)
+#define SHOW_CHANGED (USER_MASK<<3)
+
+static const char *SelectModeStrings[] = { "none", "browse", "extended", NULL };
+
+static Tk_OptionSpec TreeviewOptionSpecs[] = {
+ {TK_OPTION_STRING, "-columns", "columns", "Columns",
+ "", Tk_Offset(Treeview,tree.columnsObj), -1,
+ 0,0,COLUMNS_CHANGED | GEOMETRY_CHANGED /*| READONLY_OPTION*/ },
+ {TK_OPTION_STRING, "-displaycolumns","displayColumns","DisplayColumns",
+ "#all", Tk_Offset(Treeview,tree.displayColumnsObj), -1,
+ 0,0,DCOLUMNS_CHANGED | GEOMETRY_CHANGED },
+ {TK_OPTION_STRING, "-show", "show", "Show",
+ DEFAULT_SHOW, Tk_Offset(Treeview,tree.showObj), -1,
+ 0,0,SHOW_CHANGED | GEOMETRY_CHANGED },
+
+ {TK_OPTION_STRING_TABLE, "-selectmode", "selectMode", "SelectMode",
+ "extended", Tk_Offset(Treeview,tree.selectModeObj), -1,
+ 0,(ClientData)SelectModeStrings,0 },
+
+ {TK_OPTION_PIXELS, "-height", "height", "Height",
+ DEF_TREE_ROWS, Tk_Offset(Treeview,tree.heightObj), -1,
+ 0,0,GEOMETRY_CHANGED},
+ {TK_OPTION_STRING, "-padding", "padding", "Pad",
+ NULL, Tk_Offset(Treeview,tree.paddingObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+
+ {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
+ NULL, -1, Tk_Offset(Treeview, tree.xscroll.scrollCmd),
+ TK_OPTION_NULL_OK, 0, SCROLLCMD_CHANGED},
+ {TK_OPTION_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
+ NULL, -1, Tk_Offset(Treeview, tree.yscroll.scrollCmd),
+ TK_OPTION_NULL_OK, 0, SCROLLCMD_CHANGED},
+
+ WIDGET_TAKEFOCUS_TRUE,
+ WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
+};
+
+/*------------------------------------------------------------------------
+ * +++ Utilities.
+ */
+typedef void (*HashEntryIterator)(void *hashValue);
+
+static void foreachHashEntry(Tcl_HashTable *ht, HashEntryIterator func)
+{
+ Tcl_HashSearch search;
+ Tcl_HashEntry *entryPtr = Tcl_FirstHashEntry(ht, &search);
+ while (entryPtr != NULL) {
+ func(Tcl_GetHashValue(entryPtr));
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+}
+
+/* + unshareObj(objPtr) --
+ * Ensure that a Tcl_Obj * has refcount 1 -- either return objPtr
+ * itself, or a duplicated copy.
+ */
+static Tcl_Obj *unshareObj(Tcl_Obj *objPtr)
+{
+ if (Tcl_IsShared(objPtr)) {
+ Tcl_Obj *newObj = Tcl_DuplicateObj(objPtr);
+ Tcl_DecrRefCount(objPtr);
+ Tcl_IncrRefCount(newObj);
+ return newObj;
+ }
+ return objPtr;
+}
+
+/* DisplayLayout --
+ * Rebind, place, and draw a layout + object combination.
+ */
+static void DisplayLayout(
+ Ttk_Layout layout, void *recordPtr, Ttk_State state, Ttk_Box b, Drawable d)
+{
+ Ttk_RebindSublayout(layout, recordPtr);
+ Ttk_PlaceLayout(layout, state, b);
+ Ttk_DrawLayout(layout, state, d);
+}
+
+/* + GetColumn --
+ * Look up column by name or number.
+ * Returns: pointer to column table entry, NULL if not found.
+ * Leaves an error message in interp->result on error.
+ */
+static TreeColumn *GetColumn(
+ Tcl_Interp *interp, Treeview *tv, Tcl_Obj *columnIDObj)
+{
+ Tcl_HashEntry *entryPtr;
+ int columnIndex;
+
+ /* Check for named column:
+ */
+ entryPtr = Tcl_FindHashEntry(
+ &tv->tree.columnNames, Tcl_GetString(columnIDObj));
+ if (entryPtr) {
+ return Tcl_GetHashValue(entryPtr);
+ }
+
+ /* Check for number:
+ */
+ if (Tcl_GetIntFromObj(NULL, columnIDObj, &columnIndex) == TCL_OK) {
+ if (columnIndex < 0 || columnIndex >= tv->tree.nColumns) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ "Column index ",
+ Tcl_GetString(columnIDObj),
+ " out of bounds",
+ NULL);
+ return NULL;
+ }
+
+ return tv->tree.columns + columnIndex;
+ }
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ "Invalid column index ", Tcl_GetString(columnIDObj),
+ NULL);
+ return NULL;
+}
+
+/* + FindColumn --
+ * Look up column by name, number, or display index.
+ */
+static TreeColumn *FindColumn(
+ Tcl_Interp *interp, Treeview *tv, Tcl_Obj *columnIDObj)
+{
+ int colno;
+
+ if (sscanf(Tcl_GetString(columnIDObj), "#%d", &colno) == 1)
+ { /* Display column specification, #n */
+ if (colno >= 0 && colno < tv->tree.nDisplayColumns) {
+ return tv->tree.displayColumns[colno];
+ }
+ /* else */
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ "Column ", Tcl_GetString(columnIDObj), " out of range",
+ NULL);
+ return NULL;
+ }
+
+ return GetColumn(interp, tv, columnIDObj);
+}
+
+/* + FindItem --
+ * Locates the item with the specified identifier in the tree.
+ * If there is no such item, leaves an error message in interp.
+ */
+static TreeItem *FindItem(
+ Tcl_Interp *interp, Treeview *tv, Tcl_Obj *itemNameObj)
+{
+ const char *itemName = Tcl_GetString(itemNameObj);
+ Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&tv->tree.items, itemName);
+
+ if (!entryPtr) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "Item ", itemName, " not found", NULL);
+ return 0;
+ }
+ return Tcl_GetHashValue(entryPtr);
+}
+
+/* + GetItemListFromObj --
+ * Parse a Tcl_Obj * as a list of items.
+ * Returns a NULL-terminated array of items; result must
+ * be ckfree()d. On error, returns NULL and leaves an error
+ * message in interp.
+ */
+
+static TreeItem **GetItemListFromObj(
+ Tcl_Interp *interp, Treeview *tv, Tcl_Obj *objPtr)
+{
+ TreeItem **items;
+ Tcl_Obj **elements;
+ int i, nElements;
+
+ if (Tcl_ListObjGetElements(interp,objPtr,&nElements,&elements) != TCL_OK) {
+ return NULL;
+ }
+
+ items = (TreeItem**)ckalloc((nElements + 1)*sizeof(TreeItem*));
+ for (i = 0; i < nElements; ++i) {
+ items[i] = FindItem(interp, tv, elements[i]);
+ if (!items[i]) {
+ ckfree((ClientData)items);
+ return NULL;
+ }
+ }
+ items[i] = NULL;
+ return items;
+}
+
+/* + ItemName --
+ * Returns the item's ID.
+ */
+static const char *ItemName(Treeview *tv, TreeItem *item)
+{
+ return Tcl_GetHashKey(&tv->tree.items, item->entryPtr);
+}
+
+/* + ItemID --
+ * Returns a fresh Tcl_Obj * (refcount 0) holding the
+ * item identifier of the specified item.
+ */
+static Tcl_Obj *ItemID(Treeview *tv, TreeItem *item)
+{
+ return Tcl_NewStringObj(ItemName(tv, item), -1);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Column configuration.
+ */
+
+/* + TreeviewFreeColumns --
+ * Free column data.
+ */
+static void TreeviewFreeColumns(Treeview *tv)
+{
+ int i;
+
+ Tcl_DeleteHashTable(&tv->tree.columnNames);
+ Tcl_InitHashTable(&tv->tree.columnNames, TCL_STRING_KEYS);
+
+ if (tv->tree.columns) {
+ for (i = 0; i < tv->tree.nColumns; ++i)
+ FreeColumn(tv->tree.columns + i);
+ ckfree((ClientData)tv->tree.columns);
+ tv->tree.columns = 0;
+ }
+}
+
+/* + TreeviewInitColumns --
+ * Initialize column data when -columns changes.
+ * Returns: TCL_OK or TCL_ERROR;
+ */
+static int TreeviewInitColumns(Tcl_Interp *interp, Treeview *tv)
+{
+ Tcl_Obj **columns;
+ int i, ncols;
+
+ if (Tcl_ListObjGetElements(
+ interp, tv->tree.columnsObj, &ncols, &columns) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Free old values:
+ */
+ TreeviewFreeColumns(tv);
+
+ /*
+ * Initialize columns array and columnNames hash table:
+ */
+ tv->tree.nColumns = ncols;
+ tv->tree.columns =
+ (TreeColumn*)ckalloc(tv->tree.nColumns * sizeof(TreeColumn));
+
+ for (i = 0; i < ncols; ++i) {
+ int isNew;
+ Tcl_Obj *columnName = Tcl_DuplicateObj(columns[i]);
+
+ Tcl_HashEntry *entryPtr = Tcl_CreateHashEntry(
+ &tv->tree.columnNames, Tcl_GetString(columnName), &isNew);
+ Tcl_SetHashValue(entryPtr, tv->tree.columns + i);
+
+ InitColumn(tv->tree.columns + i);
+ Tk_InitOptions(
+ interp, (ClientData)(tv->tree.columns + i),
+ tv->tree.columnOptionTable, tv->core.tkwin);
+ Tk_InitOptions(
+ interp, (ClientData)(tv->tree.columns + i),
+ tv->tree.headingOptionTable, tv->core.tkwin);
+ Tcl_IncrRefCount(columnName);
+ tv->tree.columns[i].idObj = columnName;
+ }
+
+ return TCL_OK;
+}
+
+/* + TreeviewInitDisplayColumns --
+ * Initializes the 'displayColumns' array.
+ *
+ * Note that displayColumns[0] is always the tree column,
+ * even when SHOW_TREE is not set.
+ *
+ * @@@ TODO: disallow duplicated columns
+ */
+static int TreeviewInitDisplayColumns(Tcl_Interp *interp, Treeview *tv)
+{
+ Tcl_Obj **dcolumns;
+ int index, ndcols;
+ TreeColumn **displayColumns = 0;
+
+ if (Tcl_ListObjGetElements(interp,
+ tv->tree.displayColumnsObj, &ndcols, &dcolumns) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (!strcmp(Tcl_GetString(tv->tree.displayColumnsObj), "#all")) {
+ ndcols = tv->tree.nColumns;
+ displayColumns = (TreeColumn**)ckalloc((ndcols+1)*sizeof(TreeColumn*));
+ for (index = 0; index < ndcols; ++index) {
+ displayColumns[index+1] = tv->tree.columns + index;
+ }
+ } else {
+ displayColumns = (TreeColumn**)ckalloc((ndcols+1)*sizeof(TreeColumn*));
+ for (index = 0; index < ndcols; ++index) {
+ displayColumns[index+1] = GetColumn(interp, tv, dcolumns[index]);
+ if (!displayColumns[index+1]) {
+ ckfree((ClientData)displayColumns);
+ return TCL_ERROR;
+ }
+ }
+ }
+ displayColumns[0] = &tv->tree.column0;
+
+ if (tv->tree.displayColumns)
+ ckfree((ClientData)tv->tree.displayColumns);
+ tv->tree.displayColumns = displayColumns;
+ tv->tree.nDisplayColumns = ndcols + 1;
+
+ return TCL_OK;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Resizing.
+ * slack invariant: TreeWidth(tree) + slack = treeArea.width
+ */
+
+#define FirstColumn(tv) ((tv->tree.showFlags&SHOW_TREE) ? 0 : 1)
+
+/* + TreeWidth --
+ * Compute the requested tree width from the sum of visible column widths.
+ */
+static int TreeWidth(Treeview *tv)
+{
+ int i = FirstColumn(tv);
+ int width = 0;
+
+ while (i < tv->tree.nDisplayColumns) {
+ width += tv->tree.displayColumns[i++]->width;
+ }
+ return width;
+}
+
+/* + RecomputeSlack --
+ */
+static void RecomputeSlack(Treeview *tv)
+{
+ tv->tree.slack = tv->tree.treeArea.width - TreeWidth(tv);
+}
+
+/* + PickupSlack/DepositSlack --
+ * When resizing columns, distribute extra space to 'slack' first,
+ * and only adjust column widths if 'slack' goes to zero.
+ * That is, don't bother changing column widths if the tree
+ * is already scrolled or short.
+ */
+static int PickupSlack(Treeview *tv, int extra)
+{
+ int newSlack = tv->tree.slack + extra;
+
+ if ( (newSlack < 0 && 0 <= tv->tree.slack)
+ || (newSlack > 0 && 0 >= tv->tree.slack))
+ {
+ tv->tree.slack = 0;
+ return newSlack;
+ } else {
+ tv->tree.slack = newSlack;
+ return 0;
+ }
+}
+
+static void DepositSlack(Treeview *tv, int extra)
+{
+ tv->tree.slack += extra;
+}
+
+/* + Stretch --
+ * Adjust width of column by N pixels, down to minimum width.
+ * Returns: #pixels actually moved.
+ */
+static int Stretch(TreeColumn *c, int n)
+{
+ int newWidth = n + c->width;
+ if (newWidth < c->minWidth) {
+ n = c->minWidth - c->width;
+ c->width = c->minWidth;
+ } else {
+ c->width = newWidth;
+ }
+ return n;
+}
+
+/* + ShoveLeft --
+ * Adjust width of (stretchable) columns to the left by N pixels.
+ * Returns: leftover slack.
+ */
+static int ShoveLeft(Treeview *tv, int i, int n)
+{
+ int first = FirstColumn(tv);
+ while (n != 0 && i >= first) {
+ TreeColumn *c = tv->tree.displayColumns[i];
+ if (c->stretch) {
+ n -= Stretch(c, n);
+ }
+ --i;
+ }
+ return n;
+}
+
+/* + ShoveRight --
+ * Adjust width of (stretchable) columns to the right by N pixels.
+ * Returns: leftover slack.
+ */
+static int ShoveRight(Treeview *tv, int i, int n)
+{
+ while (n != 0 && i < tv->tree.nDisplayColumns) {
+ TreeColumn *c = tv->tree.displayColumns[i];
+ if (c->stretch) {
+ n -= Stretch(c, n);
+ }
+ ++i;
+ }
+ return n;
+}
+
+/* + DistributeWidth --
+ * Distribute n pixels evenly across all stretchable display columns.
+ * Returns: leftover slack.
+ * Notes:
+ * The "((++w % m) < r)" term is there so that the remainder r = n % m
+ * is distributed round-robin.
+ */
+static int DistributeWidth(Treeview *tv, int n)
+{
+ int w = TreeWidth(tv);
+ int m = 0;
+ int i, d, r;
+
+ for (i = FirstColumn(tv); i < tv->tree.nDisplayColumns; ++i) {
+ if (tv->tree.displayColumns[i]->stretch) {
+ ++m;
+ }
+ }
+ if (m == 0) {
+ return n;
+ }
+
+ d = n / m;
+ r = n % m;
+ if (r < 0) { r += m; --d; }
+
+ for (i = FirstColumn(tv); i < tv->tree.nDisplayColumns; ++i) {
+ TreeColumn *c = tv->tree.displayColumns[i];
+ if (c->stretch) {
+ n -= Stretch(c, d + ((++w % m) < r));
+ }
+ }
+ return n;
+}
+
+/* + ResizeColumns --
+ * Recompute column widths based on available width.
+ * Pick up slack first;
+ * Distribute the remainder evenly across stretchable columns;
+ * If any is still left over due to minwidth constraints, shove left.
+ */
+static void ResizeColumns(Treeview *tv, int newWidth)
+{
+ int delta = newWidth - (TreeWidth(tv) + tv->tree.slack);
+ DepositSlack(tv,
+ ShoveLeft(tv, tv->tree.nDisplayColumns - 1,
+ DistributeWidth(tv, PickupSlack(tv, delta))));
+}
+
+/* + DragColumn --
+ * Move the separator to the right of specified column,
+ * adjusting other column widths as necessary.
+ */
+static void DragColumn(Treeview *tv, int i, int delta)
+{
+ TreeColumn *c = tv->tree.displayColumns[i];
+ int dl = delta - ShoveLeft(tv, i-1, delta - Stretch(c, delta));
+ int dr = ShoveRight(tv, i+1, PickupSlack(tv, -dl));
+ DepositSlack(tv, dr);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Event handlers.
+ */
+
+static TreeItem *IdentifyItem(Treeview *tv, int y); /*forward*/
+
+static const unsigned int TreeviewBindEventMask =
+ KeyPressMask|KeyReleaseMask
+ | ButtonPressMask|ButtonReleaseMask
+ | PointerMotionMask|ButtonMotionMask
+ | VirtualEventMask
+ ;
+
+static void TreeviewBindEventProc(void *clientData, XEvent *event)
+{
+ Treeview *tv = clientData;
+ TreeItem *item = NULL;
+ Ttk_TagSet tagset;
+
+ /*
+ * Figure out where to deliver the event.
+ */
+ switch (event->type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ case VirtualEvent:
+ item = tv->tree.focus;
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ item = IdentifyItem(tv, event->xbutton.y);
+ break;
+ case MotionNotify:
+ item = IdentifyItem(tv, event->xmotion.y);
+ break;
+ default:
+ break;
+ }
+
+ if (!item) {
+ return;
+ }
+
+ /* ASSERT: Ttk_GetTagSetFromObj succeeds.
+ * NB: must use a local copy of the tagset,
+ * in case a binding script stomps on -tags.
+ */
+ tagset = Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, item->tagsObj);
+
+ /*
+ * Fire binding:
+ */
+ Tcl_Preserve(clientData);
+ Tk_BindEvent(tv->tree.bindingTable, event, tv->core.tkwin,
+ tagset->nTags, (void **)tagset->tags);
+ Tcl_Release(clientData);
+
+ Ttk_FreeTagSet(tagset);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Initialization and cleanup.
+ */
+
+static void TreeviewInitialize(Tcl_Interp *interp, void *recordPtr)
+{
+ Treeview *tv = recordPtr;
+ int unused;
+
+ tv->tree.itemOptionTable =
+ Tk_CreateOptionTable(interp, ItemOptionSpecs);
+ tv->tree.columnOptionTable =
+ Tk_CreateOptionTable(interp, ColumnOptionSpecs);
+ tv->tree.headingOptionTable =
+ Tk_CreateOptionTable(interp, HeadingOptionSpecs);
+ tv->tree.tagOptionTable =
+ Tk_CreateOptionTable(interp, TagOptionSpecs);
+
+ tv->tree.tagTable = Ttk_CreateTagTable(
+ interp, tv->core.tkwin, TagOptionSpecs, sizeof(DisplayItem));
+ tv->tree.bindingTable = Tk_CreateBindingTable(interp);
+ Tk_CreateEventHandler(tv->core.tkwin,
+ TreeviewBindEventMask, TreeviewBindEventProc, tv);
+
+ tv->tree.itemLayout
+ = tv->tree.cellLayout
+ = tv->tree.headingLayout
+ = tv->tree.rowLayout
+ = 0;
+ tv->tree.headingHeight = tv->tree.rowHeight = DEFAULT_ROWHEIGHT;
+ tv->tree.indent = DEFAULT_INDENT;
+
+ Tcl_InitHashTable(&tv->tree.columnNames, TCL_STRING_KEYS);
+ tv->tree.nColumns = tv->tree.nDisplayColumns = 0;
+ tv->tree.columns = NULL;
+ tv->tree.displayColumns = NULL;
+ tv->tree.showFlags = ~0;
+
+ InitColumn(&tv->tree.column0);
+ Tk_InitOptions(
+ interp, (ClientData)(&tv->tree.column0),
+ tv->tree.columnOptionTable, tv->core.tkwin);
+ Tk_InitOptions(
+ interp, (ClientData)(&tv->tree.column0),
+ tv->tree.headingOptionTable, tv->core.tkwin);
+
+ Tcl_InitHashTable(&tv->tree.items, TCL_STRING_KEYS);
+ tv->tree.serial = 0;
+
+ tv->tree.focus = tv->tree.endPtr = 0;
+
+ /* Create root item "":
+ */
+ tv->tree.root = NewItem();
+ Tk_InitOptions(interp, (ClientData)tv->tree.root,
+ tv->tree.itemOptionTable, tv->core.tkwin);
+ tv->tree.root->tagset = Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, NULL);
+ tv->tree.root->entryPtr = Tcl_CreateHashEntry(&tv->tree.items, "", &unused);
+ Tcl_SetHashValue(tv->tree.root->entryPtr, tv->tree.root);
+
+ /* Scroll handles:
+ */
+ tv->tree.xscrollHandle = TtkCreateScrollHandle(&tv->core,&tv->tree.xscroll);
+ tv->tree.yscrollHandle = TtkCreateScrollHandle(&tv->core,&tv->tree.yscroll);
+
+ /* Size parameters:
+ */
+ tv->tree.treeArea = tv->tree.headingArea = Ttk_MakeBox(0,0,0,0);
+ tv->tree.slack = 0;
+}
+
+static void TreeviewCleanup(void *recordPtr)
+{
+ Treeview *tv = recordPtr;
+
+ Tk_DeleteEventHandler(tv->core.tkwin,
+ TreeviewBindEventMask, TreeviewBindEventProc, tv);
+ Tk_DeleteBindingTable(tv->tree.bindingTable);
+ Ttk_DeleteTagTable(tv->tree.tagTable);
+
+ if (tv->tree.itemLayout) Ttk_FreeLayout(tv->tree.itemLayout);
+ if (tv->tree.cellLayout) Ttk_FreeLayout(tv->tree.cellLayout);
+ if (tv->tree.headingLayout) Ttk_FreeLayout(tv->tree.headingLayout);
+ if (tv->tree.rowLayout) Ttk_FreeLayout(tv->tree.rowLayout);
+
+ TreeviewFreeColumns(tv);
+
+ if (tv->tree.displayColumns)
+ Tcl_Free((ClientData)tv->tree.displayColumns);
+
+ foreachHashEntry(&tv->tree.items, FreeItemCB);
+ Tcl_DeleteHashTable(&tv->tree.items);
+
+ TtkFreeScrollHandle(tv->tree.xscrollHandle);
+ TtkFreeScrollHandle(tv->tree.yscrollHandle);
+}
+
+/* + TreeviewConfigure --
+ * Configuration widget hook.
+ *
+ * BUG: If user sets -columns and -displaycolumns, but -displaycolumns
+ * has an error, the widget is left in an inconsistent state.
+ */
+static int
+TreeviewConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
+{
+ Treeview *tv = recordPtr;
+ unsigned showFlags = tv->tree.showFlags;
+
+ if (mask & COLUMNS_CHANGED) {
+ if (TreeviewInitColumns(interp, tv) != TCL_OK)
+ return TCL_ERROR;
+ mask |= DCOLUMNS_CHANGED;
+ }
+ if (mask & DCOLUMNS_CHANGED) {
+ if (TreeviewInitDisplayColumns(interp, tv) != TCL_OK)
+ return TCL_ERROR;
+ }
+ if (mask & SCROLLCMD_CHANGED) {
+ TtkScrollbarUpdateRequired(tv->tree.xscrollHandle);
+ TtkScrollbarUpdateRequired(tv->tree.yscrollHandle);
+ }
+ if ( (mask & SHOW_CHANGED)
+ && GetEnumSetFromObj(
+ interp,tv->tree.showObj,showStrings,&showFlags) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ if (TtkCoreConfigure(interp, recordPtr, mask) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ tv->tree.showFlags = showFlags;
+
+ if (mask & (SHOW_CHANGED | DCOLUMNS_CHANGED)) {
+ RecomputeSlack(tv);
+ }
+ return TCL_OK;
+}
+
+/* + ConfigureItem --
+ * Set item options.
+ */
+static int ConfigureItem(
+ Tcl_Interp *interp, Treeview *tv, TreeItem *item,
+ int objc, Tcl_Obj *const objv[])
+{
+ Tk_SavedOptions savedOptions;
+ int mask;
+ Ttk_ImageSpec *newImageSpec = NULL;
+ Ttk_TagSet newTagSet = NULL;
+
+ if (Tk_SetOptions(interp, (ClientData)item, tv->tree.itemOptionTable,
+ objc, objv, tv->core.tkwin, &savedOptions, &mask)
+ != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ /* Make sure that -values is a valid list:
+ */
+ if (item->valuesObj) {
+ int unused;
+ if (Tcl_ListObjLength(interp, item->valuesObj, &unused) != TCL_OK)
+ goto error;
+ }
+
+ /* Check -image.
+ */
+ if ((mask & ITEM_OPTION_IMAGE_CHANGED) && item->imageObj) {
+ newImageSpec = TtkGetImageSpec(interp, tv->core.tkwin, item->imageObj);
+ if (!newImageSpec) {
+ goto error;
+ }
+ }
+
+ /* Check -tags.
+ * Side effect: may create new tags.
+ */
+ if (mask & ITEM_OPTION_TAGS_CHANGED) {
+ newTagSet = Ttk_GetTagSetFromObj(
+ interp, tv->tree.tagTable, item->tagsObj);
+ if (!newTagSet) {
+ goto error;
+ }
+ }
+
+ /* Keep TTK_STATE_OPEN flag in sync with item->openObj.
+ * We use both a state flag and a Tcl_Obj* resource so elements
+ * can access the value in either way.
+ */
+ if (item->openObj) {
+ int isOpen;
+ if (Tcl_GetBooleanFromObj(interp, item->openObj, &isOpen) != TCL_OK)
+ goto error;
+ if (isOpen)
+ item->state |= TTK_STATE_OPEN;
+ else
+ item->state &= ~TTK_STATE_OPEN;
+ }
+
+ /* All OK.
+ */
+ Tk_FreeSavedOptions(&savedOptions);
+ if (mask & ITEM_OPTION_TAGS_CHANGED) {
+ if (item->tagset) { Ttk_FreeTagSet(item->tagset); }
+ item->tagset = newTagSet;
+ }
+ if (mask & ITEM_OPTION_IMAGE_CHANGED) {
+ if (item->imagespec) { TtkFreeImageSpec(item->imagespec); }
+ item->imagespec = newImageSpec;
+ }
+ TtkRedisplayWidget(&tv->core);
+ return TCL_OK;
+
+error:
+ Tk_RestoreSavedOptions(&savedOptions);
+ if (newTagSet) { Ttk_FreeTagSet(newTagSet); }
+ if (newImageSpec) { TtkFreeImageSpec(newImageSpec); }
+ return TCL_ERROR;
+}
+
+/* + ConfigureColumn --
+ * Set column options.
+ */
+static int ConfigureColumn(
+ Tcl_Interp *interp, Treeview *tv, TreeColumn *column,
+ int objc, Tcl_Obj *const objv[])
+{
+ Tk_SavedOptions savedOptions;
+ int mask;
+
+ if (Tk_SetOptions(interp, (ClientData)column,
+ tv->tree.columnOptionTable, objc, objv, tv->core.tkwin,
+ &savedOptions,&mask) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ if (mask & READONLY_OPTION) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "Attempt to change read-only option", NULL);
+ goto error;
+ }
+
+ /* Propagate column width changes to overall widget request width,
+ * but only if the widget is currently unmapped, in order to prevent
+ * geometry jumping during interactive column resize.
+ */
+ if (mask & GEOMETRY_CHANGED) {
+ if (!Tk_IsMapped(tv->core.tkwin)) {
+ TtkResizeWidget(&tv->core);
+ }
+ RecomputeSlack(tv);
+ }
+ TtkRedisplayWidget(&tv->core);
+
+ /* ASSERT: SLACKINVARIANT */
+
+ Tk_FreeSavedOptions(&savedOptions);
+ return TCL_OK;
+
+error:
+ Tk_RestoreSavedOptions(&savedOptions);
+ return TCL_ERROR;
+}
+
+/* + ConfigureHeading --
+ * Set heading options.
+ */
+static int ConfigureHeading(
+ Tcl_Interp *interp, Treeview *tv, TreeColumn *column,
+ int objc, Tcl_Obj *const objv[])
+{
+ Tk_SavedOptions savedOptions;
+ int mask;
+
+ if (Tk_SetOptions(interp, (ClientData)column,
+ tv->tree.headingOptionTable, objc, objv, tv->core.tkwin,
+ &savedOptions,&mask) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ /* @@@ testing ... */
+ if ((mask & STATE_CHANGED) && column->headingStateObj) {
+ Ttk_StateSpec stateSpec;
+ if (Ttk_GetStateSpecFromObj(
+ interp, column->headingStateObj, &stateSpec) != TCL_OK)
+ {
+ goto error;
+ }
+ column->headingState = Ttk_ModifyState(column->headingState,&stateSpec);
+ Tcl_DecrRefCount(column->headingStateObj);
+ column->headingStateObj = Ttk_NewStateSpecObj(column->headingState,0);
+ Tcl_IncrRefCount(column->headingStateObj);
+ }
+
+ TtkRedisplayWidget(&tv->core);
+ Tk_FreeSavedOptions(&savedOptions);
+ return TCL_OK;
+
+error:
+ Tk_RestoreSavedOptions(&savedOptions);
+ return TCL_ERROR;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Geometry routines.
+ */
+
+/* + CountRows --
+ * Returns the number of viewable rows rooted at item
+ */
+static int CountRows(TreeItem *item)
+{
+ int rows = 1;
+
+ if (item->state & TTK_STATE_OPEN) {
+ TreeItem *child = item->children;
+ while (child) {
+ rows += CountRows(child);
+ child = child->next;
+ }
+ }
+ return rows;
+}
+
+/* + IdentifyRow --
+ * Recursive search for item at specified y position.
+ * Main work routine for IdentifyItem()
+ */
+static TreeItem *IdentifyRow(
+ Treeview *tv, /* Widget record */
+ TreeItem *item, /* Where to start search */
+ int *ypos, /* Scan position */
+ int y) /* Target y coordinate */
+{
+ while (item) {
+ int next_ypos = *ypos + tv->tree.rowHeight;
+ if (*ypos <= y && y <= next_ypos) {
+ return item;
+ }
+ *ypos = next_ypos;
+ if (item->state & TTK_STATE_OPEN) {
+ TreeItem *subitem = IdentifyRow(tv, item->children, ypos, y);
+ if (subitem) {
+ return subitem;
+ }
+ }
+ item = item->next;
+ }
+ return 0;
+}
+
+/* + IdentifyItem --
+ * Locate the item at the specified y position, if any.
+ */
+static TreeItem *IdentifyItem(Treeview *tv, int y)
+{
+ int rowHeight = tv->tree.rowHeight;
+ int ypos = tv->tree.treeArea.y - rowHeight * tv->tree.yscroll.first;
+ return IdentifyRow(tv, tv->tree.root->children, &ypos, y);
+}
+
+/* + IdentifyDisplayColumn --
+ * Returns the display column number at the specified x position,
+ * or -1 if x is outside any columns.
+ */
+static int IdentifyDisplayColumn(Treeview *tv, int x, int *x1)
+{
+ int colno = FirstColumn(tv);
+ int xpos = tv->tree.treeArea.x - tv->tree.xscroll.first;
+
+ while (colno < tv->tree.nDisplayColumns) {
+ TreeColumn *column = tv->tree.displayColumns[colno];
+ int next_xpos = xpos + column->width;
+ if (xpos <= x && x <= next_xpos + HALO) {
+ *x1 = next_xpos;
+ return colno;
+ }
+ ++colno;
+ xpos = next_xpos;
+ }
+
+ return -1;
+}
+
+/* + RowNumber --
+ * Calculate which row the specified item appears on;
+ * returns -1 if the item is not viewable.
+ * Xref: DrawForest, IdentifyItem.
+ */
+static int RowNumber(Treeview *tv, TreeItem *item)
+{
+ TreeItem *p = tv->tree.root->children;
+ int n = 0;
+
+ while (p) {
+ if (p == item)
+ return n;
+
+ ++n;
+
+ /* Find next viewable item in preorder traversal order
+ */
+ if (p->children && (p->state & TTK_STATE_OPEN)) {
+ p = p->children;
+ } else {
+ while (!p->next && p && p->parent)
+ p = p->parent;
+ if (p)
+ p = p->next;
+ }
+ }
+
+ return -1;
+}
+
+/* + ItemDepth -- return the depth of a tree item.
+ * The depth of an item is equal to the number of proper ancestors,
+ * not counting the root node.
+ */
+static int ItemDepth(TreeItem *item)
+{
+ int depth = 0;
+ while (item->parent) {
+ ++depth;
+ item = item->parent;
+ }
+ return depth-1;
+}
+
+/* + ItemRow --
+ * Returns row number of specified item relative to root,
+ * -1 if item is not viewable.
+ */
+static int ItemRow(Treeview *tv, TreeItem *p)
+{
+ TreeItem *root = tv->tree.root;
+ int rowNumber = 0;
+
+ for (;;) {
+ if (p->prev) {
+ p = p->prev;
+ rowNumber += CountRows(p);
+ } else {
+ p = p->parent;
+ if (!(p && (p->state & TTK_STATE_OPEN))) {
+ /* detached or closed ancestor */
+ return -1;
+ }
+ if (p == root) {
+ return rowNumber;
+ }
+ ++rowNumber;
+ }
+ }
+}
+
+/* + BoundingBox --
+ * Compute the parcel of the specified column of the specified item,
+ * (or the entire item if column is NULL)
+ * Returns: 0 if item or column is not viewable, 1 otherwise.
+ */
+static int BoundingBox(
+ Treeview *tv, /* treeview widget */
+ TreeItem *item, /* desired item */
+ TreeColumn *column, /* desired column */
+ Ttk_Box *bbox_rtn) /* bounding box of item */
+{
+ int row = ItemRow(tv, item);
+ Ttk_Box bbox = tv->tree.treeArea;
+
+ if (row < tv->tree.yscroll.first || row > tv->tree.yscroll.last) {
+ /* not viewable, or off-screen */
+ return 0;
+ }
+
+ bbox.y += (row - tv->tree.yscroll.first) * tv->tree.rowHeight;
+ bbox.height = tv->tree.rowHeight;
+
+ bbox.x -= tv->tree.xscroll.first;
+ bbox.width = TreeWidth(tv);
+
+ if (column) {
+ int xpos = 0, i = FirstColumn(tv);
+ while (i < tv->tree.nDisplayColumns) {
+ if (tv->tree.displayColumns[i] == column) {
+ break;
+ }
+ xpos += tv->tree.displayColumns[i]->width;
+ ++i;
+ }
+ if (i == tv->tree.nDisplayColumns) { /* specified column unviewable */
+ return 0;
+ }
+ bbox.x += xpos;
+ bbox.width = column->width;
+
+ /* Account for indentation in tree column:
+ */
+ if (column == &tv->tree.column0) {
+ int indent = tv->tree.indent * ItemDepth(item);
+ bbox.x += indent;
+ bbox.width -= indent;
+ }
+ }
+ *bbox_rtn = bbox;
+ return 1;
+}
+
+/* + IdentifyRegion --
+ */
+
+typedef enum {
+ REGION_NOTHING = 0,
+ REGION_HEADING,
+ REGION_SEPARATOR,
+ REGION_TREE,
+ REGION_CELL
+} TreeRegion;
+
+static const char *regionStrings[] = {
+ "nothing", "heading", "separator", "tree", "cell", 0
+};
+
+static TreeRegion IdentifyRegion(Treeview *tv, int x, int y)
+{
+ int x1 = 0, colno;
+
+ colno = IdentifyDisplayColumn(tv, x, &x1);
+ if (Ttk_BoxContains(tv->tree.headingArea, x, y)) {
+ if (colno < 0) {
+ return REGION_NOTHING;
+ } else if (-HALO <= x1 - x && x1 - x <= HALO) {
+ return REGION_SEPARATOR;
+ } else {
+ return REGION_HEADING;
+ }
+ } else if (Ttk_BoxContains(tv->tree.treeArea, x, y)) {
+ TreeItem *item = IdentifyItem(tv, y);
+ if (item && colno > 0) {
+ return REGION_CELL;
+ } else if (item) {
+ return REGION_TREE;
+ }
+ }
+ return REGION_NOTHING;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Display routines.
+ */
+
+/* + GetSublayout --
+ * Utility routine; acquires a sublayout for items, cells, etc.
+ */
+static Ttk_Layout GetSublayout(
+ Tcl_Interp *interp,
+ Ttk_Theme themePtr,
+ Ttk_Layout parentLayout,
+ const char *layoutName,
+ Tk_OptionTable optionTable,
+ Ttk_Layout *layoutPtr)
+{
+ Ttk_Layout newLayout = Ttk_CreateSublayout(
+ interp, themePtr, parentLayout, layoutName, optionTable);
+
+ if (newLayout) {
+ if (*layoutPtr)
+ Ttk_FreeLayout(*layoutPtr);
+ *layoutPtr = newLayout;
+ }
+ return newLayout;
+}
+
+/* + TreeviewGetLayout --
+ * GetLayout() widget hook.
+ */
+static Ttk_Layout TreeviewGetLayout(
+ Tcl_Interp *interp, Ttk_Theme themePtr, void *recordPtr)
+{
+ Treeview *tv = recordPtr;
+ Ttk_Layout treeLayout = TtkWidgetGetLayout(interp, themePtr, recordPtr);
+ Tcl_Obj *objPtr;
+ int unused;
+
+ if (!(
+ treeLayout
+ && GetSublayout(interp, themePtr, treeLayout, ".Item",
+ tv->tree.tagOptionTable, &tv->tree.itemLayout)
+ && GetSublayout(interp, themePtr, treeLayout, ".Cell",
+ tv->tree.tagOptionTable, &tv->tree.cellLayout)
+ && GetSublayout(interp, themePtr, treeLayout, ".Heading",
+ tv->tree.headingOptionTable, &tv->tree.headingLayout)
+ && GetSublayout(interp, themePtr, treeLayout, ".Row",
+ tv->tree.tagOptionTable, &tv->tree.rowLayout)
+ )) {
+ return 0;
+ }
+
+ /* Compute heading height.
+ */
+ Ttk_RebindSublayout(tv->tree.headingLayout, &tv->tree.column0);
+ Ttk_LayoutSize(tv->tree.headingLayout, 0, &unused, &tv->tree.headingHeight);
+
+ /* Get item height, indent from style:
+ * @@@ TODO: sanity-check.
+ */
+ tv->tree.rowHeight = DEFAULT_ROWHEIGHT;
+ tv->tree.indent = DEFAULT_INDENT;
+ if ((objPtr = Ttk_QueryOption(treeLayout, "-rowheight", 0))) {
+ (void)Tcl_GetIntFromObj(NULL, objPtr, &tv->tree.rowHeight);
+ }
+ if ((objPtr = Ttk_QueryOption(treeLayout, "-indent", 0))) {
+ (void)Tcl_GetIntFromObj(NULL, objPtr, &tv->tree.indent);
+ }
+
+ return treeLayout;
+}
+
+/* + TreeviewDoLayout --
+ * DoLayout() widget hook. Computes widget layout.
+ *
+ * Side effects:
+ * Computes headingArea and treeArea.
+ * Computes subtree height.
+ * Invokes scroll callbacks.
+ */
+static void TreeviewDoLayout(void *clientData)
+{
+ Treeview *tv = clientData;
+ int visibleRows;
+
+ /* ASSERT: SLACKINVARIANT */
+
+ Ttk_PlaceLayout(tv->core.layout,tv->core.state,Ttk_WinBox(tv->core.tkwin));
+ tv->tree.treeArea = Ttk_ClientRegion(tv->core.layout, "treearea");
+
+ ResizeColumns(tv, tv->tree.treeArea.width);
+ /* ASSERT: SLACKINVARIANT */
+
+ TtkScrolled(tv->tree.xscrollHandle,
+ tv->tree.xscroll.first,
+ tv->tree.xscroll.first + tv->tree.treeArea.width,
+ TreeWidth(tv));
+
+ if (tv->tree.showFlags & SHOW_HEADINGS) {
+ tv->tree.headingArea = Ttk_PackBox(
+ &tv->tree.treeArea, 1, tv->tree.headingHeight, TTK_SIDE_TOP);
+ } else {
+ tv->tree.headingArea = Ttk_MakeBox(0,0,0,0);
+ }
+
+ visibleRows = tv->tree.treeArea.height / tv->tree.rowHeight;
+ tv->tree.root->state |= TTK_STATE_OPEN;
+ TtkScrolled(tv->tree.yscrollHandle,
+ tv->tree.yscroll.first,
+ tv->tree.yscroll.first + visibleRows,
+ CountRows(tv->tree.root) - 1);
+}
+
+/* + TreeviewSize --
+ * SizeProc() widget hook. Size is determined by
+ * -height option and column widths.
+ */
+static int TreeviewSize(void *clientData, int *widthPtr, int *heightPtr)
+{
+ Treeview *tv = clientData;
+ int nRows, padHeight, padWidth;
+
+ Ttk_LayoutSize(tv->core.layout, tv->core.state, &padWidth, &padHeight);
+ Tcl_GetIntFromObj(NULL, tv->tree.heightObj, &nRows);
+
+ *widthPtr = padWidth + TreeWidth(tv);
+ *heightPtr = padHeight + tv->tree.rowHeight * nRows;
+
+ if (tv->tree.showFlags & SHOW_HEADINGS) {
+ *heightPtr += tv->tree.headingHeight;
+ }
+
+ return 1;
+}
+
+/* + ItemState --
+ * Returns the state of the specified item, based
+ * on widget state, item state, and other information.
+ */
+static Ttk_State ItemState(Treeview *tv, TreeItem *item)
+{
+ Ttk_State state = tv->core.state | item->state;
+ if (!item->children)
+ state |= TTK_STATE_LEAF;
+ if (item != tv->tree.focus)
+ state &= ~TTK_STATE_FOCUS;
+ return state;
+}
+
+/* + DrawHeadings --
+ * Draw tree headings.
+ */
+static void DrawHeadings(Treeview *tv, Drawable d)
+{
+ const int x0 = tv->tree.headingArea.x - tv->tree.xscroll.first;
+ const int y0 = tv->tree.headingArea.y;
+ const int h0 = tv->tree.headingArea.height;
+ int i = FirstColumn(tv);
+ int x = 0;
+
+ while (i < tv->tree.nDisplayColumns) {
+ TreeColumn *column = tv->tree.displayColumns[i];
+ Ttk_Box parcel = Ttk_MakeBox(x0+x, y0, column->width, h0);
+ DisplayLayout(tv->tree.headingLayout,
+ column, column->headingState, parcel, d);
+ x += column->width;
+ ++i;
+ }
+}
+
+/* + PrepareItem --
+ * Fill in a displayItem record.
+ */
+static void PrepareItem(
+ Treeview *tv, TreeItem *item, DisplayItem *displayItem)
+{
+ Ttk_Style style = Ttk_LayoutStyle(tv->core.layout);
+ Ttk_State state = ItemState(tv, item);
+
+ Ttk_TagSetValues(tv->tree.tagTable, item->tagset, displayItem);
+ Ttk_TagSetApplyStyle(tv->tree.tagTable, style, state, displayItem);
+}
+
+/* + DrawCells --
+ * Draw data cells for specified item.
+ */
+static void DrawCells(
+ Treeview *tv, TreeItem *item, DisplayItem *displayItem,
+ Drawable d, int x, int y)
+{
+ Ttk_Layout layout = tv->tree.cellLayout;
+ Ttk_State state = ItemState(tv, item);
+ Ttk_Padding cellPadding = {4, 0, 4, 0};
+ int rowHeight = tv->tree.rowHeight;
+ int nValues = 0;
+ Tcl_Obj **values = 0;
+ int i;
+
+ if (!item->valuesObj) {
+ return;
+ }
+
+ Tcl_ListObjGetElements(NULL, item->valuesObj, &nValues, &values);
+ for (i = 0; i < tv->tree.nColumns; ++i) {
+ tv->tree.columns[i].data = (i < nValues) ? values[i] : 0;
+ }
+
+ for (i = 1; i < tv->tree.nDisplayColumns; ++i) {
+ TreeColumn *column = tv->tree.displayColumns[i];
+ Ttk_Box parcel = Ttk_PadBox(
+ Ttk_MakeBox(x, y, column->width, rowHeight), cellPadding);
+
+ displayItem->textObj = column->data;
+ displayItem->anchorObj = column->anchorObj; /* <<NOTE-ANCHOR>> */
+
+ DisplayLayout(layout, displayItem, state, parcel, d);
+ x += column->width;
+ }
+}
+
+/* + DrawItem --
+ * Draw an item (row background, tree label, and cells).
+ */
+static void DrawItem(
+ Treeview *tv, TreeItem *item, Drawable d, int depth, int row)
+{
+ Ttk_State state = ItemState(tv, item);
+ DisplayItem displayItem;
+ int rowHeight = tv->tree.rowHeight;
+ int x = tv->tree.treeArea.x - tv->tree.xscroll.first;
+ int y = tv->tree.treeArea.y + rowHeight * (row - tv->tree.yscroll.first);
+
+ if (row % 2) state |= TTK_STATE_ALTERNATE;
+
+ PrepareItem(tv, item, &displayItem);
+
+ /* Draw row background:
+ */
+ {
+ Ttk_Box rowBox = Ttk_MakeBox(x, y, TreeWidth(tv), rowHeight);
+ DisplayLayout(tv->tree.rowLayout, &displayItem, state, rowBox, d);
+ }
+
+ /* Draw tree label:
+ */
+ if (tv->tree.showFlags & SHOW_TREE) {
+ int indent = depth * tv->tree.indent;
+ int colwidth = tv->tree.column0.width;
+ Ttk_Box parcel = Ttk_MakeBox(
+ x+indent, y, colwidth-indent, rowHeight);
+ if (item->textObj) { displayItem.textObj = item->textObj; }
+ if (item->imageObj) { displayItem.imageObj = item->imageObj; }
+ /* ??? displayItem.anchorObj = 0; <<NOTE-ANCHOR>> */
+ DisplayLayout(tv->tree.itemLayout, &displayItem, state, parcel, d);
+ x += colwidth;
+ }
+
+ /* Draw data cells:
+ */
+ DrawCells(tv, item, &displayItem, d, x, y);
+}
+
+/* + DrawSubtree --
+ * Draw an item and all of its (viewable) descendants.
+ *
+ * Returns:
+ * Row number of the last item drawn.
+ */
+
+static int DrawForest( /* forward */
+ Treeview *tv, TreeItem *item, Drawable d, int depth, int row);
+
+static int DrawSubtree(
+ Treeview *tv, TreeItem *item, Drawable d, int depth, int row)
+{
+ if (row >= tv->tree.yscroll.first) {
+ DrawItem(tv, item, d, depth, row);
+ }
+
+ if (item->state & TTK_STATE_OPEN) {
+ return DrawForest(tv, item->children, d, depth + 1, row + 1);
+ } else {
+ return row + 1;
+ }
+}
+
+/* + DrawForest --
+ * Draw a sequence of items and their visible descendants.
+ *
+ * Returns:
+ * Row number of the last item drawn.
+ */
+static int DrawForest(
+ Treeview *tv, TreeItem *item, Drawable d, int depth, int row)
+{
+ while (item && row <= tv->tree.yscroll.last) {
+ row = DrawSubtree(tv, item, d, depth, row);
+ item = item->next;
+ }
+ return row;
+}
+
+/* + TreeviewDisplay --
+ * Display() widget hook. Draw the widget contents.
+ */
+static void TreeviewDisplay(void *clientData, Drawable d)
+{
+ Treeview *tv = clientData;
+
+ Ttk_DrawLayout(tv->core.layout, tv->core.state, d);
+ if (tv->tree.showFlags & SHOW_HEADINGS) {
+ DrawHeadings(tv, d);
+ }
+ DrawForest(tv, tv->tree.root->children, d, 0,0);
+}
+
+/*------------------------------------------------------------------------
+ * +++ Utilities for widget commands
+ */
+
+/* + InsertPosition --
+ * Locate the previous sibling for [$tree insert].
+ *
+ * Returns a pointer to the item just before the specified index,
+ * or 0 if the item is to be inserted at the beginning.
+ */
+static TreeItem *InsertPosition(TreeItem *parent, int index)
+{
+ TreeItem *prev = 0, *next = parent->children;
+
+ while (next != 0 && index > 0) {
+ --index;
+ prev = next;
+ next = prev->next;
+ }
+
+ return prev;
+}
+
+/* + EndPosition --
+ * Locate the last child of the specified node.
+ *
+ * To avoid quadratic-time behavior in the common cases
+ * where the treeview is populated in breadth-first or
+ * depth-first order using [$tv insert $parent end ...],
+ * we cache the result from the last call to EndPosition()
+ * and start the search from there on a cache hit.
+ *
+ */
+static TreeItem *EndPosition(Treeview *tv, TreeItem *parent)
+{
+ TreeItem *endPtr = tv->tree.endPtr;
+
+ while (endPtr && endPtr->parent != parent) {
+ endPtr = endPtr->parent;
+ }
+ if (!endPtr) {
+ endPtr = parent->children;
+ }
+
+ if (endPtr) {
+ while (endPtr->next) {
+ endPtr = endPtr->next;
+ }
+ tv->tree.endPtr = endPtr;
+ }
+
+ return endPtr;
+}
+
+/* + AncestryCheck --
+ * Verify that specified item is not an ancestor of the specified parent;
+ * returns 1 if OK, 0 and leaves an error message in interp otherwise.
+ */
+static int AncestryCheck(
+ Tcl_Interp *interp, Treeview *tv, TreeItem *item, TreeItem *parent)
+{
+ TreeItem *p = parent;
+ while (p) {
+ if (p == item) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ "Cannot insert ", ItemName(tv, item),
+ " as a descendant of ", ItemName(tv, parent),
+ NULL);
+ return 0;
+ }
+ p = p->parent;
+ }
+ return 1;
+}
+
+/* + DeleteItems --
+ * Remove an item and all of its descendants from the hash table
+ * and detach them from the tree; returns a linked list (chained
+ * along the ->next pointer) of deleted items.
+ */
+static TreeItem *DeleteItems(TreeItem *item, TreeItem *delq)
+{
+ if (item->entryPtr) {
+ DetachItem(item);
+ while (item->children) {
+ delq = DeleteItems(item->children, delq);
+ }
+ Tcl_DeleteHashEntry(item->entryPtr);
+ item->entryPtr = 0;
+ item->next = delq;
+ delq = item;
+ } /* else -- item has already been unlinked */
+ return delq;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget commands -- item inquiry.
+ */
+
+/* + $tv children $item ?newchildren? --
+ * Return the list of children associated with $item
+ */
+static int TreeviewChildrenCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ TreeItem *item;
+ Tcl_Obj *result;
+
+ if (objc < 3 || objc > 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "item ?newchildren?");
+ return TCL_ERROR;
+ }
+ item = FindItem(interp, tv, objv[2]);
+ if (!item) {
+ return TCL_ERROR;
+ }
+
+ if (objc == 3) {
+ result = Tcl_NewListObj(0,0);
+ for (item = item->children; item; item = item->next) {
+ Tcl_ListObjAppendElement(interp, result, ItemID(tv, item));
+ }
+ Tcl_SetObjResult(interp, result);
+ } else {
+ TreeItem **newChildren = GetItemListFromObj(interp, tv, objv[3]);
+ TreeItem *child;
+ int i;
+
+ if (!newChildren)
+ return TCL_ERROR;
+
+ /* Sanity-check:
+ */
+ for (i=0; newChildren[i]; ++i) {
+ if (!AncestryCheck(interp, tv, newChildren[i], item)) {
+ ckfree((ClientData)newChildren);
+ return TCL_ERROR;
+ }
+ }
+
+ /* Detach old children:
+ */
+ child = item->children;
+ while (child) {
+ TreeItem *next = child->next;
+ DetachItem(child);
+ child = next;
+ }
+
+ /* Detach new children from their current locations:
+ */
+ for (i=0; newChildren[i]; ++i) {
+ DetachItem(newChildren[i]);
+ }
+
+ /* Reinsert new children:
+ * Note: it is not an error for an item to be listed more than once,
+ * though it probably should be...
+ */
+ child = 0;
+ for (i=0; newChildren[i]; ++i) {
+ if (newChildren[i]->parent) {
+ /* This is a duplicate element which has already been
+ * inserted. Ignore it.
+ */
+ continue;
+ }
+ InsertItem(item, child, newChildren[i]);
+ child = newChildren[i];
+ }
+
+ ckfree((ClientData)newChildren);
+ TtkRedisplayWidget(&tv->core);
+ }
+
+ return TCL_OK;
+}
+
+/* + $tv parent $item --
+ * Return the item ID of $item's parent.
+ */
+static int TreeviewParentCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ TreeItem *item;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "item");
+ return TCL_ERROR;
+ }
+ item = FindItem(interp, tv, objv[2]);
+ if (!item) {
+ return TCL_ERROR;
+ }
+
+ if (item->parent) {
+ Tcl_SetObjResult(interp, ItemID(tv, item->parent));
+ } else {
+ /* This is the root item. @@@ Return an error? */
+ Tcl_ResetResult(interp);
+ }
+
+ return TCL_OK;
+}
+
+/* + $tv next $item
+ * Return the ID of $item's next sibling.
+ */
+static int TreeviewNextCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ TreeItem *item;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "item");
+ return TCL_ERROR;
+ }
+ item = FindItem(interp, tv, objv[2]);
+ if (!item) {
+ return TCL_ERROR;
+ }
+
+ if (item->next) {
+ Tcl_SetObjResult(interp, ItemID(tv, item->next));
+ } /* else -- leave interp-result empty */
+
+ return TCL_OK;
+}
+
+/* + $tv prev $item
+ * Return the ID of $item's previous sibling.
+ */
+static int TreeviewPrevCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ TreeItem *item;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "item");
+ return TCL_ERROR;
+ }
+ item = FindItem(interp, tv, objv[2]);
+ if (!item) {
+ return TCL_ERROR;
+ }
+
+ if (item->prev) {
+ Tcl_SetObjResult(interp, ItemID(tv, item->prev));
+ } /* else -- leave interp-result empty */
+
+ return TCL_OK;
+}
+
+/* + $tv index $item --
+ * Return the index of $item within its parent.
+ */
+static int TreeviewIndexCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ TreeItem *item;
+ int index = 0;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "item");
+ return TCL_ERROR;
+ }
+ item = FindItem(interp, tv, objv[2]);
+ if (!item) {
+ return TCL_ERROR;
+ }
+
+ while (item->prev) {
+ ++index;
+ item = item->prev;
+ }
+
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
+ return TCL_OK;
+}
+
+/* + $tv exists $itemid --
+ * Test if the specified item id is present in the tree.
+ */
+static int TreeviewExistsCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ Tcl_HashEntry *entryPtr;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "itemid");
+ return TCL_ERROR;
+ }
+
+ entryPtr = Tcl_FindHashEntry(&tv->tree.items, Tcl_GetString(objv[2]));
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(entryPtr != 0));
+ return TCL_OK;
+}
+
+/* + $tv bbox $itemid ?$column? --
+ * Return bounding box [x y width height] of specified item.
+ */
+static int TreeviewBBoxCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ TreeItem *item = 0;
+ TreeColumn *column = 0;
+ Ttk_Box bbox;
+
+ if (objc < 3 || objc > 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "itemid ?column");
+ return TCL_ERROR;
+ }
+
+ item = FindItem(interp, tv, objv[2]);
+ if (!item) {
+ return TCL_ERROR;
+ }
+ if (objc >=4 && (column = FindColumn(interp,tv,objv[3])) == NULL) {
+ return TCL_ERROR;
+ }
+
+ if (BoundingBox(tv, item, column, &bbox)) {
+ Tcl_SetObjResult(interp, Ttk_NewBoxObj(bbox));
+ }
+
+ return TCL_OK;
+}
+
+/* + $tv identify $x $y -- (obsolescent)
+ * Implements the old, horrible, 2-argument form of [$tv identify].
+ *
+ * Returns: one of
+ * heading #n
+ * cell itemid #n
+ * item itemid element
+ * row itemid
+ */
+static int TreeviewHorribleIdentify(
+ Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], Treeview *tv)
+{
+ const char *what = "nothing", *detail = NULL;
+ TreeItem *item = 0;
+ Tcl_Obj *result;
+ int dColumnNumber;
+ char dcolbuf[16];
+ int x, y, x1;
+
+ /* ASSERT: objc == 4 */
+
+ if ( Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK
+ || Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK
+ ) {
+ return TCL_ERROR;
+ }
+
+ dColumnNumber = IdentifyDisplayColumn(tv, x, &x1);
+ if (dColumnNumber < 0) {
+ goto done;
+ }
+ sprintf(dcolbuf, "#%d", dColumnNumber);
+
+ if (Ttk_BoxContains(tv->tree.headingArea,x,y)) {
+ if (-HALO <= x1 - x && x1 - x <= HALO) {
+ what = "separator";
+ } else {
+ what = "heading";
+ }
+ detail = dcolbuf;
+ } else if (Ttk_BoxContains(tv->tree.treeArea,x,y)) {
+ item = IdentifyItem(tv, y);
+ if (item && dColumnNumber > 0) {
+ what = "cell";
+ detail = dcolbuf;
+ } else if (item) {
+ Ttk_Layout layout = tv->tree.itemLayout;
+ Ttk_Box itemBox;
+ DisplayItem displayItem;
+ Ttk_Element element;
+
+ BoundingBox(tv, item, NULL, &itemBox);
+ PrepareItem(tv, item, &displayItem); /*@@@ FIX: -text, etc*/
+ Ttk_RebindSublayout(layout, &displayItem);
+ Ttk_PlaceLayout(layout, ItemState(tv,item), itemBox);
+ element = Ttk_IdentifyElement(layout, x, y);
+
+ if (element) {
+ what = "item";
+ detail = Ttk_ElementName(element);
+ } else {
+ what = "row";
+ }
+ }
+ }
+
+done:
+ result = Tcl_NewListObj(0,0);
+ Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(what, -1));
+ if (item)
+ Tcl_ListObjAppendElement(NULL, result, ItemID(tv, item));
+ if (detail)
+ Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(detail, -1));
+
+ Tcl_SetObjResult(interp, result);
+ return TCL_OK;
+}
+
+/* + $tv identify $component $x $y --
+ * Identify the component at position x,y.
+ */
+
+static int TreeviewIdentifyCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ static const char *submethodStrings[] =
+ { "region", "item", "column", "row", "element", NULL };
+ enum { I_REGION, I_ITEM, I_COLUMN, I_ROW, I_ELEMENT };
+
+ Treeview *tv = recordPtr;
+ int submethod;
+ int x, y;
+
+ TreeRegion region;
+ Ttk_Box bbox;
+ TreeItem *item;
+ TreeColumn *column = 0;
+ int colno, x1;
+
+ if (objc == 4) { /* Old form */
+ return TreeviewHorribleIdentify(interp, objc, objv, tv);
+ } else if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "command x y");
+ return TCL_ERROR;
+ }
+
+ if ( Tcl_GetIndexFromObj(interp, objv[2],
+ submethodStrings, "command", TCL_EXACT, &submethod) != TCL_OK
+ || Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK
+ || Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK
+ ) {
+ return TCL_ERROR;
+ }
+
+ region = IdentifyRegion(tv, x, y);
+ item = IdentifyItem(tv, y);
+ colno = IdentifyDisplayColumn(tv, x, &x1);
+ column = (colno >= 0) ? tv->tree.displayColumns[colno] : NULL;
+
+ switch (submethod)
+ {
+ case I_REGION :
+ Tcl_SetObjResult(interp,Tcl_NewStringObj(regionStrings[region],-1));
+ break;
+
+ case I_ITEM :
+ case I_ROW :
+ if (item) {
+ Tcl_SetObjResult(interp, ItemID(tv, item));
+ }
+ break;
+
+ case I_COLUMN :
+ if (colno >= 0) {
+ char dcolbuf[16];
+ sprintf(dcolbuf, "#%d", colno);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(dcolbuf, -1));
+ }
+ break;
+
+ case I_ELEMENT :
+ {
+ Ttk_Layout layout = 0;
+ DisplayItem displayItem;
+ Ttk_Element element;
+
+ switch (region) {
+ case REGION_NOTHING:
+ layout = tv->core.layout;
+ return TCL_OK; /* @@@ NYI */
+ case REGION_HEADING:
+ case REGION_SEPARATOR:
+ layout = tv->tree.headingLayout;
+ return TCL_OK; /* @@@ NYI */
+ case REGION_TREE:
+ layout = tv->tree.itemLayout;
+ break;
+ case REGION_CELL:
+ layout = tv->tree.cellLayout;
+ break;
+ }
+
+ if (!BoundingBox(tv, item, column, &bbox)) {
+ return TCL_OK;
+ }
+
+ PrepareItem(tv, item, &displayItem); /*@@@ FIX: fill in -text,etc */
+ Ttk_RebindSublayout(layout, &displayItem);
+ Ttk_PlaceLayout(layout, ItemState(tv,item), bbox);
+ element = Ttk_IdentifyElement(layout, x, y);
+
+ if (element) {
+ const char *elementName = Ttk_ElementName(element);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(elementName, -1));
+ }
+ break;
+ }
+ }
+ return TCL_OK;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget commands -- item and column configuration.
+ */
+
+/* + $tv item $item ?options ....?
+ * Query or configure item options.
+ */
+static int TreeviewItemCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ TreeItem *item;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "item ?option ?value??...");
+ return TCL_ERROR;
+ }
+ if (!(item = FindItem(interp, tv, objv[2]))) {
+ return TCL_ERROR;
+ }
+
+ if (objc == 3) {
+ return TtkEnumerateOptions(interp, item, ItemOptionSpecs,
+ tv->tree.itemOptionTable, tv->core.tkwin);
+ } else if (objc == 4) {
+ return TtkGetOptionValue(interp, item, objv[3],
+ tv->tree.itemOptionTable, tv->core.tkwin);
+ } else {
+ return ConfigureItem(interp, tv, item, objc-3, objv+3);
+ }
+}
+
+/* + $tv column column ?options ....?
+ * Column data accessor
+ */
+static int TreeviewColumnCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ TreeColumn *column;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "column -option value...");
+ return TCL_ERROR;
+ }
+ if (!(column = FindColumn(interp, tv, objv[2]))) {
+ return TCL_ERROR;
+ }
+
+ if (objc == 3) {
+ return TtkEnumerateOptions(interp, column, ColumnOptionSpecs,
+ tv->tree.columnOptionTable, tv->core.tkwin);
+ } else if (objc == 4) {
+ return TtkGetOptionValue(interp, column, objv[3],
+ tv->tree.columnOptionTable, tv->core.tkwin);
+ } else {
+ return ConfigureColumn(interp, tv, column, objc-3, objv+3);
+ }
+}
+
+/* + $tv heading column ?options ....?
+ * Heading data accessor
+ */
+static int TreeviewHeadingCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ Tk_OptionTable optionTable = tv->tree.headingOptionTable;
+ Tk_Window tkwin = tv->core.tkwin;
+ TreeColumn *column;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "column -option value...");
+ return TCL_ERROR;
+ }
+ if (!(column = FindColumn(interp, tv, objv[2]))) {
+ return TCL_ERROR;
+ }
+
+ if (objc == 3) {
+ return TtkEnumerateOptions(
+ interp, column, HeadingOptionSpecs, optionTable, tkwin);
+ } else if (objc == 4) {
+ return TtkGetOptionValue(
+ interp, column, objv[3], optionTable, tkwin);
+ } else {
+ return ConfigureHeading(interp, tv, column, objc-3,objv+3);
+ }
+}
+
+/* + $tv set $item ?$column ?value??
+ * Query or configure cell values
+ */
+static int TreeviewSetCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ TreeItem *item;
+ TreeColumn *column;
+ int columnNumber;
+
+ if (objc < 3 || objc > 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "item ?column ?value??");
+ return TCL_ERROR;
+ }
+ if (!(item = FindItem(interp, tv, objv[2])))
+ return TCL_ERROR;
+
+ /* Make sure -values exists:
+ */
+ if (!item->valuesObj) {
+ item->valuesObj = Tcl_NewListObj(0,0);
+ Tcl_IncrRefCount(item->valuesObj);
+ }
+
+ if (objc == 3) {
+ /* Return dictionary:
+ */
+ Tcl_Obj *result = Tcl_NewListObj(0,0);
+ Tcl_Obj *value;
+ for (columnNumber=0; columnNumber<tv->tree.nColumns; ++columnNumber) {
+ Tcl_ListObjIndex(interp, item->valuesObj, columnNumber, &value);
+ if (value) {
+ Tcl_ListObjAppendElement(interp, result,
+ tv->tree.columns[columnNumber].idObj);
+ Tcl_ListObjAppendElement(interp, result, value);
+ }
+ }
+ Tcl_SetObjResult(interp, result);
+ return TCL_OK;
+ }
+
+ /* else -- get or set column
+ */
+ if (!(column = FindColumn(interp, tv, objv[3])))
+ return TCL_ERROR;
+
+ if (column == &tv->tree.column0) {
+ /* @@@ Maybe set -text here instead? */
+ Tcl_AppendResult(interp, "Display column #0 cannot be set", NULL);
+ return TCL_ERROR;
+ }
+
+ /* Note: we don't do any error checking in the list operations,
+ * since item->valuesObj is guaranteed to be a list.
+ */
+ columnNumber = column - tv->tree.columns;
+
+ if (objc == 4) { /* get column */
+ Tcl_Obj *result = 0;
+ Tcl_ListObjIndex(interp, item->valuesObj, columnNumber, &result);
+ if (!result) {
+ result = Tcl_NewStringObj("",0);
+ }
+ Tcl_SetObjResult(interp, result);
+ return TCL_OK;
+ } else { /* set column */
+ int length;
+
+ item->valuesObj = unshareObj(item->valuesObj);
+
+ /* Make sure -values is fully populated:
+ */
+ Tcl_ListObjLength(interp, item->valuesObj, &length);
+ while (length < tv->tree.nColumns) {
+ Tcl_Obj *empty = Tcl_NewStringObj("",0);
+ Tcl_ListObjAppendElement(interp, item->valuesObj, empty);
+ ++length;
+ }
+
+ /* Set value:
+ */
+ Tcl_ListObjReplace(interp,item->valuesObj,columnNumber,1,1,objv+4);
+ TtkRedisplayWidget(&tv->core);
+ return TCL_OK;
+ }
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget commands -- tree modification.
+ */
+
+/* + $tv insert $parent $index ?-id id? ?-option value ...?
+ * Insert a new item.
+ */
+static int TreeviewInsertCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ TreeItem *parent, *sibling, *newItem;
+ Tcl_HashEntry *entryPtr;
+ int isNew;
+
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "parent index ?-id id? -options...");
+ return TCL_ERROR;
+ }
+
+ /* Get parent node:
+ */
+ if ((parent = FindItem(interp, tv, objv[2])) == NULL) {
+ return TCL_ERROR;
+ }
+
+ /* Locate previous sibling based on $index:
+ */
+ if (!strcmp(Tcl_GetString(objv[3]), "end")) {
+ sibling = EndPosition(tv, parent);
+ } else {
+ int index;
+ if (Tcl_GetIntFromObj(interp, objv[3], &index) != TCL_OK)
+ return TCL_ERROR;
+ sibling = InsertPosition(parent, index);
+ }
+
+ /* Get node name:
+ * If -id supplied and does not already exist, use that;
+ * Otherwise autogenerate new one.
+ */
+ objc -= 4; objv += 4;
+ if (objc >= 2 && !strcmp("-id", Tcl_GetString(objv[0]))) {
+ const char *itemName = Tcl_GetString(objv[1]);
+ entryPtr = Tcl_CreateHashEntry(&tv->tree.items, itemName, &isNew);
+ if (!isNew) {
+ Tcl_AppendResult(interp, "Item ",itemName," already exists",NULL);
+ return TCL_ERROR;
+ }
+ objc -= 2; objv += 2;
+ } else {
+ char idbuf[16];
+ do {
+ ++tv->tree.serial;
+ sprintf(idbuf, "I%03X", tv->tree.serial);
+ entryPtr = Tcl_CreateHashEntry(&tv->tree.items, idbuf, &isNew);
+ } while (!isNew);
+ }
+
+ /* Create and configure new item:
+ */
+ newItem = NewItem();
+ Tk_InitOptions(
+ interp, (ClientData)newItem, tv->tree.itemOptionTable, tv->core.tkwin);
+ newItem->tagset = Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, NULL);
+ if (ConfigureItem(interp, tv, newItem, objc, objv) != TCL_OK) {
+ Tcl_DeleteHashEntry(entryPtr);
+ FreeItem(newItem);
+ return TCL_ERROR;
+ }
+
+ /* Store in hash table, link into tree:
+ */
+ Tcl_SetHashValue(entryPtr, newItem);
+ newItem->entryPtr = entryPtr;
+ InsertItem(parent, sibling, newItem);
+ TtkRedisplayWidget(&tv->core);
+
+ Tcl_SetObjResult(interp, ItemID(tv, newItem));
+ return TCL_OK;
+}
+
+/* + $tv detach $item --
+ * Unlink $item from the tree.
+ */
+static int TreeviewDetachCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ TreeItem **items;
+ int i;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "item");
+ return TCL_ERROR;
+ }
+ if (!(items = GetItemListFromObj(interp, tv, objv[2]))) {
+ return TCL_ERROR;
+ }
+
+ /* Sanity-check */
+ for (i = 0; items[i]; ++i) {
+ if (items[i] == tv->tree.root) {
+ Tcl_AppendResult(interp, "Cannot detach root item", NULL);
+ ckfree((ClientData)items);
+ return TCL_ERROR;
+ }
+ }
+
+ for (i = 0; items[i]; ++i) {
+ DetachItem(items[i]);
+ }
+
+ TtkRedisplayWidget(&tv->core);
+ ckfree((ClientData)items);
+ return TCL_OK;
+}
+
+/* + $tv delete $items --
+ * Delete each item in $items.
+ *
+ * Do this in two passes:
+ * First detach the item and all its descendants and remove them
+ * from the hash table. Free the items themselves in a second pass.
+ *
+ * It's done this way because an item may appear more than once
+ * in the list of items to delete (either directly or as a descendant
+ * of a previously deleted item.)
+ */
+
+static int TreeviewDeleteCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ TreeItem **items, *delq;
+ int i;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "items");
+ return TCL_ERROR;
+ }
+
+ if (!(items = GetItemListFromObj(interp, tv, objv[2]))) {
+ return TCL_ERROR;
+ }
+
+ /* Sanity-check:
+ */
+ for (i=0; items[i]; ++i) {
+ if (items[i] == tv->tree.root) {
+ ckfree((ClientData)items);
+ Tcl_AppendResult(interp, "Cannot delete root item", NULL);
+ return TCL_ERROR;
+ }
+ }
+
+ /* Remove items from hash table.
+ */
+ delq = 0;
+ for (i=0; items[i]; ++i) {
+ delq = DeleteItems(items[i], delq);
+ }
+
+ /* Free items:
+ */
+ while (delq) {
+ TreeItem *next = delq->next;
+ if (tv->tree.focus == delq)
+ tv->tree.focus = 0;
+ if (tv->tree.endPtr == delq)
+ tv->tree.endPtr = 0;
+ FreeItem(delq);
+ delq = next;
+ }
+
+ ckfree((ClientData)items);
+ TtkRedisplayWidget(&tv->core);
+ return TCL_OK;
+}
+
+/* + $tv move $item $parent $index
+ * Move $item to the specified $index in $parent's child list.
+ */
+static int TreeviewMoveCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ TreeItem *item, *parent;
+ TreeItem *sibling;
+
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "item parent index");
+ return TCL_ERROR;
+ }
+ if ( (item = FindItem(interp, tv, objv[2])) == 0
+ || (parent = FindItem(interp, tv, objv[3])) == 0)
+ {
+ return TCL_ERROR;
+ }
+
+ /* Locate previous sibling based on $index:
+ */
+ if (!strcmp(Tcl_GetString(objv[4]), "end")) {
+ sibling = EndPosition(tv, parent);
+ } else {
+ TreeItem *p;
+ int index;
+
+ if (Tcl_GetIntFromObj(interp, objv[4], &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ sibling = 0;
+ for (p = parent->children; p != NULL && index > 0; p = p->next) {
+ if (p != item) {
+ --index;
+ } /* else -- moving node forward, count index+1 nodes */
+ sibling = p;
+ }
+ }
+
+ /* Check ancestry:
+ */
+ if (!AncestryCheck(interp, tv, item, parent)) {
+ return TCL_ERROR;
+ }
+
+ /* Moving an item after itself is a no-op:
+ */
+ if (item == sibling) {
+ return TCL_OK;
+ }
+
+ /* Move item:
+ */
+ DetachItem(item);
+ InsertItem(parent, sibling, item);
+
+ TtkRedisplayWidget(&tv->core);
+ return TCL_OK;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget commands -- scrolling
+ */
+
+static int TreeviewXViewCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ return TtkScrollviewCommand(interp, objc, objv, tv->tree.xscrollHandle);
+}
+
+static int TreeviewYViewCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ return TtkScrollviewCommand(interp, objc, objv, tv->tree.yscrollHandle);
+}
+
+/* $tree see $item --
+ * Ensure that $item is visible.
+ */
+static int TreeviewSeeCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ TreeItem *item, *parent;
+ int rowNumber;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "item");
+ return TCL_ERROR;
+ }
+ if (!(item = FindItem(interp, tv, objv[2]))) {
+ return TCL_ERROR;
+ }
+
+ /* Make sure all ancestors are open:
+ */
+ for (parent = item->parent; parent; parent = parent->parent) {
+ if (!(parent->state & TTK_STATE_OPEN)) {
+ parent->openObj = unshareObj(parent->openObj);
+ Tcl_SetBooleanObj(parent->openObj, 1);
+ parent->state |= TTK_STATE_OPEN;
+ TtkRedisplayWidget(&tv->core);
+ }
+ }
+ tv->tree.yscroll.total = CountRows(tv->tree.root) - 1;
+
+ /* Make sure item is visible:
+ */
+ rowNumber = RowNumber(tv, item);
+ if (rowNumber < tv->tree.yscroll.first) {
+ TtkScrollTo(tv->tree.yscrollHandle, rowNumber);
+ } else if (rowNumber >= tv->tree.yscroll.last) {
+ TtkScrollTo(tv->tree.yscrollHandle,
+ tv->tree.yscroll.first + (1+rowNumber - tv->tree.yscroll.last));
+ }
+
+ return TCL_OK;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget commands -- interactive column resize
+ */
+
+/* + $tree drag $column $newX --
+ * Set right edge of display column $column to x position $X
+ */
+static int TreeviewDragCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ int left = tv->tree.treeArea.x - tv->tree.xscroll.first;
+ int i = FirstColumn(tv);
+ TreeColumn *column;
+ int newx;
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "column xposition");
+ return TCL_ERROR;
+ }
+
+ if ( (column = FindColumn(interp, tv, objv[2])) == 0
+ || Tcl_GetIntFromObj(interp, objv[3], &newx) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ for (;i < tv->tree.nDisplayColumns; ++i) {
+ TreeColumn *c = tv->tree.displayColumns[i];
+ int right = left + c->width;
+ if (c == column) {
+ DragColumn(tv, i, newx - right);
+ /* ASSERT: SLACKINVARIANT */
+ TtkRedisplayWidget(&tv->core);
+ return TCL_OK;
+ }
+ left = right;
+ }
+
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ "column ", Tcl_GetString(objv[2]), " is not displayed",
+ NULL);
+ return TCL_ERROR;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget commands -- focus and selection
+ */
+
+/* + $tree focus ?item?
+ */
+static int TreeviewFocusCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+
+ if (objc == 2) {
+ if (tv->tree.focus) {
+ Tcl_SetObjResult(interp, ItemID(tv, tv->tree.focus));
+ }
+ return TCL_OK;
+ } else if (objc == 3) {
+ TreeItem *newFocus = FindItem(interp, tv, objv[2]);
+ if (!newFocus)
+ return TCL_ERROR;
+ tv->tree.focus = newFocus;
+ TtkRedisplayWidget(&tv->core);
+ return TCL_OK;
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, "?newFocus?");
+ return TCL_ERROR;
+ }
+}
+
+/* + $tree selection ?add|remove|set|toggle $items?
+ */
+static int TreeviewSelectionCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ enum {
+ SELECTION_SET, SELECTION_ADD, SELECTION_REMOVE, SELECTION_TOGGLE
+ };
+ static const char *selopStrings[] = {
+ "set", "add", "remove", "toggle", NULL
+ };
+
+ Treeview *tv = recordPtr;
+ int selop, i;
+ TreeItem *item, **items;
+
+ if (objc == 2) {
+ Tcl_Obj *result = Tcl_NewListObj(0,0);
+ for (item = tv->tree.root->children; item; item=NextPreorder(item)) {
+ if (item->state & TTK_STATE_SELECTED)
+ Tcl_ListObjAppendElement(NULL, result, ItemID(tv, item));
+ }
+ Tcl_SetObjResult(interp, result);
+ return TCL_OK;
+ }
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?add|remove|set|toggle items?");
+ return TCL_ERROR;
+ }
+
+ if (Tcl_GetIndexFromObj(interp, objv[2], selopStrings,
+ "selection operation", 0, &selop) != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+
+ items = GetItemListFromObj(interp, tv, objv[3]);
+ if (!items) {
+ return TCL_ERROR;
+ }
+
+ switch (selop)
+ {
+ case SELECTION_SET:
+ for (item=tv->tree.root; item; item=NextPreorder(item)) {
+ item->state &= ~TTK_STATE_SELECTED;
+ }
+ /*FALLTHRU*/
+ case SELECTION_ADD:
+ for (i=0; items[i]; ++i) {
+ items[i]->state |= TTK_STATE_SELECTED;
+ }
+ break;
+ case SELECTION_REMOVE:
+ for (i=0; items[i]; ++i) {
+ items[i]->state &= ~TTK_STATE_SELECTED;
+ }
+ break;
+ case SELECTION_TOGGLE:
+ for (i=0; items[i]; ++i) {
+ items[i]->state ^= TTK_STATE_SELECTED;
+ }
+ break;
+ }
+
+ ckfree((ClientData)items);
+ TtkSendVirtualEvent(tv->core.tkwin, "TreeviewSelect");
+ TtkRedisplayWidget(&tv->core);
+
+ return TCL_OK;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget commands -- tags and bindings.
+ */
+
+/* + $tv tag bind $tag ?$sequence ?$script??
+ */
+static int TreeviewTagBindCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ Ttk_TagTable tagTable = tv->tree.tagTable;
+ Tk_BindingTable bindingTable = tv->tree.bindingTable;
+ Ttk_Tag tag;
+
+ if (objc < 4 || objc > 6) {
+ Tcl_WrongNumArgs(interp, 3, objv, "tagName ?sequence? ?script?");
+ return TCL_ERROR;
+ }
+
+ tag = Ttk_GetTagFromObj(tagTable, objv[3]);
+ if (!tag) { return TCL_ERROR; }
+
+ if (objc == 4) { /* $tv tag bind $tag */
+ Tk_GetAllBindings(interp, bindingTable, tag);
+ } else if (objc == 5) { /* $tv tag bind $tag $sequence */
+ /* TODO: distinguish "no such binding" (OK) from "bad pattern" (ERROR)
+ */
+ const char *script = Tk_GetBinding(interp,
+ bindingTable, tag, Tcl_GetString(objv[4]));
+ if (script != NULL) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(script,-1));
+ }
+ } else if (objc == 6) { /* $tv tag bind $tag $sequence $script */
+ const char *sequence = Tcl_GetString(objv[4]);
+ const char *script = Tcl_GetString(objv[5]);
+
+ if (!*script) { /* Delete existing binding */
+ Tk_DeleteBinding(interp, bindingTable, tag, sequence);
+ } else {
+ unsigned long mask = Tk_CreateBinding(interp,
+ bindingTable, tag, sequence, script, 0);
+
+ /* Test mask to make sure event is supported:
+ */
+ if (mask & (~TreeviewBindEventMask)) {
+ Tk_DeleteBinding(interp, bindingTable, tag, sequence);
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "unsupported event ", sequence,
+ "\nonly key, button, motion, and virtual events supported",
+ NULL);
+ return TCL_ERROR;
+ }
+ }
+ }
+ return TCL_OK;
+}
+
+/* + $tv tag configure $tag ?-option ?value -option value...??
+ */
+static int TreeviewTagConfigureCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ Ttk_TagTable tagTable = tv->tree.tagTable;
+ Ttk_Tag tag;
+
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "tagName ?-option ?value ...??");
+ return TCL_ERROR;
+ }
+
+ tag = Ttk_GetTagFromObj(tagTable, objv[3]);
+
+ if (objc == 4) {
+ return Ttk_EnumerateTagOptions(interp, tagTable, tag);
+ } else if (objc == 5) {
+ Tcl_Obj *result = Ttk_TagOptionValue(interp, tagTable, tag, objv[4]);
+ if (result) {
+ Tcl_SetObjResult(interp, result);
+ return TCL_OK;
+ } /* else */
+ return TCL_ERROR;
+ }
+ /* else */
+ TtkRedisplayWidget(&tv->core);
+ return Ttk_ConfigureTag(interp, tagTable, tag, objc - 4, objv + 4);
+}
+
+/* + $tv tag has $tag ?$item?
+ */
+static int TreeviewTagHasCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+
+ if (objc == 4) { /* Return list of all items with tag */
+ Ttk_Tag tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]);
+ TreeItem *item = tv->tree.root;
+ Tcl_Obj *result = Tcl_NewListObj(0,0);
+
+ while (item) {
+ if (Ttk_TagSetContains(item->tagset, tag)) {
+ Tcl_ListObjAppendElement(NULL, result, ItemID(tv, item));
+ }
+ item = NextPreorder(item);
+ }
+
+ Tcl_SetObjResult(interp, result);
+ return TCL_OK;
+ } else if (objc == 5) { /* Test if item has specified tag */
+ Ttk_Tag tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]);
+ TreeItem *item = FindItem(interp, tv, objv[4]);
+ if (!item) {
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp,
+ Tcl_NewBooleanObj(Ttk_TagSetContains(item->tagset, tag)));
+ return TCL_OK;
+ } else {
+ Tcl_WrongNumArgs(interp, 3, objv, "tagName ?item?");
+ return TCL_ERROR;
+ }
+}
+
+/* + $tv tag names $tag
+ */
+static int TreeviewTagNamesCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, "");
+ return TCL_ERROR;
+ }
+
+ return Ttk_EnumerateTags(interp, tv->tree.tagTable);
+}
+
+/* + $tv tag add $tag $items
+ */
+static void AddTag(TreeItem *item, Ttk_Tag tag)
+{
+ if (Ttk_TagSetAdd(item->tagset, tag)) {
+ if (item->tagsObj) Tcl_DecrRefCount(item->tagsObj);
+ item->tagsObj = Ttk_NewTagSetObj(item->tagset);
+ Tcl_IncrRefCount(item->tagsObj);
+ }
+}
+
+static int TreeviewTagAddCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ Ttk_Tag tag;
+ TreeItem **items;
+ int i;
+
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "tagName items");
+ return TCL_ERROR;
+ }
+
+ tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]);
+ items = GetItemListFromObj(interp, tv, objv[4]);
+
+ if (!items) {
+ return TCL_ERROR;
+ }
+
+ for (i=0; items[i]; ++i) {
+ AddTag(items[i], tag);
+ }
+
+ return TCL_OK;
+}
+
+/* + $tv tag remove $tag ?$items?
+ */
+static void RemoveTag(TreeItem *item, Ttk_Tag tag)
+{
+ if (Ttk_TagSetRemove(item->tagset, tag)) {
+ if (item->tagsObj) Tcl_DecrRefCount(item->tagsObj);
+ item->tagsObj = Ttk_NewTagSetObj(item->tagset);
+ Tcl_IncrRefCount(item->tagsObj);
+ }
+}
+
+static int TreeviewTagRemoveCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ Treeview *tv = recordPtr;
+ Ttk_Tag tag;
+
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "tagName items");
+ return TCL_ERROR;
+ }
+
+ tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]);
+
+ if (objc == 5) {
+ TreeItem **items = GetItemListFromObj(interp, tv, objv[4]);
+ int i;
+
+ if (!items) {
+ return TCL_ERROR;
+ }
+ for (i=0; items[i]; ++i) {
+ RemoveTag(items[i], tag);
+ }
+ } else if (objc == 4) {
+ TreeItem *item = tv->tree.root;
+ while (item) {
+ RemoveTag(item, tag);
+ item=NextPreorder(item);
+ }
+ }
+ return TCL_OK;
+}
+
+static const Ttk_Ensemble TreeviewTagCommands[] = {
+ { "add", TreeviewTagAddCommand,0 },
+ { "bind", TreeviewTagBindCommand,0 },
+ { "configure", TreeviewTagConfigureCommand,0 },
+ { "has", TreeviewTagHasCommand,0 },
+ { "names", TreeviewTagNamesCommand,0 },
+ { "remove", TreeviewTagRemoveCommand,0 },
+ { 0,0,0 }
+};
+
+/*------------------------------------------------------------------------
+ * +++ Widget commands record.
+ */
+static const Ttk_Ensemble TreeviewCommands[] = {
+ { "bbox", TreeviewBBoxCommand,0 },
+ { "children", TreeviewChildrenCommand,0 },
+ { "cget", TtkWidgetCgetCommand,0 },
+ { "column", TreeviewColumnCommand,0 },
+ { "configure", TtkWidgetConfigureCommand,0 },
+ { "delete", TreeviewDeleteCommand,0 },
+ { "detach", TreeviewDetachCommand,0 },
+ { "drag", TreeviewDragCommand,0 },
+ { "exists", TreeviewExistsCommand,0 },
+ { "focus", TreeviewFocusCommand,0 },
+ { "heading", TreeviewHeadingCommand,0 },
+ { "identify", TreeviewIdentifyCommand,0 },
+ { "index", TreeviewIndexCommand,0 },
+ { "instate", TtkWidgetInstateCommand,0 },
+ { "insert", TreeviewInsertCommand,0 },
+ { "item", TreeviewItemCommand,0 },
+ { "move", TreeviewMoveCommand,0 },
+ { "next", TreeviewNextCommand,0 },
+ { "parent", TreeviewParentCommand,0 },
+ { "prev", TreeviewPrevCommand,0 },
+ { "see", TreeviewSeeCommand,0 },
+ { "selection" , TreeviewSelectionCommand,0 },
+ { "set", TreeviewSetCommand,0 },
+ { "state", TtkWidgetStateCommand,0 },
+ { "tag", 0,TreeviewTagCommands },
+ { "xview", TreeviewXViewCommand,0 },
+ { "yview", TreeviewYViewCommand,0 },
+ { 0,0,0 }
+};
+
+/*------------------------------------------------------------------------
+ * +++ Widget definition.
+ */
+
+static WidgetSpec TreeviewWidgetSpec = {
+ "Treeview", /* className */
+ sizeof(Treeview), /* recordSize */
+ TreeviewOptionSpecs, /* optionSpecs */
+ TreeviewCommands, /* subcommands */
+ TreeviewInitialize, /* initializeProc */
+ TreeviewCleanup, /* cleanupProc */
+ TreeviewConfigure, /* configureProc */
+ TtkNullPostConfigure, /* postConfigureProc */
+ TreeviewGetLayout, /* getLayoutProc */
+ TreeviewSize, /* sizeProc */
+ TreeviewDoLayout, /* layoutProc */
+ TreeviewDisplay /* displayProc */
+};
+
+/*------------------------------------------------------------------------
+ * +++ Layout specifications.
+ */
+
+TTK_BEGIN_LAYOUT_TABLE(LayoutTable)
+
+TTK_LAYOUT("Treeview",
+ TTK_GROUP("Treeview.field", TTK_FILL_BOTH|TTK_BORDER,
+ TTK_GROUP("Treeview.padding", TTK_FILL_BOTH,
+ TTK_NODE("Treeview.treearea", TTK_FILL_BOTH))))
+
+TTK_LAYOUT("Item",
+ TTK_GROUP("Treeitem.padding", TTK_FILL_BOTH,
+ TTK_NODE("Treeitem.indicator", TTK_PACK_LEFT)
+ TTK_NODE("Treeitem.image", TTK_PACK_LEFT)
+ TTK_GROUP("Treeitem.focus", TTK_PACK_LEFT,
+ TTK_NODE("Treeitem.text", TTK_PACK_LEFT))))
+
+TTK_LAYOUT("Cell",
+ TTK_GROUP("Treedata.padding", TTK_FILL_BOTH,
+ TTK_NODE("Treeitem.text", TTK_FILL_BOTH)))
+
+TTK_LAYOUT("Heading",
+ TTK_NODE("Treeheading.cell", TTK_FILL_BOTH)
+ TTK_GROUP("Treeheading.border", TTK_FILL_BOTH,
+ TTK_GROUP("Treeheading.padding", TTK_FILL_BOTH,
+ TTK_NODE("Treeheading.image", TTK_PACK_RIGHT)
+ TTK_NODE("Treeheading.text", TTK_FILL_X))))
+
+TTK_LAYOUT("Row",
+ TTK_NODE("Treeitem.row", TTK_FILL_BOTH))
+
+TTK_END_LAYOUT_TABLE
+
+/*------------------------------------------------------------------------
+ * +++ Tree indicator element.
+ */
+
+typedef struct {
+ Tcl_Obj *colorObj;
+ Tcl_Obj *sizeObj;
+ Tcl_Obj *marginsObj;
+} TreeitemIndicator;
+
+static Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = {
+ { "-foreground", TK_OPTION_COLOR,
+ Tk_Offset(TreeitemIndicator,colorObj), DEFAULT_FOREGROUND },
+ { "-indicatorsize", TK_OPTION_PIXELS,
+ Tk_Offset(TreeitemIndicator,sizeObj), "12" },
+ { "-indicatormargins", TK_OPTION_STRING,
+ Tk_Offset(TreeitemIndicator,marginsObj), "2 2 4 2" },
+ { NULL, 0, 0, NULL }
+};
+
+static void TreeitemIndicatorSize(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
+{
+ TreeitemIndicator *indicator = elementRecord;
+ Ttk_Padding margins;
+ int size = 0;
+
+ Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginsObj, &margins);
+ Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);
+
+ *widthPtr = size + Ttk_PaddingWidth(margins);
+ *heightPtr = size + Ttk_PaddingHeight(margins);
+}
+
+static void TreeitemIndicatorDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, Ttk_State state)
+{
+ TreeitemIndicator *indicator = elementRecord;
+ ArrowDirection direction =
+ (state & TTK_STATE_OPEN) ? ARROW_DOWN : ARROW_RIGHT;
+ Ttk_Padding margins;
+ XColor *borderColor = Tk_GetColorFromObj(tkwin, indicator->colorObj);
+ XGCValues gcvalues; GC gc; unsigned mask;
+
+ if (state & TTK_STATE_LEAF) /* don't draw anything */
+ return;
+
+ Ttk_GetPaddingFromObj(NULL,tkwin,indicator->marginsObj,&margins);
+ b = Ttk_PadBox(b, margins);
+
+ gcvalues.foreground = borderColor->pixel;
+ gcvalues.line_width = 1;
+ mask = GCForeground | GCLineWidth;
+ gc = Tk_GetGC(tkwin, mask, &gcvalues);
+
+ TtkDrawArrow(Tk_Display(tkwin), d, gc, b, direction);
+
+ Tk_FreeGC(Tk_Display(tkwin), gc);
+}
+
+static Ttk_ElementSpec TreeitemIndicatorElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(TreeitemIndicator),
+ TreeitemIndicatorOptions,
+ TreeitemIndicatorSize,
+ TreeitemIndicatorDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Row element.
+ */
+
+typedef struct {
+ Tcl_Obj *backgroundObj;
+ Tcl_Obj *rowNumberObj;
+} RowElement;
+
+static Ttk_ElementOptionSpec RowElementOptions[] = {
+ { "-background", TK_OPTION_COLOR,
+ Tk_Offset(RowElement,backgroundObj), DEFAULT_BACKGROUND },
+ { "-rownumber", TK_OPTION_INT,
+ Tk_Offset(RowElement,rowNumberObj), "0" },
+ { NULL, 0, 0, NULL }
+};
+
+static void RowElementDraw(
+ void *clientData, void *elementRecord, Tk_Window tkwin,
+ Drawable d, Ttk_Box b, Ttk_State state)
+{
+ RowElement *row = elementRecord;
+ XColor *color = Tk_GetColorFromObj(tkwin, row->backgroundObj);
+ GC gc = Tk_GCForColor(color, d);
+ XFillRectangle(Tk_Display(tkwin), d, gc,
+ b.x, b.y, b.width, b.height);
+}
+
+static Ttk_ElementSpec RowElementSpec = {
+ TK_STYLE_VERSION_2,
+ sizeof(RowElement),
+ RowElementOptions,
+ TtkNullElementSize,
+ RowElementDraw
+};
+
+/*------------------------------------------------------------------------
+ * +++ Initialisation.
+ */
+
+MODULE_SCOPE
+void TtkTreeview_Init(Tcl_Interp *interp)
+{
+ Ttk_Theme theme = Ttk_GetDefaultTheme(interp);
+
+ RegisterWidget(interp, "ttk::treeview", &TreeviewWidgetSpec);
+
+ Ttk_RegisterElement(interp, theme, "Treeitem.indicator",
+ &TreeitemIndicatorElementSpec, 0);
+ Ttk_RegisterElement(interp, theme, "Treeitem.row", &RowElementSpec, 0);
+ Ttk_RegisterElement(interp, theme, "Treeheading.cell", &RowElementSpec, 0);
+ Ttk_RegisterElement(interp, theme, "treearea", &ttkNullElementSpec, 0);
+
+ Ttk_RegisterLayouts(theme, LayoutTable);
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkWidget.c b/generic/ttk/ttkWidget.c
new file mode 100644
index 0000000..d5e0484
--- /dev/null
+++ b/generic/ttk/ttkWidget.c
@@ -0,0 +1,789 @@
+/*
+ * Copyright (c) 2003, Joe English
+ *
+ * Core widget utilities.
+ */
+
+#include <string.h>
+#include <tk.h>
+#include "ttkTheme.h"
+#include "ttkWidget.h"
+
+#ifdef MAC_OSX_TK
+#define TK_NO_DOUBLE_BUFFERING 1
+#endif
+
+/*------------------------------------------------------------------------
+ * +++ Internal helper routines.
+ */
+
+/* UpdateLayout --
+ * Call the widget's get-layout hook to recompute corePtr->layout.
+ * Returns TCL_OK if successful, returns TCL_ERROR and leaves
+ * the layout unchanged otherwise.
+ */
+static int UpdateLayout(Tcl_Interp *interp, WidgetCore *corePtr)
+{
+ Ttk_Theme themePtr = Ttk_GetCurrentTheme(interp);
+ Ttk_Layout newLayout =
+ corePtr->widgetSpec->getLayoutProc(interp, themePtr,corePtr);
+
+ if (newLayout) {
+ if (corePtr->layout) {
+ Ttk_FreeLayout(corePtr->layout);
+ }
+ corePtr->layout = newLayout;
+ return TCL_OK;
+ }
+ return TCL_ERROR;
+}
+
+/* SizeChanged --
+ * Call the widget's sizeProc to compute new requested size
+ * and pass it to the geometry manager.
+ */
+static void SizeChanged(WidgetCore *corePtr)
+{
+ int reqWidth = 1, reqHeight = 1;
+
+ if (corePtr->widgetSpec->sizeProc(corePtr,&reqWidth,&reqHeight)) {
+ Tk_GeometryRequest(corePtr->tkwin, reqWidth, reqHeight);
+ }
+}
+
+#ifndef TK_NO_DOUBLE_BUFFERING
+
+/* BeginDrawing --
+ * Returns a Drawable for drawing the widget contents.
+ * This is normally an off-screen Pixmap, copied to
+ * the window by EndDrawing().
+ */
+static Drawable BeginDrawing(Tk_Window tkwin)
+{
+ return Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin),
+ Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
+}
+
+/* EndDrawing --
+ * Copy the drawable contents to the screen and release resources.
+ */
+static void EndDrawing(Tk_Window tkwin, Drawable d)
+{
+ XGCValues gcValues;
+ GC gc;
+
+ gcValues.function = GXcopy;
+ gcValues.graphics_exposures = False;
+ gc = Tk_GetGC(tkwin, GCFunction|GCGraphicsExposures, &gcValues);
+
+ XCopyArea(Tk_Display(tkwin), d, Tk_WindowId(tkwin), gc,
+ 0, 0, (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin),
+ 0, 0);
+
+ Tk_FreePixmap(Tk_Display(tkwin), d);
+ Tk_FreeGC(Tk_Display(tkwin), gc);
+}
+#else
+/* No double-buffering: draw directly into the window. */
+static Drawable BeginDrawing(Tk_Window tkwin) { return Tk_WindowId(tkwin); }
+static void EndDrawing(Tk_Window tkwin, Drawable d) { }
+#endif
+
+/* DrawWidget --
+ * Redraw a widget. Called as an idle handler.
+ */
+static void DrawWidget(ClientData recordPtr)
+{
+ WidgetCore *corePtr = recordPtr;
+
+ corePtr->flags &= ~REDISPLAY_PENDING;
+ if (Tk_IsMapped(corePtr->tkwin)) {
+ Drawable d = BeginDrawing(corePtr->tkwin);
+ corePtr->widgetSpec->layoutProc(recordPtr);
+ corePtr->widgetSpec->displayProc(recordPtr, d);
+ EndDrawing(corePtr->tkwin, d);
+ }
+}
+
+/* TtkRedisplayWidget --
+ * Schedule redisplay as an idle handler.
+ */
+void TtkRedisplayWidget(WidgetCore *corePtr)
+{
+ if (corePtr->flags & WIDGET_DESTROYED) {
+ return;
+ }
+
+ if (!(corePtr->flags & REDISPLAY_PENDING)) {
+ Tcl_DoWhenIdle(DrawWidget, corePtr);
+ corePtr->flags |= REDISPLAY_PENDING;
+ }
+}
+
+/* TtkResizeWidget --
+ * Recompute widget size, schedule geometry propagation and redisplay.
+ */
+void TtkResizeWidget(WidgetCore *corePtr)
+{
+ if (corePtr->flags & WIDGET_DESTROYED) {
+ return;
+ }
+
+ SizeChanged(corePtr);
+ TtkRedisplayWidget(corePtr);
+}
+
+/* TtkWidgetChangeState --
+ * Set / clear the specified bits in the 'state' flag,
+ */
+void TtkWidgetChangeState(WidgetCore *corePtr,
+ unsigned int setBits, unsigned int clearBits)
+{
+ Ttk_State oldState = corePtr->state;
+ corePtr->state = (oldState & ~clearBits) | setBits;
+ if (corePtr->state ^ oldState) {
+ TtkRedisplayWidget(corePtr);
+ }
+}
+
+/* WidgetInstanceObjCmd --
+ * Widget instance command implementation.
+ */
+static int
+WidgetInstanceObjCmd(
+ ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ WidgetCore *corePtr = clientData;
+ const Ttk_Ensemble *commands = corePtr->widgetSpec->commands;
+ int status;
+
+ Tcl_Preserve(clientData);
+ status = Ttk_InvokeEnsemble(commands,1, clientData,interp,objc,objv);
+ Tcl_Release(clientData);
+
+ return status;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Widget destruction.
+ *
+ * A widget can be destroyed when the application explicitly
+ * destroys the window or one of its ancestors via [destroy]
+ * or Tk_DestroyWindow(); when the application deletes the widget
+ * instance command; when there is an error in the widget constructor;
+ * or when another application calls XDestroyWindow on the window ID.
+ *
+ * The window receives a <DestroyNotify> event in all cases,
+ * so we do the bulk of the cleanup there. See [#2207435] for
+ * further notes (esp. re: Tk_FreeConfigOptions).
+ *
+ * Widget code that reenters the interp should only do so
+ * when the widtget is Tcl_Preserve()d, and should check
+ * the WIDGET_DESTROYED flag bit upon return.
+ */
+
+/* WidgetInstanceObjCmdDeleted --
+ * Widget instance command deletion callback.
+ */
+static void
+WidgetInstanceObjCmdDeleted(ClientData clientData)
+{
+ WidgetCore *corePtr = clientData;
+ corePtr->widgetCmd = NULL;
+ if (corePtr->tkwin != NULL)
+ Tk_DestroyWindow(corePtr->tkwin);
+}
+
+/* FreeWidget --
+ * Final cleanup for widget; called via Tcl_EventuallyFree().
+ */
+static void
+FreeWidget(char *memPtr)
+{
+ ckfree(memPtr);
+}
+
+/* DestroyWidget --
+ * Main widget destructor; called from <DestroyNotify> event handler.
+ */
+static void
+DestroyWidget(WidgetCore *corePtr)
+{
+ corePtr->flags |= WIDGET_DESTROYED;
+
+ corePtr->widgetSpec->cleanupProc(corePtr);
+
+ Tk_FreeConfigOptions(
+ (ClientData)corePtr, corePtr->optionTable, corePtr->tkwin);
+
+ if (corePtr->layout) {
+ Ttk_FreeLayout(corePtr->layout);
+ }
+
+ if (corePtr->flags & REDISPLAY_PENDING) {
+ Tcl_CancelIdleCall(DrawWidget, corePtr);
+ }
+
+ corePtr->tkwin = NULL;
+ if (corePtr->widgetCmd) {
+ Tcl_Command cmd = corePtr->widgetCmd;
+ corePtr->widgetCmd = 0;
+ /* NB: this can reenter the interpreter via a command traces */
+ Tcl_DeleteCommandFromToken(corePtr->interp, cmd);
+ }
+ Tcl_EventuallyFree(corePtr, FreeWidget);
+}
+
+/*
+ * CoreEventProc --
+ * Event handler for basic events.
+ * Processes Expose, Configure, FocusIn/Out, and Destroy events.
+ * Also handles <<ThemeChanged>> virtual events.
+ *
+ * For Expose and Configure, simply schedule the widget for redisplay.
+ * For Destroy events, handle the cleanup process.
+ *
+ * For Focus events, set/clear the focus bit in the state field.
+ * It turns out this is impossible to do correctly in a binding script,
+ * because Tk filters out focus events with detail == NotifyInferior.
+ *
+ * For Deactivate/Activate pseudo-events, set/clear the background state
+ * flag.
+ */
+
+static const unsigned CoreEventMask
+ = ExposureMask
+ | StructureNotifyMask
+ | FocusChangeMask
+ | VirtualEventMask
+ | ActivateMask
+ | EnterWindowMask
+ | LeaveWindowMask
+ ;
+
+static void CoreEventProc(ClientData clientData, XEvent *eventPtr)
+{
+ WidgetCore *corePtr = clientData;
+
+ switch (eventPtr->type)
+ {
+ case ConfigureNotify :
+ TtkRedisplayWidget(corePtr);
+ break;
+ case Expose :
+ if (eventPtr->xexpose.count == 0) {
+ TtkRedisplayWidget(corePtr);
+ }
+ break;
+ case DestroyNotify :
+ Tk_DeleteEventHandler(
+ corePtr->tkwin, CoreEventMask,CoreEventProc,clientData);
+ DestroyWidget(corePtr);
+ break;
+ case FocusIn:
+ case FocusOut:
+ /* Don't process "virtual crossing" events */
+ if ( eventPtr->xfocus.detail == NotifyInferior
+ || eventPtr->xfocus.detail == NotifyAncestor
+ || eventPtr->xfocus.detail == NotifyNonlinear)
+ {
+ if (eventPtr->type == FocusIn)
+ corePtr->state |= TTK_STATE_FOCUS;
+ else
+ corePtr->state &= ~TTK_STATE_FOCUS;
+ TtkRedisplayWidget(corePtr);
+ }
+ break;
+ case ActivateNotify:
+ corePtr->state &= ~TTK_STATE_BACKGROUND;
+ TtkRedisplayWidget(corePtr);
+ break;
+ case DeactivateNotify:
+ corePtr->state |= TTK_STATE_BACKGROUND;
+ TtkRedisplayWidget(corePtr);
+ break;
+ case LeaveNotify:
+ corePtr->state &= ~TTK_STATE_HOVER;
+ TtkRedisplayWidget(corePtr);
+ break;
+ case EnterNotify:
+ corePtr->state |= TTK_STATE_HOVER;
+ TtkRedisplayWidget(corePtr);
+ break;
+ case VirtualEvent:
+ if (!strcmp("ThemeChanged", ((XVirtualEvent *)(eventPtr))->name)) {
+ (void)UpdateLayout(corePtr->interp, corePtr);
+ SizeChanged(corePtr);
+ TtkRedisplayWidget(corePtr);
+ }
+ default:
+ /* can't happen... */
+ break;
+ }
+}
+
+/*
+ * WidgetWorldChanged --
+ * Default Tk_ClassWorldChangedProc() for widgets.
+ * Invoked whenever fonts or other system resources are changed;
+ * recomputes geometry.
+ */
+static void WidgetWorldChanged(ClientData clientData)
+{
+ WidgetCore *corePtr = clientData;
+ SizeChanged(corePtr);
+ TtkRedisplayWidget(corePtr);
+}
+
+static Tk_ClassProcs widgetClassProcs = {
+ sizeof(Tk_ClassProcs), /* size */
+ WidgetWorldChanged, /* worldChangedProc */
+ NULL, /* createProc */
+ NULL /* modalProc */
+};
+
+/*
+ * TtkWidgetConstructorObjCmd --
+ * General-purpose widget constructor command implementation.
+ * ClientData is a WidgetSpec *.
+ */
+int TtkWidgetConstructorObjCmd(
+ ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ WidgetSpec *widgetSpec = clientData;
+ const char *className = widgetSpec->className;
+ Tk_OptionTable optionTable =
+ Tk_CreateOptionTable(interp, widgetSpec->optionSpecs);
+ Tk_Window tkwin;
+ void *recordPtr;
+ WidgetCore *corePtr;
+ Tk_SavedOptions savedOptions;
+ int i;
+
+ if (objc < 2 || objc % 2 == 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
+ return TCL_ERROR;
+ }
+
+ /* Check if a -class option has been specified.
+ * We have to do this before the InitOptions() call,
+ * since InitOptions() is affected by the widget class.
+ */
+ for (i = 2; i < objc; i += 2) {
+ if (!strcmp(Tcl_GetString(objv[i]), "-class")) {
+ className = Tcl_GetString(objv[i+1]);
+ break;
+ }
+ }
+
+ tkwin = Tk_CreateWindowFromPath(
+ interp, Tk_MainWindow(interp), Tcl_GetString(objv[1]), NULL);
+ if (tkwin == NULL)
+ return TCL_ERROR;
+
+ /*
+ * Allocate and initialize the widget record.
+ */
+ recordPtr = ckalloc(widgetSpec->recordSize);
+ memset(recordPtr, 0, widgetSpec->recordSize);
+ corePtr = recordPtr;
+
+ corePtr->tkwin = tkwin;
+ corePtr->interp = interp;
+ corePtr->widgetSpec = widgetSpec;
+ corePtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(tkwin),
+ WidgetInstanceObjCmd, recordPtr, WidgetInstanceObjCmdDeleted);
+ corePtr->optionTable = optionTable;
+ corePtr->layout = NULL;
+ corePtr->flags = 0;
+ corePtr->state = 0;
+
+ Tk_SetClass(tkwin, className);
+ Tk_SetClassProcs(tkwin, &widgetClassProcs, recordPtr);
+ Tk_SetWindowBackgroundPixmap(tkwin, ParentRelative);
+
+ widgetSpec->initializeProc(interp, recordPtr);
+
+ Tk_CreateEventHandler(tkwin, CoreEventMask, CoreEventProc, recordPtr);
+
+ /*
+ * Initial configuration.
+ */
+
+ Tcl_Preserve(corePtr);
+ if (Tk_InitOptions(interp, recordPtr, optionTable, tkwin) != TCL_OK) {
+ goto error;
+ }
+
+ if (Tk_SetOptions(interp, recordPtr, optionTable,
+ objc - 2, objv + 2, tkwin, &savedOptions, NULL) != TCL_OK) {
+ Tk_RestoreSavedOptions(&savedOptions);
+ goto error;
+ } else {
+ Tk_FreeSavedOptions(&savedOptions);
+ }
+ if (widgetSpec->configureProc(interp, recordPtr, ~0) != TCL_OK)
+ goto error;
+ if (widgetSpec->postConfigureProc(interp, recordPtr, ~0) != TCL_OK)
+ goto error;
+
+ if (WidgetDestroyed(corePtr))
+ goto error;
+
+ Tcl_Release(corePtr);
+
+ SizeChanged(corePtr);
+ Tk_MakeWindowExist(tkwin);
+
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(tkwin), -1));
+ return TCL_OK;
+
+error:
+ if (WidgetDestroyed(corePtr)) {
+ Tcl_SetResult(interp, "Widget has been destroyed", TCL_STATIC);
+ } else {
+ Tk_DestroyWindow(tkwin);
+ }
+ Tcl_Release(corePtr);
+ return TCL_ERROR;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Default implementations for widget hook procedures.
+ */
+
+/* TtkWidgetGetLayout --
+ * Default getLayoutProc.
+ * Looks up the layout based on the -style resource (if specified),
+ * otherwise use the widget class.
+ */
+Ttk_Layout TtkWidgetGetLayout(
+ Tcl_Interp *interp, Ttk_Theme themePtr, void *recordPtr)
+{
+ WidgetCore *corePtr = recordPtr;
+ const char *styleName = 0;
+
+ if (corePtr->styleObj)
+ styleName = Tcl_GetString(corePtr->styleObj);
+
+ if (!styleName || *styleName == '\0')
+ styleName = corePtr->widgetSpec->className;
+
+ return Ttk_CreateLayout(interp, themePtr, styleName,
+ recordPtr, corePtr->optionTable, corePtr->tkwin);
+}
+
+/*
+ * TtkWidgetGetOrientedLayout --
+ * Helper routine. Same as TtkWidgetGetLayout, but prefixes
+ * "Horizontal." or "Vertical." to the style name, depending
+ * on the value of the 'orient' option.
+ */
+Ttk_Layout TtkWidgetGetOrientedLayout(
+ Tcl_Interp *interp, Ttk_Theme themePtr, void *recordPtr, Tcl_Obj *orientObj)
+{
+ WidgetCore *corePtr = recordPtr;
+ const char *baseStyleName = 0;
+ Tcl_DString styleName;
+ int orient = TTK_ORIENT_HORIZONTAL;
+ Ttk_Layout layout;
+
+ Tcl_DStringInit(&styleName);
+
+ /* Prefix:
+ */
+ Ttk_GetOrientFromObj(NULL, orientObj, &orient);
+ if (orient == TTK_ORIENT_HORIZONTAL)
+ Tcl_DStringAppend(&styleName, "Horizontal.", -1);
+ else
+ Tcl_DStringAppend(&styleName, "Vertical.", -1);
+
+ /* Add base style name:
+ */
+ if (corePtr->styleObj)
+ baseStyleName = Tcl_GetString(corePtr->styleObj);
+ if (!baseStyleName || *baseStyleName == '\0')
+ baseStyleName = corePtr->widgetSpec->className;
+
+ Tcl_DStringAppend(&styleName, baseStyleName, -1);
+
+ /* Create layout:
+ */
+ layout= Ttk_CreateLayout(interp, themePtr, Tcl_DStringValue(&styleName),
+ recordPtr, corePtr->optionTable, corePtr->tkwin);
+
+ Tcl_DStringFree(&styleName);
+
+ return layout;
+}
+
+/* TtkNullInitialize --
+ * Default widget initializeProc (no-op)
+ */
+void TtkNullInitialize(Tcl_Interp *interp, void *recordPtr)
+{
+}
+
+/* TtkNullPostConfigure --
+ * Default widget postConfigureProc (no-op)
+ */
+int TtkNullPostConfigure(Tcl_Interp *interp, void *clientData, int mask)
+{
+ return TCL_OK;
+}
+
+/* TtkCoreConfigure --
+ * Default widget configureProc.
+ * Handles -style option.
+ */
+int TtkCoreConfigure(Tcl_Interp *interp, void *clientData, int mask)
+{
+ WidgetCore *corePtr = clientData;
+ int status = TCL_OK;
+
+ if (mask & STYLE_CHANGED) {
+ status = UpdateLayout(interp, corePtr);
+ }
+
+ return status;
+}
+
+/* TtkNullCleanup --
+ * Default widget cleanupProc (no-op)
+ */
+void TtkNullCleanup(void *recordPtr)
+{
+ return;
+}
+
+/* TtkWidgetDoLayout --
+ * Default widget layoutProc.
+ */
+void TtkWidgetDoLayout(void *clientData)
+{
+ WidgetCore *corePtr = clientData;
+ Ttk_PlaceLayout(corePtr->layout,corePtr->state,Ttk_WinBox(corePtr->tkwin));
+}
+
+/* TtkWidgetDisplay --
+ * Default widget displayProc.
+ */
+void TtkWidgetDisplay(void *recordPtr, Drawable d)
+{
+ WidgetCore *corePtr = recordPtr;
+ Ttk_DrawLayout(corePtr->layout, corePtr->state, d);
+}
+
+/* TtkWidgetSize --
+ * Default widget sizeProc()
+ */
+int TtkWidgetSize(void *recordPtr, int *widthPtr, int *heightPtr)
+{
+ WidgetCore *corePtr = recordPtr;
+ Ttk_LayoutSize(corePtr->layout, corePtr->state, widthPtr, heightPtr);
+ return 1;
+}
+
+/*------------------------------------------------------------------------
+ * +++ Default implementations for widget subcommands.
+ */
+
+/* $w cget -option
+ */
+int TtkWidgetCgetCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ WidgetCore *corePtr = recordPtr;
+ Tcl_Obj *result;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option");
+ return TCL_ERROR;
+ }
+ result = Tk_GetOptionValue(interp, recordPtr,
+ corePtr->optionTable, objv[2], corePtr->tkwin);
+ if (result == NULL)
+ return TCL_ERROR;
+ Tcl_SetObjResult(interp, result);
+ return TCL_OK;
+}
+
+/* $w configure ?-option ?value ....??
+ */
+int TtkWidgetConfigureCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ WidgetCore *corePtr = recordPtr;
+ Tcl_Obj *result;
+
+ if (objc == 2) {
+ result = Tk_GetOptionInfo(interp, recordPtr,
+ corePtr->optionTable, NULL, corePtr->tkwin);
+ } else if (objc == 3) {
+ result = Tk_GetOptionInfo(interp, recordPtr,
+ corePtr->optionTable, objv[2], corePtr->tkwin);
+ } else {
+ Tk_SavedOptions savedOptions;
+ int status;
+ int mask = 0;
+
+ status = Tk_SetOptions(interp, recordPtr,
+ corePtr->optionTable, objc - 2, objv + 2,
+ corePtr->tkwin, &savedOptions, &mask);
+ if (status != TCL_OK)
+ return status;
+
+ if (mask & READONLY_OPTION) {
+ Tcl_SetResult(interp,
+ "Attempt to change read-only option", TCL_STATIC);
+ Tk_RestoreSavedOptions(&savedOptions);
+ return TCL_ERROR;
+ }
+
+ status = corePtr->widgetSpec->configureProc(interp, recordPtr, mask);
+ if (status != TCL_OK) {
+ Tk_RestoreSavedOptions(&savedOptions);
+ return status;
+ }
+ Tk_FreeSavedOptions(&savedOptions);
+
+ status = corePtr->widgetSpec->postConfigureProc(interp,recordPtr,mask);
+ if (WidgetDestroyed(corePtr)) {
+ Tcl_SetResult(interp, "Widget has been destroyed", TCL_STATIC);
+ status = TCL_ERROR;
+ }
+ if (status != TCL_OK) {
+ return status;
+ }
+
+ if (mask & (STYLE_CHANGED | GEOMETRY_CHANGED)) {
+ SizeChanged(corePtr);
+ }
+
+ TtkRedisplayWidget(corePtr);
+ result = Tcl_NewObj();
+ }
+
+ if (result == 0) {
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, result);
+ return TCL_OK;
+}
+
+/* $w state ? $stateSpec ?
+ *
+ * If $stateSpec is specified, modify the widget state accordingly,
+ * return a new stateSpec representing the changed bits.
+ *
+ * Otherwise, return a statespec matching all the currently-set bits.
+ */
+
+int TtkWidgetStateCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ WidgetCore *corePtr = recordPtr;
+ Ttk_StateSpec spec;
+ int status;
+ Ttk_State oldState, changed;
+
+ if (objc == 2) {
+ Tcl_SetObjResult(interp,
+ Ttk_NewStateSpecObj(corePtr->state, 0ul));
+ return TCL_OK;
+ }
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "state-spec");
+ return TCL_ERROR;
+ }
+ status = Ttk_GetStateSpecFromObj(interp, objv[2], &spec);
+ if (status != TCL_OK)
+ return status;
+
+ oldState = corePtr->state;
+ corePtr->state = Ttk_ModifyState(corePtr->state, &spec);
+ changed = corePtr->state ^ oldState;
+
+ TtkRedisplayWidget(corePtr);
+
+ Tcl_SetObjResult(interp,
+ Ttk_NewStateSpecObj(oldState & changed, ~oldState & changed));
+ return status;
+}
+
+/* $w instate $stateSpec ?$script?
+ *
+ * Tests if widget state matches $stateSpec.
+ * If $script is specified, execute script if state matches.
+ * Otherwise, return true/false
+ */
+
+int TtkWidgetInstateCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ WidgetCore *corePtr = recordPtr;
+ Ttk_State state = corePtr->state;
+ Ttk_StateSpec spec;
+ int status = TCL_OK;
+
+ if (objc < 3 || objc > 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "state-spec ?script?");
+ return TCL_ERROR;
+ }
+ status = Ttk_GetStateSpecFromObj(interp, objv[2], &spec);
+ if (status != TCL_OK)
+ return status;
+
+ if (objc == 3) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewBooleanObj(Ttk_StateMatches(state,&spec)));
+ } else if (objc == 4) {
+ if (Ttk_StateMatches(state,&spec)) {
+ status = Tcl_EvalObjEx(interp, objv[3], 0);
+ }
+ }
+ return status;
+}
+
+/* $w identify $x $y
+ * $w identify element $x $y
+ * Returns: name of element at $x, $y
+ */
+int TtkWidgetIdentifyCommand(
+ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+{
+ WidgetCore *corePtr = recordPtr;
+ Ttk_Element element;
+ static const char *whatTable[] = { "element", NULL };
+ int x, y, what;
+
+ if (objc < 4 || objc > 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?what? x y");
+ return TCL_ERROR;
+ }
+ if (objc == 5) {
+ /* $w identify element $x $y */
+ if (Tcl_GetIndexFromObj(interp,objv[2],whatTable,"option",0,&what)
+ != TCL_OK)
+ {
+ return TCL_ERROR;
+ }
+ }
+
+ if ( Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK
+ || Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK
+ ) {
+ return TCL_ERROR;
+ }
+
+ element = Ttk_IdentifyElement(corePtr->layout, x, y);
+ if (element) {
+ const char *elementName = Ttk_ElementName(element);
+ Tcl_SetObjResult(interp,Tcl_NewStringObj(elementName,-1));
+ }
+
+ return TCL_OK;
+}
+
+/*EOF*/
diff --git a/generic/ttk/ttkWidget.h b/generic/ttk/ttkWidget.h
new file mode 100644
index 0000000..9e9ab69
--- /dev/null
+++ b/generic/ttk/ttkWidget.h
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2003, Joe English
+ * Helper routines for widget implementations.
+ */
+
+#ifndef _TTKWIDGET
+#define _TTKWIDGET
+
+/*
+ * State flags for 'flags' field.
+ */
+#define WIDGET_DESTROYED 0x0001
+#define REDISPLAY_PENDING 0x0002 /* scheduled call to RedisplayWidget */
+#define CURSOR_ON 0x0020 /* See TtkBlinkCursor() */
+#define WIDGET_USER_FLAG 0x0100 /* 0x0100 - 0x8000 for user flags */
+
+/*
+ * Bit fields for OptionSpec 'mask' field:
+ */
+#define READONLY_OPTION 0x1
+#define STYLE_CHANGED 0x2
+#define GEOMETRY_CHANGED 0x4
+
+/*
+ * Core widget elements
+ */
+typedef struct WidgetSpec_ WidgetSpec; /* Forward */
+
+typedef struct
+{
+ Tk_Window tkwin; /* Window associated with widget */
+ Tcl_Interp *interp; /* Interpreter associated with widget. */
+ WidgetSpec *widgetSpec; /* Widget class hooks */
+ Tcl_Command widgetCmd; /* Token for widget command. */
+ Tk_OptionTable optionTable; /* Option table */
+ Ttk_Layout layout; /* Widget layout */
+
+ /*
+ * Storage for resources:
+ */
+ Tcl_Obj *takeFocusPtr; /* Storage for -takefocus option */
+ Tcl_Obj *cursorObj; /* Storage for -cursor option */
+ Tcl_Obj *styleObj; /* Name of currently-applied style */
+ Tcl_Obj *classObj; /* Class name (readonly option) */
+
+ Ttk_State state; /* Current widget state */
+ unsigned int flags; /* internal flags, see above */
+
+} WidgetCore;
+
+/*
+ * Widget specifications:
+ */
+struct WidgetSpec_
+{
+ const char *className; /* Widget class name */
+ size_t recordSize; /* #bytes in widget record */
+ const Tk_OptionSpec *optionSpecs; /* Option specifications */
+ const Ttk_Ensemble *commands; /* Widget instance subcommands */
+
+ /*
+ * Hooks:
+ */
+ void (*initializeProc)(Tcl_Interp *, void *recordPtr);
+ void (*cleanupProc)(void *recordPtr);
+ int (*configureProc)(Tcl_Interp *, void *recordPtr, int flags);
+ int (*postConfigureProc)(Tcl_Interp *, void *recordPtr, int flags);
+ Ttk_Layout (*getLayoutProc)(Tcl_Interp *,Ttk_Theme, void *recordPtr);
+ int (*sizeProc)(void *recordPtr, int *widthPtr, int *heightPtr);
+ void (*layoutProc)(void *recordPtr);
+ void (*displayProc)(void *recordPtr, Drawable d);
+};
+
+/*
+ * Common factors for widget implementations:
+ */
+MODULE_SCOPE void TtkNullInitialize(Tcl_Interp *, void *);
+MODULE_SCOPE int TtkNullPostConfigure(Tcl_Interp *, void *, int);
+MODULE_SCOPE void TtkNullCleanup(void *recordPtr);
+MODULE_SCOPE Ttk_Layout TtkWidgetGetLayout(
+ Tcl_Interp *, Ttk_Theme, void *recordPtr);
+MODULE_SCOPE Ttk_Layout TtkWidgetGetOrientedLayout(
+ Tcl_Interp *, Ttk_Theme, void *recordPtr, Tcl_Obj *orientObj);
+MODULE_SCOPE int TtkWidgetSize(void *recordPtr, int *w, int *h);
+MODULE_SCOPE void TtkWidgetDoLayout(void *recordPtr);
+MODULE_SCOPE void TtkWidgetDisplay(void *recordPtr, Drawable);
+
+MODULE_SCOPE int TtkCoreConfigure(Tcl_Interp*, void *, int mask);
+
+/* Common widget commands:
+ */
+MODULE_SCOPE int TtkWidgetConfigureCommand(
+ void *,Tcl_Interp *, int, Tcl_Obj*const[]);
+MODULE_SCOPE int TtkWidgetCgetCommand(
+ void *,Tcl_Interp *, int, Tcl_Obj*const[]);
+MODULE_SCOPE int TtkWidgetInstateCommand(
+ void *,Tcl_Interp *, int, Tcl_Obj*const[]);
+MODULE_SCOPE int TtkWidgetStateCommand(
+ void *,Tcl_Interp *, int, Tcl_Obj*const[]);
+MODULE_SCOPE int TtkWidgetIdentifyCommand(
+ void *,Tcl_Interp *, int, Tcl_Obj*const[]);
+
+/* Widget constructor:
+ */
+MODULE_SCOPE int TtkWidgetConstructorObjCmd(
+ ClientData, Tcl_Interp*, int, Tcl_Obj*const[]);
+
+#define RegisterWidget(interp, name, specPtr) \
+ Tcl_CreateObjCommand(interp, name, \
+ TtkWidgetConstructorObjCmd, (ClientData)specPtr,NULL)
+
+/* WIDGET_TAKEFOCUS_TRUE --
+ * WIDGET_TAKEFOCUS_FALSE --
+ * Add one or the other of these to each OptionSpecs table
+ * to indicate whether the widget should take focus
+ * during keyboard traversal.
+ */
+#define WIDGET_TAKEFOCUS_TRUE \
+ {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", \
+ "ttk::takefocus", Tk_Offset(WidgetCore, takeFocusPtr), -1, 0,0,0 }
+#define WIDGET_TAKEFOCUS_FALSE \
+ {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", \
+ "", Tk_Offset(WidgetCore, takeFocusPtr), -1, 0,0,0 }
+
+/* WIDGET_INHERIT_OPTIONS(baseOptionSpecs) --
+ * Add this at the end of an OptionSpecs table to inherit
+ * the options from 'baseOptionSpecs'.
+ */
+#define WIDGET_INHERIT_OPTIONS(baseOptionSpecs) \
+ {TK_OPTION_END, 0,0,0, NULL, -1,-1, 0, (ClientData)baseOptionSpecs, 0}
+
+/* All widgets should inherit from ttkCoreOptionSpecs[].
+ */
+MODULE_SCOPE Tk_OptionSpec ttkCoreOptionSpecs[];
+
+/*
+ * Useful routines for use inside widget implementations:
+ */
+/* extern int WidgetDestroyed(WidgetCore *); */
+#define WidgetDestroyed(corePtr) ((corePtr)->flags & WIDGET_DESTROYED)
+
+MODULE_SCOPE void TtkWidgetChangeState(WidgetCore *,
+ unsigned int setBits, unsigned int clearBits);
+
+MODULE_SCOPE void TtkRedisplayWidget(WidgetCore *);
+MODULE_SCOPE void TtkResizeWidget(WidgetCore *);
+
+MODULE_SCOPE void TtkTrackElementState(WidgetCore *);
+MODULE_SCOPE void TtkBlinkCursor(WidgetCore *);
+
+/*
+ * -state option values (compatibility)
+ */
+MODULE_SCOPE void TtkCheckStateOption(WidgetCore *, Tcl_Obj *);
+
+/*
+ * Variable traces:
+ */
+typedef void (*Ttk_TraceProc)(void *recordPtr, const char *value);
+typedef struct TtkTraceHandle_ Ttk_TraceHandle;
+
+MODULE_SCOPE Ttk_TraceHandle *Ttk_TraceVariable(
+ Tcl_Interp*, Tcl_Obj *varnameObj, Ttk_TraceProc callback, void *clientData);
+MODULE_SCOPE void Ttk_UntraceVariable(Ttk_TraceHandle *);
+MODULE_SCOPE int Ttk_FireTrace(Ttk_TraceHandle *);
+
+/*
+ * Virtual events:
+ */
+MODULE_SCOPE void TtkSendVirtualEvent(Tk_Window tgtWin, const char *eventName);
+
+/*
+ * Helper routines for data accessor commands:
+ */
+MODULE_SCOPE int TtkEnumerateOptions(
+ Tcl_Interp *, void *, const Tk_OptionSpec *, Tk_OptionTable, Tk_Window);
+MODULE_SCOPE int TtkGetOptionValue(
+ Tcl_Interp *, void *, Tcl_Obj *optName, Tk_OptionTable, Tk_Window);
+
+/*
+ * Helper routines for scrolling widgets (see scroll.c).
+ */
+typedef struct {
+ int first; /* First visible item */
+ int last; /* Last visible item */
+ int total; /* Total #items */
+ char *scrollCmd; /* Widget option */
+} Scrollable;
+
+typedef struct ScrollHandleRec *ScrollHandle;
+
+MODULE_SCOPE ScrollHandle TtkCreateScrollHandle(WidgetCore *, Scrollable *);
+MODULE_SCOPE void TtkFreeScrollHandle(ScrollHandle);
+
+MODULE_SCOPE int TtkScrollviewCommand(
+ Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], ScrollHandle);
+
+MODULE_SCOPE void TtkScrollTo(ScrollHandle, int newFirst);
+MODULE_SCOPE void TtkScrolled(ScrollHandle, int first, int last, int total);
+MODULE_SCOPE void TtkScrollbarUpdateRequired(ScrollHandle);
+
+/*
+ * Tag sets (work in progress, half-baked)
+ */
+
+typedef struct TtkTag *Ttk_Tag;
+typedef struct TtkTagTable *Ttk_TagTable;
+typedef struct TtkTagSet { /* TODO: make opaque */
+ Ttk_Tag *tags;
+ int nTags;
+} *Ttk_TagSet;
+
+MODULE_SCOPE Ttk_TagTable Ttk_CreateTagTable(
+ Tcl_Interp *, Tk_Window tkwin, Tk_OptionSpec[], int recordSize);
+MODULE_SCOPE void Ttk_DeleteTagTable(Ttk_TagTable);
+
+MODULE_SCOPE Ttk_Tag Ttk_GetTag(Ttk_TagTable, const char *tagName);
+MODULE_SCOPE Ttk_Tag Ttk_GetTagFromObj(Ttk_TagTable, Tcl_Obj *);
+
+MODULE_SCOPE Tcl_Obj *Ttk_TagOptionValue(
+ Tcl_Interp *, Ttk_TagTable, Ttk_Tag, Tcl_Obj *optionName);
+
+MODULE_SCOPE int Ttk_EnumerateTagOptions(
+ Tcl_Interp *, Ttk_TagTable, Ttk_Tag);
+
+MODULE_SCOPE int Ttk_EnumerateTags(Tcl_Interp *, Ttk_TagTable);
+
+MODULE_SCOPE int Ttk_ConfigureTag(
+ Tcl_Interp *interp, Ttk_TagTable tagTable, Ttk_Tag tag,
+ int objc, Tcl_Obj *const objv[]);
+
+MODULE_SCOPE Ttk_TagSet Ttk_GetTagSetFromObj(
+ Tcl_Interp *interp, Ttk_TagTable, Tcl_Obj *objPtr);
+MODULE_SCOPE Tcl_Obj *Ttk_NewTagSetObj(Ttk_TagSet);
+
+MODULE_SCOPE void Ttk_FreeTagSet(Ttk_TagSet);
+
+MODULE_SCOPE int Ttk_TagSetContains(Ttk_TagSet, Ttk_Tag tag);
+MODULE_SCOPE int Ttk_TagSetAdd(Ttk_TagSet, Ttk_Tag tag);
+MODULE_SCOPE int Ttk_TagSetRemove(Ttk_TagSet, Ttk_Tag tag);
+
+MODULE_SCOPE void Ttk_TagSetValues(Ttk_TagTable, Ttk_TagSet, void *record);
+MODULE_SCOPE void Ttk_TagSetApplyStyle(Ttk_TagTable,Ttk_Style,Ttk_State,void*);
+
+/*
+ * String tables for widget resource specifications:
+ */
+
+MODULE_SCOPE const char *ttkOrientStrings[];
+MODULE_SCOPE const char *ttkCompoundStrings[];
+MODULE_SCOPE const char *ttkDefaultStrings[];
+
+/*
+ * ... other option types...
+ */
+MODULE_SCOPE int TtkGetLabelAnchorFromObj(
+ Tcl_Interp*, Tcl_Obj*, Ttk_PositionSpec *);
+
+/*
+ * Platform-specific initialization.
+ */
+
+#if defined(__WIN32__)
+#define Ttk_PlatformInit Ttk_WinPlatformInit
+MODULE_SCOPE int Ttk_PlatformInit(Tcl_Interp *);
+#elif defined(MAC_OSX_TK)
+#define Ttk_PlatformInit Ttk_MacOSXPlatformInit
+MODULE_SCOPE int Ttk_PlatformInit(Tcl_Interp *);
+#else
+#define Ttk_PlatformInit(interp) /* TTK_X11PlatformInit() */
+#endif
+
+#endif /* _TTKWIDGET */